Example #1
0
        def check_isomorphic(conformer):
            """
            Compares whatever is in the log file 'f' 
            to the SMILES of the passed in 'conformer'
            """
            starting_molecule = RMGMolecule(smiles=conformer.smiles)
            starting_molecule = starting_molecule.to_single_bonds()

            atoms = self.read_log(
                os.path.join(scratch_dir, f)
            )

            test_molecule = RMGMolecule()
            test_molecule.from_xyz(
                atoms.arrays["numbers"],
                atoms.arrays["positions"]
            )
            if not starting_molecule.is_isomorphic(test_molecule):
                logging.info(
                    "Output geometry of {} is not isomorphic with input geometry".format(calc.label))
                return False
            else:
                logging.info(
                "{} was successful and was validated!".format(calc.label))
                return True
Example #2
0
    def calculate_symmetry_number(self):

        numbers = self.ase_molecule.numbers
        positions = self.ase_molecule.positions

        mol = RMGMolecule()
        mol.from_xyz(numbers, positions)
        try:
            species = RMGSpecies(molecule=[mol])
            self._symmetry_number = species.get_symmetry_number()
        except ValueError:
            self._symmetry_number = mol.get_symmetry_number()

        return self._symmetry_number
Example #3
0
def geo_to_mol(coords, nums):
    """
    Convert molecular geometry specified by atomic coordinates and
    atomic numbers to RMG molecule.

    Use Open Babel for most cases because it's better at recognizing
    long bonds. Use RMG for hydrogen because Open Babel can't do it for
    mysterious reasons.
    """
    if list(nums) == [1, 1]:
        mol = Molecule()
        mol.from_xyz(nums, coords)
    else:
        xyz = '{}\n\n'.format(len(nums))
        xyz += '\n'.join(
            '{0}  {1[0]: .10f}  {1[1]: .10f}  {1[2]: .10f}'.format(n, c)
            for n, c in zip(nums, coords))
        mol = pybel.readstring('xyz', xyz)
        mol = pybel_to_rmg(mol)
    return mol
Example #4
0
    def opt_conf(i, rmsd_cutoff):
        """
        A helper function to optimize the geometry of a conformer.
        Only for use within this parent function
        """
        conformer = conformers[i]

        calculator = conformer.ase_molecule.get_calculator()

        labels = []
        for bond in conformer.get_bonds():
            labels.append(bond.atom_indices)
    
        if isinstance(conformer, TS):
            label = conformer.reaction_label
            ind1 = conformer.rmg_molecule.get_labeled_atoms("*1")[0].sorting_label
            ind2 = conformer.rmg_molecule.get_labeled_atoms("*3")[0].sorting_label
            labels.append([ind1, ind2])
            type = 'ts'
        else:
            label = conformer.smiles
            type = 'species'

        if isinstance(calc, FileIOCalculator):
            if calculator.directory:
                directory = calculator.directory 
            else: 
                directory = 'conformer_logs'
            calculator.label = "{}_{}".format(conformer.smiles, i)
            calculator.directory = os.path.join(directory, label,'{}_{}'.format(conformer.smiles, i))
            if not os.path.exists(calculator.directory):
                try:
                    os.makedirs(calculator.directory)
                except OSError:
                    logging.info("An error occured when creating {}".format(calculator.directory))

            calculator.atoms = conformer.ase_molecule

        conformer.ase_molecule.set_calculator(calculator)
        opt = BFGS(conformer.ase_molecule, logfile=None)

        if type == 'species':
            if isinstance(i,int):
                c = FixBondLengths(labels)
                conformer.ase_molecule.set_constraint(c)
            try:
                opt.run(steps=1e6)
            except RuntimeError:
                logging.info("Optimization failed...we will use the unconverged geometry")
                pass
            if str(i) == 'ref':
                conformer.update_coords_from("ase")
                try:
                    rmg_mol = Molecule()
                    rmg_mol.from_xyz(
                        conformer.ase_molecule.arrays["numbers"],
                        conformer.ase_molecule.arrays["positions"]
                    )
                    if not rmg_mol.is_isomorphic(reference_mol):
                        logging.info("{}_{} is not isomorphic with reference mol".format(conformer,str(i)))
                        return False
                except AtomTypeError:
                    logging.info("Could not create a RMG Molecule from optimized conformer coordinates...assuming not isomorphic")
                    return False
        
        if type == 'ts':
            c = FixBondLengths(labels)
            conformer.ase_molecule.set_constraint(c)
            try:
                opt.run(fmax=0.20, steps=1e6)
            except RuntimeError:
                logging.info("Optimization failed...we will use the unconverged geometry")
                pass

        conformer.update_coords_from("ase")  
        energy = get_energy(conformer)
        conformer.energy = energy
        if len(return_dict)>0:
            conformer_copy = conformer.copy()
            for index,post in return_dict.items():
                conf_copy = conformer.copy()
                conf_copy.ase_molecule.positions = post
                conf_copy.update_coords_from("ase")
                rmsd = rdMolAlign.GetBestRMS(conformer_copy.rdkit_molecule,conf_copy.rdkit_molecule)
                if rmsd <= rmsd_cutoff:
                    return True
        if str(i) != 'ref':
            return_dict[i] = conformer.ase_molecule.get_positions()
        return True
Example #5
0
    def validate_irc(self):
        """
        A method to verify an IRC calc
        """

        logging.info("Validating IRC file...")
        irc_path = os.path.join(
            self.directory, "ts", self.conformer.reaction_label, "irc",
            self.conformer.reaction_label + "_irc_" +
            self.conformer.direction + "_" + str(self.conformer.index) +
            ".log")

        complete, converged = self.verify_output_file(irc_path)
        if not complete:
            logging.info("It seems that the IRC claculation did not complete")
            return False
        if not converged:
            logging.info("The IRC calculation did not converge...")
            return False

        pth1 = list()
        steps = list()
        with open(irc_path) as output_file:
            for line in output_file:
                line = line.strip()

                if line.startswith('Point Number:'):
                    if int(line.split()[2]) > 0:
                        if int(line.split()[-1]) == 1:
                            pt_num = int(line.split()[2])
                            pth1.append(pt_num)
                        else:
                            pass
                elif line.startswith('# OF STEPS ='):
                    num_step = int(line.split()[-1])
                    steps.append(num_step)
        # This indexes the coordinate to be used from the parsing
        if steps == []:
            logging.error('No steps taken in the IRC calculation!')
            return False
        else:
            pth1End = sum(steps[:pth1[-1]])
            # Compare the reactants and products
            irc_parse = ccread(irc_path)

            atomcoords = irc_parse.atomcoords
            atomnos = irc_parse.atomnos

            mol1 = RMGMolecule()
            mol1.from_xyz(atomnos, atomcoords[pth1End])
            mol2 = RMGMolecule()
            mol2.from_xyz(atomnos, atomcoords[-1])

            test_reaction = RMGReaction(
                reactants=mol1.split(),
                products=mol2.split(),
            )

            r, p = self.conformer.reaction_label.split("_")

            reactants = []
            products = []

            for react in r.split("+"):
                react = RMGMolecule(smiles=react)
                reactants.append(react)

            for prod in p.split("+"):
                prod = RMGMolecule(smiles=prod)
                products.append(prod)

            possible_reactants = []
            possible_products = []
            for reactant in reactants:
                possible_reactants.append(
                    reactant.generate_resonance_structures())

            for product in products:
                possible_products.append(
                    product.generate_resonance_structures())

            possible_reactants = list(itertools.product(*possible_reactants))
            possible_products = list(itertools.product(*possible_products))

            for possible_reactant in possible_reactants:
                reactant_list = []
                for react in possible_reactant:
                    reactant_list.append(react.to_single_bonds())

                for possible_product in possible_products:
                    product_list = []
                    for prod in possible_product:
                        product_list.append(prod.to_single_bonds())

                    target_reaction = RMGReaction(
                        reactants=list(reactant_list),
                        products=list(product_list))

                    if target_reaction.is_isomorphic(test_reaction):
                        logging.info("IRC calculation was successful!")
                        return True
            logging.info("IRC calculation failed for {} :(".format(irc_path))
            return False