Esempio n. 1
0
    def optimize(self, shot=0, method="newton", crit=1e-4):
        """ Optimize the geometry and align the optimized geometry to the starting geometry. """

        logger.error(
            'Geometry optimizations are not yet implemented in AMBER interface'
        )
        raise NotImplementedError

        # Code from tinkerio.py
        if os.path.exists('%s.xyz_2' % self.name):
            os.unlink('%s.xyz_2' % self.name)
        self.mol[shot].write('%s.xyz' % self.name, ftype="tinker")
        if method == "newton":
            if self.rigid: optprog = "optrigid"
            else: optprog = "optimize"
        elif method == "bfgs":
            if self.rigid: optprog = "minrigid"
            else: optprog = "minimize"
        o = self.calltinker("%s %s.xyz %f" % (optprog, self.name, crit))
        # Silently align the optimized geometry.
        M12 = Molecule("%s.xyz" % self.name, ftype="tinker") + Molecule(
            "%s.xyz_2" % self.name, ftype="tinker")
        if not self.pbc:
            M12.align(center=False)
        M12[1].write("%s.xyz_2" % self.name, ftype="tinker")
        rmsd = M12.ref_rmsd(0)[1]
        cnvgd = 0
        mode = 0
        for line in o:
            s = line.split()
            if len(s) == 0: continue
            if "Optimally Conditioned Variable Metric Optimization" in line:
                mode = 1
            if "Limited Memory BFGS Quasi-Newton Optimization" in line:
                mode = 1
            if mode == 1 and isint(s[0]): mode = 2
            if mode == 2:
                if isint(s[0]): E = float(s[1])
                else: mode = 0
            if "Normal Termination" in line:
                cnvgd = 1
        if not cnvgd:
            for line in o:
                logger.info(str(line) + '\n')
            logger.info(
                "The minimization did not converge in the geometry optimization - printout is above.\n"
            )
        return E, rmsd
Esempio n. 2
0
def parse_atomtype_line(line):
    """ Parses the 'atomtype' line.
    
    Parses lines like this:\n
    <tt> opls_135     CT    6   12.0107    0.0000    A    3.5000e-01    2.7614e-01\n
    C       12.0107    0.0000    A    3.7500e-01    4.3932e-01\n
    Na  11    22.9897    0.0000    A    6.068128070229e+03  2.662662556402e+01  0.0000e+00 ; PARM 5 6\n </tt>
    Look at all the variety!

    @param[in] line Input line.
    @return answer Dictionary containing:\n
    atom type\n
    bonded atom type (if any)\n
    atomic number (if any)\n
    atomic mass\n
    charge\n
    particle type\n
    force field parameters\n
    number of optional fields
    """
    # First split the line up to the comment.  We don't care about the comment at this time
    sline = line.split(';')[0].split()
    # The line must contain at least six fields to be considered data.
    if len(sline) < 6:
        return
    # Using variable "wrd" because the line has a variable number of fields
    # Can you think of a better way?
    wrd = 0
    bonus = 0
    atomtype = sline[wrd]
    batomtype = sline[wrd]
    wrd += 1
    # The bonded atom type, a pecularity of OPLS-AA
    # Test if it begins with a letter.  Seems to work. :)
    if re.match('[A-Za-z]',sline[wrd]):
        batomtype = sline[wrd]
        wrd += 1
        bonus += 1
    # Now to test if the next line is an atomic number or a mass.
    # Atomic numbers never have decimals...
    atomicnum = -1
    if isint(sline[wrd]):
        atomicnum = int(sline[wrd])
        wrd += 1
        bonus += 1
    # The mass can be overridden in the 'atoms' section.
    mass = float(sline[wrd])
    wrd += 1
    # Atom types have a default charge though this is almost always overridden
    chg  = float(sline[wrd])
    wrd += 1
    # Particle type. Actual atom or virtual site?
    ptp  = sline[wrd]
    wrd += 1
    param = [float(i) for i in sline[wrd:]]
    answer = {'atomtype':atomtype, 'batomtype':batomtype, 'atomicnum':atomicnum, 'mass':mass, 'chg':chg, 'ptp':ptp, 'param':param, 'bonus':bonus}
    return answer
Esempio n. 3
0
    def optimize(self, shot=0, method="newton", crit=1e-4):

        """ Optimize the geometry and align the optimized geometry to the starting geometry. """

        logger.error('Geometry optimizations are not yet implemented in AMBER interface')
        raise NotImplementedError
    
        # Code from tinkerio.py
        if os.path.exists('%s.xyz_2' % self.name):
            os.unlink('%s.xyz_2' % self.name)
        self.mol[shot].write('%s.xyz' % self.name, ftype="tinker")
        if method == "newton":
            if self.rigid: optprog = "optrigid"
            else: optprog = "optimize"
        elif method == "bfgs":
            if self.rigid: optprog = "minrigid"
            else: optprog = "minimize"
        o = self.calltinker("%s %s.xyz %f" % (optprog, self.name, crit))
        # Silently align the optimized geometry.
        M12 = Molecule("%s.xyz" % self.name, ftype="tinker") + Molecule("%s.xyz_2" % self.name, ftype="tinker")
        if not self.pbc:
            M12.align(center=False)
        M12[1].write("%s.xyz_2" % self.name, ftype="tinker")
        rmsd = M12.ref_rmsd(0)[1]
        cnvgd = 0
        mode = 0
        for line in o:
            s = line.split()
            if len(s) == 0: continue
            if "Optimally Conditioned Variable Metric Optimization" in line: mode = 1
            if "Limited Memory BFGS Quasi-Newton Optimization" in line: mode = 1
            if mode == 1 and isint(s[0]): mode = 2
            if mode == 2:
                if isint(s[0]): E = float(s[1])
                else: mode = 0
            if "Normal Termination" in line:
                cnvgd = 1
        if not cnvgd:
            for line in o:
                logger.info(str(line) + '\n')
            logger.info("The minimization did not converge in the geometry optimization - printout is above.\n")
        return E, rmsd
Esempio n. 4
0
def is_mol2_atom(line):
    s = line.split()
    if len(s) < 9:
        return False
    return all([
        isint(s[0]),
        isfloat(s[2]),
        isfloat(s[3]),
        isfloat(s[4]),
        isfloat(s[8])
    ])
Esempio n. 5
0
    def normal_modes(self, shot=0, optimize=True):

        logger.error('Normal modes are not yet implemented in AMBER interface')
        raise NotImplementedError

        # Copied from tinkerio.py
        if optimize:
            self.optimize(shot, crit=1e-6)
            o = self.calltinker("vibrate %s.xyz_2 a" % (self.name))
        else:
            warn_once("Asking for normal modes without geometry optimization?")
            self.mol[shot].write('%s.xyz' % self.name, ftype="tinker")
            o = self.calltinker("vibrate %s.xyz a" % (self.name))
        # Read the TINKER output.  The vibrational frequencies are ordered.
        # The six modes with frequencies closest to zero are ignored
        readev = False
        calc_eigvals = []
        calc_eigvecs = []
        for line in o:
            s = line.split()
            if "Vibrational Normal Mode" in line:
                freq = float(s[-2])
                readev = False
                calc_eigvals.append(freq)
                calc_eigvecs.append([])
            elif "Atom" in line and "Delta X" in line:
                readev = True
            elif readev and len(s) == 4 and all(
                [isint(s[0]),
                 isfloat(s[1]),
                 isfloat(s[2]),
                 isfloat(s[3])]):
                calc_eigvecs[-1].append([float(i) for i in s[1:]])
        calc_eigvals = np.array(calc_eigvals)
        calc_eigvecs = np.array(calc_eigvecs)
        # Sort by frequency absolute value and discard the six that are closest to zero
        calc_eigvecs = calc_eigvecs[np.argsort(np.abs(calc_eigvals))][6:]
        calc_eigvals = calc_eigvals[np.argsort(np.abs(calc_eigvals))][6:]
        # Sort again by frequency
        calc_eigvecs = calc_eigvecs[np.argsort(calc_eigvals)]
        calc_eigvals = calc_eigvals[np.argsort(calc_eigvals)]
        os.system("rm -rf *.xyz_* *.[0-9][0-9][0-9]")
        return calc_eigvals, calc_eigvecs
Esempio n. 6
0
    def feed(self, line, linindep=False):
        """ Feed in a line.

        @param[in] line     The line of data

        """
        if linindep:
            if match('^ *!', line):
                self.destroy = True
            else:
                self.destroy = False
            line = sub('^ *!', '', line)

        line = line.split('!')[0].strip()
        s = line.split()
        self.ln += 1
        # No sense in doing anything for an empty line or a comment line.
        if len(s) == 0 or match('^ *!', line): return None, None
        # Now go through all the cases.
        if match('^[A-Za-z][A-Za-z]? +[0-9]$', line):
            # This is supposed to match the element line. For example 'Li 0'
            self.element = s[0].capitalize()
            self.isdata = False
            self.destroy = False
        elif len(s) == 3 and match('[SPDFGH]+', s[0]) and isint(
                s[1]) and isfloat(s[2]):
            self.amom = s[0]
            if self.amom == self.last_amom:
                self.basis_number[self.element] += 1
            else:
                self.basis_number[self.element] = 0
                self.last_amom = self.amom
            self.contraction_number = -1
            self.isdata = True
            # This is supposed to match a line like 'P   1   1.00'
        elif len(s) == 2 and isfloat(s[0]) and isfloat(s[1]):
            self.contraction_number += 1
            self.isdata = True
        else:
            self.isdata = False
            self.destroy = False
Esempio n. 7
0
    def feed(self, line, linindep=False):
        """ Feed in a line.

        @param[in] line     The line of data

        """
        if linindep:
            if match('^ *!',line): 
                self.destroy = True
            else:
                self.destroy = False
            line = sub('^ *!','',line)

        line       = line.split('!')[0].strip()
        s          = line.split()
        self.ln   += 1
        # No sense in doing anything for an empty line or a comment line.
        if len(s) == 0 or match('^ *!',line): return None, None
        # Now go through all the cases.
        if match('^[A-Za-z][A-Za-z]? +[0-9]$',line):
            # This is supposed to match the element line. For example 'Li 0'
            self.element = capitalize(s[0])
            self.isdata = False
            self.destroy = False
        elif len(s) == 3 and match('[SPDFGH]+',s[0]) and isint(s[1]) and isfloat(s[2]):
            self.amom = s[0]
            if self.amom == self.last_amom:
                self.basis_number[self.element] += 1
            else:
                self.basis_number[self.element] = 0
                self.last_amom = self.amom
            self.contraction_number = -1
            self.isdata = True
            # This is supposed to match a line like 'P   1   1.00'
        elif len(s) == 2 and isfloat(s[0]) and isfloat(s[1]):
            self.contraction_number += 1
            self.isdata = True
        else:
            self.isdata = False
            self.destroy = False
Esempio n. 8
0
    def normal_modes(self, shot=0, optimize=True):

        logger.error('Normal modes are not yet implemented in AMBER interface')
        raise NotImplementedError

        # Copied from tinkerio.py
        if optimize:
            self.optimize(shot, crit=1e-6)
            o = self.calltinker("vibrate %s.xyz_2 a" % (self.name))
        else:
            warn_once("Asking for normal modes without geometry optimization?")
            self.mol[shot].write('%s.xyz' % self.name, ftype="tinker")
            o = self.calltinker("vibrate %s.xyz a" % (self.name))
        # Read the TINKER output.  The vibrational frequencies are ordered.
        # The six modes with frequencies closest to zero are ignored
        readev = False
        calc_eigvals = []
        calc_eigvecs = []
        for line in o:
            s = line.split()
            if "Vibrational Normal Mode" in line:
                freq = float(s[-2])
                readev = False
                calc_eigvals.append(freq)
                calc_eigvecs.append([])
            elif "Atom" in line and "Delta X" in line:
                readev = True
            elif readev and len(s) == 4 and all([isint(s[0]), isfloat(s[1]), isfloat(s[2]), isfloat(s[3])]):
                calc_eigvecs[-1].append([float(i) for i in s[1:]])
        calc_eigvals = np.array(calc_eigvals)
        calc_eigvecs = np.array(calc_eigvecs)
        # Sort by frequency absolute value and discard the six that are closest to zero
        calc_eigvecs = calc_eigvecs[np.argsort(np.abs(calc_eigvals))][6:]
        calc_eigvals = calc_eigvals[np.argsort(np.abs(calc_eigvals))][6:]
        # Sort again by frequency
        calc_eigvecs = calc_eigvecs[np.argsort(calc_eigvals)]
        calc_eigvals = calc_eigvals[np.argsort(calc_eigvals)]
        os.system("rm -rf *.xyz_* *.[0-9][0-9][0-9]")
        return calc_eigvals, calc_eigvecs
Esempio n. 9
0
    def feed(self, line, linindep=False):
        """ Feed in a line.

        @param[in] line     The line of data

        """
        line       = line.split('!')[0].strip()
        s          = line.split()
        self.ln   += 1
        # No sense in doing anything for an empty line or a comment line.
        if len(s) == 0 or match('^ *!',line): return None, None
        # Now go through all the cases.
        if match('^[A-Za-z][A-Za-z]? +[0-9]$',line):
            # This is supposed to match the element line. For example 'Li 0'
            self.element = capitalize(s[0])
            self.radii[self.element] = float(s[1])
            self.isdata = False
            self.point = 0
        elif len(s) >= 2 and isint(s[0]) and isfloat(s[1]):
            self.point += 1
            self.isdata = True
        else:
            self.isdata = False
Esempio n. 10
0
    def feed(self, line, linindep=False):
        """ Feed in a line.

        @param[in] line     The line of data

        """
        line = line.split('!')[0].strip()
        s = line.split()
        self.ln += 1
        # No sense in doing anything for an empty line or a comment line.
        if len(s) == 0 or match('^ *!', line): return None, None
        # Now go through all the cases.
        if match('^[A-Za-z][A-Za-z]? +[0-9]$', line):
            # This is supposed to match the element line. For example 'Li 0'
            self.element = s[0].capitalize()
            self.radii[self.element] = float(s[1])
            self.isdata = False
            self.point = 0
        elif len(s) >= 2 and isint(s[0]) and isfloat(s[1]):
            self.point += 1
            self.isdata = True
        else:
            self.isdata = False
Esempio n. 11
0
    QDict[i] = float("%.4f" % Q)

# Try to zero out the atomic charge.

print(
    "The following code aims to get an integer-charge molecule using precision 4 floating points."
)
TQ = sum([QDict[T[i]] for i in range(na)])
print("All atom types have been selected; molecule has a net charge of %.4f" %
      TQ)
Corr1 = (float("%.4f" % (-1 * TQ / na)))
choice = input(
    "Create overall integer charge (enter integer), enter your own (enter float), or skip this step (hit Enter)? --> "
) + " "
#if 'y' == choice[0] or 'Y' == choice[0]:
if isint(choice.strip()):
    WantQ = int(choice)
    Corr1 = (float("%.4f" % ((WantQ - 1 * TQ) / na)))
    for i in QDict:
        QDict[i] += Corr1
    TQ = sum([QDict[T[i]] for i in range(na)])
    print("Adding a charge of %.4f to each atom" % Corr1)
    print(
        "Now all atom types have been selected; molecule has a net charge of %.4f"
        % TQ)
else:
    try:
        Corr1 = float(choice)
        for i in QDict:
            QDict[i] += Corr1
        TQ = sum([QDict[T[i]] for i in range(na)])
Esempio n. 12
0
def is_mol2_atom(line):
    s = line.split()
    if len(s) < 9:
        return False
    return all([isint(s[0]), isfloat(s[2]), isfloat(s[3]), isfloat(s[4]), isfloat(s[8])])
Esempio n. 13
0
        COM = "OPLS " + OPLSExplanations[sline[0]]
        BAT[i] = i
        OPLSNicks[BAT[i]] = SelectedLine.split()[1]
        TEDict[BAT[i]] = Element
    M[i] = [ANum,PeriodicTable[Element],SIG,EPS,COM]
    QDict[i] = float("%.4f" % Q)

# Try to zero out the atomic charge.

print "The following code aims to get an integer-charge molecule using precision 4 floating points."
TQ = sum([QDict[T[i]] for i in range(na)])
print "All atom types have been selected; molecule has a net charge of %.4f" % TQ
Corr1 = (float("%.4f" % (-1*TQ/na)))
choice = raw_input("Create overall integer charge (enter integer), enter your own (enter float), or skip this step (hit Enter)? --> ") + " "
#if 'y' == choice[0] or 'Y' == choice[0]:
if isint(choice.strip()):
    WantQ = int(choice)
    Corr1 = (float("%.4f" % ((WantQ - 1*TQ)/na)))
    for i in QDict:
        QDict[i] += Corr1
    TQ = sum([QDict[T[i]] for i in range(na)])
    print "Adding a charge of %.4f to each atom" % Corr1
    print "Now all atom types have been selected; molecule has a net charge of %.4f" % TQ
else:
    try:
        Corr1 = float(choice)
        for i in QDict:
            QDict[i] += Corr1
        TQ = sum([QDict[T[i]] for i in range(na)])
        print "Now all atom types have been selected; molecule has a net charge of %.4f" % TQ
    except: print "You didn't enter a number, exiting this section"