コード例 #1
0
def ring_system_decomposed_atom_keys(rsy, rng_keys=None, check=True):
    """ decomposed atom keys for a polycyclic ring system in a graph

    The ring system is decomposed into a ring and a series of arcs that can
    be used to successively construct the system

    :param rsy: the ring system
    :param rng_keys: keys for the first ring in the decomposition; if None, the
        smallest ring in the system will be chosen
    """
    if rng_keys is None:
        rng = sorted(rings(rsy), key=atom_count)[0]
        rng_keys = sorted_ring_atom_keys(rng)

    # check the arguments, if requested
    if check:
        # check that the graph is connected
        assert is_connected(rsy), "Ring system can't be disconnected."

        # check that the graph is actually a ring system
        assert is_ring_system(rsy), (
            "This is not a ring system graph:\n{:s}".format(string(rsy)))

        # check that rng is a subgraph of rsy
        assert set(rng_keys) <= atom_keys(rsy), (
            "{}\n^ Rings system doesn't contain ring as subgraph:\n{}".format(
                string(rsy, one_indexed=False), str(rng_keys)))

    bnd_keys = list(mit.windowed(rng_keys + rng_keys[:1], 2))

    # Remove bonds for the ring
    rsy = remove_bonds(rsy, bnd_keys)
    keys_lst = [rng_keys]
    done_keys = set(rng_keys)

    while bond_keys(rsy):

        # Determine shortest paths for the graph with one more ring/arc deleted
        sp_dct = atom_shortest_paths(rsy)

        # The shortest path will be the next shortest arc in the system
        arc_keys = min((sp_dct[i][j]
                        for i, j in itertools.combinations(done_keys, 2)
                        if j in sp_dct[i]),
                       key=len)

        # Add this arc to the list
        keys_lst.append(arc_keys)

        # Add these keys to the list of done keys
        done_keys |= set(arc_keys)

        # Delete tbond keys for the new arc and continue to the next iteration
        bnd_keys = list(map(frozenset, mit.windowed(arc_keys, 2)))
        rsy = remove_bonds(rsy, bnd_keys)

    keys_lst = tuple(map(tuple, keys_lst))
    return keys_lst
コード例 #2
0
ファイル: vmat.py プロジェクト: sjklipp/autochem
def continue_ring_system(gra, keys_lst, vma, zma_keys):
    """ continue constructing a v-matrix for a ring system

    Exactly one atom in the ring system must already be in the v-matrix, and
    this atom must be in the starting ring of the decomposed ring system key
    list.
    """
    # First, get the ring keys
    keys_lst = list(keys_lst)
    keys = keys_lst.pop(0)

    # Break the bonds joining the last pair of atoms in each arc
    gra = remove_bonds(gra, [(k[-1], k[-2]) for k in keys_lst])

    # Start by constructing the v-matrix for the first ring
    vma, zma_keys = continue_ring(gra, keys, vma, zma_keys)

    # Now, complete the ring system by continuing the v-matrix along each arc
    for keys in keys_lst:
        # Note that the atoms on each end of the arc are already in the
        # v-matrix, so we ignore those
        vma, zma_keys = continue_chain(gra,
                                       keys[1:-1],
                                       vma,
                                       zma_keys,
                                       term_hydrogens=False)

    return vma, zma_keys
コード例 #3
0
ファイル: vmat.py プロジェクト: sjklipp/autochem
def ring_system(gra, keys_lst):
    """ generate a v-matrix for a ring system

    :param gra: the graph
    :param keys_lst: the first entry contains keys for a ring and each next one
        contains keys for an arc that starts and ends on atoms in the preceding
        entries
    """
    # First, get the ring keys
    keys_lst = list(keys_lst)
    keys = keys_lst.pop(0)

    # Break the bonds joining the last pair of atoms in each arc
    gra = remove_bonds(gra, [(k[-1], k[-2]) for k in keys_lst])

    # Start by constructing the v-matrix for the first ring
    vma, zma_keys = ring(gra, keys)

    # Now, complete the ring system by continuing the v-matrix along each arc
    for keys in keys_lst:
        # Note that the atoms on each end of the arc are already in the
        # v-matrix, so we ignore those
        vma, zma_keys = continue_chain(gra, keys[1:-1], vma, zma_keys)

    return vma, zma_keys
コード例 #4
0
def reactants_graph(tsg):
    """ get a graph of the reactants from a transition state graph
    """
    frm_bnd_keys = forming_bond_keys(tsg)
    ord_dct = dict_.transform_values(bond_orders(tsg), func=round)
    gra = set_bond_orders(tsg, ord_dct)
    gra = remove_bonds(gra, frm_bnd_keys)
    return gra
コード例 #5
0
def apply(tra, xgr):
    """ apply this transformation to a graph
    """
    brk_bnd_keys = broken_bond_keys(tra)
    frm_bnd_keys = formed_bond_keys(tra)
    # in case some bonds are broken *and* formed, we subtract the other set
    xgr = remove_bonds(xgr, brk_bnd_keys - frm_bnd_keys)
    xgr = add_bonds(xgr, frm_bnd_keys - brk_bnd_keys)
    return xgr
コード例 #6
0
def atom_groups(gra, atm):
    """ return a list of groups off of one atom
    """
    adj_atms = atoms_neighbor_atom_keys(gra)
    keys = []
    for atmi in adj_atms[atm]:
        key = [atm, atmi]
        key.sort()
        key = frozenset(key)
        keys.append(key)
    gras = remove_bonds(gra, keys)
    return connected_components(gras)
コード例 #7
0
ファイル: _graph.py プロジェクト: sjklipp/autochem
def atom_groups(gra, atm, stereo=False):
    """ return a list of groups off of one atom
    """
    if not stereo:
        gra = without_stereo_parities(gra)
    adj_atms = atoms_neighbor_atom_keys(gra)
    keys = []
    for atmi in adj_atms[atm]:
        key = [atm, atmi]
        key.sort()
        key = frozenset(key)
        keys.append(key)
    gras = remove_bonds(gra, keys)
    return connected_components(gras)
コード例 #8
0
ファイル: vmat.py プロジェクト: sjklipp/autochem
def ring(gra, keys):
    """ generate a v-matrix for a ring

    All neighboring atoms along the ring will be included

    :param gra: the graph
    :param keys: ring keys, in the order they should appear in the z-matrix
    """
    # Break the bond between the first and last atoms to make this a chain
    gra = remove_bonds(gra, [(keys[0], keys[-1])])

    # Now, construct a v-matrix for the chain
    vma, zma_keys = chain(gra, keys, term_hydrogens=True)
    return vma, zma_keys
コード例 #9
0
def _substitution(atmsa, neighsa, bndsa, atmsb, xgr1, xgr2):
    ret_tra = None
    for atmi in atmsa:
        if _is_heavy(atmi, atmsa):
            i_neighs = neighsa[atmi]
            for atmj in i_neighs:
                bnd_break_key_ij = _get_bnd_key(atmi, atmj, bndsa)
                new_xgr = remove_bonds(xgr1, [bnd_break_key_ij])
                for atmk in atmsb:
                    if atmk not in (atmi, atmj):
                        bnd_form_key_ik = frozenset({atmi, atmk})
                        newnew_xgr = add_bonds(new_xgr, [bnd_form_key_ik])
                        atm_key_dct = _full_isomorphism(newnew_xgr, xgr2)
                        if atm_key_dct:
                            tra = [[bnd_form_key_ik], [bnd_break_key_ij]]
                            ret_tra = tra
    return ret_tra
コード例 #10
0
def radical_dissociation_prods(gra, pgra1):
    """ given a dissociation product, determine the other product
    """
    gra = without_fractional_bonds(gra)

    pgra2 = None
    rads = sing_res_dom_radical_atom_keys(gra)
    adj_atms = atoms_neighbor_atom_keys(gra)
    # adj_idxs = tuple(adj_atms[rad] for rad in rads)
    for rad in rads:
        for adj in adj_atms[rad]:
            for group in atom_groups(gra, adj):
                if full_isomorphism(explicit(group), explicit(pgra1)):
                    pgra2 = remove_atoms(gra, atom_keys(group))
                    # pgra2 = remove_bonds(pgra2, bond_keys(group))
                    if bond_keys(group) in pgra2:
                        pgra2 = remove_bonds(pgra2, bond_keys(group))
    return (pgra1, pgra2)
コード例 #11
0
ファイル: vmat.py プロジェクト: sjklipp/autochem
def continue_ring(gra, keys, vma, zma_keys):
    """ continue constructing a v-matrix around a ring

    All neighboring atoms along the ring will be included

    Exactly one atom in the ring must already be in the v-matrix.
    """
    # Find the connecting key
    key = next((k for k in keys if k in zma_keys), None)
    assert key is not None, (
        "There must be a ring atom already in the v-matrix")

    # Cycle the connecting key to the front of the ring
    keys = cycle_ring_atom_key_to_front(keys, key)

    # Break the bond between the first and last atoms to make this a chain
    gra = remove_bonds(gra, [(keys[0], keys[-1])])

    # Now, construct a v-matrix for the chain
    vma, zma_keys = continue_chain(gra, keys, vma, zma_keys)
    return vma, zma_keys
コード例 #12
0
def _insertion(atmsa, neighsa, bndsa, atmsb, neighsb, xgr1, xgr2):
    """Do the insertion for an order of reactants
    """
    ret_tra = None
    for i in atmsa:
        if _is_heavy(i, atmsa):
            i_neighs = neighsa[i]
            for j in i_neighs:
                bnd_break_key_ij = _get_bnd_key(i, j, bndsa)
                new_xgr = remove_bonds(xgr1, [bnd_break_key_ij])
                for k in atmsb:
                    if _is_heavy(k, atmsb) and (k != i and k != j
                                                and i not in neighsb[k]
                                                and j not in neighsb[k]):
                        bnd_form_key_ik = {i, k}
                        bnd_form_key_jk = {j, k}
                        newnew_xgr = add_bonds(
                            new_xgr, [bnd_form_key_ik, bnd_form_key_jk])
                        atm_key_dct = _full_isomorphism(newnew_xgr, xgr2)
                        if atm_key_dct:
                            tra = [[bnd_form_key_ik, bnd_form_key_jk],
                                   [bnd_break_key_ij]]
                            ret_tra = tra
    return ret_tra
コード例 #13
0
def elimination(xgr1, xgr2):
    """identifies elimination reactions
    """
    assert xgr1 == _explicit(xgr1) and xgr2 == _explicit(xgr2)
    tra = None
    xgrs1 = _connected_components(xgr1)
    xgrs2 = _connected_components(xgr2)
    tras = []
    if len(xgrs1) == 1 and len(xgrs2) == 2:
        atms = atoms(xgr1)
        neighs = atom_neighbor_keys(xgr1)
        bnds = bond_keys(xgr1)
        radicals = _resonance_dominant_radical_atom_keys(xgr1)
        lonepairs = atom_lone_pair_counts(xgr1)
        for atmi in atms:
            i_neighs = neighs[atmi]
            for atmj in i_neighs:
                bnd_break_key_ij = _get_bnd_key(atmi, atmj, bnds)
                new_xgr = remove_bonds(xgr1, [bnd_break_key_ij])
                new_xgrs = _connected_components(new_xgr)
                if len(new_xgrs) == 2:
                    xgra, xgrb = new_xgrs
                    atmsa = atoms(xgra)
                    if atmi not in atmsa.keys():
                        xgrb, xgra = xgra, xgrb
                        atmsa = atoms(xgra)
                    neighsa = atom_neighbor_keys(xgra)
                    atmsb = atoms(xgrb)
                    neighs_i = neighsa[atmi]
                    for atmk in atmsb:
                        if atmk in radicals:
                            for atml in neighs_i:
                                neighs_l = neighsa[atml]
                                if atml != atmj:
                                    bnd_break_key_il = _get_bnd_key(
                                        atmi, atml, bnds)
                                    bnd_form_key_kl = frozenset({atmk, atml})
                                    newnew_xgr = remove_bonds(
                                        new_xgr, [bnd_break_key_il])
                                    newnew_xgr = add_bonds(
                                        newnew_xgr, [bnd_form_key_kl])
                                    atm_key_dct = _full_isomorphism(
                                        newnew_xgr, xgr2)
                                    if atm_key_dct:
                                        tra = [[bnd_form_key_kl],
                                               [
                                                   bnd_break_key_ij,
                                                   bnd_break_key_il
                                               ]]
                                        return tra
                                for atmm in neighs_l:
                                    if atmm != atmi:
                                        bnd_break_key_lm = _get_bnd_key(
                                            atml, atmm, bnds)
                                        bnd_form_key_km = frozenset(
                                            {atmk, atmm})
                                        newnew_xgr = remove_bonds(
                                            new_xgr, [bnd_break_key_lm])
                                        newnew_xgr = add_bonds(
                                            newnew_xgr, [bnd_form_key_km])
                                        atm_key_dct = _full_isomorphism(
                                            newnew_xgr, xgr2)
                                        if atm_key_dct:
                                            tras.append([[bnd_form_key_km],
                                                         [
                                                             bnd_break_key_ij,
                                                             bnd_break_key_lm
                                                         ]])
        for atmi in atms:
            i_neighs = neighs[atmi]
            print('atmi test:', atmi)
            print('i_neighs test:', i_neighs)
            for atmj in i_neighs:
                bnd_break_key_ij = _get_bnd_key(atmi, atmj, bnds)
                new_xgr = remove_bonds(xgr1, [bnd_break_key_ij])
                new_xgrs = _connected_components(new_xgr)
                if len(new_xgrs) == 2:
                    xgra, xgrb = new_xgrs
                    atmsa = atoms(xgra)
                    if atmi not in atmsa.keys():
                        xgrb, xgra = xgra, xgrb
                        atmsa = atoms(xgra)
                    neighsa = atom_neighbor_keys(xgra)
                    atmsb = atoms(xgrb)
                    neighs_i = neighsa[atmi]
                    print('len atmsb test:', len(atmsb))
                    for atmk in atmsb:
                        if lonepairs[atmk] > 0 or len(atmsb) == 1:
                            # if lonepairs[atmk] > 0:
                            for atml in neighs_i:
                                neighs_l = neighsa[atml]
                                if atml != atmj:
                                    bnd_break_key_il = _get_bnd_key(
                                        atmi, atml, bnds)
                                    bnd_form_key_kl = frozenset({atmk, atml})
                                    newnew_xgr = remove_bonds(
                                        new_xgr, [bnd_break_key_il])
                                    newnew_xgr = add_bonds(
                                        newnew_xgr, [bnd_form_key_kl])
                                    atm_key_dct = _full_isomorphism(
                                        newnew_xgr, xgr2)
                                    if atm_key_dct:
                                        tra = [[bnd_form_key_kl],
                                               [
                                                   bnd_break_key_ij,
                                                   bnd_break_key_il
                                               ]]
                                        return tra
                                for atmm in neighs_l:
                                    if atmm != atmi:
                                        bnd_break_key_lm = _get_bnd_key(
                                            atml, atmm, bnds)
                                        bnd_form_key_km = frozenset(
                                            {atmk, atmm})
                                        newnew_xgr = remove_bonds(
                                            new_xgr, [bnd_break_key_lm])
                                        newnew_xgr = add_bonds(
                                            newnew_xgr, [bnd_form_key_km])
                                        atm_key_dct = _full_isomorphism(
                                            newnew_xgr, xgr2)
                                        if atm_key_dct:
                                            tras.append([[bnd_form_key_km],
                                                         [
                                                             bnd_break_key_ij,
                                                             bnd_break_key_lm
                                                         ]])
    if len(tras) < 1:
        tras = None
    return tras