def cbhone(ich, balance=True): """ Fragments molecule in a way that conserves each heavy-atom/heavy-atom bond INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule gra = automol.inchi.graph(ich) atms = automol.graph.atoms(gra) bnd_ords = automol.graph.one_resonance_dominant_bond_orders(gra) rad_atms = list(automol.graph.sing_res_dom_radical_atom_keys(gra)) atm_vals = automol.graph.atom_element_valences(gra) adj_atms = automol.graph.atoms_neighbor_atom_keys(gra) # Determine CBHone fragments frags = {} for atm in atm_vals: for adj in list(adj_atms[atm]): if atm > adj: vali = atm_vals[atm] valj = atm_vals[adj] if atm in rad_atms: vali -= 1 if adj in rad_atms: valj -= 1 key = frozenset({atm, adj}) bnd_ord = list(bnd_ords[key])[0] vali -= bnd_ord valj -= bnd_ord atm_dic = { 0: (atms[atm][0], int(vali), None), 1: (atms[adj][0], int(valj), None) } bnd_dic = {frozenset({0, 1}): (1, None)} gra = (atm_dic, bnd_dic) frag = automol.graph.inchi(gra) util.add2dic(frags, frag) frags = {k: v for k, v in frags.items() if v} if not frags: frags = cbhzed(ich) # Balance if balance: balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: zedfrags = cbhzed(ich, balance=False) newfrags = frags.copy() for frag in zedfrags: util.add2dic(newfrags, frag, -zedfrags[frag]) frags = {k: v for k, v in newfrags.items() if v} balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags(ich, frags) return frags
def _add_frag_to_frags(key, coeff, grai, frags): newname = None repeat = False for name, frags_dct in frags.items(): if key in frags_dct: if key == 'exp_gra': if automol.graph.full_isomorphism(frags_dct[key], grai): newname = name repeat = True else: if frags_dct[key] == grai: newname = name repeat = True if not repeat: newname = len(frags.keys()) frags[newname] = {} frags[newname][key] = grai util.add2dic(frags[newname], 'coeff', coeff) return frags
def cbhzed(ich, balance=True): """ Fragments molecule so that each heavy-atom is a seperate fragment INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule gra = automol.inchi.graph(ich) rad_atms = list(automol.graph.sing_res_dom_radical_atom_keys(gra)) atm_vals = automol.graph.atom_element_valences(gra) atms = automol.graph.atoms(gra) adj_atms = automol.graph.atoms_neighbor_atom_keys(gra) # Determine CBHzed fragments frags = {} for atm in atm_vals: coeff = 1 if not balance: coeff = (util.branch_point(adj_atms[atm]) * util.terminal_moiety(adj_atms[atm])) if atm in rad_atms: atm_vals[atm] -= 1 atm_dic = {0: (atms[atm][0], int(atm_vals[atm]), None)} gra = (atm_dic, {}) frag = automol.graph.inchi(gra) util.add2dic(frags, frag, coeff) if balance: balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags(ich, frags) return frags
def cbhthree(ich, balance=True): """ Fragments molecule to retain each heavy-atom -- heavy-atom bond, and keep the bonds of each atm1 b1 atm2 b2 atm3 b3 atm4 b4 atm5 would give atm1 [b1] atm2 b2 atm3, atm1 b1 atm2 [b2] atm3 b3 atm4, atm2 b2 atm3 [b3] atm4 b4 atm5, and atm3 b3 atm4 [b4] atm5 INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule gra = automol.inchi.graph(ich) atms = automol.graph.atoms(gra) bnd_ords = automol.graph.one_resonance_dominant_bond_orders(gra) rad_atms = list(automol.graph.sing_res_dom_radical_atom_keys(gra)) atm_vals = automol.graph.atom_element_valences(gra) adj_atms = automol.graph.atoms_neighbor_atom_keys(gra) # Determine CBHfour fragments frags = {} for bnd in list(bnd_ords): atm_dic = {} bnd_dic = {} bnd_dic[frozenset({0, 1})] = (list(bnd_ords[bnd])[0], None) for i, atm in enumerate(list(bnd)): vali = atm_vals[atm] if atm in rad_atms: vali -= 1 for adj in list(adj_atms[atm]): key = frozenset({atm, adj}) bnd_ord = list(bnd_ords[key])[0] vali -= bnd_ord atm_dic[i] = (atms[atm][0], int(vali), None) for j, adj in enumerate(list(adj_atms[atm]), start=1): if adj not in list(bnd): valj = atm_vals[adj] if adj in rad_atms: valj -= 1 key = frozenset({atm, adj}) bnd_ord = list(bnd_ords[key])[0] valj -= bnd_ord atm_dic[i * 4 + j + 1] = (atms[adj][0], int(valj), None) bnd_dic[frozenset({i, i * 4 + j + 1})] = (bnd_ord, None) gra = (atm_dic, bnd_dic) frag = automol.graph.inchi(gra) util.add2dic(frags, frag) if not frags: frags = cbhtwo(frags) if balance: balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: newfrags = frags.copy() twofrags = cbhtwo(ich, balance=False) for frag in twofrags: util.add2dic(newfrags, frag, -twofrags[frag]) frags = {k: v for k, v in newfrags.items() if v} # balance_ = util.balancec(ich, frags) # balance_ = {k: v for k, v in balance_.items() if v} # if balance_: # newfrags = frags.copy() # newerfrags = {} # onefrags = cbhone(ich, balance=False) # for frag in onefrags: # util.add2dic(newfrags, frag, - onefrags[frag]) # frags = {k: v for k, v in newfrags.items() if v} # balance_ = util.balancec(ich, frags) # balance_ = {k: v for k, v in balance_.items() if v} # if balance_: # newfrags = frags.copy() # zedfrags = cbhzed(ich, balance=False) # for frag in zedfrags: # util.add2dic(newfrags, frag, zedfrags[frag]) # frags = {k: v for k, v in newfrags.items() if v} # balance_ = util.balancec(ich, frags) # balance_ = {k: v for k, v in balance_.items() if v} # if balance_: # frags = util.balancec_frags(ich, frags) # balance = util.balancec(ich, frags) # balance_ = {k: v for k, v in balance_.items() if v} return frags
def cbhtwo(ich, balance=True): """ Fragments molecule for each heavy-atom to stay bonded to its adjacent atoms INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule gra = automol.inchi.graph(ich) atms = automol.graph.atoms(gra) bnd_ords = automol.graph.one_resonance_dominant_bond_orders(gra) rad_atms = list(automol.graph.sing_res_dom_radical_atom_keys(gra)) atm_vals = automol.graph.atom_element_valences(gra) adj_atms = automol.graph.atoms_neighbor_atom_keys(gra) # Determine CBHtwo fragments frags = {} for atm in atms: vali = atm_vals[atm] if atm in rad_atms: vali -= 1 # First loop over all atoms of this frag to get saturation of atomi for adj in list(adj_atms[atm]): key = frozenset({atm, adj}) bnd_ord = list(bnd_ords[key])[0] vali -= bnd_ord atm_dic = {0: (atms[atm][0], int(vali), None)} bnd_dic = {} # Then start adding bonds to the bnddic and atomdic j = 0 coeff = 1 if not balance: coeff = (util.branch_point(adj_atms[atm]) * util.terminal_moiety(adj_atms[atm])) for adj in list(adj_atms[atm]): j += 1 valj = atm_vals[adj] if adj in rad_atms: valj -= 1 key = frozenset({atm, adj}) bnd_ord = list(bnd_ords[key])[0] valj -= bnd_ord atm_dic[j] = (atms[adj][0], int(valj), None) bnd_dic[frozenset({0, j})] = (1, None) gra = (atm_dic, bnd_dic) frag = automol.graph.inchi(gra) util.add2dic(frags, frag, coeff) frags = {k: v for k, v in frags.items() if v} if not frags: frags = cbhone(frags) # Balance if balance: balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: newfrags = frags.copy() onefrags = cbhone(ich, balance=False) for frag in onefrags: util.add2dic(newfrags, frag, -onefrags[frag]) frags = {k: v for k, v in newfrags.items() if v} balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: newfrags = frags.copy() zedfrags = cbhzed(ich, balance=False) for frag in zedfrags: util.add2dic(newfrags, frag, zedfrags[frag]) frags = {k: v for k, v in newfrags.items() if v} balance_ = util.balance(ich, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags(ich, frags) return frags
def cbhone_habs(gra, site, atms, bnd_ords, atm_vals, adj_atms, bal=True): """ Fragments molecule so that each heavy-atom is a seperate fragment INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ frags = {} for bnd in bnd_ords: atma, atmb = bnd grai = (atms.copy(), bnd_ords.copy()) extended_site = None if ((atms[atma][0] != 'H' or atma in site) and (atms[atmb][0] != 'H' or atmb in site)): if atma in site and atmb in site: continue coeff = 1.0 if atmb in site: atmb, atma = atma, atmb if atma in site: key = 'ts_gra' extended_site = [*site, atmb] elif atms[atma][0] != 'H' and atms[atmb][0] != 'H': key = 'exp_gra' extended_site = [atma, atmb] if extended_site is not None: for site_atm in extended_site: for atm_x in adj_atms[site_atm]: if atm_x not in extended_site and atms[atm_x][0] != 'H': grai = cleave_group_and_saturate( grai, bnd_ords, site_atm, atm_x) grai = automol.graph.explicit(grai) frags = _add_frag_to_frags(key, coeff, grai, frags) frags = tsutil.simplify_gra_frags(frags) if bal: balance_ = util.balance_ts(gra, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: if not frags: zedfrags = cbhzed_habs(gra, site, atms, bnd_ords, atm_vals, adj_atms, bal=True) else: zedfrags = cbhzed_habs(gra, site, atms, bnd_ords, atm_vals, adj_atms, bal=False) newfrags = frags.copy() for zedfrags_dct in zedfrags.values(): newname = None repeat = False if 'exp_gra' in zedfrags_dct: key = 'exp_gra' for onename in newfrags: if 'exp_gra' in newfrags[onename]: if automol.graph.full_isomorphism( newfrags[onename][key], zedfrags_dct[key]): newname = onename repeat = True else: key = 'ts_gra' if not repeat: newname = len(newfrags.keys()) newfrags[newname] = {} newfrags[newname][key] = zedfrags_dct[key] if not frags: util.add2dic(newfrags[newname], 'coeff', zedfrags_dct['coeff']) else: util.add2dic(newfrags[newname], 'coeff', -zedfrags_dct['coeff']) frags = newfrags balance_ = util.balance_ts(gra, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags_ts(gra, frags) frags = tsutil.simplify_gra_frags(frags) return frags
def cbhone_habs(gra, site, bal=True): """ Fragments molecule so that each heavy-atom is a seperate fragment INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule _, atms, bnd_ords, atm_vals, _ = tsutil.ts_graph(gra, site) # Determine CBHone fragments frags = {} for bnd in bnd_ords: atma, atmb = bnd if ((atms[atma][0] != 'H' or atma in site) and (atms[atmb][0] != 'H' or atmb in site)): if atma in site and atmb in site: continue coeff = 1.0 if atmb in site: atmb, atma = atma, atmb if atma in site: key1 = [site[0], site[1]] key1.sort() key = frozenset({*key1}) bnd_ord1 = list(bnd_ords[key])[0] atm_dic = { 0: (atms[site[0]][0], atm_vals[site[0]]-bnd_ord1, None)} bnd_dct = {frozenset({0, 1}): (bnd_ord1, None)} key1 = [site[2], site[1]] key1.sort() key = frozenset({*key1}) bnd_ord2 = list(bnd_ords[key])[0] atm_dic[2] = ( atms[site[2]][0], atm_vals[site[2]]-bnd_ord2, None) atm_dic[1] = ( atms[site[1]][0], atm_vals[site[1]]-bnd_ord1-bnd_ord2, None) bnd_dct[frozenset({1, 2})] = (bnd_ord2, None) key1 = [atma, atmb] key1.sort() key = frozenset({*key1}) bnd_ord1 = list(bnd_ords[key])[0] atm_dic[3] = (atms[atmb][0], atm_vals[atmb]-bnd_ord1, None) if atma == site[0]: atm_dic[0] = ( atm_dic[0][0], atm_dic[0][1] - bnd_ord1, None) bnd_dct[frozenset({0, 3})] = (bnd_ord1, None) elif atma == site[2]: atm_dic[2] = ( atm_dic[2][0], atm_dic[2][1] - bnd_ord1, None) bnd_dct[frozenset({2, 3})] = (bnd_ord1, None) elif atma == site[1]: atm_dic[1] = ( atm_dic[1][0], atm_dic[1][1] - bnd_ord1, None) bnd_dct[frozenset({1, 3})] = (bnd_ord1, None) else: bnd_ord = list(bnd_ords[bnd])[0] atm_dic = { 0: (atms[atma][0], int(atm_vals[atma])-bnd_ord, None)} atm_dic[1] = (atms[atmb][0], int(atm_vals[atmb])-bnd_ord, None) bnd_dct = {frozenset({0, 1}): (bnd_ord, None)} grai = (atm_dic, bnd_dct) try: grai = automol.graph.explicit(grai) key = 'exp_gra' except: key = 'ts_gra' newname = None repeat = False for name in frags: if key in frags[name]: if key == 'exp_gra': if automol.graph.full_isomorphism( frags[name][key], grai): newname = name repeat = True else: if frags[name][key] == grai: newname = name repeat = True if not repeat: newname = len(frags.keys()) frags[newname] = {} frags[newname][key] = grai util.add2dic(frags[newname], 'coeff', coeff) frags = tsutil.simplify_gra_frags(frags) if bal: balance_ = util.balance_ts(gra, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: zedfrags = cbhzed_habs(gra, site, bal=False) newfrags = frags.copy() for zedname in zedfrags: newname = None repeat = False if 'exp_gra' in zedfrags[zedname]: key = 'exp_gra' for onename in newfrags: if 'exp_gra' in newfrags[onename]: if automol.graph.full_isomorphism( newfrags[onename][key], zedfrags[zedname][key]): newname = onename repeat = True else: key = 'ts_gra' if not repeat: newname = len(newfrags.keys()) newfrags[newname] = {} newfrags[newname][key] = zedfrags[zedname][key] util.add2dic( newfrags[newname], 'coeff', -zedfrags[zedname]['coeff']) frags = newfrags balance_ = util.balance_ts(gra, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags_ts(gra, frags) frags = tsutil.simplify_gra_frags(frags) return frags
def cbhzed_habs(gra, site, bal=True): """ Fragments molecule so that each heavy-atom is a seperate fragment INPUT: ich -- STR inchi name for molecule OUTPUT frags -- DIC dictionary with keys as STR inchi name for fragments and value as INT their coefficient """ # Graphical info about molecule _, atms, bnd_ords, atm_vals, adj_atms = tsutil.ts_graph(gra, site) # Determine CBHzed fragments frags = {} for atm in atm_vals: if (atms[atm][0] != 'H' or atm in site): if atm in (site[1], site[2]): continue coeff = 1.0 if not bal: if atm in site: nonhyd_adj_atms1 = tsutil.remove_hyd_from_adj_atms( atms, adj_atms[site[0]], site, other_adj=adj_atms[site[2]]) nonhyd_adj_atms2 = tsutil.remove_hyd_from_adj_atms( atms, adj_atms[site[2]], site, other_adj=adj_atms[site[0]]) nonhyd_adj_atms3 = [] for adj in adj_atms[site[0]]: if adj in adj_atms[site[2]]: nonhyd_adj_atms3 = tsutil.remove_hyd_from_adj_atms( atms, adj_atms[adj], othersite=site) coeff = ( util.branch_point( nonhyd_adj_atms1, nonhyd_adj_atms2, nonhyd_adj_atms3) * util.terminal_moiety( nonhyd_adj_atms1, nonhyd_adj_atms2, nonhyd_adj_atms3, endisterm=False) ) else: nonhyd_adj_atms = tsutil.remove_hyd_from_adj_atms( atms, adj_atms[atm]) coeff = ( util.branch_point(nonhyd_adj_atms) * util.terminal_moiety(nonhyd_adj_atms) ) if atm == site[0]: key1 = [site[0], site[1]] key1.sort() key = frozenset({*key1}) bnd_ord1 = list(bnd_ords[key])[0] atm_dic = {0: (atms[atm][0], atm_vals[atm]-bnd_ord1, None)} bnd_dct = {frozenset({0, 1}): (bnd_ord1, None)} key1 = [site[2], site[1]] key1.sort() key = frozenset({*key1}) bnd_ord2 = list(bnd_ords[key])[0] atm_dic[2] = ( atms[site[2]][0], atm_vals[site[2]]-bnd_ord2, None) atm_dic[1] = ( atms[site[1]][0], atm_vals[site[1]]-bnd_ord1-bnd_ord2, None) bnd_dct[frozenset({1, 2})] = (bnd_ord2, None) else: bnd_dct = {} atm_dic = {0: (atms[atm][0], int(atm_vals[atm]), None)} grai = (atm_dic, bnd_dct) try: grai = automol.graph.explicit(grai) key = 'exp_gra' except: key = 'ts_gra' newname = None repeat = False for name in frags: if key in frags[name]: if automol.graph.full_isomorphism(frags[name][key], grai): newname = name repeat = True if not repeat: newname = len(frags.keys()) frags[newname] = {} frags[newname][key] = grai util.add2dic(frags[newname], 'coeff', coeff) frags = tsutil.simplify_gra_frags(frags) if bal: balance_ = util.balance_ts(gra, frags) balance_ = {k: v for k, v in balance_.items() if v} if balance_: frags = util.balance_frags_ts(gra, frags) frags = tsutil.simplify_gra_frags(frags) return frags