sisl icon indicating copy to clipboard operation
sisl copied to clipboard

sanitize_orbs with categories

Open zerothi opened this issue 2 years ago • 14 comments

I didn't know it existed :sweat_smile:. Do you think it could make sense to have orbital categories as well? Basically I would like to get orbital indices using orbital properties like quantum numbers

Originally posted by @pfebrer in https://github.com/zerothi/sisl/issues/446#issuecomment-1061808397

zerothi avatar Mar 08 '22 20:03 zerothi

I agree. However, we should probably make sanitize_orbs into a 2 argument function atoms, orbitals since one may wish to subset not only based on orbitals?

Or perhaps orbitals, atoms=None? This would allow one to use it seamlessly everywhere? What this work?

zerothi avatar Mar 08 '22 20:03 zerothi

Hmm I guess if orbitals accepts categories, there would already be a OrbitalAtoms category or something like that which would be used with the atoms keyword. So you should be able to filter by atoms already with that. There is no simple way to document the coupling between two arguments, so I think a single orbitals argument that accepts categories should be less confusing.

pfebrer avatar Mar 08 '22 22:03 pfebrer

But consider you want only s orbitals on H atoms, this would require a filtering of the orbital list after getting all of them, I don't think it would make sense that orbitals argument also selects atoms.

zerothi avatar Mar 09 '22 05:03 zerothi

If you have an atoms argument, would you accept orbital indices in orbitals? What would these indices represent? I.e. would you first do a geometry.sub(atoms) and then get the orbitals, in which case indices would have changed?

pfebrer avatar Mar 09 '22 09:03 pfebrer

I would assume that atoms is a pre-filter for where you would search atoms for the orbitals. So yes, something like that.

zerothi avatar Mar 09 '22 09:03 zerothi

It is because i would have a hard time creating categories for orbitals that actually filter atoms? Right...

zerothi avatar Mar 09 '22 09:03 zerothi

@pfebrer what do you think here?

zerothi avatar Mar 14 '22 08:03 zerothi

Hmm I'm not sure I understand the issues completely. I still don't understand the advantages of having atoms as a prefilter instead of just having an OrbitalCategory that can filter by atoms. If a category's categorize method gets orbitals one by one, then it's hard to create the atom filter. But if it just gets the geometry (as you were proposing in the last discussions I believe), it's quite easy.

pfebrer avatar Mar 14 '22 15:03 pfebrer

Hmm I'm not sure I understand the issues completely. I still don't understand the advantages of having atoms as a prefilter instead of just having an OrbitalCategory that can filter by atoms. If a category's categorize method gets orbitals one by one, then it's hard to create the atom filter. But if it just gets the geometry (as you were proposing in the last discussions I believe), it's quite easy.

It just seems weird to me to duplicate AtomsCategory for orbital filtering? How would you do a category that first chooses C then pz?

zerothi avatar Mar 14 '22 16:03 zerothi

I think there would just be an OrbitalCategory called OrbitalAtoms, which accepts the atoms argument and on categorize just sanitizes it with Geometry._sanitize_atoms. Then you could combine this one with another category (e.g. to get the pz orbitals) as you usually combine categories.

This basically means that if you want certain atoms AND pz you would do something like:

method_with_orbitals_as_first_argument({"atoms": whatever, "l": 1, "m": 0}, ...)

which is quite similar to what you would do if atoms was an argument. But additionally it leaves room for much more flexibility to combine the OrbitalAtoms category however you want.

pfebrer avatar Mar 14 '22 16:03 pfebrer

But the internal algorithm will the need to distinguish the two arguments... And will your method enable all variants of AtomsCategory... Hmm perhaps, I need to relook at the code!

zerothi avatar Mar 14 '22 16:03 zerothi

But the internal algorithm will the need to distinguish the two arguments...

No, why? Just as you can do atoms={"fx": (0, 0.5)} because there's an AtomCategory called AtomFx, you should be able to do orbitals={"atoms": {"fx": (0, 0.5)}} because there is an OrbitalCategory called OrbitalAtoms.

This category would look something like this:

class OrbitalAtoms(OrbitalCategory):
    def __init__(self, atoms):
        self._atoms = atoms

    def categorize(self, geometry):
        atoms = geometry._sanitize_atoms(self._atoms)

        categorized = np.full(geometry.no, NullCategory)
        orb_indices = # Somehow get the orbital indices corresponding to the atoms
        categorized[orb_indices] = self
        
        return categorized

which would allow atoms to be not only categories but whatever _sanitize_atoms accepts.

pfebrer avatar Mar 15 '22 08:03 pfebrer

Ok, I agree. It seems like a good idea, in this regard the opposite might also be interesting, an AtomOrbitals category ;)

zerothi avatar Mar 27 '22 10:03 zerothi

It would be nice indeed, well played hahah.

These two would probably ease some operations, because I've had some trouble trying to relate orbitals with atoms in my code.

pfebrer avatar Mar 27 '22 11:03 pfebrer