def union(gra1, gra2): """ a union of two graphs """ assert not atom_keys(gra1) & atom_keys(gra2) atm_dct = {} atm_dct.update(atoms(gra1)) atm_dct.update(atoms(gra2)) bnd_dct = {} bnd_dct.update(bonds(gra1)) bnd_dct.update(bonds(gra2)) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def add_bonds(gra, keys, ord_dct=None, ste_par_dct=None, check=True): """ add bonds to this molecular graph """ bnd_keys = set(bond_keys(gra)) bnd_ord_dct = bond_orders(gra) bnd_ste_par_dct = bond_stereo_parities(gra) keys = set(map(frozenset, keys)) ord_dct = {} if ord_dct is None else ord_dct ste_par_dct = {} if ste_par_dct is None else ste_par_dct if check: assert not keys & bnd_keys, ( '{} and {} have a non-empty intersection'.format(keys, bnd_keys)) assert set(ord_dct.keys()) <= keys assert set(ste_par_dct.keys()) <= keys bnd_keys.update(keys) bnd_ord_dct.update(ord_dct) bnd_ste_par_dct.update(ste_par_dct) atm_dct = atoms(gra) bnd_dct = _create.bonds_from_data(bond_keys=bnd_keys, bond_orders=bnd_ord_dct, bond_stereo_parities=bnd_ste_par_dct) gra = _create.from_atoms_and_bonds(atoms=atm_dct, bonds=bnd_dct) return gra
def bond_induced_subgraph(gra, bnd_keys): """ the subgraph induced by a subset of the bonds """ atm_keys = set(itertools.chain(*bnd_keys)) bnd_keys = set(bnd_keys) assert atm_keys <= atom_keys(gra) atm_dct = dict_.by_key(atoms(gra), atm_keys) bnd_dct = dict_.by_key(bonds(gra), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def subgraph(gra, atm_keys): """ the subgraph induced by a subset of the atoms """ atm_keys = set(atm_keys) assert atm_keys <= atom_keys(gra) bnd_keys = set(filter(lambda x: x <= atm_keys, bond_keys(gra))) atm_dct = dict_.by_key(atoms(gra), atm_keys) bnd_dct = dict_.by_key(bonds(gra), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def atom_count(gra, with_dummy=False, with_implicit=True): """ count the number of atoms in this molecule by default, this includes implicit hydrogens and excludes dummy atoms """ if not with_dummy: gra = without_dummy_atoms(gra) natms = len(atoms(gra)) if with_implicit: atm_imp_hyd_vlc_dct = atom_implicit_hydrogen_valences(gra) natms += sum(atm_imp_hyd_vlc_dct.values()) return natms
def remove_bonds(gra, bnd_keys, check=True): """ remove bonds from the molecular graph """ all_bnd_keys = bond_keys(gra) bnd_keys = set(map(frozenset, bnd_keys)) if check: assert bnd_keys <= all_bnd_keys bnd_keys = all_bnd_keys - bnd_keys atm_dct = atoms(gra) bnd_dct = dict_.by_key(bonds(gra), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def frozen(gra): """ hashable, sortable, immutable container of graph data """ atm_keys = sorted(atom_keys(gra)) bnd_keys = sorted(bond_keys(gra), key=sorted) # make it sortable by replacing Nones with -infinity atm_vals = numpy.array(dict_.values_by_key(atoms(gra), atm_keys)) bnd_vals = numpy.array(dict_.values_by_key(bonds(gra), bnd_keys)) atm_vals[numpy.equal(atm_vals, None)] = -numpy.inf bnd_vals[numpy.equal(bnd_vals, None)] = -numpy.inf frz_atms = tuple(zip(atm_keys, map(tuple, atm_vals))) frz_bnds = tuple(zip(bnd_keys, map(tuple, bnd_vals))) return (frz_atms, frz_bnds)