示例#1
0
    def get_irc_calc(self,
                     ts=None,
                     mem="5GB",
                     nprocshared=20,
                     scratch=".",
                     method="m062x",
                     basis="6-311+g(2df,2p)"):
        "A method to create the IRC calculator object"

        if ts is None:
            if self.ts is None:
                return None
            elif not isinstance(self.conformer, TS):
                return None
            else:
                ts = self.conformer

        ts.rmg_molecule.updateMultiplicity()
        label = ts.reaction_label.replace(
            "(", "left").replace(")", "right") + "_irc_" + str(ts.index)

        calc = ASEGaussian(mem=mem,
                           nprocshared=nprocshared,
                           label=label,
                           scratch=scratch,
                           method=method,
                           basis=basis,
                           extra="irc=(calcall)",
                           multiplicity=ts.rmg_molecule.multiplicity)
        calc.atoms = ts.ase_molecule
        del calc.parameters['force']

        return calc
示例#2
0
    def get_overall_calc(self,
                         ts=None,
                         direction="forward",
                         settings=None,
                         scratch=None):
        """
        A method to create a calculator that optimizes the overall geometry of a `TS` object

        Parameters:
        - ts (TS): A `TS` object that you want to perform calculations on
        - direction (str): the forward or reverse direction of the `TS` object
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """

        if settings is None:
            settings = self.settings
        if scratch is None:
            scratch = self.scratch

        method = settings["method"]
        basis = settings["basis"]
        mem = settings["mem"]
        nprocshared = settings["nprocshared"]

        assert direction.lower() in ["forward", "reverse"]

        assert isinstance(ts, TS), "A TS object was not provided..."

        ts.rmg_molecule.updateMultiplicity()

        label = ts.reaction_label + "_" + direction.lower() + "_" + str(
            ts.index)

        new_scratch = os.path.join(scratch, "ts", ts.reaction_label,
                                   "conformers")

        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        calc = ASEGaussian(
            mem=mem,
            nprocshared=nprocshared,
            label=label,
            scratch=new_scratch,
            method=method,
            basis=basis,
            extra=
            "opt=(ts,calcfc,noeigentest,maxcycles=900) freq scf=(maxcycle=900) IOP(7/33=1,2/16=3)",
            multiplicity=ts.rmg_molecule.multiplicity)
        calc.atoms = ts.ase_molecule
        del calc.parameters['force']

        return calc
示例#3
0
    def get_rotor_calc(self,
                       conformer=None,
                       torsion=None,
                       mem="5GB",
                       nprocshared=20,
                       scratch=".",
                       method="m062x",
                       basis="6-311+g(2df,2p)",
                       steps=36,
                       step_size=10.0):
        """
        A method to create all of the calculators needed to perform hindered rotor calculations given a conformer and a torsion
        """

        assert (torsion and (isinstance(torsion, Torsion))
                ), "To create a rotor calculator, you must provide a Torsion object."

        if not conformer:
            if not self.conformer:
                return None
            conformer = self.conformer

        assert isinstance(
            conformer, Conformer), "A Conformer object was not provided..."

        string = ""
        for bond in conformer.bonds:
            i, j = bond.atom_indices
            string += "B {} {}\n".format(i + 1, j + 1)

        i, j, k, l = torsion.atom_indices
        string += "D {} {} {} {} S {} {}".format(i + 1, j + 1, k + 1, l + 1, steps, float(step_size))

        if isinstance(conformer, TS):
            label = self.label + "_tor_{}_{}".format(j, k)
        elif isinstance(conformer, Conformer):
            label = Chem.rdinchi.InchiToInchiKey(Chem.MolToInchi(
                Chem.MolFromSmiles(conformer.smiles))).strip("-N")
            label += "_tor{}{}".format(j, k)

        label = conformer.smiles + "_tor_{}_{}".format(j, k)
        conformer.rmg_molecule.updateMultiplicity()
        mult = conformer.rmg_molecule.multiplicity

        calc = ASEGaussian(mem=mem,
                           nprocshared=nprocshared,
                           label=label,
                           scratch=scratch,
                           method=method,
                           basis=basis,
                           extra="Opt=(CalcFC,ModRedun)",
                           multiplicity=mult,
                           addsec=[string])

        calc.atoms = conformer.ase_molecule
        del calc.parameters['force']

        return calc
示例#4
0
    def get_center_calc(self):
        """
        A method to create a calculator that optimizes the reaction center of a `TS` object

        Parameters:
        - ts (TS): A `TS` object that you want to perform calculations on
        - direction (str): the forward or reverse direction of the `TS` object
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """

        assert self.conformer.direction.lower() in ["forward", "reverse"]

        assert isinstance(self.conformer,
                          TS), "A TS object was not provided..."

        indicies = []
        for i, atom in enumerate(self.conformer.rmg_molecule.atoms):
            if not (atom.label != ""):
                indicies.append(i)

        addsec = ""
        for combo in list(itertools.combinations(indicies, 2)):
            a, b = combo
            addsec += "{0} {1} F\n".format(a + 1, b + 1)

        self.conformer.rmg_molecule.updateMultiplicity()

        label = self.conformer.reaction_label + "_" + self.conformer.direction.lower(
        ) + "_center_" + str(self.conformer.index)

        new_scratch = os.path.join(self.directory, "ts",
                                   self.conformer.reaction_label, "conformers")

        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        ase_gaussian = ASEGaussian(
            mem=self.settings["mem"],
            nprocshared=self.settings["nprocshared"],
            label=label,
            scratch=new_scratch,
            method=self.settings["method"],
            basis=self.settings["basis"],
            extra=
            "Opt=(ts,calcfc,noeigentest,ModRedun,maxcycles=900) scf=(maxcycle=900)",
            multiplicity=self.conformer.rmg_molecule.multiplicity,
            addsec=[addsec[:-1]])
        ase_gaussian.atoms = self.conformer.ase_molecule
        del ase_gaussian.parameters['force']

        return ase_gaussian
示例#5
0
    def get_shell_calc(self):
        """
        A method to create a calculator that optimizes the reaction shell of a `TS` object

        Parameters:
        - ts (TS): A `TS` object that you want to perform calculations on
        - direction (str): the forward or reverse direction of the `TS` object
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - directory (str): a directory where you want log files to be written to

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """
        assert isinstance(self.conformer,
                          TS), "A TS object was not provided..."
        assert self.conformer.direction.lower() in ["forward", "reverse"]

        self.conformer.rmg_molecule.updateMultiplicity()

        label = self.conformer.reaction_label + "_" + self.conformer.direction.lower(
        ) + "_shell_" + str(self.conformer.index)

        new_scratch = os.path.join(self.directory, "ts",
                                   self.conformer.reaction_label, "conformers")

        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        ind1 = self.conformer.rmg_molecule.getLabeledAtom("*1").sortingLabel
        ind2 = self.conformer.rmg_molecule.getLabeledAtom("*2").sortingLabel
        ind3 = self.conformer.rmg_molecule.getLabeledAtom("*3").sortingLabel

        combos = ""
        combos += "{0} {1} F\n".format(ind1 + 1, ind2 + 1)
        combos += "{0} {1} F\n".format(ind2 + 1, ind3 + 1)
        combos += "{0} {1} {2} F".format(ind1 + 1, ind2 + 1, ind3 + 1)

        ase_gaussian = ASEGaussian(
            mem=self.settings["mem"],
            nprocshared=self.settings["nprocshared"],
            label=label,
            scratch=new_scratch,
            method=self.settings["method"],
            basis=self.settings["basis"],
            extra=
            "Opt=(ModRedun,Loose,maxcycles=900) Int(Grid=SG1) scf=(maxcycle=900)",
            multiplicity=self.conformer.rmg_molecule.multiplicity,
            addsec=[combos])
        ase_gaussian.atoms = self.conformer.ase_molecule
        del ase_gaussian.parameters['force']

        return ase_gaussian
示例#6
0
    def get_conformer_calc(self):
        """
        A method that creates a calculator for a `Conformer` that will perform a geometry optimization

        Parameters:
        - conformer (Conformer): A `Conformer` object that you want to perform hindered rotor calculations on
        - torsion (Torsion): A `Torsion` object that you want to perform hindered rotor calculations about
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to
        - convergence (str): ['verytight','tight','' (default)], specifies the convergence criteria of the geometry optimization

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """

        if isinstance(self.conformer, TS):
            logging.info(
                "TS object provided, cannot obtain a species calculator for a TS"
            )
            return None

        assert isinstance(self.conformer,
                          Conformer), "A Conformer object was not provided..."

        self.conformer.rmg_molecule.updateMultiplicity()

        label = "{}_{}".format(self.conformer.smiles, self.conformer.index)

        new_scratch = os.path.join(self.directory, "species",
                                   self.conformer.smiles, "conformers")

        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        ase_gaussian = ASEGaussian(
            mem=self.settings["mem"],
            nprocshared=self.settings["nprocshared"],
            label=label,
            scratch=new_scratch,
            method=self.settings["method"],
            basis=self.settings["basis"],
            extra=
            "opt=(calcfc,maxcycles=900,{}) freq IOP(7/33=1,2/16=3) scf=(maxcycle=900)"
            .format(self.convergence),
            multiplicity=self.conformer.rmg_molecule.multiplicity)
        ase_gaussian.atoms = self.conformer.ase_molecule
        del ase_gaussian.parameters['force']
        return ase_gaussian
示例#7
0
    def get_center_calc(self,
                        ts=None,
                        mem="5GB",
                        nprocshared=20,
                        scratch=".",
                        method="m062x",
                        basis="6-311+g(2df,2p)"):
        "A method to create a calculator that optimizes the reaction shell"

        if ts is None:
            if self.ts is None:
                return None
            elif not isinstance(self.conformer, TS):
                return None
            else:
                ts = self.conformer

        assert isinstance(ts, TS), "A TS object was not provided..."

        indicies = []
        for i, atom in enumerate(ts.rmg_molecule.atoms):
            if not (atom.label != ""):
                indicies.append(i)

        combos = ""
        for combo in list(itertools.combinations(indicies, 2)):
            a, b = combo
            combos += "{0} {1} F\n".format(a + 1, b + 1)

        ts.rmg_molecule.updateMultiplicity()

        label = ts.reaction_label.replace(
            "(", "left").replace(")", "right") + "_center_" + str(ts.index)

        calc = ASEGaussian(mem=mem,
                           nprocshared=nprocshared,
                           label=label,
                           scratch=scratch,
                           method=method,
                           basis=basis,
                           extra="Opt=(ModRedun,Loose,maxcycles=900) Int(Grid=SG1)",
                           multiplicity=ts.rmg_molecule.multiplicity,
                           addsec=[combos[:-1]])
        calc.atoms = ts.ase_molecule
        del calc.parameters['force']

        return calc
示例#8
0
    def get_species_calc(self,
                         conformer=None,
                         mem="5GB",
                         nprocshared=20,
                         scratch=".",
                         method="m062x",
                         basis="6-311+g(2df,2p)"):
        "A method that creates a calculator for a reactant or product that will perform a geometry optimization"

        if not conformer:
            if not self.conformer:
                return None
            conformer = self.conformer

        if isinstance(conformer, TS):
            logging.info(
                "TS object provided, cannot obtain a species calculator for a TS")
            return None

        assert isinstance(
            conformer, Conformer), "A Conformer object was not provided..."

        conformer.rmg_molecule.updateMultiplicity()

        # using this round about way of doing stuff because rmg's
        # `toAugumentedInChIKey` method doesn't work on our cluster

        smiles = conformer.rmg_molecule.toSMILES()
        label = Chem.rdinchi.InchiToInchiKey(Chem.MolToInchi(
            Chem.MolFromSmiles(smiles))).strip("-N") + "_{}".format(conformer.index)

        calc = ASEGaussian(
            mem=mem,
            nprocshared=nprocshared,
            label=label,
            scratch=scratch,
            method=method,
            basis=basis,
            extra="opt=(calcfc,verytight,gdiis,maxcycles=900) freq IOP(2/16=3)",
            multiplicity=conformer.rmg_molecule.multiplicity)
        calc.atoms = conformer.ase_molecule
        del calc.parameters['force']

        return calc
示例#9
0
    def get_irc_calc(self):
        """
        A method to create a calculator that runs an IRC calculation the overall geometry of a `TS` object

        Parameters:
        - ts (TS): A `TS` object that you want to perform calculations on
        - direction (str): the forward or reverse direction of the `TS` object
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """

        assert isinstance(self.conformer,
                          TS), "A TS object was not provided..."

        self.conformer.rmg_molecule.updateMultiplicity()
        label = self.conformer.reaction_label + "_irc_" + self.conformer.direction + "_" + str(
            self.conformer.index)

        new_scratch = os.path.join(self.directory, "ts",
                                   self.conformer.reaction_label, "irc")
        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        ase_gaussian = ASEGaussian(
            mem=self.settings["mem"],
            nprocshared=self.settings["nprocshared"],
            label=label,
            scratch=new_scratch,
            method=self.settings["method"],
            basis=self.settings["basis"],
            extra="irc=(calcall)",
            multiplicity=self.conformer.rmg_molecule.multiplicity)
        ase_gaussian.atoms = self.conformer.ase_molecule
        del ase_gaussian.parameters['force']

        return ase_gaussian
示例#10
0
    def get_overall_calc(self,
                         ts=None,
                         mem="5GB",
                         nprocshared=20,
                         scratch=".",
                         method="m062x",
                         basis="6-311+g(2df,2p)"):
        "A method to create a calculator that optimizes the reaction shell"

        if ts is None:
            if self.ts is None:
                return None
            elif not isinstance(self.conformer, TS):
                return None
            else:
                ts = self.conformer

        assert isinstance(ts, TS), "A TS object was not provided..."

        ts.rmg_molecule.updateMultiplicity()

        label = ts.reaction_label.replace(
            "(", "left").replace(")", "right") + "_" + str(ts.index)

        calc = ASEGaussian(
            mem=mem,
            nprocshared=nprocshared,
            label=label,
            scratch=scratch,
            method=method,
            basis=basis,
            extra="opt=(ts,calcfc,noeigentest,maxcycles=900) freq",
            multiplicity=ts.rmg_molecule.multiplicity)
        calc.atoms = ts.ase_molecule
        del calc.parameters['force']

        return calc
示例#11
0
    def get_rotor_calc(self,
                       conformer=None,
                       torsion=None,
                       settings=None,
                       scratch=None,
                       steps=36,
                       step_size=10.0):
        """
        A method to create all of the calculators needed to perform hindered rotor calculations given a `Conformer` and a `Torsion`.

        Parameters:
        - conformer (Conformer): A `Conformer` object that you want to perform hindered rotor calculations on
        - torsion (Torsion): A `Torsion` object that you want to perform hindered rotor calculations about
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to
        - steps (int): the number of steps you want performed in this scan
        - step_size (float): the size, in degrees, of the step you to scan along

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """
        if settings is None:
            settings = self.settings
        if scratch is None:
            scratch = self.scratch

        method = settings["method"]
        basis = settings["basis"]
        mem = settings["mem"]
        nprocshared = settings["nprocshared"]

        assert (
            torsion and (isinstance(torsion, Torsion))
        ), "To create a rotor calculator, you must provide a Torsion object."

        assert isinstance(conformer,
                          Conformer), "A Conformer object was not provided..."

        if isinstance(conformer, TS):
            extra = "Opt=(ts,CalcFC,ModRedun)"
        else:
            extra = "Opt=(CalcFC,ModRedun)"

        string = ""
        for bond in conformer.bonds:
            i, j = bond.atom_indices
            string += "B {} {}\n".format(i + 1, j + 1)

        i, j, k, l = torsion.atom_indices
        string += "D {} {} {} {} S {} {}\n".format(i + 1, j + 1, k + 1, l + 1,
                                                   steps, float(step_size))

        if isinstance(conformer, TS):
            label = da = conformer.reaction_label
            label += "_{}by{}_{}_{}".format(steps, int(step_size), j, k)
            t = "ts"
        elif isinstance(conformer, Conformer):
            label = da = conformer.smiles
            label += "_{}by{}_{}_{}".format(steps, int(step_size), j, k)
            t = "species"

        for locked_torsion in conformer.torsions:  # TODO: maybe doesn't work;
            if sorted(locked_torsion.atom_indices) != sorted(
                    torsion.atom_indices):
                a, b, c, d = locked_torsion.atom_indices
                string += 'D {0} {1} {2} {3} F\n'.format(
                    a + 1, b + 1, c + 1, d + 1)

        conformer.rmg_molecule.updateMultiplicity()
        mult = conformer.rmg_molecule.multiplicity

        new_scratch = os.path.join(scratch, t, da, "rotors")

        calc = ASEGaussian(mem=mem,
                           nprocshared=nprocshared,
                           label=label,
                           scratch=new_scratch,
                           method=method,
                           basis=basis,
                           extra=extra,
                           multiplicity=mult,
                           addsec=[string[:-1]])

        calc.atoms = conformer.ase_molecule
        del calc.parameters['force']

        return calc
示例#12
0
    def get_conformer_calc(self,
                           conformer=None,
                           settings=None,
                           scratch=None,
                           convergence=None):
        """
        A method that creates a calculator for a `Conformer` that will perform a geometry optimization

        Parameters:
        - conformer (Conformer): A `Conformer` object that you want to perform hindered rotor calculations on
        - torsion (Torsion): A `Torsion` object that you want to perform hindered rotor calculations about
        - settings (dict): a dictionary of settings containing method, basis, mem, nprocshared
        - scratch (str): a directory where you want log files to be written to
        - steps (int): the number of steps you want performed in this scan
        - step_size (float): the size, in degrees, of the step you to scan along
        - convergence (str): ['verytight','tight','' (default)], specifies the convergence criteria of the geometry optimization

        Returns:
        - calc (ASEGaussian): an ASEGaussian calculator with all of the proper setting specified
        """
        if settings is None:
            settings = self.settings
        if scratch is None:
            scratch = self.scratch
        if convergence is None:
            convergence = self.convergence

        assert convergence.lower() in ["", "verytight", "tight", "loose"]

        method = settings["method"]
        basis = settings["basis"]
        mem = settings["mem"]
        nprocshared = settings["nprocshared"]

        if isinstance(conformer, TS):
            logging.info(
                "TS object provided, cannot obtain a species calculator for a TS"
            )
            return None

        assert isinstance(conformer,
                          Conformer), "A Conformer object was not provided..."

        conformer.rmg_molecule.updateMultiplicity()

        short_label = conformer.smiles
        label = short_label + "_{}".format(conformer.index)

        new_scratch = os.path.join(scratch, "species", short_label,
                                   "conformers")

        try:
            os.makedirs(new_scratch)
        except OSError:
            pass

        calc = ASEGaussian(
            mem=mem,
            nprocshared=nprocshared,
            label=label,
            scratch=new_scratch,
            method=method,
            basis=basis,
            extra=
            "opt=(CalcFC,MaxCycles=900,{}) freq IOp(7/33=1,2/16=3) scf=(MaxCycle=900)"
            .format(convergence),
            multiplicity=conformer.rmg_molecule.multiplicity)
        calc.atoms = conformer.ase_molecule
        calc.convergence = convergence
        del calc.parameters['force']

        return calc