Skip to content

Group

addAtom(self, atom)

Add an atom to this group

Parameters:

Name Type Description Default
atom [Atom]

an atom instance

required
Source code in molpy/group.py
def addAtom(self, atom: Atom):
    """ Add an atom to this group

    Args:
        atom ([Atom]): an atom instance
    """
    # atom.parent = self
    if atom not in self._atoms:
        self.atoms.append(atom)
        self._adj[atom] = {}

getAtoms(self)

get atoms from this group

Returns:

Type Description
List

List of atoms

Source code in molpy/group.py
def getAtoms(self):
    """ get atoms from this group

    Returns:
        List: List of atoms
    """
    return self._atoms

getBasisCycles(self, root=None)

Returns a list of cycles which form a basis for cycles of G. A basis for cycles of a network is a minimal collection of cycles such that any cycle in the network can be written as a sum of cycles in the basis. Here summation of cycles is defined as "exclusive or" of the edges. Cycle bases are useful, e.g. when deriving equations for electric circuits using Kirchhoff's Laws. Parameters

Args: root(Atom): Specify starting node for basis, optional

Returns:

Type Description

A list of cycle lists. Each cycle list is a list of nodes which forms a cycle (loop) in G.

Examples:

>>> G = nx.Graph()
>>> nx.add_cycle(G, [0, 1, 2, 3])
>>> nx.add_cycle(G, [0, 3, 4, 5])
>>> print(nx.cycle_basis(G, 0))
[[3, 4, 5, 0], [1, 2, 3, 0]]

!!! notes ----- This is adapted from algorithm CACM 491 [1]_. References ---------- .. [1] Paton, K. An algorithm for finding a fundamental set of cycles of a graph. Comm. ACM 12, 9 (Sept 1969), 514-518. See Also -------- simple_cycles

Source code in molpy/group.py
def getBasisCycles(self, root=None):

    """Returns a list of cycles which form a basis for cycles of G.
    A basis for cycles of a network is a minimal collection of
    cycles such that any cycle in the network can be written
    as a sum of cycles in the basis.  Here summation of cycles
    is defined as "exclusive or" of the edges. Cycle bases are
    useful, e.g. when deriving equations for electric circuits
    using Kirchhoff's Laws.
    Parameters

    Args: 
        root(Atom): Specify starting node for basis, optional

    Returns:
        A list of cycle lists.  Each cycle list is a list of nodes
        which forms a cycle (loop) in G.

    Examples:
        >>> G = nx.Graph()
        >>> nx.add_cycle(G, [0, 1, 2, 3])
        >>> nx.add_cycle(G, [0, 3, 4, 5])
        >>> print(nx.cycle_basis(G, 0))
        [[3, 4, 5, 0], [1, 2, 3, 0]]
    Notes:
        -----
        This is adapted from algorithm CACM 491 [1]_.
        References
        ----------
        .. [1] Paton, K. An algorithm for finding a fundamental set of
        cycles of a graph. Comm. ACM 12, 9 (Sept 1969), 514-518.
        See Also
        --------
        simple_cycles
    """        

    gnodes = set(self.getAtoms())
    cycles = []
    while gnodes:
        if root is None:
            root = gnodes.pop()
        stack = [root]
        pred = {root: root}
        used = {root: set()}
        while stack:  # walk the spanning tree finding cycles
            z = stack.pop()  # use last-in so cycles easier to find
            zused = used[z]
            for nbr in z.bondedAtoms:
                if nbr not in used:  # new node
                    pred[nbr] = z
                    stack.append(nbr)
                    used[nbr] = {z}
                elif nbr == z:  # self loops
                    cycles.append([z])
                elif nbr not in zused:  # found a cycle
                    pn = used[nbr]
                    cycle = [nbr, z]
                    p = pred[z]
                    while p not in pn:
                        cycle.append(p)
                        p = pred[p]
                    cycle.append(p)
                    cycles.append(cycle)
                    used[nbr].add(z)
        gnodes -= set(pred)
        root = None
    return cycles

getCovalentMap(self)

calculate covalent map from atoms in this group.

Source code in molpy/group.py
def getCovalentMap(self):
    """ calculate covalent map from atoms in this group.
    """        
    atoms = self.getAtoms()
    covalentMap = np.zeros((len(atoms), len(atoms)), dtype=int)
    visited = np.zeros_like(covalentMap, dtype=int)

    def find(nodes, vis):
        nextLevelNodes = []
        for node in nodes:
            nodeidx = atoms.index(node)
            if vis[nodeidx] == 1:
                continue
            vis[nodeidx] = 1
            covalentMap[rootidx, nodeidx] = depth
            nextLevelNodes.extend(dropwhile(lambda node: vis[atoms.index(node)] == 1, node.bondedAtoms))
            nextLevelNodes = list(set(nextLevelNodes))
        return nextLevelNodes

    for root in atoms:
        rootidx = atoms.index(root)
        vis = visited[rootidx]
        vis[rootidx] = 1
        depth = 1
        nodes = find(root.bondedAtoms, vis)
        depth += 1
        while True:
            if nodes == []:
                break
            nodes = find(nodes, vis)
            depth += 1
    self._covalentMap = covalentMap
    return covalentMap

getSubGroup(self, name, atoms)

Specify some atoms in the group and return the subgroup composed of these atoms

Parameters:

Name Type Description Default
name str

name of subgroup

required
atoms Iterable[Atom]

list of atoms contained in the subgroup

required

Returns:

Type Description
Group

new subgroup

Source code in molpy/group.py
def getSubGroup(self, name, atoms):
    """Specify some atoms in the group and return the subgroup composed of these atoms

    Args:
        name (str): name of subgroup
        atoms (Iterable[Atom]): list of atoms contained in the subgroup

    Returns:
        Group: new subgroup
    """
    # check
    atoms = list(set(atoms))
    for atom in atoms:
        if atom not in self:
            raise ValueError(f'{atom} not in this group')

    # add atoms
    subgroup = Group(name)
    subgroup.addAtoms(atoms)

    # add bonds
    for atom in atoms:
        for bondedAtom in atom.bondedAtoms:
            if bondedAtom in subgroup:
                bond = subgroup._adj.get(atom, {})
                bond[bondedAtom] = atom.bonds[bondedAtom]
    return subgroup

removeAtom(self, atom)

Remove atom from this group but not destory it

Removes the atom and all adjacent bonds. Attempting to remove a non-existent node will raise an exception.

Parameters:

Name Type Description Default
atom Atom

[description]

required
Source code in molpy/group.py
def removeAtom(self, atom: Atom):
    """Remove atom from this group but not destory it

    Removes the atom and all adjacent bonds.
    Attempting to remove a non-existent node will raise an exception.

    Args:
        atom (Atom): [description]
    """
    # remove atom from atom list
    del self._atoms[self._atoms.index(atom)]

    # remove related bonds
    nbrs = list(self._adj[atom])
    for u in nbrs:
        del self._adj[u][atom]  # remove edges
    del self._adj[atom]  # remove node

setTopoByCovalentMap(self, covalentMap)

set topology info by a numpy-like covalent map.

Parameters:

Name Type Description Default
covalentMap np.ndarray

2-d ndarray

required
Source code in molpy/group.py
def setTopoByCovalentMap(self, covalentMap: np.ndarray):
    """ set topology info by a numpy-like covalent map.

    Args:
        covalentMap (np.ndarray): 2-d ndarray
    """
    atoms = self.getAtoms()
    for i, nbond in np.ndenumerate(covalentMap):
        if nbond == 1:
            atom1 = atoms[i[0]]
            atom2 = atoms[i[1]]
            self._adj[atom1][atom2] = atom1.bondto(atom2)