コード例 #1
0
ファイル: amberio.py プロジェクト: albaugh/forcebalance
    def setopts(self, **kwargs):
        
        """ Called by __init__ ; Set AMBER-specific options. """

        ## The directory containing TINKER executables (e.g. dynamic)
        if 'amberhome' in kwargs:
            self.amberhome = kwargs['amberhome']
            if not os.path.exists(os.path.join(self.amberhome,"sander")):
                warn_press_key("The 'sander' executable indicated by %s doesn't exist! (Check amberhome)" \
                                   % os.path.join(self.amberhome,"sander"))
        else:
            warn_once("The 'amberhome' option was not specified; using default.")
            if which('sander') == '':
                warn_press_key("Please add AMBER executables to the PATH or specify amberhome.")
            self.amberhome = os.path.split(which('sander'))[0]
        
        with wopen('.quit.leap') as f:
            print >> f, 'quit'

        # AMBER search path
        self.spath = []
        for line in self.callamber('tleap -f .quit.leap'):
            if 'Adding' in line and 'to search path' in line:
                self.spath.append(line.split('Adding')[1].split()[0])
        os.remove('.quit.leap')
コード例 #2
0
ファイル: psi4io.py プロジェクト: albaugh/forcebalance
 def driver(self):
     ## Actually run PSI4.
     if not in_fd() and CheckBasis():
         logger.info("Now checking for linear dependencies.\n")
         _exec("cp %s %s.bak" % (self.GBSfnm, self.GBSfnm), print_command=False)
         ln0 = self.write_nested_destroy(self.GBSfnm, self.FF.linedestroy_save)
         o = wopen(".lindep.dat")
         for line in open(self.DATfnm).readlines():
             s = line.split("#")[0].split()
             if len(s) == 3 and s[0].lower() == 'basis' and s[1].lower() == 'file':
                 print >> o, "basis file %s" % self.GBSfnm
             else:
                 print >> o, line,
         o.close()
         _exec("mv .lindep.dat %s" % self.DATfnm, print_command=False)
         _exec("psi4 %s" % self.DATfnm, print_command=False)
         LI = GBS_Reader()
         LI_lines = {}
         ## Read in the commented linindep.gbs file and ensure that these same lines are commented in the new .gbs file
         for line in open('linindep.gbs'):
             LI.feed(line,linindep=True)
             key = '.'.join([str(i) for i in LI.element,LI.amom,LI.basis_number[LI.element],LI.contraction_number])
             if LI.isdata:
                 if key in LI_lines:
                     logger.info("Duplicate key found:\n")
                     logger.info("%s\n" % key)
                     logger.info(str(LI_lines[key]))
                     logger.info(line)
                     warn_press_key("In %s, the LI_lines dictionary should not contain repeated keys!" % __file__)
                 LI_lines[key] = (line, LI.destroy)
コード例 #3
0
    def setopts(self, **kwargs):
        """ Called by __init__ ; Set AMBER-specific options. """

        ## The directory containing TINKER executables (e.g. dynamic)
        if 'amberhome' in kwargs:
            self.amberhome = kwargs['amberhome']
            if not os.path.exists(os.path.join(self.amberhome, "sander")):
                warn_press_key("The 'sander' executable indicated by %s doesn't exist! (Check amberhome)" \
                                   % os.path.join(self.amberhome,"sander"))
        else:
            warn_once(
                "The 'amberhome' option was not specified; using default.")
            if which('sander') == '':
                warn_press_key(
                    "Please add AMBER executables to the PATH or specify amberhome."
                )
            self.amberhome = os.path.split(which('sander'))[0]

        with wopen('.quit.leap') as f:
            print >> f, 'quit'

        # AMBER search path
        self.spath = []
        for line in self.callamber('tleap -f .quit.leap'):
            if 'Adding' in line and 'to search path' in line:
                self.spath.append(line.split('Adding')[1].split()[0])
        os.remove('.quit.leap')
コード例 #4
0
    def __init__(self, options, tgt_opts, forcefield):
        super(THCDF_Psi4, self).__init__(options, tgt_opts, forcefield)

        # Parse the input.dat file to figure out the elements and molecules
        MolSection = False
        ElemList = []
        self.Molecules = []
        self.throw_outs = []
        for line in open(os.path.join(self.root, self.tgtdir,
                                      "input.dat")).readlines():
            line = line.strip()
            s = line.split()
            if len(s) >= 3 and s[0].lower() == 'molecule' and s[2] == '{':
                MolSection = True
                self.Molecules.append(s[1])
            elif len(s) >= 1 and s[0] == '}':
                MolSection = False
            elif MolSection and len(s) >= 4 and match(
                    "^[A-Za-z]+$", s[0]) and isfloat(s[1]) and isfloat(
                        s[2]) and isfloat(s[3]):
                ElemList.append(s[0].capitalize())
        self.Elements = set(ElemList)
        xgrad = []
        for p in self.pgrad:
            Pelem = []
            for pid in self.FF.plist[p].split():
                # Extract the chemical element.
                Pelem.append(pid.split(':')[1].split(',')[0].split('=')[1])
            Pelem = set(Pelem)
            if len(self.Elements.intersection(Pelem)) == 0:
                xgrad.append(p)
        for p in xgrad:
            self.pgrad.remove(p)
        ## Psi4 basis set file
        gbslist = [i for i in self.FF.fnms if os.path.splitext(i)[1] == '.gbs']
        if len(gbslist) != 1:
            warn_press_key(
                "In %s, you should only have exactly one .gbs file in the list of force field files!"
                % __file__)
        self.GBSfnm = gbslist[0]
        ## Psi4 input file for calculation of linear dependencies
        ## This is actually a file in 'forcefield' until we can figure out a better system
        if CheckBasis():
            datlist = [
                i for i in self.FF.fnms if os.path.splitext(i)[1] == '.dat'
            ]
            if len(datlist) != 1:
                warn_press_key(
                    "In %s, you should only have exactly one .dat file in the list of force field files!"
                    % __file__)
            self.DATfnm = datlist[0]
        ## Prepare the temporary directory
        self.prepare_temp_directory(options, tgt_opts)
コード例 #5
0
    def read(self,mvals,AGrad=False,AHess=False):

        """ 

        Read data from disk for the initial optimization step if the
        user has provided the directory to the "read" option.  

        """
        mvals1 = np.loadtxt('mvals.txt')

        if len(mvals) > 0 and (np.max(np.abs(mvals1 - mvals)) > 1e-3):
            warn_press_key("mvals from mvals.txt does not match up with get! (Are you reading data from a previous run?)\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
        
        return lp_load('objective.p')
コード例 #6
0
ファイル: target.py プロジェクト: leeping/forcebalance
    def read(self,mvals,AGrad=False,AHess=False):

        """ 

        Read data from disk for the initial optimization step if the
        user has provided the directory to the "read" option.  

        """
        mvals1 = np.loadtxt('mvals.txt')

        if len(mvals) > 0 and (np.max(np.abs(mvals1 - mvals)) > 1e-3):
            warn_press_key("mvals from mvals.txt does not match up with get! (Are you reading data from a previous run?)\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
        
        return lp_load('objective.p')
コード例 #7
0
ファイル: gmxqpio.py プロジェクト: mlaury/forcebalance
 def prepare_temp_directory(self, options, tgt_opts):
     os.environ["GMX_NO_SOLV_OPT"] = "TRUE"
     os.environ["GMX_NO_ALLVSALL"] = "TRUE"
     abstempdir = os.path.join(self.root,self.tempdir)
     if options['gmxpath'] == None or options['gmxsuffix'] == None:
         warn_press_key('Please set the options gmxpath and gmxsuffix in the input file!')
     if not os.path.exists(os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix'])):
         warn_press_key('The mdrun executable pointed to by %s doesn\'t exist! (Check gmxpath and gmxsuffix)' % os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix']))
     # Link the necessary programs into the temporary directory
     LinkFile(os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix']),os.path.join(abstempdir,"mdrun"))
     LinkFile(os.path.join(options['gmxpath'],"grompp"+options['gmxsuffix']),os.path.join(abstempdir,"grompp"))
     LinkFile(os.path.join(options['gmxpath'],"trjconv"+options['gmxsuffix']),os.path.join(abstempdir,"trjconv"))
     # Link the run files
     LinkFile(os.path.join(self.root,self.tgtdir,"conf.gro"),os.path.join(abstempdir,"conf.gro"))
     LinkFile(os.path.join(self.root,self.tgtdir,"grompp.mdp"),os.path.join(abstempdir,"grompp.mdp"))
     LinkFile(os.path.join(self.root,self.tgtdir,"topol.top"),os.path.join(abstempdir,"topol.top"))
コード例 #8
0
ファイル: target.py プロジェクト: JNapoli/forcebalance
    def read(self,mvals,AGrad=False,AHess=False):

        """ 

        Read data from disk for the initial optimization step if the
        user has provided the directory to the "read" option.  

        """
        mvals1 = np.loadtxt('mvals.txt')

        if mvals1.shape != mvals.shape:
            warn_press_key("mvals from forcebalance.p has different shape compared to internal values!\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
        elif len(mvals1) > 0 and (np.max(np.abs(mvals1 - mvals)) > 1e-3):
            warn_press_key("mvals from forcebalance.p does not match up with internal values! (Are you reading data from a previous run?)\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
        
        return lp_load('objective.p')
コード例 #9
0
ファイル: gmxio.py プロジェクト: mlaury/forcebalance
 def prepare_temp_directory(self,options,tgt_opts):
     """ Prepare the temporary directory by copying in important files. """
     os.environ["GMX_NO_SOLV_OPT"] = "TRUE"
     os.environ["GMX_NO_ALLVSALL"] = "TRUE"
     abstempdir = os.path.join(self.root,self.tempdir)
     if options['gmxpath'] == None or options['gmxsuffix'] == None:
         warn_press_key('Please set the options gmxpath and gmxsuffix in the input file!')
     if not os.path.exists(os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix'])):
         warn_press_key('The mdrun executable pointed to by %s doesn\'t exist! (Check gmxpath and gmxsuffix)' % os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix']))
     # Link the necessary programs into the temporary directory
     LinkFile(os.path.join(os.path.split(__file__)[0],"data","npt.py"),os.path.join(abstempdir,"npt.py"))
     LinkFile(os.path.join(os.path.split(__file__)[0],"data","rungmx.sh"),os.path.join(abstempdir,"rungmx.sh"))
     # Link the run files
     for phase in ["liquid","gas"]:
         LinkFile(os.path.join(self.root,self.tgtdir,"%s.mdp" % phase),os.path.join(abstempdir,"%s.mdp" % phase))
         LinkFile(os.path.join(self.root,self.tgtdir,"%s.top" % phase),os.path.join(abstempdir,"%s.top" % phase))
         LinkFile(os.path.join(self.root,self.tgtdir,"%s.gro" % phase),os.path.join(abstempdir,"%s.gro" % phase))
コード例 #10
0
ファイル: gmxio.py プロジェクト: rmcgibbo/forcebalance
 def interaction_driver_all(self, dielectric=False):
     """ Computes the energy and force using GROMACS for a trajectory.  This does not require GROMACS-X2. """
     # Remove backup files.
     rm_gmx_baks(os.getcwd())
     # Do the interacting calculation.
     _exec(["./grompp", "-f", "interaction.mdp", "-n", "index.ndx"], print_command=False)
     _exec(["./mdrun", "-nt", "1", "-rerunvsite", "-rerun", "all.gro"], print_command=False)
     # Gather information
     _exec(["./g_energy","-xvg","no"], print_command=False, stdin="Potential\n")
     Interact = array([float(l.split()[1]) for l in open('energy.xvg').readlines()])
     # Do the excluded calculation.
     _exec(["./grompp", "-f", "excluded.mdp", "-n", "index.ndx"], print_command=False)
     _exec(["./mdrun", "-nt", "1", "-rerunvsite", "-rerun", "all.gro"], print_command=False)
     # Gather information
     _exec(["./g_energy","-xvg","no"], print_command=False, stdin="Potential\n")
     Excluded = array([float(l.split()[1]) for l in open('energy.xvg').readlines()])
     # The interaction energy.
     M = Interact - Excluded
     # Now we have the MM interaction energy.
     # We need the COSMO component of the interaction energy now...
     if dielectric:
         traj_dimer = deepcopy(self.traj)
         traj_dimer.add_quantum("qtemp_D.in")
         traj_dimer.write("qchem_dimer.in",ftype="qcin")
         traj_monoA = deepcopy(self.traj)
         traj_monoA.add_quantum("qtemp_A.in")
         traj_monoA.write("qchem_monoA.in",ftype="qcin")
         traj_monoB = deepcopy(self.traj)
         traj_monoB.add_quantum("qtemp_B.in")
         traj_monoB.write("qchem_monoB.in",ftype="qcin")
         wq = getWorkQueue()
         if wq == None:
             warn_press_key("To proceed past this point, a Work Queue must be present")
         print "Computing the dielectric energy"
         Diel_D = QChem_Dielectric_Energy("qchem_dimer.in",wq)
         Diel_A = QChem_Dielectric_Energy("qchem_monoA.in",wq)
         # The dielectric energy for a water molecule should never change.
         if hasattr(self,"Diel_B"):
             Diel_B = self.Diel_B
         else:
             Diel_B = QChem_Dielectric_Energy("qchem_monoB.in",self.wq)
             self.Diel_B = Diel_B
         self.Dielectric = Diel_D - Diel_A - Diel_B
     M += self.Dielectric
     return M
コード例 #11
0
ファイル: psi4io.py プロジェクト: albaugh/forcebalance
    def __init__(self,options,tgt_opts,forcefield):
        super(THCDF_Psi4,self).__init__(options,tgt_opts,forcefield)

        # Parse the input.dat file to figure out the elements and molecules
        MolSection = False
        ElemList = []
        self.Molecules = []
        self.throw_outs = []
        for line in open(os.path.join(self.root,self.tgtdir,"input.dat")).readlines():
            line = line.strip()
            s = line.split()
            if len(s) >= 3 and s[0].lower() == 'molecule' and s[2] == '{':
                MolSection = True
                self.Molecules.append(s[1])
            elif len(s) >= 1 and s[0] == '}':
                MolSection = False
            elif MolSection and len(s) >= 4 and match("^[A-Za-z]+$",s[0]) and isfloat(s[1]) and isfloat(s[2]) and isfloat(s[3]):
                ElemList.append(capitalize(s[0]))
        self.Elements = set(ElemList)
        xgrad = []
        for p in self.pgrad:
            Pelem = []
            for pid in self.FF.plist[p].split():
                # Extract the chemical element.
                Pelem.append(pid.split(':')[1].split(',')[0].split('=')[1])
            Pelem = set(Pelem)
            if len(self.Elements.intersection(Pelem)) == 0:
                xgrad.append(p)
        for p in xgrad:
            self.pgrad.remove(p)
        ## Psi4 basis set file
        gbslist = [i for i in self.FF.fnms if os.path.splitext(i)[1] == '.gbs']
        if len(gbslist) != 1:
            warn_press_key("In %s, you should only have exactly one .gbs file in the list of force field files!" % __file__)
        self.GBSfnm = gbslist[0]
        ## Psi4 input file for calculation of linear dependencies
        ## This is actually a file in 'forcefield' until we can figure out a better system
        if CheckBasis():
            datlist = [i for i in self.FF.fnms if os.path.splitext(i)[1] == '.dat']
            if len(datlist) != 1:
                warn_press_key("In %s, you should only have exactly one .dat file in the list of force field files!" % __file__)
            self.DATfnm = datlist[0]
        ## Prepare the temporary directory
        self.prepare_temp_directory(options,tgt_opts)
コード例 #12
0
    def energy_rmsd(self, shot=0, optimize=True):
        """ Calculate energy of the selected structure (optionally minimize and return the minimized energy and RMSD). In kcal/mol. """

        logger.error(
            'Geometry optimization is not yet implemented in AMBER interface')
        raise NotImplementedError

        rmsd = 0.0
        # This line actually runs TINKER
        # xyzfnm = sysname+".xyz"
        if optimize:
            E_, rmsd = self.optimize(shot)
            o = self.calltinker("analyze %s.xyz_2 E" % self.name)
            #----
            # Two equivalent ways to get the RMSD, here for reference.
            #----
            # M1 = Molecule("%s.xyz" % self.name, ftype="tinker")
            # M2 = Molecule("%s.xyz_2" % self.name, ftype="tinker")
            # M1 += M2
            # rmsd = M1.ref_rmsd(0)[1]
            #----
            # oo = self.calltinker("superpose %s.xyz %s.xyz_2 1 y u n 0" % (self.name, self.name))
            # for line in oo:
            #     if "Root Mean Square Distance" in line:
            #         rmsd = float(line.split()[-1])
            #----
            os.system("rm %s.xyz_2" % self.name)
        else:
            o = self.calltinker("analyze %s.xyz E" % self.name)
        # Read the TINKER output.
        E = None
        for line in o:
            if "Total Potential Energy" in line:
                E = float(line.split()[-2].replace('D', 'e'))
        if E == None:
            logger.error(
                "Total potential energy wasn't encountered when calling analyze!\n"
            )
            raise RuntimeError
        if optimize and abs(E - E_) > 0.1:
            warn_press_key(
                "Energy from optimize and analyze aren't the same (%.3f vs. %.3f)"
                % (E, E_))
        return E, rmsd
コード例 #13
0
ファイル: gmxio.py プロジェクト: rmcgibbo/forcebalance
 def prepare_temp_directory(self, options, tgt_opts):
     os.environ["GMX_NO_SOLV_OPT"] = "TRUE"
     abstempdir = os.path.join(self.root,self.tempdir)
     if options['gmxpath'] == None or options['gmxsuffix'] == None:
         warn_press_key('Please set the options gmxpath and gmxsuffix in the input file!')
     if not os.path.exists(os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix'])):
         warn_press_key('The mdrun executable pointed to by %s doesn\'t exist! (Check gmxpath and gmxsuffix)' % os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix']))
     # Link the necessary programs into the temporary directory
     LinkFile(os.path.join(options['gmxpath'],"mdrun"+options['gmxsuffix']),os.path.join(abstempdir,"mdrun"))
     LinkFile(os.path.join(options['gmxpath'],"grompp"+options['gmxsuffix']),os.path.join(abstempdir,"grompp"))
     LinkFile(os.path.join(options['gmxpath'],"g_energy"+options['gmxsuffix']),os.path.join(abstempdir,"g_energy"))
     # Link the run files
     LinkFile(os.path.join(self.root,self.tgtdir,"index.ndx"),os.path.join(abstempdir,"index.ndx"))
     #LinkFile(os.path.join(self.root,self.tgtdir,"shot.mdp"),os.path.join(abstempdir,"shot.mdp"))
     LinkFile(os.path.join(self.root,self.tgtdir,self.topfnm),os.path.join(abstempdir,self.topfnm))
     # Write the trajectory to the temp-directory
     self.traj.write(os.path.join(abstempdir,"all.gro"),select=range(self.ns))
     # Print out the first conformation in all.gro to use as conf.gro
     self.traj.write(os.path.join(abstempdir,"conf.gro"),select=[0])
コード例 #14
0
ファイル: amberio.py プロジェクト: albaugh/forcebalance
    def energy_rmsd(self, shot=0, optimize=True):

        """ Calculate energy of the selected structure (optionally minimize and return the minimized energy and RMSD). In kcal/mol. """

        logger.error('Geometry optimization is not yet implemented in AMBER interface')
        raise NotImplementedError

        rmsd = 0.0
        # This line actually runs TINKER
        # xyzfnm = sysname+".xyz"
        if optimize:
            E_, rmsd = self.optimize(shot)
            o = self.calltinker("analyze %s.xyz_2 E" % self.name)
            #----
            # Two equivalent ways to get the RMSD, here for reference.
            #----
            # M1 = Molecule("%s.xyz" % self.name, ftype="tinker")
            # M2 = Molecule("%s.xyz_2" % self.name, ftype="tinker")
            # M1 += M2
            # rmsd = M1.ref_rmsd(0)[1]
            #----
            # oo = self.calltinker("superpose %s.xyz %s.xyz_2 1 y u n 0" % (self.name, self.name))
            # for line in oo:
            #     if "Root Mean Square Distance" in line:
            #         rmsd = float(line.split()[-1])
            #----
            os.system("rm %s.xyz_2" % self.name)
        else:
            o = self.calltinker("analyze %s.xyz E" % self.name)
        # Read the TINKER output. 
        E = None
        for line in o:
            if "Total Potential Energy" in line:
                E = float(line.split()[-2].replace('D','e'))
        if E == None:
            logger.error("Total potential energy wasn't encountered when calling analyze!\n")
            raise RuntimeError
        if optimize and abs(E-E_) > 0.1:
            warn_press_key("Energy from optimize and analyze aren't the same (%.3f vs. %.3f)" % (E, E_))
        return E, rmsd
コード例 #15
0
ファイル: gmxio.py プロジェクト: mlaury/forcebalance
 def __init__(self,options,tgt_opts,forcefield):
     super(Liquid_GMX,self).__init__(options,tgt_opts,forcefield)
     # Number of threads in mdrun
     self.set_option(tgt_opts,'mdrun_threads')
     self.liquid_fnm = "liquid.gro"
     self.liquid_conf = Molecule(os.path.join(self.root, self.tgtdir,"liquid.gro"))
     self.liquid_traj = None
     self.gas_fnm = "gas.gro"
     if os.path.exists(os.path.join(self.root, self.tgtdir,"all.gro")):
         self.liquid_traj = Molecule(os.path.join(self.root, self.tgtdir,"all.gro"))
         print "Found collection of starting conformations, length %i!" % len(self.liquid_traj)
     if self.do_self_pol:
         warn_press_key("Self-polarization correction not implemented yet when using GMX")
     # Command prefix.
     self.nptpfx = 'sh rungmx.sh'
      # Suffix to command string for launching NPT simulations.
     self.nptsfx += ["--nt %i" % self.mdrun_threads]
     # List of extra files to upload to Work Queue.
     self.nptfiles += ['rungmx.sh', 'liquid.top', 'liquid.mdp', 'gas.top', 'gas.mdp']
     # MD engine argument supplied to command string for launching NPT simulations.
     self.engine = "gromacs"
     # Send back the trajectory file.
     if self.save_traj > 0:
         self.extra_output = ['liquid-md.trr']
コード例 #16
0
ファイル: gmxio.py プロジェクト: rmcgibbo/forcebalance
 def __init__(self,options,tgt_opts,forcefield):
     super(Liquid_GMX,self).__init__(options,tgt_opts,forcefield)
     # self.DynDict = OrderedDict()
     # self.DynDict_New = OrderedDict()
     if self.do_self_pol:
         warn_press_key("Self-polarization correction not implemented yet when using GMX")
コード例 #17
0
 def parse_optgeo_options(filename):
     """ Parse an optgeo_options.txt file into specific OptGeoTarget Target Options"""
     logger.info("Reading optgeo options from file: %s\n" % filename)
     global_opts = OrderedDict()
     sys_opts = OrderedDict()
     section = None
     section_opts = OrderedDict()
     with open(filename) as f:
         for ln, line in enumerate(f, 1):
             # Anything after "#" is a comment
             line = line.split("#", maxsplit=1)[0].strip()
             if not line: continue
             ls = line.split()
             key = ls[0].lower()
             if key[0] == "$":
                 # section sign $
                 if key == '$end':
                     if section is None:
                         warn_press_key(
                             "Line %i: Encountered $end before any section."
                             % ln)
                     elif section == 'global':
                         # global options read finish
                         global_opts = section_opts
                     elif section == 'system':
                         # check if system section contains name
                         if 'name' not in section_opts:
                             warn_press_key(
                                 "Line %i: You need to specify a name for the system section ending."
                                 % ln)
                         elif section_opts['name'] in sys_opts:
                             warn_press_key(
                                 "Line %i: A system named %s already exists in Systems"
                                 % (ln, section_opts['name']))
                         else:
                             sys_opts[section_opts['name']] = section_opts
                     section = None
                     section_opts = OrderedDict()
                 else:
                     if section is not None:
                         warn_press_key(
                             "Line %i: Encountered section start %s before previous section $end."
                             % (ln, key))
                     if key == '$global':
                         section = 'global'
                     elif key == '$system':
                         section = 'system'
                     else:
                         warn_press_key(
                             "Line %i: Encountered unsupported section name %s "
                             % (ln, key))
             else:
                 # put normal key-value options into section_opts
                 if key in ['name', 'geometry', 'topology']:
                     if len(ls) != 2:
                         warn_press_key(
                             "Line %i: one value expected for key %s" %
                             (ln, key))
                     if section == 'global':
                         warn_press_key(
                             "Line %i: key %s should not appear in $global section"
                             % (ln, key))
                     section_opts[key] = ls[1]
                 elif key in [
                         'bond_denom', 'angle_denom', 'dihedral_denom',
                         'improper_denom'
                 ]:
                     if len(ls) != 2:
                         warn_press_key(
                             "Line %i: one value expected for key %s" %
                             (ln, key))
                     section_opts[key] = float(ls[1])
                 elif key == 'mol2':
                     # special parsing for mol2 option for SMIRNOFF engine
                     # the value is a list of filenames
                     section_opts[key] = ls[1:]
     # apply a few default global options
     global_opts.setdefault('bond_denom', 0.02)
     global_opts.setdefault('angle_denom', 3)
     global_opts.setdefault('dihedral_denom', 10.0)
     global_opts.setdefault('improper_denom', 10.0)
     # copy global options into each system
     for sys_name, sys_opt_dict in sys_opts.items():
         for k, v in global_opts.items():
             # do not overwrite system options
             sys_opt_dict.setdefault(k, v)
         for k in ['name', 'geometry', 'topology']:
             if k not in sys_opt_dict:
                 warn_press_key(
                     "key %s missing in system section named %s" %
                     (k, sys_name))
     return sys_opts
コード例 #18
0
ファイル: psi4io.py プロジェクト: leeping/forcebalance
    def driver(self):
        ## Actually run PSI4.
        if not in_fd() and CheckBasis():
            logger.info("Now checking for linear dependencies.\n")
            _exec("cp %s %s.bak" % (self.GBSfnm, self.GBSfnm), print_command=False)
            ln0 = self.write_nested_destroy(self.GBSfnm, self.FF.linedestroy_save)
            o = wopen(".lindep.dat")
            for line in open(self.DATfnm).readlines():
                s = line.split("#")[0].split()
                if len(s) == 3 and s[0].lower() == 'basis' and s[1].lower() == 'file':
                    print("basis file %s" % self.GBSfnm, file=o)
                else:
                    print(line, end=' ', file=o)
            o.close()
            _exec("mv .lindep.dat %s" % self.DATfnm, print_command=False)
            _exec("psi4 %s" % self.DATfnm, print_command=False)
            LI = GBS_Reader()
            LI_lines = {}
            ## Read in the commented linindep.gbs file and ensure that these same lines are commented in the new .gbs file
            for line in open('linindep.gbs'):
                LI.feed(line,linindep=True)
                key = '.'.join([str(i) for i in (LI.element,LI.amom,LI.basis_number[LI.element],LI.contraction_number)])
                if LI.isdata:
                    if key in LI_lines:
                        logger.info("Duplicate key found:\n")
                        logger.info("%s\n" % key)
                        logger.info(str(LI_lines[key]))
                        logger.info(line)
                        warn_press_key("In %s, the LI_lines dictionary should not contain repeated keys!" % __file__)
                    LI_lines[key] = (line, LI.destroy)
            ## Now build a "Frankenstein" .gbs file composed of the original .gbs file but with data from the linindep.gbs file!
            FK = GBS_Reader()
            FK_lines = []
            self.FF.linedestroy_this = []
            self.FF.prmdestroy_this = []
            for ln, line in enumerate(open(self.GBSfnm).readlines()):
                FK.feed(line)
                key = '.'.join([str(i) for i in (FK.element,FK.amom,FK.basis_number[FK.element],FK.contraction_number)])
                if FK.isdata and key in LI_lines:
                    if LI_lines[key][1]:
                        logger.info("Destroying line %i (originally %i): " % (ln, ln0[ln]))
                        logger.info(line)
                        self.FF.linedestroy_this.append(ln)
                        for p_destroy in [i for i, fld in enumerate(self.FF.pfields) if any([subfld[0] == self.GBSfnm and subfld[1] == ln0[ln] for subfld in fld])]:
                            logger.info("Destroying parameter %i located at line %i (originally %i) with fields given by: %s" % (p_destroy, ln, ln0[ln], str(self.FF.pfields[p_destroy])))
                            self.FF.prmdestroy_this.append(p_destroy)
                    FK_lines.append(LI_lines[key][0])
                else:
                    FK_lines.append(line)
            o = wopen('franken.gbs')
            for line in FK_lines:
                print(line, end=' ', file=o)
            o.close()
            _exec("cp %s.bak %s" % (self.GBSfnm, self.GBSfnm), print_command=False)
            
            if len(list(itertools.chain(*(self.FF.linedestroy_save + [self.FF.linedestroy_this])))) > 0:
                logger.info("All lines removed: " + self.FF.linedestroy_save + [self.FF.linedestroy_this] + '\n')
                logger.info("All prms removed: " + self.FF.prmdestroy_save + [self.FF.prmdestroy_this] + '\n')

        self.write_nested_destroy(self.GBSfnm, self.FF.linedestroy_save + [self.FF.linedestroy_this])
        _exec("psi4", print_command=False, outfnm="psi4.stdout")
        if not in_fd():
            for line in open('psi4.stdout').readlines():
                if "MP2 Energy:" in line:
                    self.MP2_Energy = float(line.split()[-1])
                elif "DF Energy:" in line:
                    self.DF_Energy = float(line.split()[-1])
        Ans = np.array([[float(i) for i in line.split()] for line in open("objective.dat").readlines()])
        os.unlink("objective.dat")
        return Ans
コード例 #19
0
def parse_interactions(input_file):
    """ Parse through the interactions input file.

    @param[in]  input_file The name of the input file.
    
    """
    # Three dictionaries of return variables.
    Systems = OrderedDict()
    Interactions = OrderedDict()
    Globals = {}
    InterNum = 0
    InterName = "I0"
    InterDict = {}
    SystemName = None
    SystemDict = {}
    
    logger.info("Reading interactions from file: %s\n" % input_file)
    section = "NONE"
    fobj = open(input_file).readlines()
    for ln, line in enumerate(fobj):
        # Anything after "#" is a comment
        line = line.split("#")[0].strip()
        s = line.split()
        # Skip over blank lines
        if len(s) == 0:
            continue
        key = s[0].lower()
        # If line starts with a $, this signifies that we're in a new section.
        if re.match('^\$',line):
            word = re.sub('^\$','',line).upper()
            if word == "END": # End of a section, time to reinitialize variables.
                if section == "GLOBAL": pass
                elif section == "SYSTEM":
                    if SystemName is None:
                        warn_press_key("You need to specify a name for the system on line %i" % ln)
                    elif SystemName in Systems:
                        warn_press_key("A system named %s already exists in Systems" % SystemName)
                    Systems[SystemName] = SystemDict
                    SystemName = None
                    SystemDict = {}
                elif section == "INTERACTION":
                    if InterName in InterDict:
                        warn_press_key("A system named %s already exists in InterDict" % InterName)
                    Interactions[InterName] = InterDict
                    InterNum += 1
                    InterName = "I%i" % InterNum
                    InterDict = {}
                else:
                    warn_press_key("Encountered $end for unsupported section %s on line %i" % (word, ln))
                section = "NONE"
            elif section == "NONE":
                section = word
            else:
                warn_press_key("Encountered section keyword %s when already in section %s" % (word, section))
        elif section == "GLOBAL":
            if key in ['keyfile', 'energy_unit']:
                Globals[key] = s[1]
            elif key == 'optimize':
                if len(s) == 1 or s[1].lower() in ['y','yes','true']:
                    logger.info("Optimizing ALL systems by default\n")
                    Globals[key] = True
                else:
                    Globals[key] = False
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
        elif section == "SYSTEM":
            if key == 'name':
                SystemName = s[1]
            elif key == 'geometry':
                SystemDict[key] = s[1]
            elif key == 'rmsd_weight':
                SystemDict[key] = float(s[1])
            elif key == 'select':
                SystemDict[key] = s[1]
            elif key == 'optimize':
                if len(s) == 1 or s[1].lower() in ['y','yes','true']:
                    SystemDict[key] = True
                    logger.info("Optimizing system %s\n" % SystemName)
                else:
                    SystemDict[key] = False
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
        elif section == "INTERACTION":
            if key == 'name':
                InterName = s[1]
            elif key == 'equation':
                InterDict[key] = ' '.join(s[1:])
            elif key == 'energy':
                InterDict[key] = float(s[1])
            elif key == 'weight':
                InterDict[key] = float(s[1])
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
    return Globals, Systems, Interactions
コード例 #20
0
    def prepare(self, pbc=False, **kwargs):
        """ Called by __init__ ; prepare the temp directory and figure out the topology. """

        if hasattr(self, 'FF'):
            if not (os.path.exists(self.FF.amber_frcmod)
                    and os.path.exists(self.FF.amber_mol2)):
                # If the parameter files don't already exist, create them for the purpose of
                # preparing the engine, but then delete them afterward.
                prmtmp = True
                self.FF.make(np.zeros(self.FF.np))
            # Currently force field object only allows one mol2 and frcmod file although this can be lifted.
            self.mol2 = [self.FF.amber_mol2]
            self.frcmod = [self.FF.amber_frcmod]
            if 'mol2' in kwargs:
                logger.error(
                    "FF object is provided, which overrides mol2 keyword argument"
                )
                raise RuntimeError
            if 'frcmod' in kwargs:
                logger.error(
                    "FF object is provided, which overrides frcmod keyword argument"
                )
                raise RuntimeError
        else:
            prmtmp = False
            self.mol2 = listfiles(kwargs.get('mol2'), 'mol2', err=True)
            self.frcmod = listfiles(kwargs.get('frcmod'), 'frcmod', err=True)

        # Figure out the topology information.
        self.leap()
        o = self.callamber("rdparm %s.prmtop" % self.name,
                           stdin="printAtoms\nprintBonds\nexit\n",
                           persist=True,
                           print_error=False)

        # Once we do this, we don't need the prmtop and inpcrd anymore
        os.unlink("%s.inpcrd" % self.name)
        os.unlink("%s.prmtop" % self.name)
        os.unlink("leap.log")

        mode = 'None'
        self.AtomLists = defaultdict(list)
        G = nx.Graph()
        for line in o:
            s = line.split()
            if 'Atom' in line:
                mode = 'Atom'
            elif 'Bond' in line:
                mode = 'Bond'
            elif 'RDPARM MENU' in line:
                continue
            elif 'EXITING' in line:
                break
            elif len(s) == 0:
                continue
            elif mode == 'Atom':
                # Based on parsing lines like these:
                """
   327:  HA   -0.01462  1.0 (  23:HIP )  H1    E   
   328:  CB   -0.33212 12.0 (  23:HIP )  CT    3   
   329:  HB2   0.10773  1.0 (  23:HIP )  HC    E   
   330:  HB3   0.10773  1.0 (  23:HIP )  HC    E   
   331:  CG    0.18240 12.0 (  23:HIP )  CC    B   
                """
                # Based on variable width fields.
                atom_number = int(line.split(':')[0])
                atom_name = line.split()[1]
                atom_charge = float(line.split()[2])
                atom_mass = float(line.split()[3])
                rnn = line.split('(')[1].split(')')[0].split(':')
                residue_number = int(rnn[0])
                residue_name = rnn[1]
                atom_type = line.split(')')[1].split()[0]
                self.AtomLists['Name'].append(atom_name)
                self.AtomLists['Charge'].append(atom_charge)
                self.AtomLists['Mass'].append(atom_mass)
                self.AtomLists['ResidueNumber'].append(residue_number)
                self.AtomLists['ResidueName'].append(residue_name)
                # Not sure if this works
                G.add_node(atom_number)
            elif mode == 'Bond':
                a, b = (int(i)
                        for i in (line.split('(')[1].split(')')[0].split(',')))
                G.add_edge(a, b)

        self.AtomMask = [a == 'A' for a in self.AtomLists['ParticleType']]

        # Use networkx to figure out a list of molecule numbers.
        # gs = nx.connected_component_subgraphs(G)
        # tmols = [gs[i] for i in np.argsort(np.array([min(g.nodes()) for g in gs]))]
        # mnodes = [m.nodes() for m in tmols]
        # self.AtomLists['MoleculeNumber'] = [[i+1 in m for m in mnodes].index(1) for i in range(self.mol.na)]

        ## Write out the trajectory coordinates to a .mdcrd file.

        # I also need to write the trajectory
        if 'boxes' in self.mol.Data.keys():
            warn_press_key(
                "Writing %s-all.crd file with no periodic box information" %
                self.name)
            del self.mol.Data['boxes']

        if hasattr(self, 'target') and hasattr(self.target, 'shots'):
            self.qmatoms = target.qmatoms
            self.mol.write("%s-all.crd" % self.name,
                           select=range(self.target.shots),
                           ftype="mdcrd")
        else:
            self.qmatoms = self.mol.na
            self.mol.write("%s-all.crd" % self.name, ftype="mdcrd")

        if prmtmp:
            for f in self.FF.fnms:
                os.unlink(f)
コード例 #21
0
ファイル: npt_tinker.py プロジェクト: mlaury/forcebalance
def main():

    """
    Run the script with -h for help
    Usage: python npt_tinker.py input.xyz [-k input.key] liquid_production_steps liquid_timestep liquid_interval temperature(K) pressure(atm)
    """

    if not os.path.exists(args.liquid_xyzfile):
        warn_press_key("Warning: %s does not exist, script cannot continue" % args.liquid_xyzfile)

    # Set up some conversion factors
    # All units are in kJ/mol
    N = niterations
    # Conversion factor for kT derived from:
    # In [6]: 1.0 / ((1.0 * kelvin * BOLTZMANN_CONSTANT_kB * AVOGADRO_CONSTANT_NA) / kilojoule_per_mole)
    # Out[6]: 120.27221251395186
    T     = temperature
    mBeta = -120.27221251395186 / temperature
    Beta  =  120.27221251395186 / temperature
    kT    =  0.0083144724712202 * temperature
    # Conversion factor for pV derived from:
    # In [14]: 1.0 * atmosphere * nanometer ** 3 * AVOGADRO_CONSTANT_NA / kilojoule_per_mole
    # Out[14]: 0.061019351687175
    pcon  =  0.061019351687175

    # Load the force field in from the ForceBalance pickle.
    FF,mvals,h,AGrad = lp_load(open('forcebalance.p'))
    
    # Create the force field XML files.
    FF.make(mvals)

    #=================================================================#
    #     Get the number of molecules from the liquid xyz file.       #
    #=================================================================#

    xin = "%s" % args.liquid_xyzfile + ("" if args.liquid_keyfile == None else " -k %s" % args.liquid_keyfile)
    cmdstr = "./analyze %s" % xin
    oanl = _exec(cmdstr,stdin="G",print_command=True,print_to_screen=True)
    molflag = False
    for line in oanl:
        if 'Number of Molecules' in line:
            if not molflag:
                NMol = int(line.split()[-1])
                molflag = True
            else:
                raise Exception("TINKER output contained more than one line with the words 'Number of Molecules'")
    if molflag:
        print "Detected %i Molecules" % NMol
    if not molflag:
        raise Exception("Failed to detect the number of molecules")

    #=================================================================#
    # Run the simulation for the full system and analyze the results. #
    #=================================================================#
    Rhos, Potentials, Kinetics, Volumes, Dips = run_simulation(args.liquid_xyzfile,args.liquid_keyfile,tstep=timestep,nstep=nsteps,neq=nequiliterations,npr=niterations,verbose=True)
    Energies = Potentials + Kinetics
    V  = Volumes
    pV = pressure * Volumes
    H = Energies + pV

    # Get the energy and dipole gradients.
    print "Post-processing the liquid simulation snapshots."
    G, GDx, GDy, GDz = energy_dipole_derivatives(mvals,h,FF,args.liquid_xyzfile,args.liquid_keyfile,AGrad)
    print

    #==============================================#
    # Now run the simulation for just the monomer. #
    #==============================================#
    _a, mPotentials, mKinetics, _b, _c = run_simulation(args.gas_xyzfile,args.gas_keyfile,tstep=m_timestep,nstep=m_nsteps,neq=m_nequiliterations,npr=m_niterations,pbc=False)
    mEnergies = mPotentials + mKinetics
    mN = len(mEnergies)
    print "Post-processing the gas simulation snapshots."
    mG = energy_derivatives(mvals,h,FF,args.gas_xyzfile,args.gas_keyfile,AGrad)
    print

    numboots = 1000    
    def bootstats(func,inputs):
        # Calculate error using bootstats method
        dboot = []
        for i in range(numboots):
            newins = {k : v[np.random.randint(len(v),size=len(v))] for k,v in inputs.items()}
            dboot.append(np.mean(func(**newins)))
        return func(**inputs),np.std(np.array(dboot))
        
    def calc_arr(b = None, **kwargs):
        # This tomfoolery is required because of Python syntax;
        # default arguments must come after nondefault arguments
        # and kwargs must come at the end.  This function is used
        # in bootstrap error calcs and also in derivative calcs.
        if 'arr' in kwargs:
            arr = kwargs['arr']
        if b == None: b = np.ones(len(arr),dtype=float)
        return bzavg(arr,b)

    # The density in kg/m^3.
    # Note: Not really necessary to use bootstrap here, but good to 
    # demonstrate the principle.
    Rho_avg,  Rho_err  = bootstats(calc_arr,{'arr':Rhos})
    Rho_err *= np.sqrt(statisticalInefficiency(Rhos))

    print "The finite difference step size is:",h

    # The first density derivative
    GRho = mBeta * (flat(np.mat(G) * col(Rhos)) / N - np.mean(Rhos) * np.mean(G, axis=1))

    FDCheck = False

    Sep = printcool("Density: % .4f +- % .4f kg/m^3, Analytic Derivative" % (Rho_avg, Rho_err))
    FF.print_map(vals=GRho)
    print Sep

    if FDCheck:
        Sep = printcool("Numerical Derivative:")
        GRho1 = property_derivatives(mvals, h, FF, args.liquid_xyzfile, args.liquid_keyfile, kT, calc_arr, {'arr':Rhos})
        FF.print_map(vals=GRho1)
        Sep = printcool("Difference (Absolute, Fractional):")
        absfrac = ["% .4e  % .4e" % (i-j, (i-j)/j) for i,j in zip(GRho, GRho1)]
        FF.print_map(vals=absfrac)

    # The enthalpy of vaporization in kJ/mol.
    Ene_avg,  Ene_err  = bootstats(calc_arr,{'arr':Energies})
    mEne_avg, mEne_err = bootstats(calc_arr,{'arr':mEnergies})
    pV_avg,   pV_err   = bootstats(calc_arr,{'arr':pV})
    Ene_err  *= np.sqrt(statisticalInefficiency(Energies))
    mEne_err *= np.sqrt(statisticalInefficiency(mEnergies))
    pV_err   *= np.sqrt(statisticalInefficiency(pV))

    Hvap_avg = mEne_avg - Ene_avg / NMol + kT - np.mean(pV) / NMol
    Hvap_err = np.sqrt(Ene_err**2 / NMol**2 + mEne_err**2 + pV_err**2/NMol**2)

    # Build the first Hvap derivative.
    GHvap = np.mean(G,axis=1)
    GHvap += mBeta * (flat(np.mat(G) * col(Energies)) / N - Ene_avg * np.mean(G, axis=1))
    GHvap /= NMol
    GHvap -= np.mean(mG,axis=1)
    GHvap -= mBeta * (flat(np.mat(mG) * col(mEnergies)) / N - mEne_avg * np.mean(mG, axis=1))
    GHvap *= -1
    GHvap -= mBeta * (flat(np.mat(G) * col(pV)) / N - np.mean(pV) * np.mean(G, axis=1)) / NMol

    print "Box total energy:", np.mean(Energies)
    print "Monomer total energy:", np.mean(mEnergies)

    Sep = printcool("Enthalpy of Vaporization: % .4f +- %.4f kJ/mol, Derivatives below" % (Hvap_avg, Hvap_err))
    FF.print_map(vals=GHvap)
    print Sep

    # Define some things to make the analytic derivatives easier.
    Gbar = np.mean(G,axis=1)
    def covde(vec):
        return flat(np.mat(G)*col(vec))/N - Gbar*np.mean(vec)
    def avg(vec):
        return np.mean(vec)

    ## Thermal expansion coefficient and bootstrap error estimation
    def calc_alpha(b = None, **kwargs):
        if 'h_' in kwargs:
            h_ = kwargs['h_']
        if 'v_' in kwargs:
            v_ = kwargs['v_']
        if b == None: b = np.ones(len(v_),dtype=float)
        return 1/(kT*T) * (bzavg(h_*v_,b)-bzavg(h_,b)*bzavg(v_,b))/bzavg(v_,b)

    Alpha, Alpha_err = bootstats(calc_alpha,{'h_':H, 'v_':V})
    Alpha_err *= np.sqrt(max(statisticalInefficiency(V),statisticalInefficiency(H)))

    ## Thermal expansion coefficient analytic derivative
    GAlpha1 = mBeta * covde(H*V) / avg(V)
    GAlpha2 = Beta * avg(H*V) * covde(V) / avg(V)**2
    GAlpha3 = flat(np.mat(G)*col(V))/N/avg(V) - Gbar
    GAlpha4 = Beta * covde(H)
    GAlpha  = (GAlpha1 + GAlpha2 + GAlpha3 + GAlpha4)/(kT*T)
    Sep = printcool("Thermal expansion coefficient: % .4e +- %.4e K^-1\nAnalytic Derivative:" % (Alpha, Alpha_err))
    FF.print_map(vals=GAlpha)
    if FDCheck:
        GAlpha_fd = property_derivatives(mvals, h, FF, args.liquid_xyzfile, args.liquid_keyfile, kT, calc_alpha, {'h_':H,'v_':V})
        Sep = printcool("Numerical Derivative:")
        FF.print_map(vals=GAlpha_fd)
        Sep = printcool("Difference (Absolute, Fractional):")
        absfrac = ["% .4e  % .4e" % (i-j, (i-j)/j) for i,j in zip(GAlpha, GAlpha_fd)]
        FF.print_map(vals=absfrac)

    ## Isothermal compressibility
    # In [15]: 1.0*bar*nanometer**3/kilojoules_per_mole/item
    # Out[15]: 0.06022141792999999

    bar_unit = 0.06022141793
    def calc_kappa(b=None, **kwargs):
        if 'v_' in kwargs:
            v_ = kwargs['v_']
        if b == None: b = np.ones(len(v_),dtype=float)
        return bar_unit / kT * (bzavg(v_**2,b)-bzavg(v_,b)**2)/bzavg(v_,b)

    Kappa, Kappa_err = bootstats(calc_kappa,{'v_':V})
    Kappa_err *= np.sqrt(statisticalInefficiency(V))

    ## Isothermal compressibility analytic derivative
    Sep = printcool("Isothermal compressibility:    % .4e +- %.4e bar^-1\nAnalytic Derivative:" % (Kappa, Kappa_err))
    GKappa1 = -1 * Beta**2 * avg(V) * covde(V**2) / avg(V)**2
    GKappa2 = +1 * Beta**2 * avg(V**2) * covde(V) / avg(V)**2
    GKappa3 = +1 * Beta**2 * covde(V)
    GKappa  = bar_unit*(GKappa1 + GKappa2 + GKappa3)
    FF.print_map(vals=GKappa)
    if FDCheck:
        GKappa_fd = property_derivatives(mvals, h, FF, args.liquid_xyzfile, args.liquid_keyfile, kT, calc_kappa, {'v_':V})
        Sep = printcool("Numerical Derivative:")
        FF.print_map(vals=GKappa_fd)
        Sep = printcool("Difference (Absolute, Fractional):")
        absfrac = ["% .4e  % .4e" % (i-j, (i-j)/j) for i,j in zip(GKappa, GKappa_fd)]
        FF.print_map(vals=absfrac)

    ## Isobaric heat capacity
    def calc_cp(b=None, **kwargs):
        if 'h_' in kwargs:
            h_ = kwargs['h_']
        if b == None: b = np.ones(len(h_),dtype=float)
        Cp_  = 1/(NMol*kT*T) * (bzavg(h_**2,b) - bzavg(h_,b)**2)
        Cp_ *= 1000 / 4.184
        return Cp_

    Cp, Cp_err = bootstats(calc_cp, {'h_':H})
    Cp_err *= np.sqrt(statisticalInefficiency(H))

    ## Isobaric heat capacity analytic derivative
    GCp1 = 2*covde(H) * 1000 / 4.184 / (NMol*kT*T)
    GCp2 = mBeta*covde(H**2) * 1000 / 4.184 / (NMol*kT*T)
    GCp3 = 2*Beta*avg(H)*covde(H) * 1000 / 4.184 / (NMol*kT*T)
    GCp  = GCp1 + GCp2 + GCp3
    Sep = printcool("Isobaric heat capacity:        % .4e +- %.4e cal mol-1 K-1\nAnalytic Derivative:" % (Cp, Cp_err))
    FF.print_map(vals=GCp)
    if FDCheck:
        GCp_fd = property_derivatives(mvals, h, FF, args.liquid_xyzfile, args.liquid_keyfile, kT, calc_cp, {'h_':H})
        Sep = printcool("Numerical Derivative:")
        FF.print_map(vals=GCp_fd)
        Sep = printcool("Difference (Absolute, Fractional):")
        absfrac = ["% .4e  % .4e" % (i-j, (i-j)/j) for i,j in zip(GCp,GCp_fd)]
        FF.print_map(vals=absfrac)

    ## Dielectric constant
    # eps0 = 8.854187817620e-12 * coulomb**2 / newton / meter**2
    # epsunit = 1.0*(debye**2) / nanometer**3 / BOLTZMANN_CONSTANT_kB / kelvin
    # prefactor = epsunit/eps0/3
    prefactor = 30.348705333964077
    def calc_eps0(b=None, **kwargs):
        if 'd_' in kwargs: # Dipole moment vector.
            d_ = kwargs['d_']
        if 'v_' in kwargs: # Volume.
            v_ = kwargs['v_']
        if b == None: b = np.ones(len(v_),dtype=float)
        dx = d_[:,0]
        dy = d_[:,1]
        dz = d_[:,2]
        D2  = bzavg(dx**2,b)-bzavg(dx,b)**2
        D2 += bzavg(dy**2,b)-bzavg(dy,b)**2
        D2 += bzavg(dz**2,b)-bzavg(dz,b)**2
        return prefactor*D2/bzavg(v_,b)/T

    Eps0, Eps0_err = bootstats(calc_eps0,{'d_':Dips, 'v_':V})
    Eps0 += 1.0
    Eps0_err *= np.sqrt(np.mean([statisticalInefficiency(Dips[:,0]),statisticalInefficiency(Dips[:,1]),statisticalInefficiency(Dips[:,2])]))

    ## Dielectric constant analytic derivative
    Dx = Dips[:,0]
    Dy = Dips[:,1]
    Dz = Dips[:,2]
    D2 = avg(Dx**2)+avg(Dy**2)+avg(Dz**2)-avg(Dx)**2-avg(Dy)**2-avg(Dz)**2
    GD2  = 2*(flat(np.mat(GDx)*col(Dx))/N - avg(Dx)*(np.mean(GDx,axis=1))) - Beta*(covde(Dx**2) - 2*avg(Dx)*covde(Dx))
    GD2 += 2*(flat(np.mat(GDy)*col(Dy))/N - avg(Dy)*(np.mean(GDy,axis=1))) - Beta*(covde(Dy**2) - 2*avg(Dy)*covde(Dy))
    GD2 += 2*(flat(np.mat(GDz)*col(Dz))/N - avg(Dz)*(np.mean(GDz,axis=1))) - Beta*(covde(Dz**2) - 2*avg(Dz)*covde(Dz))
    GEps0 = prefactor*(GD2/avg(V) - mBeta*covde(V)*D2/avg(V)**2)/T
    Sep = printcool("Dielectric constant:           % .4e +- %.4e\nAnalytic Derivative:" % (Eps0, Eps0_err))
    FF.print_map(vals=GEps0)
    if FDCheck:
        GEps0_fd = property_derivatives(mvals, h, FF, args.liquid_xyzfile, args.liquid_keyfile, kT, calc_eps0, {'d_':Dips,'v_':V})
        Sep = printcool("Numerical Derivative:")
        FF.print_map(vals=GEps0_fd)
        Sep = printcool("Difference (Absolute, Fractional):")
        absfrac = ["% .4e  % .4e" % (i-j, (i-j)/j) for i,j in zip(GEps0,GEps0_fd)]
        FF.print_map(vals=absfrac)

    ## Print the final force field.
    pvals = FF.make(mvals)

    with open(os.path.join('npt_result.p'),'w') as f: lp_dump((Rhos, Volumes, Potentials, Energies, Dips, G, [GDx, GDy, GDz], mPotentials, mEnergies, mG, Rho_err, Hvap_err, Alpha_err, Kappa_err, Cp_err, Eps0_err, NMol),f)
コード例 #22
0
ファイル: optimizer.py プロジェクト: mlaury/forcebalance
    def step(self, xk, data, trust):
        """ Computes the next step in the parameter space.  There are lots of tricks here that I will document later.

        @param[in] G The gradient
        @param[in] H The Hessian
        @param[in] trust The trust radius
        
        """
        from scipy import optimize

        X, G, H = (data['X0'], data['G0'], data['H0']) if self.bhyp else (data['X'], data['G'], data['H'])
        H1 = H.copy()
        H1 = np.delete(H1, self.excision, axis=0)
        H1 = np.delete(H1, self.excision, axis=1)
        Eig = eig(H1)[0]            # Diagonalize Hessian
        Emin = min(Eig)
        if Emin < self.eps:         # Mix in SD step if Hessian minimum eigenvalue is negative
            # Experiment.
            Adj = max(self.eps, 0.01*abs(Emin)) - Emin
            logger.info("Hessian has a small or negative eigenvalue (%.1e), mixing in some steepest descent (%.1e) to correct this.\n" % (Emin, Adj))
            logger.info("Eigenvalues are:\n")   ###
            pvec1d(Eig)                ###
            H += Adj*np.eye(H.shape[0])

        if self.bhyp:
            G = np.delete(G, self.excision)
            H = np.delete(H, self.excision, axis=0)
            H = np.delete(H, self.excision, axis=1)
            xkd = np.delete(xk, self.excision)
            if self.Objective.Penalty.fmul != 0.0:
                warn_press_key("Using the multiplicative hyperbolic penalty is discouraged!")
            # This is the gradient and Hessian without the contributions from the hyperbolic constraint.
            Obj0 = {'X':X,'G':G,'H':H}
            class Hyper(object):
                def __init__(self, HL, Penalty):
                    self.H = HL.copy()
                    self.dx = 1e10 * np.ones(len(HL),dtype=float)
                    self.Val = 0
                    self.Grad = np.zeros(len(HL),dtype=float)
                    self.Hess = np.zeros((len(HL),len(HL)),dtype=float)
                    self.Penalty = Penalty
                def _compute(self, dx):
                    self.dx = dx.copy()
                    Tmp = np.mat(self.H)*col(dx)
                    Reg_Term   = self.Penalty.compute(xkd+flat(dx), Obj0)
                    self.Val   = (X + np.dot(dx, G) + 0.5*row(dx)*Tmp + Reg_Term[0] - data['X'])[0,0]
                    self.Grad  = flat(col(G) + Tmp) + Reg_Term[1]
                def compute_val(self, dx):
                    if norm(dx - self.dx) > 1e-8:
                        self._compute(dx)
                    return self.Val
                def compute_grad(self, dx):
                    if norm(dx - self.dx) > 1e-8:
                        self._compute(dx)
                    return self.Grad
                def compute_hess(self, dx):
                    if norm(dx - self.dx) > 1e-8:
                        self._compute(dx)
                    return self.Hess
            def hyper_solver(L):
                dx0 = np.zeros(len(xkd),dtype=float)
                #dx0 = np.delete(dx0, self.excision)
                # HL = H + (L-1)**2*np.diag(np.diag(H))
                # Attempt to use plain Levenberg
                HL = H + (L-1)**2*np.eye(len(H))

                HYP = Hyper(HL, self.Objective.Penalty)
                try:
                    Opt1 = optimize.fmin_bfgs(HYP.compute_val,dx0,fprime=HYP.compute_grad,gtol=1e-5,full_output=True,disp=0)
                except:
                    Opt1 = optimize.fmin(HYP.compute_val,dx0,full_output=True,disp=0)
                try:
                    Opt2 = optimize.fmin_bfgs(HYP.compute_val,-xkd,fprime=HYP.compute_grad,gtol=1e-5,full_output=True,disp=0)
                except:
                    Opt2 = optimize.fmin(HYP.compute_val,-xkd,full_output=True,disp=0)
                #Opt2 = optimize.fmin(HYP.compute_val,-xkd,full_output=True,disp=0)
                dx1, sol1 = Opt1[0], Opt1[1]
                dx2, sol2 = Opt2[0], Opt2[1]
                dxb, sol = (dx1, sol1) if sol1 <= sol2 else (dx2, sol2)
                for i in self.excision:    # Reinsert deleted coordinates - don't take a step in those directions
                    dxb = np.insert(dxb, i, 0)
                return dxb, sol
        else:
            # G0 and H0 are used for determining the expected function change.
            G0 = G.copy()
            H0 = H.copy()
            G = np.delete(G, self.excision)
            H = np.delete(H, self.excision, axis=0)
            H = np.delete(H, self.excision, axis=1)
            
            logger.debug("Inverting Hessian:\n")                 ###
            logger.debug(" G:\n")                                ###
            pvec1d(G,precision=5, loglevel=DEBUG)                ###
            logger.debug(" H:\n")                                ###
            pmat2d(H,precision=5, loglevel=DEBUG)                ###
            
            Hi = invert_svd(np.mat(H))
            dx = flat(-1 * Hi * col(G))
            
            logger.debug(" dx:\n")                               ###
            pvec1d(dx,precision=5, loglevel=DEBUG)                     ###
            # dxa = -solve(H, G)          # Take Newton Raphson Step ; use -1*G if want steepest descent.
            # dxa = flat(dxa)
            # print " dxa:"                              ###
            # pvec1d(dxa,precision=5)                    ###
            
            logger.info('\n')                                      ###
            for i in self.excision:    # Reinsert deleted coordinates - don't take a step in those directions
                dx = np.insert(dx, i, 0)
            def para_solver(L):
                # Levenberg-Marquardt
                # HT = H + (L-1)**2*np.diag(np.diag(H))
                # Attempt to use plain Levenberg
                HT = H + (L-1)**2*np.eye(len(H))
                logger.debug("Inverting Scaled Hessian:\n")                       ###
                logger.debug(" G:\n")                                             ###
                pvec1d(G,precision=5, loglevel=DEBUG)                                   ###
                logger.debug(" HT: (Scal = %.4f)\n" % (1+(L-1)**2))               ###
                pmat2d(HT,precision=5, loglevel=DEBUG)                                  ###
                Hi = invert_svd(np.mat(HT))
                dx = flat(-1 * Hi * col(G))
                logger.debug(" dx:\n")                                            ###
                pvec1d(dx,precision=5, loglevel=DEBUG)                                  ###
                # dxa = -solve(HT, G)
                # dxa = flat(dxa)
                # print " dxa:"                                           ###
                # pvec1d(dxa,precision=5)                                 ###
                # print                                                   ###
                sol = flat(0.5*row(dx)*np.mat(H)*col(dx))[0] + np.dot(dx,G)
                for i in self.excision:    # Reinsert deleted coordinates - don't take a step in those directions
                    dx = np.insert(dx, i, 0)
                return dx, sol
    
        def solver(L):
            return hyper_solver(L) if self.bhyp else para_solver(L)
    
        def trust_fun(L):
            N = norm(solver(L)[0])
            logger.debug("\rL = %.4e, Hessian diagonal addition = %.4e: found length %.4e, objective is %.4e\n" % (L, (L-1)**2, N, (N - trust)**2))
            return (N - trust)**2

        def search_fun(L):
            # Evaluate ONLY the objective function.  Most useful when
            # the objective is cheap, but the derivative is expensive.
            dx, sol = solver(L) # dx is how much the step changes from the previous step.
            # This is our trial step.
            xk_ = dx + xk
            Result = self.Objective.Full(xk_,0,verbose=False)['X'] - data['X']
            logger.info("Searching! Hessian diagonal addition = %.4e, L = % .4e, length %.4e, result %.4e\n" % ((L-1)**2,L,norm(dx),Result))
            return Result
        
        if self.trust0 > 0: # This is the trust region code.
            bump = False
            dx, expect = solver(1)
            dxnorm = norm(dx)
            if dxnorm > trust:
                bump = True
                # Tried a few optimizers here, seems like Brent works well.
                # Okay, the problem with Brent is that the tolerance is fractional.  
                # If the optimized value is zero, then it takes a lot of meaningless steps.
                LOpt = optimize.brent(trust_fun,brack=(self.lmg,self.lmg*4),tol=1e-6)
                ### Result = optimize.fmin_powell(trust_fun,3,xtol=self.search_tol,ftol=self.search_tol,full_output=1,disp=0)
                ### LOpt = Result[0]
                dx, expect = solver(LOpt)
                dxnorm = norm(dx)

                logger.info("\rLevenberg-Marquardt: %s step found (length %.3e), % .8f added to Hessian diagonal\n" % ('hyperbolic-regularized' if self.bhyp else 'Newton-Raphson', dxnorm, (LOpt-1)**2))
        else: # This is the nonlinear search code.
            # First obtain a step that is the same length as the provided trust radius.
            LOpt = optimize.brent(trust_fun,brack=(self.lmg,self.lmg*4),tol=1e-6)
            bump = False
            Result = optimize.brent(search_fun,brack=(LOpt,LOpt*4),tol=self.search_tol,full_output=1)
            ### optimize.fmin(search_fun,0,xtol=1e-8,ftol=data['X']*0.1,full_output=1,disp=0)
            ### Result = optimize.fmin_powell(search_fun,3,xtol=self.search_tol,ftol=self.search_tol,full_output=1,disp=0)
            dx, _ = solver(Result[0])
            expect = Result[1]

        ## Decide which parameters to redirect.
        ## Currently not used.
        if self.Objective.Penalty.ptyp in [3,4,5]:
            self.FF.make_redirect(dx+xk)

        return dx, expect, bump
コード例 #23
0
ファイル: optimizer.py プロジェクト: mlaury/forcebalance
    def MainOptimizer(self,b_BFGS=0):
        """ The main ForceBalance adaptive trust-radius pseudo-Newton optimizer.  Tried and true in many situations. :)

        Usually this function is called with the BFGS or NewtonRaphson
        method.  The NewtonRaphson method is consistently the best
        method I have, because I always provide at least an
        approximate Hessian to the objective function.  The BFGS
        method is vestigial and currently does not work.

        BFGS is a pseudo-Newton method in the sense that it builds an
        approximate Hessian matrix from the gradient information in previous
        steps; Newton-Raphson requires the actual Hessian matrix.
        However, the algorithms are similar in that they both compute the
        step by inverting the Hessian and multiplying by the gradient.

        The method adaptively changes the step size.  If the step is
        sufficiently good (i.e. the objective function goes down by a
        large fraction of the predicted decrease), then the step size
        is increased; if the step is bad, then it rejects the step and
        tries again.

        The optimization is terminated after either a function value or
        step size tolerance is reached.

        @param[in] b_BFGS Switch to use BFGS (True) or Newton-Raphson (False)

        """
        if any(['liquid' in tgt.name.lower() for tgt in self.Objective.Targets]) and self.conv_obj < 1e-3:
            warn_press_key("Condensed phase targets detected - may not converge with current choice of convergence_objective (%.e)\nRecommended range is 1e-2 - 1e-1 for this option." % self.conv_obj)
        # Parameters for the adaptive trust radius
        a = self.adapt_fac  # Default value is 0.5, decrease to make more conservative.  Zero to turn off all adaptive.
        b = self.adapt_damp # Default value is 0.5, increase to make more conservative
        printcool( "Main Optimizer\n%s Mode%s" % ("BFGS" if b_BFGS else "Newton-Raphson", " (Static Radius)" if a == 0.0 else " (Adaptive Radius)"), ansi=1, bold=1)
        # First, set a bunch of starting values
        Ord         = 1 if b_BFGS else 2
        #Ord         = 2
        global ITERATION_NUMBER
        ITERATION_NUMBER = 0
        global GOODSTEP
        Best_Step = 1
        if all(i in self.chk for i in ['xk','X','G','H','ehist','x_best','xk_prev','trust']):
            logger.info("Reading initial objective, gradient, Hessian from checkpoint file\n")
            xk, X, G, H, ehist     = self.chk['xk'], self.chk['X'], self.chk['G'], self.chk['H'], self.chk['ehist']
            X_best, xk_prev, trust = self.chk['x_best'], self.chk['xk_prev'], self.chk['trust']
        else:
            xk       = self.mvals0.copy()
            logger.info('\n')
            data     = self.Objective.Full(xk,Ord,verbose=True)
            X, G, H  = data['X'], data['G'], data['H']
            ehist    = np.array([X])
            xk_prev  = xk.copy()
            trust    = abs(self.trust0)
            X_best   = X

        X_prev   = X
        G_prev   = G.copy()
        H_stor   = H.copy()
        ndx    = 0.0
        color  = "\x1b[1m"
        nxk = norm(xk)
        ngr = norm(G)

        Quality  = 0.0
        restep = False
        GOODSTEP = 1
        Ord         = 1 if b_BFGS else 2

        while 1: # Loop until convergence is reached.
            ## Put data into the checkpoint file
            self.chk = {'xk': xk, 'X' : X, 'G' : G, 'H': H, 'ehist': ehist,
                        'x_best': X_best,'xk_prev': xk_prev, 'trust': trust}
            if self.wchk_step:
                self.writechk()
            stdfront = len(ehist) > self.hist and np.std(np.sort(ehist)[:self.hist]) or (len(ehist) > 0 and np.std(ehist) or 0.0)
            stdfront *= 2
            logger.info("%6s%12s%12s%12s%14s%12s%12s\n" % ("Step", "  |k|  ","  |dk|  "," |grad| ","    -=X2=-  ","Delta(X2)", "StepQual"))
            logger.info("%6i%12.3e%12.3e%12.3e%s%14.5e\x1b[0m%12.3e% 11.3f\n\n" % (ITERATION_NUMBER, nxk, ndx, ngr, color, X, stdfront, Quality))
            # Check the convergence criteria
            if ngr < self.conv_grd:
                logger.info("Convergence criterion reached for gradient norm (%.2e)\n" % self.conv_grd)
                break
            if ITERATION_NUMBER == self.maxstep:
                logger.info("Maximum number of optimization steps reached (%i)\n" % ITERATION_NUMBER)
                break
            if ndx < self.conv_stp and ITERATION_NUMBER > 0 and not restep:
                logger.info("Convergence criterion reached in step size (%.2e)\n" % self.conv_stp)
                break
            if stdfront < self.conv_obj and len(ehist) > self.hist and not restep: # Factor of two is so [0,1] stdev is normalized to 1
                logger.info("Convergence criterion reached for objective function (%.2e)\n" % self.conv_obj)
                break
            if self.print_grad:
                bar = printcool("Total Gradient",color=4)
                self.FF.print_map(vals=G,precision=8)
                logger.info(bar)
            if self.print_hess:
                bar = printcool("Total Hessian",color=4)
                pmat2d(H,precision=8)
                logger.info(bar)
            for key, val in self.Objective.ObjDict.items():
                if Best_Step:
                    self.Objective.ObjDict_Last[key] = val
            restep = False
            dx, dX_expect, bump = self.step(xk, data, trust)
            old_pk = self.FF.create_pvals(xk)
            old_xk = xk.copy()
            # Increment the iteration counter.
            ITERATION_NUMBER += 1
            # Take a step in the parameter space.
            xk += dx
            if self.print_vals:
                pk = self.FF.create_pvals(xk)
                dp = pk - old_pk
                bar = printcool("Mathematical Parameters (Current + Step = Next)",color=5)
                self.FF.print_map(vals=["% .4e %s %.4e = % .4e" % (old_xk[i], '+' if dx[i] >= 0 else '-', abs(dx[i]), xk[i]) for i in range(len(xk))])
                logger.info(bar)
                bar = printcool("Physical Parameters (Current + Step = Next)",color=5)
                self.FF.print_map(vals=["% .4e %s %.4e = % .4e" % (old_pk[i], '+' if dp[i] >= 0 else '-', abs(dp[i]), pk[i]) for i in range(len(pk))])
                logger.info(bar)
            # Evaluate the objective function and its derivatives.
            data        = self.Objective.Full(xk,Ord,verbose=True)
            X, G, H = data['X'], data['G'], data['H']
            ndx = norm(dx)
            nxk = norm(xk)
            ngr = norm(G)
            drc = abs(flat(dx)).argmax()

            dX_actual = X - X_prev
            try:
                Quality = dX_actual / dX_expect
            except:
                logger.warning("Warning: Step size of zero detected (i.e. wrong direction).  Try reducing the finite_difference_h parameter\n")
                Quality = 1.0 # This is a step length of zero.

            if Quality <= 0.25 and X < (X_prev + self.err_tol) and self.trust0 > 0:
                # If the step quality is bad, then we should decrease the trust radius.
                trust = max(ndx*(1./(1+a)), self.mintrust)
                logger.info("Low quality step, reducing trust radius to % .4e\n" % trust)
            if Quality >= 0.75 and bump and self.trust0 > 0:
                # If the step quality is good, then we should increase the trust radius.
                # The 'a' factor is how much we should grow or shrink the trust radius each step
                # and the 'b' factor determines how closely we are tied down to the original value.
                # Recommend values 0.5 and 0.5
                trust += a*trust*np.exp(-b*(trust/self.trust0 - 1))
            if X > (X_prev + self.err_tol):
                Best_Step = 0
                # Toggle switch for rejection (experimenting with no rejection)
                Rejects = True
                GOODSTEP = 0
                Reevaluate = True
                trust = max(ndx*(1./(1+a)), self.mintrust)
                logger.info("Rejecting step and reducing trust radius to % .4e\n" % trust)
                if Rejects:
                    xk = xk_prev.copy()
                    if Reevaluate:
                        restep = True
                        color = "\x1b[91m"
                        logger.info("%6s%12s%12s%12s%14s%12s%12s\n" % ("Step", "  |k|  ","  |dk|  "," |grad| ","    -=X2=-  ","Delta(X2)", "StepQual"))
                        logger.info("%6i%12.3e%12.3e%12.3e%s%14.5e\x1b[0m%12.3e% 11.3f\n\n" % (ITERATION_NUMBER, nxk, ndx, ngr, color, X, stdfront, Quality))
                        printcool("Objective function rises!\nRe-evaluating at the previous point..",color=1)
                        ITERATION_NUMBER += 1
                        data        = self.Objective.Full(xk,Ord,verbose=True)
                        GOODSTEP = 1
                        X, G, H = data['X'], data['G'], data['H']
                        X_prev = X
                        dx *= 0
                        ndx = norm(dx)
                        nxk = norm(xk)
                        ngr = norm(G)
                        Quality = 0.0
                        color = "\x1b[0m"
                    else:
                        color = "\x1b[91m"
                        G = G_prev.copy()
                        H = H_stor.copy()
                        data = deepcopy(datastor)
                    continue
            else:
                GOODSTEP = 1
                if X > X_best:
                    Best_Step = 0
                    color = "\x1b[95m"
                else:
                    Best_Step = 1
                    color = "\x1b[92m"
                    X_best = X
                ehist = np.append(ehist, X)
            # Hessian update for BFGS.
            if b_BFGS:
                Hnew = H_stor.copy()
                Dx   = col(xk - xk_prev)
                Dy   = col(G  - G_prev)
                Mat1 = (Dy*Dy.T)/(Dy.T*Dx)[0,0]
                Mat2 = ((Hnew*Dx)*(Hnew*Dx).T)/(Dx.T*Hnew*Dx)[0,0]
                Hnew += Mat1-Mat2
                H = Hnew.copy()
                data['H'] = H.copy()

            datastor= deepcopy(data)
            G_prev  = G.copy()
            H_stor  = H.copy()
            xk_prev = xk.copy()
            X_prev  = X
            if len(self.FF.parmdestroy_this) > 0:
                self.FF.parmdestroy_save.append(self.FF.parmdestroy_this)
                self.FF.linedestroy_save.append(self.FF.linedestroy_this)
        
        bar = printcool("Final objective function value\nFull: % .6e  Un-penalized: % .6e" % (data['X'],data['X0']), '@', bold=True, color=2)
        return xk
コード例 #24
0
    def driver(self):
        ## Actually run PSI4.
        if not in_fd() and CheckBasis():
            logger.info("Now checking for linear dependencies.\n")
            _exec("cp %s %s.bak" % (self.GBSfnm, self.GBSfnm),
                  print_command=False)
            ln0 = self.write_nested_destroy(self.GBSfnm,
                                            self.FF.linedestroy_save)
            o = wopen(".lindep.dat")
            for line in open(self.DATfnm).readlines():
                s = line.split("#")[0].split()
                if len(s) == 3 and s[0].lower() == 'basis' and s[1].lower(
                ) == 'file':
                    print("basis file %s" % self.GBSfnm, file=o)
                else:
                    print(line, end=' ', file=o)
            o.close()
            _exec("mv .lindep.dat %s" % self.DATfnm, print_command=False)
            _exec("psi4 %s" % self.DATfnm, print_command=False)
            LI = GBS_Reader()
            LI_lines = {}
            ## Read in the commented linindep.gbs file and ensure that these same lines are commented in the new .gbs file
            for line in open('linindep.gbs'):
                LI.feed(line, linindep=True)
                key = '.'.join([
                    str(i)
                    for i in (LI.element, LI.amom, LI.basis_number[LI.element],
                              LI.contraction_number)
                ])
                if LI.isdata:
                    if key in LI_lines:
                        logger.info("Duplicate key found:\n")
                        logger.info("%s\n" % key)
                        logger.info(str(LI_lines[key]))
                        logger.info(line)
                        warn_press_key(
                            "In %s, the LI_lines dictionary should not contain repeated keys!"
                            % __file__)
                    LI_lines[key] = (line, LI.destroy)
            ## Now build a "Frankenstein" .gbs file composed of the original .gbs file but with data from the linindep.gbs file!
            FK = GBS_Reader()
            FK_lines = []
            self.FF.linedestroy_this = []
            self.FF.prmdestroy_this = []
            for ln, line in enumerate(open(self.GBSfnm).readlines()):
                FK.feed(line)
                key = '.'.join([
                    str(i)
                    for i in (FK.element, FK.amom, FK.basis_number[FK.element],
                              FK.contraction_number)
                ])
                if FK.isdata and key in LI_lines:
                    if LI_lines[key][1]:
                        logger.info("Destroying line %i (originally %i): " %
                                    (ln, ln0[ln]))
                        logger.info(line)
                        self.FF.linedestroy_this.append(ln)
                        for p_destroy in [
                                i for i, fld in enumerate(self.FF.pfields)
                                if any([
                                    subfld[0] == self.GBSfnm
                                    and subfld[1] == ln0[ln] for subfld in fld
                                ])
                        ]:
                            logger.info(
                                "Destroying parameter %i located at line %i (originally %i) with fields given by: %s"
                                % (p_destroy, ln, ln0[ln],
                                   str(self.FF.pfields[p_destroy])))
                            self.FF.prmdestroy_this.append(p_destroy)
                    FK_lines.append(LI_lines[key][0])
                else:
                    FK_lines.append(line)
            o = wopen('franken.gbs')
            for line in FK_lines:
                print(line, end=' ', file=o)
            o.close()
            _exec("cp %s.bak %s" % (self.GBSfnm, self.GBSfnm),
                  print_command=False)

            if len(
                    list(
                        itertools.chain(*(self.FF.linedestroy_save +
                                          [self.FF.linedestroy_this])))) > 0:
                logger.info("All lines removed: " + self.FF.linedestroy_save +
                            [self.FF.linedestroy_this] + '\n')
                logger.info("All prms removed: " + self.FF.prmdestroy_save +
                            [self.FF.prmdestroy_this] + '\n')

        self.write_nested_destroy(
            self.GBSfnm, self.FF.linedestroy_save + [self.FF.linedestroy_this])
        _exec("psi4", print_command=False, outfnm="psi4.stdout")
        if not in_fd():
            for line in open('psi4.stdout').readlines():
                if "MP2 Energy:" in line:
                    self.MP2_Energy = float(line.split()[-1])
                elif "DF Energy:" in line:
                    self.DF_Energy = float(line.split()[-1])
        Ans = np.array([[float(i) for i in line.split()]
                        for line in open("objective.dat").readlines()])
        os.unlink("objective.dat")
        return Ans
コード例 #25
0
def write_leap(fnm,
               mol2=[],
               frcmod=[],
               pdb=None,
               prefix='amber',
               spath=[],
               delcheck=False):
    """ Parse and edit an AMBER LEaP input file. Output file is written to inputfile_ (with trailing underscore.) """
    have_fmod = []
    have_mol2 = []
    # The lines that will be printed out to actually run tleap
    line_out = []
    aload = ['loadamberparams', 'source', 'loadoff']
    aload_eq = ['loadmol2']
    spath.append('.')

    for line in open(fnm):
        # Skip comment lines
        if line.strip().startswith('#'): continue
        line = line.split('#')[0]
        s = line.split()
        ll = line.lower()
        ls = line.lower().split()
        # Check to see if all files being loaded are in the search path
        if '=' in line:
            if ll.split('=')[1].split()[0] in aload_eq:
                if not any(
                    [os.path.exists(os.path.join(d, s[-1])) for d in spath]):
                    logger.error("The file in this line cannot be loaded : " +
                                 line.strip())
                    raise RuntimeError
        elif len(ls) > 0 and ls[0] in aload:
            if not any([os.path.exists(os.path.join(d, s[-1]))
                        for d in spath]):
                logger.error("The file in this line cannot be loaded : " +
                             line.strip())
                raise RuntimeError
        if len(s) >= 2 and ls[0] == 'loadamberparams':
            have_fmod.append(s[1])
        if len(s) >= 2 and 'loadmol2' in ll:
            have_mol2.append(s[-1])
        if len(s) >= 2 and 'loadpdb' in ll:
            # Adopt the AMBER molecule name from the loadpdb line.
            ambername = line.split('=')[0].strip()
            # If we pass in our own PDB, then this line is replaced.
            if pdb != None:
                line = '%s = loadpdb %s\n' % (ambername, pdb)
        if len(s) >= 1 and ls[0] == 'check' and delcheck:
            # Skip over check steps if so decreed
            line = "# " + line
        if 'saveamberparm' in ll:
            # We'll write the saveamberparm line ourselves
            continue
        if len(s) >= 1 and ls[0] == 'quit':
            # Don't write the quit line.
            break
        if not line.endswith('\n'): line += '\n'
        line_out.append(line)
    # Sanity checks: If frcmod and mol2 files are provided to this function,
    # they should be in the leap.cmd file as well.  There should be exactly
    # one PDB file being loaded.
    for i in frcmod:
        if i not in have_fmod:
            warn_press_key("WARNING: %s is not being loaded in %s" % (i, fnm))
    for i in mol2:
        if i not in have_mol2:
            warn_press_key("WARNING: %s is not being loaded in %s" % (i, fnm))

    fout = fnm + '_'
    line_out.append('saveamberparm %s %s.prmtop %s.inpcrd\n' %
                    (ambername, prefix, prefix))
    line_out.append('quit\n')
    with wopen(fout) as f:
        print >> f, ''.join(line_out)
コード例 #26
0
ファイル: amberio.py プロジェクト: albaugh/forcebalance
def write_leap(fnm, mol2=[], frcmod=[], pdb=None, prefix='amber', spath = [], delcheck=False):
    """ Parse and edit an AMBER LEaP input file. Output file is written to inputfile_ (with trailing underscore.) """
    have_fmod = []
    have_mol2 = []
    # The lines that will be printed out to actually run tleap
    line_out = []
    aload = ['loadamberparams', 'source', 'loadoff']
    aload_eq = ['loadmol2']
    spath.append('.')
             
    for line in open(fnm):
        # Skip comment lines
        if line.strip().startswith('#') : continue
        line = line.split('#')[0]
        s = line.split()
        ll = line.lower()
        ls = line.lower().split()
        # Check to see if all files being loaded are in the search path
        if '=' in line:
            if ll.split('=')[1].split()[0] in aload_eq:
                if not any([os.path.exists(os.path.join(d, s[-1])) for d in spath]):
                    logger.error("The file in this line cannot be loaded : " + line.strip())
                    raise RuntimeError
        elif len(ls) > 0 and ls[0] in aload:
            if not any([os.path.exists(os.path.join(d, s[-1])) for d in spath]):
                logger.error("The file in this line cannot be loaded : " + line.strip())
                raise RuntimeError
        if len(s) >= 2 and ls[0] == 'loadamberparams':
            have_fmod.append(s[1])
        if len(s) >= 2 and 'loadmol2' in ll:
            have_mol2.append(s[-1])
        if len(s) >= 2 and 'loadpdb' in ll:
            # Adopt the AMBER molecule name from the loadpdb line.
            ambername = line.split('=')[0].strip()
            # If we pass in our own PDB, then this line is replaced.
            if pdb != None:
                line = '%s = loadpdb %s\n' % (ambername, pdb)
        if len(s) >= 1 and ls[0] == 'check' and delcheck:
            # Skip over check steps if so decreed
            line = "# " + line
        if 'saveamberparm' in ll: 
            # We'll write the saveamberparm line ourselves
            continue
        if len(s) >= 1 and ls[0] == 'quit':
            # Don't write the quit line.
            break
        if not line.endswith('\n') : line += '\n'
        line_out.append(line)
    # Sanity checks: If frcmod and mol2 files are provided to this function,
    # they should be in the leap.cmd file as well.  There should be exactly
    # one PDB file being loaded.
    for i in frcmod:
        if i not in have_fmod:
            warn_press_key("WARNING: %s is not being loaded in %s" % (i, fnm))
    for i in mol2:
        if i not in have_mol2:
            warn_press_key("WARNING: %s is not being loaded in %s" % (i, fnm))

    fout = fnm+'_'
    line_out.append('saveamberparm %s %s.prmtop %s.inpcrd\n' % (ambername, prefix, prefix))
    line_out.append('quit\n')
    with wopen(fout) as f: print >> f, ''.join(line_out)
コード例 #27
0
ファイル: binding.py プロジェクト: andysim/forcebalance
def parse_interactions(input_file):
    """ Parse through the interactions input file.

    @param[in]  input_file The name of the input file.
    
    """
    # Three dictionaries of return variables.
    Systems = OrderedDict()
    Interactions = OrderedDict()
    Globals = {}
    InterNum = 0
    InterName = "I0"
    InterDict = {}
    SystemName = None
    SystemDict = {}
    
    logger.info("Reading interactions from file: %s\n" % input_file)
    section = "NONE"
    fobj = open(input_file).readlines()
    for ln, line in enumerate(fobj):
        # Anything after "#" is a comment
        line = line.split("#")[0].strip()
        s = line.split()
        # Skip over blank lines
        if len(s) == 0:
            continue
        key = s[0].lower()
        # If line starts with a $, this signifies that we're in a new section.
        if re.match('^\$',line):
            word = re.sub('^\$','',line).upper()
            if word == "END": # End of a section, time to reinitialize variables.
                if section == "GLOBAL": pass
                elif section == "SYSTEM":
                    if SystemName == None:
                        warn_press_key("You need to specify a name for the system on line %i" % ln)
                    elif SystemName in Systems:
                        warn_press_key("A system named %s already exists in Systems" % SystemName)
                    Systems[SystemName] = SystemDict
                    SystemName = None
                    SystemDict = {}
                elif section == "INTERACTION":
                    if InterName in InterDict:
                        warn_press_key("A system named %s already exists in InterDict" % InterName)
                    Interactions[InterName] = InterDict
                    InterNum += 1
                    InterName = "I%i" % InterNum
                    InterDict = {}
                else:
                    warn_press_key("Encountered $end for unsupported section %s on line %i" % (word, ln))
                section = "NONE"
            elif section == "NONE":
                section = word
            else:
                warn_press_key("Encountered section keyword %s when already in section %s" % (word, section))
        elif section == "GLOBAL":
            if key in ['keyfile', 'energy_unit']:
                Globals[key] = s[1]
            elif key == 'optimize':
                if len(s) == 1 or s[1].lower() in ['y','yes','true']:
                    logger.info("Optimizing ALL systems by default\n")
                    Globals[key] = True
                else:
                    Globals[key] = False
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
        elif section == "SYSTEM":
            if key == 'name':
                SystemName = s[1]
            elif key == 'geometry':
                SystemDict[key] = s[1]
            elif key == 'rmsd_weight':
                SystemDict[key] = float(s[1])
            elif key == 'select':
                SystemDict[key] = s[1]
            elif key == 'optimize':
                if len(s) == 1 or s[1].lower() in ['y','yes','true']:
                    SystemDict[key] = True
                    logger.info("Optimizing system %s\n" % SystemName)
                else:
                    SystemDict[key] = False
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
        elif section == "INTERACTION":
            if key == 'name':
                InterName = s[1]
            elif key == 'equation':
                InterDict[key] = ' '.join(s[1:])
            elif key == 'energy':
                InterDict[key] = float(s[1])
            elif key == 'weight':
                InterDict[key] = float(s[1])
            else:
                warn_press_key("Encountered unsupported key %s in section %s on line %i" % (key, section, ln))
    return Globals, Systems, Interactions
コード例 #28
0
ファイル: amberio.py プロジェクト: albaugh/forcebalance
    def prepare(self, pbc=False, **kwargs):

        """ Called by __init__ ; prepare the temp directory and figure out the topology. """

        if hasattr(self,'FF'):
            if not (os.path.exists(self.FF.amber_frcmod) and os.path.exists(self.FF.amber_mol2)):
                # If the parameter files don't already exist, create them for the purpose of
                # preparing the engine, but then delete them afterward.
                prmtmp = True
                self.FF.make(np.zeros(self.FF.np))
            # Currently force field object only allows one mol2 and frcmod file although this can be lifted.
            self.mol2 = [self.FF.amber_mol2]
            self.frcmod = [self.FF.amber_frcmod]
            if 'mol2' in kwargs:
                logger.error("FF object is provided, which overrides mol2 keyword argument")
                raise RuntimeError
            if 'frcmod' in kwargs:
                logger.error("FF object is provided, which overrides frcmod keyword argument")
                raise RuntimeError
        else:
            prmtmp = False
            self.mol2 = listfiles(kwargs.get('mol2'), 'mol2', err=True)
            self.frcmod = listfiles(kwargs.get('frcmod'), 'frcmod', err=True)

        # Figure out the topology information.
        self.leap()
        o = self.callamber("rdparm %s.prmtop" % self.name, 
                           stdin="printAtoms\nprintBonds\nexit\n", 
                           persist=True, print_error=False)

        # Once we do this, we don't need the prmtop and inpcrd anymore
        os.unlink("%s.inpcrd" % self.name)
        os.unlink("%s.prmtop" % self.name)
        os.unlink("leap.log")

        mode = 'None'
        self.AtomLists = defaultdict(list)
        G = nx.Graph()
        for line in o:
            s = line.split()
            if 'Atom' in line:
                mode = 'Atom'
            elif 'Bond' in line:
                mode = 'Bond'
            elif 'RDPARM MENU' in line:
                continue
            elif 'EXITING' in line:
                break
            elif len(s) == 0:
                continue
            elif mode == 'Atom':
                # Based on parsing lines like these:
                """
   327:  HA   -0.01462  1.0 (  23:HIP )  H1    E   
   328:  CB   -0.33212 12.0 (  23:HIP )  CT    3   
   329:  HB2   0.10773  1.0 (  23:HIP )  HC    E   
   330:  HB3   0.10773  1.0 (  23:HIP )  HC    E   
   331:  CG    0.18240 12.0 (  23:HIP )  CC    B   
                """
                # Based on variable width fields.
                atom_number = int(line.split(':')[0])
                atom_name = line.split()[1]
                atom_charge = float(line.split()[2])
                atom_mass = float(line.split()[3])
                rnn = line.split('(')[1].split(')')[0].split(':')
                residue_number = int(rnn[0])
                residue_name = rnn[1]
                atom_type = line.split(')')[1].split()[0]
                self.AtomLists['Name'].append(atom_name)
                self.AtomLists['Charge'].append(atom_charge)
                self.AtomLists['Mass'].append(atom_mass)
                self.AtomLists['ResidueNumber'].append(residue_number)
                self.AtomLists['ResidueName'].append(residue_name)
                # Not sure if this works
                G.add_node(atom_number)
            elif mode == 'Bond':
                a, b = (int(i) for i in (line.split('(')[1].split(')')[0].split(',')))
                G.add_edge(a, b)

        self.AtomMask = [a == 'A' for a in self.AtomLists['ParticleType']]

        # Use networkx to figure out a list of molecule numbers.
        # gs = nx.connected_component_subgraphs(G)
        # tmols = [gs[i] for i in np.argsort(np.array([min(g.nodes()) for g in gs]))]
        # mnodes = [m.nodes() for m in tmols]
        # self.AtomLists['MoleculeNumber'] = [[i+1 in m for m in mnodes].index(1) for i in range(self.mol.na)]

        ## Write out the trajectory coordinates to a .mdcrd file.

        # I also need to write the trajectory
        if 'boxes' in self.mol.Data.keys():
            warn_press_key("Writing %s-all.crd file with no periodic box information" % self.name)
            del self.mol.Data['boxes']

        if hasattr(self, 'target') and hasattr(self.target,'shots'):
            self.qmatoms = target.qmatoms
            self.mol.write("%s-all.crd" % self.name, select=range(self.target.shots), ftype="mdcrd")
        else:
            self.qmatoms = self.mol.na
            self.mol.write("%s-all.crd" % self.name, ftype="mdcrd")

        if prmtmp:
            for f in self.FF.fnms: 
                os.unlink(f)