Esempio n. 1
0
def main():
    # Get user input.
    args = parse_user_input()
    _exec("rm -f ts-analyze.tar.bz2 irc_transition.xyz irc_transition.vib",
          print_command=False)
    # Standardize base name to "irc_transition".
    shutil.copy2(args.ts, 'irc_transition.xyz')
    # Run Q-Chem calculations..
    QCT = QChem("irc_transition.xyz",
                charge=args.charge,
                mult=args.mult,
                method=args.method,
                basis=args.basis)
    # Ensure stability.
    QCT.make_stable()
    # Single point calculation for bond order matrix.
    QCT.jobtype = 'sp'
    QCT.remextra = OrderedDict([('scf_final_print', '1')])
    QCT.calculate()
    np.savetxt("irc_transition.bnd",
               QCT.load_qcout().qm_bondorder,
               fmt="%8.3f")
    # Frequency calculation.
    QCT.jobtype = 'freq'
    QCT.calculate()
    QCT.write_vdata('irc_transition.vib')
    tarexit()
Esempio n. 2
0
def tarexit():
    # Archive files and quit.
    _exec("rm -f *.btr", print_command=False)
    _exec("touch %s.err" % os.path.splitext(sys.argv[1])[0],
          print_command=False)
    _exec("tar cjf result.tar.bz2 *.xyz %s" % ' '.join([
        i for i in os.listdir('.')
        if (i.startswith('qc') and not os.path.isdir(i))
    ]),
          print_command=False)
    _exec("touch result.tar.bz2", print_command=False)
    sys.exit()
Esempio n. 3
0
def main():
    # Get user input.
    args = parse_user_input()
    M = Molecule(args.initial)

    # Write growing string input files.
    # Note that cycles are "throttled" to 100, because larger numbers will hit queue time limits and we lose all the work :(
    # with open("qcoptions.in",'w') as f: print >> f, qcoptions.format(method=args.method, basis=args.basis)
    prepare_template(qcrem_default,
                     "qcoptions.in",
                     args.charge,
                     args.mult,
                     args.method,
                     args.basis,
                     epsilon=args.epsilon,
                     molecule=M)
    with open("inpfile", 'w') as f:
        print(inpfile.format(xyz=args.initial,
                             path=os.getcwd() + '/',
                             chg=args.charge,
                             mult=args.mult,
                             cyc=min(100, args.cycles),
                             npts=len(M),
                             images=args.images),
              file=f)

    # Bootleg file-based interface for triggering stability analysis.
    if args.stab: _exec("touch Do_Stability_Analysis", print_command=False)

    # Execute the growing string calculation.
    try:
        _exec("gstring.exe", print_command=True, print_to_screen=True)
        _exec("cp $(ls str[0-9]*.xyz -v | tail -1) final-string.xyz",
              print_command=True,
              persist=True)
        Images = None
        for qcout in os.popen("ls gs[0-9][0-9].out -v").readlines():
            if Images == None:
                Images = Molecule(qcout.strip(),
                                  build_topology=False).without('qcrems')
            else:
                Images += Molecule(qcout.strip(),
                                   build_topology=False).without('qcrems')
        Images.get_populations().write('final-string.pop', ftype="xyz")
    except:
        tarexit.include = ['*']
        tarexit()

    # Archive files and exit.
    tarexit()
Esempio n. 4
0
def main():
    # Get user input.
    args = parse_user_input()
    if len(args.methods) > 2:
        logger.error("Unsure what to do with >2 electronic structure methods")
        raise RuntimeError
    # Delete the result from previous jobs
    _exec("rm -rf ts_result.tar.bz2", print_command=False)
    # Perform transition state search.
    # First run the TS-calculation with the smaller basis set
    QCTS1 = QChemTS(args.tsest,
                    charge=args.charge,
                    mult=args.mult,
                    method=args.methods[0],
                    basis=args.bases[0],
                    finalize=(len(args.methods) == 1),
                    qcin='qcts1.in',
                    vout='irc_transition.vib')
    QCTS1.write('ts1.xyz')
    if len(args.methods) == 2:
        print(' --== \x1b[1;92mUpgrading\x1b[0m ==--')
        QCTS2 = QChemTS("ts1.xyz",
                        charge=args.charge,
                        mult=args.mult,
                        method=args.methods[1],
                        basis=args.bases[1],
                        finalize=True,
                        qcin='qcts2.in',
                        vout='irc_transition.vib')
        QCTS2.write('ts2.xyz')
        qcdir = QCTS2.qcdir
        shutil.copy2('ts2.xyz', 'ts.xyz')
    else:
        qcdir = QCTS1.qcdir
        shutil.copy2('ts1.xyz', 'ts.xyz')
    # Intrinsic reaction coordinate calculation.
    print("Intrinsic reaction coordinate..")
    # Process and save IRC results.
    M_IRC, E_IRC = QChemIRC("ts.xyz",
                            charge=args.charge,
                            mult=args.mult,
                            method=args.methods[-1],
                            basis=args.bases[-1],
                            qcdir=qcdir,
                            xyz0=args.initpath)
    M_IRC.write("irc.xyz")
    M_IRC.get_populations().write('irc.pop', ftype='xyz')
    # Save the IRC energy as a function of arc length.
    ArcMol = arc(M_IRC, RMSD=True)
    ArcMolCumul = np.insert(np.cumsum(ArcMol), 0, 0.0)
    np.savetxt("irc.nrg",
               np.hstack((ArcMolCumul.reshape(-1, 1), E_IRC.reshape(-1, 1))),
               fmt="% 14.6f",
               header="Arclength(Ang) Energy(kcal/mol)")
    # Create IRC with equally spaced structures.
    M_IRC_EV = SpaceIRC(M_IRC, E_IRC, RMSD=True)
    M_IRC_EV.write("irc_spaced.xyz")
    # Run two final single point calculations with SCF_FINAL_PRINT set to 1
    M_IRC[0].write("irc_reactant.xyz")
    M_IRC[-1].write("irc_product.xyz")
    QCR = QChem("irc_reactant.xyz",
                charge=args.charge,
                mult=args.mult,
                method=args.methods[-1],
                basis=args.bases[-1])
    QCP = QChem("irc_product.xyz",
                charge=args.charge,
                mult=args.mult,
                method=args.methods[-1],
                basis=args.bases[-1])
    shutil.copy2("ts.xyz", "irc_transition.xyz")
    QCT = QChem("irc_transition.xyz",
                charge=args.charge,
                mult=args.mult,
                method=args.methods[-1],
                basis=args.bases[-1])

    def FinalSCF(SP):
        SP.make_stable()
        SP.jobtype = 'sp'
        SP.remextra = OrderedDict([('scf_final_print', '1')])
        SP.calculate()

    FinalSCF(QCR)
    FinalSCF(QCP)
    FinalSCF(QCT)
    np.savetxt("irc_reactant.bnd", QCR.load_qcout().qm_bondorder, fmt="%8.3f")
    np.savetxt("irc_product.bnd", QCP.load_qcout().qm_bondorder, fmt="%8.3f")
    np.savetxt("irc_transition.bnd",
               QCT.load_qcout().qm_bondorder,
               fmt="%8.3f")

    # Calculate ZPEs, entropy, enthalpy for Delta-G calcs
    # Should be able to take out freq calcs of R and P once we get can confidently get rid of this section.
    QCR.remextra = OrderedDict()
    QCP.remextra = OrderedDict()
    QCT.remextra = OrderedDict()
    QCR.freq()
    R = QCR.load_qcout()
    QCP.freq()
    P = QCP.load_qcout()
    QCT.freq()
    T = QCT.load_qcout()
    nrgfile = open('deltaG.nrg', 'w')
    deltaH = P.qm_energies[0] * Ha_to_kcalmol + P.qm_zpe[
        0] - R.qm_energies[0] * Ha_to_kcalmol - R.qm_zpe[0]
    deltaG = deltaH - P.qm_entropy[0] * 0.29815 + P.qm_enthalpy[
        0] + R.qm_entropy[0] * 0.29815 - R.qm_enthalpy[0]
    Ha = T.qm_energies[0] * Ha_to_kcalmol + T.qm_zpe[
        0] - R.qm_energies[0] * Ha_to_kcalmol - R.qm_zpe[0]
    Ga = Ha - T.qm_entropy[0] * 0.29815 + T.qm_enthalpy[
        0] + R.qm_entropy[0] * 0.29815 - R.qm_enthalpy[0]
    nrgfile.write(
        "=> ** The following data is referenced to reactant and product complexes **\n"
    )
    nrgfile.write(
        "=> ** WARNING! Data may not be accurate in cases with >1 molecule        **\n"
    )
    nrgfile.write(
        "=> ** Activation enthalpy H_a (0K) =         %.4f kcal/mol               **\n"
        % Ha)
    nrgfile.write(
        "=> ** Activation Gibbs energy G_a (STP) =    %.4f kcal/mol               **\n"
        % Ga)
    nrgfile.write(
        "=> ** Delta-H(0K) =                          %.4f kcal/mol               **\n"
        % deltaH)
    nrgfile.write(
        "=> ** Delta-G(STP) =                         %.4f kcal/mol               **\n"
        % deltaG)

    # Calculate Delta-G's based on fragment information from reactant and product
    # Get data from fragment nrg files
    if args.fragpath == None:
        fragpath = os.path.abspath('../../../../../fragments')
    else:
        fragpath = args.fragpath
    formulas = []
    nrg = []
    zpe = []
    entr = []
    enth = []
    validity = []
    for frm in os.listdir(fragpath):
        optdir = os.path.join(fragpath, frm, "opt")
        if os.path.exists(os.path.join(optdir, 'fragmentopt.nrg')):
            fragnrgfile = open(os.path.join(optdir, 'fragmentopt.nrg'))
            formulas.append(fragnrgfile.readline().strip())
            nrg.append(float(fragnrgfile.readline().split()[3]))
            zpe.append(float(fragnrgfile.readline().split()[2]))
            entr.append(float(fragnrgfile.readline().split()[3]))
            enth.append(float(fragnrgfile.readline().split()[3]))
            validity.append(fragnrgfile.readline().strip())
            fragnrgfile.close()
    # Compare list of molecules to choose right energy
    formulasR = []
    formulasP = []
    nrgR = 0.0
    nrgP = 0.0
    R.build_topology()
    for subg in R.molecules:
        formulasR.append(subg.ef())
    formulasR = sorted(formulasR)
    P.build_topology()
    for subg in P.molecules:
        formulasP.append(subg.ef())
    formulasP = sorted(formulasP)
    for i in range(len(formulas)):
        formlist = sorted(formulas[i].split())
        if formlist == formulasR and validity[i] != "invalid":
            nrgR = nrg[i]
            zpeR = zpe[i]
            entrR = entr[i]
            enthR = enth[i]
        if formlist == formulasP and validity[i] != "invalid":
            nrgP = nrg[i]
            zpeP = zpe[i]
            entrP = entr[i]
            enthP = enth[i]
    # Calculate energetics
    if nrgR != 0.0:
        Ha = T.qm_energies[0] * Ha_to_kcalmol + T.qm_zpe[
            0] - nrgR * Ha_to_kcalmol - zpeR
        Ga = Ha - T.qm_entropy[0] * 0.29815 + T.qm_enthalpy[
            0] + entrR * 0.29815 - enthR
        nrgfile.write(
            "=> ## The following data is calculated referenced to isolated reactant and product molecules:\n"
        )
        nrgfile.write(
            "=> ## Activation enthalpy H_a (0K) =         %.4f kcal/mol               ##\n"
            % Ha)
        nrgfile.write(
            "=> ## Activation Gibbs energy G_a (STP) =    %.4f kcal/mol               ##\n"
            % Ga)
    else:
        nrgfile.write(
            "=> Reactant state could not be identified among fragment calculations\n"
        )
        nrgfile.write(
            "=> No energetics referenced to isolated molecules will be calculated for this pathway\n"
        )
    if nrgR != 0.0 and nrgP != 0.0:
        deltaH = nrgP * Ha_to_kcalmol + zpeP - nrgR * Ha_to_kcalmol - zpeR
        deltaG = deltaH - entrP * 0.29815 + enthP + entrR * 0.29815 - enthR
        nrgfile.write(
            "=> ## Delta-H(0K) =                          %.4f kcal/mol               **\n"
            % deltaH)
        nrgfile.write(
            "=> ## Delta-G(STP) =                         %.4f kcal/mol               **\n"
            % deltaG)
    elif nrgP == 0.0:
        nrgfile.write(
            "=> Product state could not be identified among fragment calculations\n"
        )
        nrgfile.write(
            "=> No reaction energies referenced to isolated molecules will be calculated for this pathway\n"
        )
    nrgfile.close()
    print("\x1b[1;92mIRC Success!\x1b[0m")
    tarexit()
Esempio n. 5
0
warnings.simplefilter("ignore")
from nanoreactor import contact
from nanoreactor.molecule import *
from nanoreactor.nanoreactor import *
from nanoreactor.nifty import _exec, printcool_dictionary, printcool
from scipy import optimize
import time
import math
import os, sys, re
import itertools
import traceback
from copy import deepcopy
from collections import OrderedDict, Counter

# Delete the result from previous jobs
_exec("rm -rf neb_result.tar.bz2")

# Adjustable Settings
tcin = """
basis           6-31g*
method          uhf
charge          {chg}
spinmult        {spn}
nstep           4000
threall         1.0e-12
run             ts
scf             diis+a
maxit           50
min_nebk        1
min_coordinates cartesian
ts_method       neb_frozen
Esempio n. 6
0
def main():
    # Parse user input.
    args = parse_user_input()
    # Load IRC coordinates.
    M = Molecule(args.xyz)
    M.load_popxyz(args.pop)
    # Rebuild bonds for the reactant (0th frame).
    R = M[0]
    R.build_topology()
    # Rebuild bonds for the product (last frame).
    P = M[-1]
    P.build_topology()
    # Don't draw reaction if the reactant and product are the same.
    if MolEqual(R, P):
        logger.info(
            "Exiting because reactant and product molecules are the same")
        sys.exit()
    # Load Mayer bond order matrices.
    load_bondorder(R, P)
    # Create SVG drawings of the reactant and product.
    canr, strr = make_obmol(R, "reactant")
    canp, strp = make_obmol(P, "product")
    # IRC energy.
    ArcE = np.loadtxt(args.energy)
    E = ArcE[:, 1]
    # "Canonicalize" the reaction direction.
    fwd = True
    if max([len(m.L())
            for m in R.molecules]) > max([len(m.L()) for m in P.molecules]):
        # Reactions should go in the direction of increasing molecule size.
        fwd = False
    elif (max([len(m.L()) for m in R.molecules]) == max(
        [len(m.L()) for m in P.molecules])) and (E[0] < E[-1]):
        # If molecules on both sides are the same size, go in the exothermic direction.
        fwd = False
    if fwd:
        shutil.copy2("irc.nrg", "plot.nrg")
        with open("reaction.can", "w") as f:
            print >> f, "%s>>%s" % (canr, canp)
    else:
        ArcE = ArcE[::-1]
        ArcE[:, 0] *= -1
        ArcE[:, 0] -= ArcE[:, 0][0]
        ArcE[:, 1] -= ArcE[:, 1][0]
        np.savetxt("plot.nrg",
                   ArcE,
                   fmt="% 14.6f",
                   header="Arclength(Ang) Energy(kcal/mol)")
        strr, strp = strp, strr
        E = E[::-1]
        with open("reaction.can", "w") as f:
            print >> f, "%s>>%s" % (canp, canr)
    # This string looks something like C2H2 + H2O -> C2H4O.
    # The funny character is a Unicode entity for the "right arrow"
    strrxn = strr + ' &#10230; ' + strp
    # Create the components of the final image.
    # First write a text box with the chemical equation.
    with open("reaction_text.svg", "w") as f:
        print >> f, svgrect.format(text=strrxn,
                                   frgb="255,210,80",
                                   srgb="255,165,128")
    # Next write a text box with the charge and multiplicity.
    net_charge = int(round(sum(M.qm_mulliken_charges[0])))
    net_mult = int(abs(round(sum(M.qm_mulliken_spins[0]))) + 1)
    with open("chargemult_text.svg", "w") as f:
        print >> f, svgrect.format(text="Charge = %i ; Multiplicity = %i" %
                                   (net_charge, net_mult),
                                   frgb="194,225,132",
                                   srgb="154,205,50")
    # Write a text box with the reaction energy and barrier height.
    with open("energy_text.svg", "w") as f:
        print >> f, svgrect.format(
            text="&#916;E = %.2f kcal ; E&#8336; = %.2f kcal" %
            (E[-1] - E[0], np.max(E)),
            frgb="142,200,255",
            srgb="30,144,255")
    # Run script to generate energy diagram plot (uses Gnuplot).
    _exec("plot-rc.sh", print_command=False)
    # Write a text heading with the location of the calculation on disk.
    with open("folder_text.svg", "w") as f:
        print >> f, svgtext.format(text="Path: %s" % os.getcwd().split(
            os.environ['HOME'])[-1].split("Refinement")[-1].strip('/'))
    # Print some skeleton SVG files (actually part of this script).
    with open("arrow.svg", "w") as f:
        print >> f, svgarrow
    with open("base.svg", "w") as f:
        print >> f, svgbase
    # Finally, compose the image.
    compose(fwd)
Esempio n. 7
0
def InterpolatePath(Path1, fnm, verbose=True, outfnm=None):
    """ Given a path in the form of a Molecule object,
    equalize the velocities and perform internal coordinate interpolation.
    If outfnm is provided, then the final smoothed path is saved to that file name.
    Otherwise, the "stage1" and "stage2" files will be written.
    """

    # First align the frames in the path.
    Path1.align()

    # Perform a linear interpolation so we get a constant movement path that isn't jerky.
    ArcPath1 = arc(Path1, RMSD=True)
    if verbose:
        print(
            "Before velocity equalizing, movement is %.3f +- %.3f A, max %.3f, min %.3f"
            % (np.mean(ArcPath1), np.std(ArcPath1), np.max(ArcPath1),
               np.min(ArcPath1)))
    MaxVel = np.max(ArcPath1)
    ConstantVelocity(Path1, RMSD=True)
    ArcPath1 = arc(Path1, RMSD=True)
    ArcPath1Cumul = np.insert(np.cumsum(ArcPath1), 0, 0.0)
    if verbose:
        print(
            "After velocity equalizing,  movement is %.3f +- %.3f A, max %.3f, min %.3f"
            % (np.mean(ArcPath1), np.std(ArcPath1), np.max(ArcPath1),
               np.min(ArcPath1)))

    # Write the path to a file
    path1fnm = "%s_stage1.xyz" % os.path.splitext(fnm)[0]
    if verbose: print("Writing velocity-equalized path to %s" % path1fnm)
    Path1.write(path1fnm)

    path2fnm = "%s_stage2.xyz" % os.path.splitext(fnm)[0]
    neb0fnm = "%s_dc.xyz" % os.path.splitext(fnm)[0]

    # The smoothing strength is set to one-third of the trajectory length.
    # Values too large lead to unreliable results.  This is also fine tuned.
    smoothing_strength = min(61, (len(Path1) / 5) * 2 + 1)

    # This requires the nebterpolator package to be in the current directory.
    if not os.path.exists(path2fnm):
        _exec("Nebterpolate.py %s %i %s" %
              (path1fnm, smoothing_strength, path2fnm),
              print_to_screen=verbose,
              print_command=verbose,
              persist=True)
    else:
        print("Interpolated path exists")

    if os.path.exists(path2fnm):
        if verbose: print("Interpolated path is saved to %s" % path2fnm)
        Path2 = Molecule(path2fnm)
        ArcPath2 = arc(Path2, RMSD=True)
        ArcPath2Cumul = np.insert(np.cumsum(ArcPath2), 0, 0.0)
        if verbose:
            print(
                "Internal interpolation modifies the path length from %.3f to %.3f Angstrom, ; max movement %.3f"
                % (ArcPath1Cumul[-1], ArcPath2Cumul[-1], np.max(ArcPath2)))
        if np.max(ArcPath2) > 2.0 * MaxVel:
            if verbose: print("\x1b[91mJump detected!\x1b[0m")
            Jump = True
        else:
            Jump = False
        ConstantVelocity(Path2, RMSD=True)
        ArcPath2 = arc(Path2, RMSD=True)
        if verbose:
            print(
                "Velocity equalized: movement is %.3f +- %.3f A, max %.3f, min %.3f"
                % (np.mean(ArcPath2), np.std(ArcPath2), np.max(ArcPath2),
                   np.min(ArcPath2)))
        Path2.comms = Path1.comms[:]
        Path2.write(path2fnm)
        # Print out 11 frames for NEB.
        if Jump or (ArcPath2Cumul[-1] > ArcPath1Cumul[-1]):
            if verbose:
                print(
                    "Internal interpolation did \x1b[91mnot\x1b[0m improve the trajectory"
                )
            Path1_ = Molecule(path1fnm)
            feleven = np.array([
                int(round(i))
                for i in np.linspace(0,
                                     len(Path1_) - 1, min(len(Path1_), 11))
            ])
            Path1_[feleven].write(neb0fnm)
            BestPath = path1fnm
        else:
            if verbose:
                print(
                    "Internal interpolation has \x1b[92mimproved\x1b[0m the trajectory"
                )
            feleven = np.array([
                int(round(i))
                for i in np.linspace(0,
                                     len(Path2) - 1, min(len(Path2), 11))
            ])
            Path2[feleven].write(neb0fnm)
            BestPath = path2fnm
    else:
        if verbose:
            print(
                "Internal interpolation did not generate a file, it may have failed"
            )
        Path1_ = Molecule(path1fnm)
        feleven = np.array([
            int(round(i))
            for i in np.linspace(0,
                                 len(Path1_) - 1, min(len(Path1_), 11))
        ])
        Path1_[feleven].write(neb0fnm)
        BestPath = path1fnm
    if verbose: print("NEB starting path saved to %s" % neb0fnm)
    if outfnm != None:
        os.system("mv %s %s" % (BestPath, outfnm))
        os.system("rm -f %s" % path1fnm)
        os.system("rm -f %s" % path2fnm)
        finalfns.append(outfnm)
        nebfns.append(neb0fnm)
    else:
        finalfns.append(BestPath)
        nebfns.append(neb0fnm)
    return BestPath