@classmethod<EOL><INDENT>def from_geometry(cls, molecule, do_orders=False, scaling=<NUM_LIT:1.0>):<DEDENT>
from molmod.bonds import bonds<EOL>unit_cell = molecule.unit_cell<EOL>pair_search = PairSearchIntra(<EOL>molecule.coordinates,<EOL>bonds.max_length*bonds.bond_tolerance*scaling,<EOL>unit_cell<EOL>)<EOL>orders = []<EOL>lengths = []<EOL>edges = []<EOL>for i0, i1, delta, distance in pair_search:<EOL><INDENT>bond_order = bonds.bonded(molecule.numbers[i0], molecule.numbers[i1], distance/scaling)<EOL>if bond_order is not None:<EOL><INDENT>if do_orders:<EOL><INDENT>orders.append(bond_order)<EOL><DEDENT>lengths.append(distance)<EOL>edges.append((i0,i1))<EOL><DEDENT><DEDENT>if do_orders:<EOL><INDENT>result = cls(edges, molecule.numbers, orders, symbols=molecule.symbols)<EOL><DEDENT>else:<EOL><INDENT>result = cls(edges, molecule.numbers, symbols=molecule.symbols)<EOL><DEDENT>slated_for_removal = set([])<EOL>threshold = <NUM_LIT:0.5>**<NUM_LIT:0.5><EOL>for c, ns in result.neighbors.items():<EOL><INDENT>lengths_ns = []<EOL>for n in ns:<EOL><INDENT>delta = molecule.coordinates[n] - molecule.coordinates[c]<EOL>if unit_cell is not None:<EOL><INDENT>delta = unit_cell.shortest_vector(delta)<EOL><DEDENT>length = np.linalg.norm(delta)<EOL>lengths_ns.append([length, delta, n])<EOL><DEDENT>lengths_ns.sort(reverse=True, key=(lambda r: r[<NUM_LIT:0>]))<EOL>for i0, (length0, delta0, n0) in enumerate(lengths_ns):<EOL><INDENT>for i1, (length1, delta1, n1) in enumerate(lengths_ns[:i0]):<EOL><INDENT>if length1 == <NUM_LIT:0.0>:<EOL><INDENT>continue<EOL><DEDENT>cosine = np.dot(delta0, delta1)/length0/length1<EOL>if cosine > threshold:<EOL><INDENT>slated_for_removal.add((c,n1))<EOL>lengths_ns[i1][<NUM_LIT:0>] = <NUM_LIT:0.0><EOL><DEDENT><DEDENT><DEDENT><DEDENT>mask = np.ones(len(edges), bool)<EOL>for i0, i1 in slated_for_removal:<EOL><INDENT>edge_index = result.edge_index.get(frozenset([i0,i1]))<EOL>if edge_index is None:<EOL><INDENT>raise ValueError('<STR_LIT>' % (i0, i1))<EOL><DEDENT>mask[edge_index] = False<EOL><DEDENT>edges = [edges[i] for i in range(len(edges)) if mask[i]]<EOL>if do_orders:<EOL><INDENT>bond_order = [bond_order[i] for i in range(len(bond_order)) if mask[i]]<EOL>result = cls(edges, molecule.numbers, orders)<EOL><DEDENT>else:<EOL><INDENT>result = cls(edges, molecule.numbers)<EOL><DEDENT>lengths = [lengths[i] for i in range(len(lengths)) if mask[i]]<EOL>result.bond_lengths = np.array(lengths)<EOL>return result<EOL>
Construct a MolecularGraph object based on interatomic distances

           All short distances are computed with the binning module and compared
           with a database of bond lengths. Based on this comparison, bonded
           atoms are detected.

           Before marking a pair of atoms A and B as bonded, it is also checked
           that there is no third atom C somewhat between A and B.
           When an atom C exists that is closer to B (than A) and the angle
           A-B-C is less than 45 degrees, atoms A and B are not bonded.
           Similarly if C is closer to A (than B) and the angle B-A-C is less
           then 45 degrees, A and B are not connected.

           Argument:
            | ``molecule``  --  The molecule to derive the graph from

           Optional arguments:
            | ``do_orders``  --  set to True to estimate the bond order
            | ``scaling``  --  scale the threshold for the connectivity. increase
                               this to 1.5 in case of transition states when a
                               fully connected topology is required.