Ejemplo n.º 1
0
def test_get_bond_rearrangs():

    if os.path.exists('test_bond_rearrangs.txt'):
        os.remove('test_bond_rearrangs.txt')

    # ethane --> Ch3 + Ch3
    reac = Molecule(smiles='CC')
    prod = Molecule(atoms=[Atom('C', -8.3, 1.4, 0.0),
                           Atom('C', 12, 1.7, -0.0),
                           Atom('H', -8.6, 0.5, -0.5),
                           Atom('H', -8.6, 2.3, -0.4),
                           Atom('H', -8.6, 1.3, 1),
                           Atom('H', 12.3, 1.7, -1.0),
                           Atom('H', 12.4, 0.8, 0.4),
                           Atom('H', 12.3, 2.5, 0.5)])

    assert br.get_bond_rearrangs(ReactantComplex(reac), ProductComplex(prod), name='test') == [br.BondRearrangement(breaking_bonds=[(0, 1)])]

    # Rerunning the get function should read test_bond_rearrangs.txt, so modify it, swapping 0 and 1 in the breaking
    # bond then reopen
    with open('test_bond_rearrangs.txt', 'w') as rearr_file:
        print('fbond\n'
              'bbonds\n'
              '1 0\n'
              'end', file=rearr_file)

    rearr = br.get_bond_rearrangs(ReactantComplex(reac), ProductComplex(prod), name='test')[0]
    assert rearr == BondRearrangement(breaking_bonds=[(1, 0)])

    assert br.get_bond_rearrangs(ReactantComplex(prod), ProductComplex(reac), name='test2') is None

    # If reactants and products are identical then the rearrangement is undetermined
    assert br.get_bond_rearrangs(ReactantComplex(reac), ProductComplex(reac), name='test3') is None

    os.remove('test_bond_rearrangs.txt')
Ejemplo n.º 2
0
def test_one_to_three_dissociation():

    r = Reactant(name='tet_int', smiles='CC(OS(Cl)=O)(Cl)O')
    p1 = Product(name='acyl', smiles='CC(Cl)=[OH+]')
    p2 = Product(name='so2', smiles='O=S=O')
    p3 = Product(name='chloride', smiles='[Cl-]')

    reaction = Reaction(r, p1, p2, p3, solvent_name='thf')
    assert reaction.type is Dissociation

    # Generate reactants and product complexes then find the single possible
    # bond rearrangement
    reactant, product = get_complexes(reaction)
    reaction.reactant, reaction.product = reactant, product
    bond_rearrangs = get_bond_rearrangs(reactant, product, name=str(reaction))
    assert len(bond_rearrangs) == 1
    os.remove(f'{str(reaction)}_bond_rearrangs.txt')

    # This dissociation breaks two bonds and forms none
    bond_rearrangement = bond_rearrangs[0]
    assert len(bond_rearrangement.fbonds) == 0
    assert len(bond_rearrangement.bbonds) == 2

    # Ensure there is at least one bond function that could give the TS
    ts_funcs_params = get_ts_guess_function_and_params(reaction,
                                                       bond_rearrangement)
    assert len(list(ts_funcs_params)) > 0
Ejemplo n.º 3
0
def get_truncated_ts(reaction, bond_rearr):
    """Get the TS of a truncated reactant and product complex"""

    # Truncate the reactant and product complex to the core atoms so the full
    # TS can be template-d
    f_reactant = reaction.reactant.copy()
    f_product = reaction.product.copy()

    # Set the truncated reactant and product for this reaction
    reaction.reactant = get_truncated_complex(f_reactant, bond_rearr)
    reaction.product = get_truncated_complex(f_product, bond_rearr)

    # Re-find the bond rearrangements, which should exist
    reaction.name += '_truncated'
    bond_rearrangs = get_bond_rearrangs(reaction.reactant,
                                        reaction.product,
                                        name=reaction.name)

    if bond_rearrangs is None:
        logger.error('Truncation generated a complex with 0 rearrangements')
        return None

    # Find all the possible TSs
    for bond_rearr in bond_rearrangs:
        get_ts(reaction, reaction.reactant, bond_rearr, is_truncated=True)

    # Reset the reactant, product and name of the full reaction
    reaction.reactant = f_reactant
    reaction.product = f_product
    reaction.name = reaction.name.rstrip('_truncated')

    logger.info('Done with truncation')
    return None
Ejemplo n.º 4
0
def test_3b():
    reac = Molecule(atoms=[Atom('H', 0, 0, 0), Atom('H', 0.6, 0, 0), Atom('H', 1.2, 0, 0), Atom('H', 1.8, 0, 0)])
    make_graph(reac, allow_invalid_valancies=True)
    prod = Molecule(atoms=[Atom('H', 0, 0, 0), Atom('H', 10, 0, 0), Atom('H', 20, 0, 0), Atom('H', 30, 0, 0)])

    # Reactants to products must break three bonds but this is not yet supported in any form
    assert br.get_bond_rearrangs(ReactantComplex(reac), ProductComplex(prod), name='3b_test') is None
Ejemplo n.º 5
0
def test_2b():
    reac = Molecule(atoms=[Atom('H', 0, 0, 0), Atom('H', 0.6, 0, 0), Atom('H', 1.2, 0, 0)])
    make_graph(reac, allow_invalid_valancies=True)
    prod = Molecule(atoms=[Atom('H', 0, 0, 0), Atom('H', 10, 0, 0), Atom('H', 20, 0, 0)])

    # Reactants to products must break two bonds
    assert len(br.get_bond_rearrangs(ReactantComplex(reac), ProductComplex(prod), name='2b_test')) == 1
    os.remove('2b_test_bond_rearrangs.txt')

    assert br.get_fbonds_bbonds_2b(reac, prod, [], [[(0, 1), (1, 2)]], [], [], [(0, 2)], []) == [br.BondRearrangement(breaking_bonds=[(0, 1), (1, 2)])]
Ejemplo n.º 6
0
def test_two_possibles():

    ch2ch3f = Molecule(name='radical', charge=0, mult=2,
                       smiles='FC[C]([H])[H]')

    ch3ch2f = Molecule(name='radical', charge=0, mult=2,
                       smiles='C[C]([H])F')

    rearrs = br.get_bond_rearrangs(ReactantComplex(ch2ch3f), ProductComplex(ch3ch2f),
                                   name='H_migration')

    # There are two possibilities for H migration by they should be considered the same
    assert len(rearrs) == 1
    os.remove('H_migration_bond_rearrangs.txt')
Ejemplo n.º 7
0
def test_multiple_possibilities():
    r1 = Molecule(name='h_dot', smiles='[H]')
    r2 = Molecule(name='methane', smiles='C')
    p1 = Molecule(name='h2', smiles='[HH]')
    p2 = Molecule(name='ch3_dot', smiles='[CH3]')

    reac = ReactantComplex(r1, r2)
    reac.print_xyz_file()

    rearrs = br.get_bond_rearrangs(reac, ProductComplex(p1, p2),
                                   name='H_subst')
    os.remove('H_subst_bond_rearrangs.txt')

    # All H abstractions are the same
    assert len(rearrs) == 1
Ejemplo n.º 8
0
def test_detection():

    # F- + H2CCHCH2Cl -> FCH2CHCH2 + Cl-
    reaction = Reaction(Reactant(name='F-', charge=-1, atoms=[Atom('F')]),
                        Reactant(name='alkeneCl', smiles='C=CCCl'),
                        Product(name='alkeneF', smiles='C=CCF'),
                        Product(name='Cl-', charge=-1, atoms=[Atom('Cl')]))

    assert reaction.type == Substitution

    reactant, product = get_complexes(reaction)

    bond_rearrs = get_bond_rearrangs(reactant, product, name='SN2')

    # autodE should find both direct SN2 and SN2' pathways
    assert len(bond_rearrs) == 2
    os.remove('SN2_bond_rearrangs.txt')
Ejemplo n.º 9
0
def test_prune_small_rings2():
    reaction = ade.Reaction('CCCC=C>>C=C.C=CC')
    reaction.find_complexes()

    ade.Config.skip_small_ring_tss = False
    bond_rearrs = br.get_bond_rearrangs(reactant=reaction.reactant,
                                        product=reaction.product,
                                        name='tmp',
                                        save=False)
    assert len(bond_rearrs) > 2

    ade.Config.skip_small_ring_tss = True

    br.prune_small_ring_rearrs(bond_rearrs, reaction.reactant)
    assert len(bond_rearrs) == 2

    # Should find the 6-membered TS
    assert (bond_rearrs[0].n_membered_rings(reaction.reactant) == [6]
            or bond_rearrs[1].n_membered_rings(reaction.reactant) == [6])
Ejemplo n.º 10
0
def find_tss(reaction):
    """Find all the possible the transition states of a reaction

    Arguments:
        reaction (list(autode.reaction.Reaction)): Reaction

    Returns:
        list: list of transition state objects
    """
    logger.info('Finding possible transition states')
    reactant, product = reaction.reactant, reaction.product

    if species_are_isomorphic(reactant, product):
        logger.error('Reactant and product complexes are isomorphic. Cannot'
                     ' find a TS')
        return None

    bond_rearrs = get_bond_rearrangs(reactant, product, name=str(reaction))

    if bond_rearrs is None:
        logger.error('Could not find a set of forming/breaking bonds')
        return None

    tss = []
    for bond_rearrangement in bond_rearrs:
        logger.info(f'Locating transition state using active bonds '
                    f'{bond_rearrangement.all}')

        ts = get_ts(reaction, reactant, bond_rearrangement)

        if ts is not None:
            tss.append(ts)

    if len(tss) == 0:
        logger.error('Did not find any transition state(s)')
        return None

    logger.info(
        f'Found *{len(tss)}* transition state(s) that lead to products')
    return tss