コード例 #1
0
def test_full_calc_with_xtb():

    sn2_neb = neb.NEB(
        initial_species=Species(name='inital',
                                charge=-1,
                                mult=0,
                                atoms=xyz_file_to_atoms('sn2_init.xyz')),
        final_species=Species(name='final',
                              charge=-1,
                              mult=0,
                              atoms=xyz_file_to_atoms('sn2_final.xyz')),
        num=14)

    sn2_neb.interpolate_geometries()

    xtb = XTB()

    # Don't run the NEB without a working XTB install
    if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'):
        return

    xtb.path = shutil.which('xtb')
    sn2_neb.calculate(method=xtb, n_cores=2)

    # There should be a peak in this surface
    assert len(list(sn2_neb.get_species_saddle_point())) > 0

    assert all(image.energy is not None for image in sn2_neb.images)

    energies = [image.energy for image in sn2_neb.images]
    path_energy = sum(energy - min(energies) for energy in energies)

    assert 0.35 < path_energy < 0.45
コード例 #2
0
def test_get_ts_guess_neb():

    reactant = Reactant(name='inital',
                        charge=-1,
                        mult=0,
                        solvent_name='water',
                        atoms=xyz_file_to_atoms(init_xyz))

    product = Reactant(name='final',
                       charge=-1,
                       mult=0,
                       solvent_name='water',
                       atoms=xyz_file_to_atoms(final_xyz))

    xtb = XTB()

    # Don't run the NEB without a working XTB install
    if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'):
        return

    xtb.path = shutil.which('xtb')

    ts_guess = neb.get_ts_guess_neb(reactant, product, method=xtb, n=10)

    assert ts_guess is not None
    # Approximate distances at the TS guess
    assert 1.8 < ts_guess.get_distance(0, 2) < 2.2  # C-F
    assert 1.9 < ts_guess.get_distance(2, 1) < 2.3  # C-Cl

    if os.path.exists('NEB'):
        shutil.rmtree('NEB')

    if os.path.exists('neb.xyz'):
        os.remove('neb.xyz')
コード例 #3
0
ファイル: test_graphs.py プロジェクト: t-young31/autodE
def test_isomorphic_no_active():
    os.chdir(os.path.join(here, 'data'))

    ts_syn = Conformer(name='syn_ts', charge=-1, mult=0, atoms=xyz_file_to_atoms('E2_ts_syn.xyz'))
    mol_graphs.make_graph(ts_syn)
    mol_graphs.set_active_mol_graph(ts_syn, active_bonds=[(8, 5), (0, 5), (1, 2)])

    ts_anti = Conformer(name='anti_ts', charge=-1, mult=0, atoms=xyz_file_to_atoms('E2_ts.xyz'))
    mol_graphs.make_graph(ts_anti)

    assert mol_graphs.is_isomorphic(ts_syn.graph, ts_anti.graph, ignore_active_bonds=True)

    os.chdir(here)
コード例 #4
0
def test_graph_no_other_bonds():

    reac = Reactant(name='r',
                    atoms=xyz_file_to_atoms('h_shift_correct_ts_mode.xyz'))
    br = BondRearrangement(breaking_bonds=[(1, 10)],
                           forming_bonds=[(5, 10)])

    calc = Calculation(name='h_shift',
                       molecule=reac,
                       method=orca,
                       keywords=orca.keywords.opt_ts,
                       n_cores=1)
    calc.output.filename = 'h_shift_correct_ts_mode.out'
    calc.output.file_lines = open('h_shift_correct_ts_mode.out', 'r').readlines()

    f_ts = Species(name='f_displaced', charge=0, mult=1,
                   atoms=get_displaced_atoms_along_mode(calc,
                                                        mode_number=6,
                                                        disp_magnitude=1.0))

    b_ts = Species(name='b_displaced', charge=0, mult=1,
                   atoms=get_displaced_atoms_along_mode(calc,
                                                        mode_number=6,
                                                        disp_magnitude=-1.0))

    assert not imag_mode_generates_other_bonds(ts=reac,
                                               f_species=f_ts,
                                               b_species=b_ts,
                                               bond_rearrangement=br)
コード例 #5
0
ファイル: molecules.py プロジェクト: duartegroup/gap-train
    def __init__(self,
                 xyz_filename=None,
                 charge=0,
                 spin_multiplicity=1,
                 gmx_itp_filename=None,
                 atoms=None):
        """Molecule e.g. H2O

        -----------------------------------------------------------------------
        :param xyz_filename: (str)

        :param charge: (int)

        :param spin_multiplicity: (int)

        :param gmx_itp_filename: (str) Filename(path) of the GROMACS .itp file
                                 containing MM parameters required to simulate

        :param atoms: (list(autode.atoms.Atom))
        """
        if xyz_filename is not None:
            atoms = xyz_file_to_atoms(xyz_filename)

        super().__init__(charge=charge,
                         spin_multiplicity=spin_multiplicity,
                         atoms=atoms)

        self.itp_filename = gmx_itp_filename
        self.name = str(self)

        logger.info(f'Initialised {self.name}\n'
                    f'Number of atoms      = {self.n_atoms}\n'
                    f'GROMACS itp filename = {self.itp_filename}')
コード例 #6
0
def test_translate_rotate():

    reactant = ReactantComplex(
        Reactant(name='F-', charge=-1, atoms=[Atom('F')]),
        Reactant(name='alkeneCl', atoms=xyz_file_to_atoms('alkene.xyz')))

    assert len(reactant.molecules) == 2

    # Initially the geometry is not sensible
    assert reactant.get_distance(0, 2) < 1.0

    # SN2' bond rearrangement
    bond_rearr = BondRearrangement(forming_bonds=[(0, 1)],
                                   breaking_bonds=[(3, 4)])

    translate_rotate_reactant(reactant, bond_rearr, shift_factor=1.5)
    assert len(reactant.atoms) == 10
    os.remove('complex.xyz')

    # The geometry should now be sensible
    for i in range(1, 10):
        assert reactant.get_distance(0, i) > 2.0

    # Should be closer to the end carbon than the middle
    assert reactant.get_distance(0, 1) < reactant.get_distance(0, 2)
コード例 #7
0
ファイル: conf_gen.py プロジェクト: gabegomes/autodE
def get_atoms_from_generated_file(species, xyz_filename):
    """
    Get atoms from a previously generated  .xyz file, if the atoms match

    Arguments:
        species (autode.species.Species):
        xyz_filename (str):

    Returns:
        (list(autode.atoms.Atoms)) or None: Atoms from file
    """

    if not os.path.exists(xyz_filename):
        return None

    atoms = xyz_file_to_atoms(filename=xyz_filename)

    if len(atoms) != species.n_atoms:
        return None

    all_atoms_match = all(atoms[i].label == species.atoms[i].label
                          for i in range(species.n_atoms))

    if all_atoms_match:
        logger.info('Conformer has already been generated')
        return atoms

    return None
コード例 #8
0
ファイル: test_neb.py プロジェクト: gabegomes/autodE
def test_get_ts_guess_neb():

    reactant = Reactant(name='inital',
                        charge=-1,
                        mult=0,
                        solvent_name='water',
                        atoms=xyz_file_to_atoms('sn2_init.xyz'))

    product = Reactant(name='final',
                       charge=-1,
                       mult=0,
                       solvent_name='water',
                       atoms=xyz_file_to_atoms('sn2_final.xyz'))

    xtb = XTB()

    # Don't run the NEB without a working XTB install
    if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'):
        return

    xtb.path = shutil.which('xtb')

    ts_guess = get_ts_guess_neb(reactant, product, method=xtb, n=10)

    assert ts_guess is not None
    # Approximate distances at the TS guess
    assert 1.8 < ts_guess.distance(0, 2) < 2.3  # C-F
    assert 1.9 < ts_guess.distance(2, 1) < 2.5  # C-Cl

    if os.path.exists('NEB'):
        shutil.rmtree('NEB')

    if os.path.exists('neb.xyz'):
        os.remove('neb.xyz')

    # Trying to get a TS guess with an unavailable method should return None
    # as a TS guess
    orca = ORCA()
    orca.path = None

    orca_ts_guess = get_ts_guess_neb(reactant, product, method=orca, n=10)
    assert orca_ts_guess is None
コード例 #9
0
    def _init_xyz_file(self, xyz_filename):
        """Initialise a molecule from a .xyz file"""
        logger.info('Generating species from .xyz file')

        self.set_atoms(atoms=xyz_file_to_atoms(xyz_filename))

        # Override the default name with something more descriptive
        if self.name == 'molecule' or self.name.endswith('.xyz'):
            self.name = xyz_filename.rstrip('.xyz')

        return None
コード例 #10
0
def test_xyz_file_incorrect_first_line():
    with open('test.xyz', 'w') as xyz_file:
        print('XXX',
              'wrong first line',
              'H   0.0   0.0   0.0',
              sep='\n', file=xyz_file)

    with pytest.raises(XYZfileWrongFormat):
        _ = xyz_file_to_atoms('test.xyz')

    os.remove('test.xyz')
コード例 #11
0
def test_xyz_file_incorrect_n_atoms():

    with open('test.xyz', 'w') as xyz_file:
        print('2',
              'wrongly declared number of atoms',
              'H   0.0   0.0   0.0',
              sep='\n', file=xyz_file)

    with pytest.raises(XYZfileWrongFormat):
        _ = xyz_file_to_atoms('test.xyz')

    os.remove('test.xyz')
コード例 #12
0
def test_xyz_file_to_atoms():

    atoms = xyz_file_to_atoms(filename='opt_orca.xyz')
    assert len(atoms) == 5
    assert type(atoms) == list
    assert type(atoms[0]) == Atom
    assert atoms[0].coord[0] == -0.137572

    with pytest.raises(XYZfileDidNotExist):
        xyz_file_to_atoms(filename='test')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='opt_orca_broken.xyz')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='opt_orca_broken2.xyz')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='wrong_ext.mol')
コード例 #13
0
ファイル: test_truncation.py プロジェクト: gabegomes/autodE
def test_large_truncation():

    mol = ReactantComplex(
        Reactant(name='product', atoms=xyz_file_to_atoms('product.xyz')))

    bond_rearr = BondRearrangement(breaking_bonds=[(7, 8), (14, 18)])

    assert mol.n_atoms == 50

    truncated = get_truncated_complex(r_complex=mol,
                                      bond_rearrangement=bond_rearr)

    assert truncated.n_atoms == 27
    assert truncated.graph.number_of_edges() == 28
コード例 #14
0
def test_attack_cost():

    subst_centers = substitution.get_substitution_centres(reactant=reac_complex,
                                                          bond_rearrangement=bond_rearr,
                                                          shift_factor=2)

    ideal_complex = ReactantComplex(f, ch3cl)
    ideal_complex.set_atoms(atoms=xyz_file_to_atoms(os.path.join(here, 'data', 'sn2_reac_complex.xyz')))

    attack_cost = substitution.attack_cost(reac_complex, subst_centers, attacking_mol_idx=0)
    ideal_attack_cost = substitution.attack_cost(ideal_complex, subst_centers, attacking_mol_idx=0)

    # The cost function should be larger for the randomly located reaction complex compared to the ideal
    assert attack_cost > ideal_attack_cost
コード例 #15
0
ファイル: test_truncation.py プロジェクト: gabegomes/autodE
def test_two_component_truncation():

    propylbromide = Reactant(name='RBr', atoms=xyz_file_to_atoms('RBr.xyz'))
    chloride = Reactant(name='Cl', smiles='[Cl-]')

    mol = ReactantComplex(chloride, propylbromide)
    bond_rearr = BondRearrangement(forming_bonds=[(0, 3)],
                                   breaking_bonds=[(3, 4)])

    truncated = get_truncated_complex(r_complex=mol,
                                      bond_rearrangement=bond_rearr)

    # Should truncate to ethylbromide + Cl-
    assert truncated.n_atoms == 9
コード例 #16
0
    def set_atoms(self, xyz_filename=None, atoms=None):
        """
        Set self.atoms from either an xyz file or a list of atoms

        :param xyz_filename: (str)
        :param atoms: (list(autode.atoms.Atom))
        """
        if xyz_filename is not None:
            self.atoms = xyz_file_to_atoms(xyz_filename)

        if atoms is not None:
            self.atoms = atoms

        self.forces = None
        return None
コード例 #17
0
def test_subst():

    reactant = Reactant(name='sn2_r', atoms=xyz_file_to_atoms('reactant.xyz'))

    # SN2' bond rearrangement
    bond_rearr = BondRearrangement(forming_bonds=[(0, 1)],
                                   breaking_bonds=[(3, 4)])

    subst_centers = get_substitution_centres(reactant,
                                             bond_rearr,
                                             shift_factor=1.0)

    assert len(subst_centers) == 1

    # get_substitution_centres should add a dummy atom so the ACX angle is
    # defined
    assert len(reactant.atoms) == 11
コード例 #18
0
def test_xyz_file_to_atoms():

    os.chdir(os.path.join(here, 'data'))

    atoms = xyz_file_to_atoms(filename='opt_orca.xyz')
    assert len(atoms) == 5
    assert type(atoms) == list
    assert type(atoms[0]) == Atom
    assert atoms[0].coord[0] == -0.137572

    with pytest.raises(XYZfileDidNotExist):
        xyz_file_to_atoms(filename='test')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='opt_orca_broken.xyz')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='opt_orca_broken2.xyz')

    with pytest.raises(XYZfileWrongFormat):
        xyz_file_to_atoms(filename='opt_orca.out')

    os.chdir(here)
コード例 #19
0
ファイル: test_ts.py プロジェクト: jmgx30/autodE
def test_optts_no_reactants_products():

    da_ts_guess = TSguess(atoms=xyz_file_to_atoms('da_TS_guess.xyz'))
    da_ts = TransitionState(da_ts_guess)
    da_ts.optimise()

    assert len(da_ts.imaginary_frequencies) == 1
    imag_freq = da_ts.imaginary_frequencies[0]

    assert -500 < imag_freq < -300  # cm-1

    # Should raise exceptions for TSs not initialised with reactants and
    # products
    with pytest.raises(ValueError):
        _ = da_ts.could_have_correct_imag_mode()

    with pytest.raises(ValueError):
        _ = da_ts.has_correct_imag_mode()
コード例 #20
0
def test_random_grid_positions():

    system = System(box_size=[10, 12, 14])
    methane = Molecule(os.path.join(here, 'data', 'methane.xyz'))
    system.add_molecules(methane, n=5)

    config = system.random(grid=True)
    config.save(filename='test_random.xyz')

    # Minimum pairwise distance should be ~ the C-H distance (1.109 Å)
    atoms = xyz_file_to_atoms('test_random.xyz')
    coords = np.array([atom.coord for atom in atoms])
    dist_matrix = distance_matrix(coords, coords)

    # Distance matrix has zeros along the diagonals so add the identity
    assert np.min(dist_matrix + 9 * np.identity(len(coords))) > 1.1

    os.remove('test_random.xyz')
コード例 #21
0
ファイル: rmsd.py プロジェクト: t-young31/autodE
def get_and_copy_unique_confs(xyz_filenames, only_heavy_atoms, threshold_rmsd):
    """For each xyz file generate a species and copy it to a folder if it is
    unique based on an RMSD threshold"""

    molecules = [
        Species(name=fn.rstrip('.xyz'),
                atoms=xyz_file_to_atoms(fn),
                charge=0,
                mult=1) for fn in xyz_filenames
    ]

    if only_heavy_atoms:
        molecules = get_molecules_no_hydrogens(molecules)

    unique_mol_ids = []

    for i in range(len(molecules)):
        mol = molecules[i]

        is_unique = True

        for j in unique_mol_ids:
            rmsd = calc_rmsd(coords1=mol.get_coordinates(),
                             coords2=molecules[j].get_coordinates())

            if rmsd < threshold_rmsd:
                is_unique = False
                break

        if is_unique:
            unique_mol_ids.append(i)

    print('Number of unique molecules = ', len(unique_mol_ids))

    # Copy all the unique .xyz files to a new folder
    if not os.path.exists(folder_name):
        os.mkdir(folder_name)

    for i in unique_mol_ids:
        xyz_filename = xyz_filenames[i]
        copyfile(xyz_filename, os.path.join(folder_name, xyz_filename))

    return None
コード例 #22
0
def has_correct_mode(name, fbonds, bbonds):

    reac = Reactant(name='r', atoms=xyz_file_to_atoms(f'{name}.xyz'))

    calc = Calculation(name=name,
                       molecule=reac,
                       method=orca,
                       keywords=orca.keywords.opt_ts,
                       n_cores=1)

    calc.output.filename = f'{name}.out'
    calc.output.file_lines = open(f'{name}.out', 'r').readlines()

    bond_rearr = BondRearrangement(breaking_bonds=bbonds,
                                   forming_bonds=fbonds)

    # Don't require all bonds to be breaking/making in a 'could be ts' function
    return imag_mode_has_correct_displacement(calc, bond_rearr,
                                              delta_threshold=0.05,
                                              req_all=False)
コード例 #23
0
def test_removing_active_bonds():

    filepath = os.path.join(here, 'data', 'neb', 'co_complex.xyz')

    mol = Molecule(name='co_complex', atoms=xyz_file_to_atoms(filepath))

    bbond = BreakingBond(atom_indexes=(1, 2), species=mol)
    fbond = FormingBond(atom_indexes=(3, 1), species=mol)

    bonds = neb.active_bonds_no_rings(mol, fbonds=[fbond], bbonds=[bbond])

    # Should remove the breaking bond as it forms a ring with an already
    # present atom pair
    assert len(bonds) == 1
    assert isinstance(bonds[0], FormingBond)

    # Also check that the number of images to generate are somewhat reasonable
    n_images = neb.calc_n_images(fbonds=[fbond],
                                 bbonds=[bbond],
                                 average_spacing=0.1)
    assert 0 < n_images < 20
コード例 #24
0
def test_mp2_numerical_gradients():

    calc = Calculation(
        name='tmp',
        molecule=Molecule(atoms=xyz_file_to_atoms('tmp_orca.xyz')),
        method=method,
        keywords=method.keywords.grad)
    calc.output.filename = 'tmp_orca.out'
    calc.output.file_lines = open(calc.output.filename, 'r').readlines()

    gradients = calc.get_gradients()
    assert len(gradients) == 6
    expected = np.array([-0.00971201, -0.00773534, -0.02473580
                         ]) / Constants.a02ang
    assert np.linalg.norm(expected - gradients[0]) < 1e-6

    # Test for different printing with numerical..
    calc.output.filename = 'numerical_orca.out'
    calc.output.file_lines = open(calc.output.filename, 'r').readlines()
    gradients = calc.get_gradients()
    assert len(gradients) == 6
    expected = np.array([0.012397372, 0.071726232, -0.070942743
                         ]) / Constants.a02ang
    assert np.linalg.norm(expected - gradients[0]) < 1e-6
コード例 #25
0
ファイル: vaskas_conformers.py プロジェクト: t-young31/autodE
from autode import Molecule
from autode.input_output import xyz_file_to_atoms
from autode.conformers import conf_gen, Conformer
from autode.methods import XTB

# Initialise the complex from a .xyz file containing a square planar structure
vaskas = Molecule(name='vaskas', atoms=xyz_file_to_atoms('vaskas.xyz'))

# Set up some distance constraints where the keys are the atom indexes and
# the value the distance in Å. Fixing the Cl-P, Cl-P and Cl-C(=O) distances
# enforces a square planar geometry
distance_constraints = {
    (1, 2): vaskas.get_distance(1, 2),
    (1, 3): vaskas.get_distance(1, 3),
    (1, 4): vaskas.get_distance(1, 4)
}

# Generate 5 conformers
for n in range(5):

    # Apply random displacements to each atom and minimise under a bonded +
    # repulsive forcefield including the distance constraints
    atoms = conf_gen.get_simanl_atoms(species=vaskas,
                                      dist_consts=distance_constraints,
                                      conf_n=n)

    # Generate a conformer from these atoms then optimise with XTB
    conformer = Conformer(name=f'vaskas_conf{n}', atoms=atoms)

    conformer.optimise(method=XTB())
    conformer.print_xyz_file()
コード例 #26
0
ファイル: benchmark.py プロジェクト: t-young31/autodE
                Product(name='diene2', smiles='C/C=C/CC/C=C/C'),
                name='cope_rearrangement')

da = Reaction(Reactant(name='butadiene', smiles='C=CC=C'),
              Reactant(name='ethene', smiles='C=C'),
              Product(name='cyclohexene', smiles='C1C=CCCC1'),
              name='diels_alder')

h_shift = Reaction(Reactant(name='radical1', smiles='CC[C]([H])[H]'),
                   Product(name='radical2', smiles='C[C]([H])C'),
                   name='h_shift')

int1_xyz = os.path.join(data_path, 'INT1.xyz')
int2_xyz = os.path.join(data_path, 'INT2.xyz')

mig_insert = Reaction(Reactant(name='INT1', atoms=xyz_file_to_atoms(int1_xyz)),
                      Product(name='INT2', atoms=xyz_file_to_atoms(int2_xyz)),
                      name='h_insert')

print(f'Name            v_imag / cm-1       Time / min         Success')
for reaction in [sn2, cope, da, h_shift, mig_insert]:

    start_time = time()
    reaction.locate_transition_state()
    freq = reaction.ts.imaginary_frequencies[0]

    print(f'{reaction.name:.15}'
          f'{freq:15.1f}'
          f'{(time()- start_time)/60:15.1f}'
          f'{"✓" if freq < -100 else "✗":.15s}')