def without_stereo_parities(xgr): """ graph with stereo assignments wiped out """ atm_ste_par_dct = dict_.by_key({}, atom_keys(xgr), fill_val=None) bnd_ste_par_dct = dict_.by_key({}, bond_keys(xgr), fill_val=None) xgr = set_atom_stereo_parities(xgr, atm_ste_par_dct) xgr = set_bond_stereo_parities(xgr, bnd_ste_par_dct) return xgr
def subgraph(xgr, atm_keys): """ the subgraph induced by a subset of the atoms """ atm_keys = set(atm_keys) assert atm_keys <= atom_keys(xgr) bnd_keys = set(filter(lambda x: x <= atm_keys, bond_keys(xgr))) atm_dct = dict_.by_key(atoms(xgr), atm_keys) bnd_dct = dict_.by_key(bonds(xgr), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
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 bond_induced_subgraph(xgr, bnd_keys, saddle=False): """ 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(xgr) if not saddle: assert bnd_keys <= bond_keys(xgr) atm_dct = dict_.by_key(atoms(xgr), atm_keys) bnd_dct = dict_.by_key(bonds(xgr), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def standard_form(ich, remove_stereo=False): """ return an inchi string in standard form (eventually we should just designate standard-form as standard inchi ordering for all but the hardcoded exceptions, which we can put at the end) """ if remove_stereo: fml_slyr = formula_sublayer(ich) main_dct = main_sublayers(ich) char_dct = charge_sublayers(ich) ste_dct = {} iso_dct = dict_.by_key(isotope_sublayers(ich), automol.create.inchi.ISO_NONSTE_PFXS) else: fml_slyr = formula_sublayer(ich) main_dct = main_sublayers(ich) char_dct = charge_sublayers(ich) ste_dct = stereo_sublayers(ich) iso_dct = isotope_sublayers(ich) ich = from_data(fml_slyr, main_dct=main_dct, char_dct=char_dct, ste_dct=ste_dct, iso_dct=iso_dct) return recalculate(ich)
def _join_sublayers(dcts): pfxs = sorted(functools.reduce(set.union, map(set, dcts))) if 's' in pfxs: pfxs.remove('s') dcts = [dict_.by_key(dct, pfxs, fill_val='') for dct in dcts] slyrs_lst = [[dct[pfx] for dct in dcts] for pfx in pfxs] dct = {pfx: (_join_sublayer_strings(slyrs) if pfx != 'm' else _join_m_sublayer_strings(slyrs)) for pfx, slyrs in zip(pfxs, slyrs_lst)} return dct
def remove_bonds(xgr, bnd_keys): """ remove bonds from the molecular graph """ all_bnd_keys = bond_keys(xgr) bnd_keys = set(bnd_keys) assert bnd_keys <= all_bnd_keys bnd_keys = all_bnd_keys - bnd_keys atm_dct = atoms(xgr) bnd_dct = dict_.by_key(bonds(xgr), bnd_keys) return _create.from_atoms_and_bonds(atm_dct, bnd_dct)
def bond_symmetry_numbers(gra, frm_bnd_key=None, brk_bnd_key=None): """ symmetry numbers, by bond the (approximate) symmetry number of the torsional potential for this bond, based on the hydrogen counts for each atom It is reduced to 1 if one of the H atoms in the torsional bond is a neighbor to the special bonding atom (the atom that is being transferred) """ imp_gra = implicit(gra) atm_imp_hyd_vlc_dct = atom_implicit_hydrogen_valences(imp_gra) bnd_keys = bond_keys(imp_gra) tfr_atm = None if frm_bnd_key and brk_bnd_key: for atm_f in list(frm_bnd_key): for atm_b in list(brk_bnd_key): if atm_f == atm_b: tfr_atm = atm_f if tfr_atm: neighbor_dct = atom_neighbor_keys(gra) nei_tfr = neighbor_dct[tfr_atm] atms = gra[0] all_hyds = [] for atm in atms: if atms[atm][0] == 'H': all_hyds.append(atm) else: nei_tfr = {} bnd_sym_num_dct = {} bnd_sym_nums = [] for bnd_key in bnd_keys: bnd_sym = 1 vlc = max(map(atm_imp_hyd_vlc_dct.__getitem__, bnd_key)) if vlc == 3: bnd_sym = 3 if tfr_atm: for atm in nei_tfr: nei_s = neighbor_dct[atm] h_nei = 0 for nei in nei_s: if nei in all_hyds: h_nei += 1 if h_nei == 3: bnd_sym = 1 bnd_sym_nums.append(bnd_sym) bnd_sym_num_dct = dict(zip(bnd_keys, bnd_sym_nums)) # fill in the rest of the bonds for completeness bnd_sym_num_dct = dict_.by_key(bnd_sym_num_dct, bond_keys(gra), fill_val=1) return bnd_sym_num_dct
def explicit(xgr, atm_keys=None): """ make the hydrogens at these atoms explicit """ atm_keys = backbone_keys(xgr) if atm_keys is None else atm_keys atm_keys = sorted(atm_keys) atm_imp_hyd_vlc_dct = dict_.by_key(atom_implicit_hydrogen_valences(xgr), atm_keys) atm_exp_hyd_keys_dct = {} next_atm_key = max(atom_keys(xgr)) + 1 for atm_key in atm_keys: imp_hyd_vlc = atm_imp_hyd_vlc_dct[atm_key] atm_exp_hyd_keys_dct[atm_key] = set( range(next_atm_key, next_atm_key + imp_hyd_vlc)) next_atm_key += imp_hyd_vlc xgr = set_atom_implicit_hydrogen_valences( xgr, dict_.by_key({}, atm_keys, fill_val=0)) xgr = add_atom_explicit_hydrogen_keys(xgr, atm_exp_hyd_keys_dct) return xgr
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 implicit(xgr, atm_keys=None): """ make the hydrogens at these atoms implicit """ atm_keys = backbone_keys(xgr) if atm_keys is None else atm_keys atm_exp_hyd_keys_dct = dict_.by_key(atom_explicit_hydrogen_keys(xgr), atm_keys) inc_imp_hyd_keys_dct = dict_.transform_values(atm_exp_hyd_keys_dct, len) xgr = add_atom_implicit_hydrogen_valences(xgr, inc_imp_hyd_keys_dct) exp_hyd_keys = set(itertools.chain(*atm_exp_hyd_keys_dct.values())) xgr = remove_atoms(xgr, exp_hyd_keys) return xgr
def add_atom_explicit_hydrogen_keys(xgr, atm_exp_hyd_keys_dct): """ add explicit hydrogens by atom """ assert set(atm_exp_hyd_keys_dct.keys()) <= atom_keys(xgr) for atm_key, atm_exp_hyd_keys in atm_exp_hyd_keys_dct.items(): assert not set(atm_exp_hyd_keys) & atom_keys(xgr) atm_exp_hyd_bnd_keys = { frozenset({atm_key, atm_exp_hyd_key}) for atm_exp_hyd_key in atm_exp_hyd_keys } atm_exp_hyd_sym_dct = dict_.by_key({}, atm_exp_hyd_keys, fill_val='H') xgr = add_atoms(xgr, atm_exp_hyd_sym_dct) xgr = add_bonds(xgr, atm_exp_hyd_bnd_keys) return xgr
def add_atom_explicit_hydrogen_keys(gra, atm_exp_hyd_keys_dct): """ add explicit hydrogens by atom """ assert set(atm_exp_hyd_keys_dct.keys()) <= atom_keys(gra), ( '{} !<= {}'.format(set(atm_exp_hyd_keys_dct.keys()), atom_keys(gra))) for atm_key, atm_exp_hyd_keys in atm_exp_hyd_keys_dct.items(): assert not set(atm_exp_hyd_keys) & atom_keys(gra) atm_exp_hyd_bnd_keys = { frozenset({atm_key, atm_exp_hyd_key}) for atm_exp_hyd_key in atm_exp_hyd_keys } atm_exp_hyd_sym_dct = dict_.by_key({}, atm_exp_hyd_keys, fill_val='H') gra = add_atoms(gra, atm_exp_hyd_sym_dct) gra = add_bonds(gra, atm_exp_hyd_bnd_keys) return gra
def without_bond_orders(xgr): """ resonance graph with maximum spin (i.e. no pi bonds) """ bnd_keys = bond_keys(xgr) - dummy_bond_keys(xgr) bnd_ord_dct = dict_.by_key({}, bnd_keys, fill_val=1) return set_bond_orders(xgr, bnd_ord_dct)