Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging Atom/Orbital etc. #775

Open
zerothi opened this issue May 22, 2024 · 1 comment
Open

Merging Atom/Orbital etc. #775

zerothi opened this issue May 22, 2024 · 1 comment

Comments

@zerothi
Copy link
Owner

zerothi commented May 22, 2024

Describe the feature
It would be nice if one could deterministically merge two atoms/orbitals etc. in a consistent way.
The usecase would be when a users has a simple geometry, but wants to read in from other sources which contains more information (but not necessarily everything).

The difficult thing here is the orbitals, should one be able to merge an Orbital and a AtomicOrbital, and how to select these things.

However, having this centralized in the objects would make these things much simpler.

@zerothi
Copy link
Owner Author

zerothi commented May 22, 2024

For orbital:

    def merge(self, other) -> Orbital:
        """ Merges two orbitals into one, with a preference of `self` """
        cls = self.__class__
        s = self.__getstate__()
        o = other.__getstate__()

        def inst_merge(typ, op):
            for k, v in s.items():
                if isinstance(v, typ):
                    s[k] = op(v, o[k])
        def key_merge(key, op):
            for k, v in s.items():
                if k == key:
                    s[k] = op(v, o[k])
        
        if isinstance(other, cls):
            inst_merge(float, max)
            # tag is defined for this orbital, no change
            key_merge("tag", lambda s, o: v if v else o)
            return cls(**s)

for atom

    def merge(self, other: Atom) -> Atom:
        """Merges two atoms into a single one, the calling atom will have precedence

        When merging there will be a couple of rules that will apply:

        1. When in doubt, the calling atom will have precedence.
        2. If the two atoms have the same `Z` value, they can be merged,
           otherwise, `self` will be returned *as-is*.
        3. The tag is only overwritten if not set.
        4. There is no way to decide which mass to choose. It will *always*
           take `self`.
        5. The orbitals requires explicit handling, the order will prefer
           `self`, but if there is more information in `other` those will
           be copied over.
        
        
        Parameters
        ----------
        other : Atom
            the other atom to merge into a single one
        """
        if self.Z != other.Z:
            return self
        mass = self.mass
        tag = self._tag or other._tag
        
        orbs = []
        for sorb in self:
            oorb = other[sorb.name()]
            if oorb is None:
                orbs.append(sorb)
                continue
            if isinstance(sorb, type(oorb)):
                # same type, now only check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant