Пример #1
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
Пример #2
0
def substitution(rct_gras, prd_gras):
    """ find an substitution transformation

    Substitutions are identified by breaking one bond in the reactants and one
    bond from the products and checking for isomorphism.
    """
    _assert_is_valid_reagent_graph_list(rct_gras)
    _assert_is_valid_reagent_graph_list(prd_gras)

    tras = []
    rct_idxs = None
    prd_idxs = None

    is_triv = is_trivial_reaction(rct_gras, prd_gras)

    if len(rct_gras) == 2 and len(prd_gras) == 2 and not is_triv:
        rct_gra = union_from_sequence(rct_gras)
        prd_gra = union_from_sequence(prd_gras)

        rct_bnd_keys = bond_keys(rct_gra)
        prd_bnd_keys = bond_keys(prd_gra)
        for rct_bnd_key, prd_bnd_key in itertools.product(
                rct_bnd_keys, prd_bnd_keys):
            rct_gra_ = remove_bonds(rct_gra, [rct_bnd_key])
            prd_gra_ = remove_bonds(prd_gra, [prd_bnd_key])

            inv_atm_key_dct = full_isomorphism(prd_gra_, rct_gra_)
            if inv_atm_key_dct:
                brk_bnd_key = rct_bnd_key
                frm_bnd_key = frozenset(
                    map(inv_atm_key_dct.__getitem__, prd_bnd_key))

                tra = trans.from_data(
                    rxn_class=par.REACTION_CLASS.SUBSTITUTION,
                    frm_bnd_keys=[frm_bnd_key],
                    brk_bnd_keys=[brk_bnd_key])
                tras.append(tra)

                rct_idxs = _argsort_reactants(rct_gras)
                prd_idxs = _argsort_reactants(prd_gras)

    tras = tuple(set(tras))
    return tras, rct_idxs, prd_idxs
Пример #3
0
def prod_homolytic_scission(gra):
    """ products of homolytic single bond scission
    """

    prod_gras = tuple()

    single_bonds = bonds_of_order(gra, mbond=1)
    for bond in single_bonds:
        gra2 = remove_bonds(gra, [frozenset(bond)])
        disconn_gras = automol.graph.connected_components(gra2)
        prod_gras += (disconn_gras, )

    return _unique_gras(prod_gras)
Пример #4
0
def ring_forming_scission(rct_gras, prd_gras):
    """ find a ring forming reaction that eliminates a radical group
    """
    _assert_is_valid_reagent_graph_list(rct_gras)
    _assert_is_valid_reagent_graph_list(prd_gras)

    tras = []
    rct_idxs = None
    prd_idxs = None

    is_triv = is_trivial_reaction(rct_gras, prd_gras)

    if len(rct_gras) == 1 and len(prd_gras) == 2 and not is_triv:
        rgra, = rct_gras
        pgra1, pgra2 = prd_gras
        pgra = automol.graph.union(pgra1, pgra2)
        rad_atm_keys = unsaturated_atom_keys(rgra)
        atms, bnds = rgra
        ngb_atms = automol.graph.atom_neighbor_keys(rgra)

        for rad_atm in rad_atm_keys:
            for xatm in atms:
                if (xatm != rad_atm and atms[xatm][1] != 'H'
                        and xatm not in ngb_atms[rad_atm] and not tras):
                    for natm in ngb_atms[xatm]:
                        if natm != rad_atm:
                            xgra = atms.copy(), bnds.copy()
                            xgra = add_bonds(xgra,
                                             [frozenset({rad_atm, xatm})])
                            xgra = remove_bonds(xgra,
                                                [frozenset({xatm, natm})])
                            atm_key_dct = full_isomorphism(xgra, pgra)
                            if atm_key_dct:
                                tra = trans.from_data(
                                    rxn_class=(
                                        par.REACTION_CLASS.RING_FORM_SCISSION),
                                    frm_bnd_keys=[{rad_atm, xatm}],
                                    brk_bnd_keys=[
                                        {xatm, natm},
                                    ])
                                tras.append(tra)
                                break

                # sort the reactants so that the largest species is first
        rct_idxs = (0, )
        prd_idxs = _argsort_reactants(prd_gras)
        tras = tuple(tras)

    return tras, rct_idxs, prd_idxs
Пример #5
0
def prod_beta_scission(gra):
    """ products of beta scission
    """

    prod_gras = tuple()

    rad_idxs = resonance_dominant_radical_atom_keys(gra)
    single_bonds = bonds_of_order(gra, mbond=1)

    for rad_idx in rad_idxs:
        rad_neighs = atoms_neighbor_atom_keys(gra)[rad_idx]
        for single_bond in single_bonds:
            bond = frozenset(single_bond)
            if rad_neighs & bond and rad_idx not in bond:
                gra2 = remove_bonds(gra, [bond])
                disconn_gras = automol.graph.connected_components(gra2)
                prod_gras += (disconn_gras, )

    return _unique_gras(prod_gras)
Пример #6
0
def elimination(rct_gras, prd_gras):
    """ find an elimination transformation

    Eliminations are identified by breaking two bonds from the reactant,
    forming three fragments. This will form one "central fragment" with two
    break sites and two "end fragments" with one break site each. If the
    central fragment plus the two end fragments, joined at their break sites,
    matches the products, this is an elimination reaction.
    """
    _assert_is_valid_reagent_graph_list(rct_gras)
    _assert_is_valid_reagent_graph_list(prd_gras)

    tras = []
    rct_idxs = None
    prd_idxs = None

    is_triv = is_trivial_reaction(rct_gras, prd_gras)

    if len(rct_gras) == 1 and len(prd_gras) == 2 and not is_triv:
        rct_gra, = rct_gras
        rct_bnd_keys = bond_keys(rct_gra)
        # Loop over pairs of bonds and break them. Then, if this forms three
        # fragments, join the two end fragments and compare the result to the
        # products.
        for brk_bnd_key1, brk_bnd_key2 in itertools.combinations(rct_bnd_keys,
                                                                 r=2):
            rct_gra_ = remove_bonds(rct_gra, [brk_bnd_key1, brk_bnd_key2])

            # Find the central fragment, which is the one connected to both
            # break sites. If there's a loop there may not be a central
            # fragment, in which case this function will return None.
            cent_frag_atm_keys = _central_fragment_atom_keys(
                rct_gra_, brk_bnd_key1, brk_bnd_key2)
            if cent_frag_atm_keys is not None:
                atm1_key, = brk_bnd_key1 - cent_frag_atm_keys
                atm2_key, = brk_bnd_key2 - cent_frag_atm_keys
                frm_bnd_key = frozenset({atm1_key, atm2_key})
                rct_gra_ = add_bonds(rct_gra_, [frm_bnd_key])

                prd_gra = union_from_sequence(prd_gras)
                atm_key_dct = full_isomorphism(rct_gra_, prd_gra)
                if atm_key_dct:
                    tra = trans.from_data(
                        rxn_class=par.REACTION_CLASS.ELIMINATION,
                        frm_bnd_keys=[frm_bnd_key],
                        brk_bnd_keys=[brk_bnd_key1, brk_bnd_key2])
                    tras.append(tra)

                    rct_idxs = (0, )

                    cent_prd_atm_keys = frozenset(
                        map(atm_key_dct.__getitem__, cent_frag_atm_keys))

                    if cent_prd_atm_keys <= atom_keys(prd_gras[0]):
                        prd_idxs = (0, 1)
                    else:
                        assert cent_prd_atm_keys <= atom_keys(prd_gras[1])
                        prd_idxs = (1, 0)

    tras = tuple(tras)
    return tras, rct_idxs, prd_idxs