示例#1
0
    def read_reference_data(self):
        """ Read the reference hydrational data from a file. """
        # Read the HFE data file.  This is a very simple file format:
        self.IDs = []
        self.expval = OrderedDict()
        self.experr = OrderedDict()
        self.nicknames = OrderedDict()
        # We don't need every single line to be the same.  This
        # indicates whether *any* molecule has a nickname for printing
        # out the nickname column.
        self.have_nicks = False
        # Again for experimental errors.  Note that we're NOT using them in the optimization at this time.
        self.have_experr = False
        for line in open(self.datafile).readlines():
            s = line.expandtabs().strip().split('#')[0].split()
            if len(s) == 0: continue
            ID = s[0]
            self.IDs.append(ID)
            # Dynamic field number for the experimental data.
            nxt = 1
            # If the next field is a string, then it's the "nickname"
            if not isfloat(s[1]):
                self.have_nicks = True
                self.nicknames[ID] = s[1]
                nxt += 1
            else:
                # We don't need nicknames on every single line.
                self.nicknames[ID] = ID
            # Read the experimental value.
            self.expval[ID] = float(s[nxt])
            # Read the experimental error bar, or use a default value of 0.6 (from Mobley).
            if len(s) > (nxt + 1):
                self.have_experr = True
                self.experr[ID] = float(s[nxt + 1])
            else:
                self.experr[ID] = 0.6

        self.molecules = OrderedDict([
            (i,
             os.path.abspath(
                 os.path.join(self.root, self.tgtdir, 'molecules',
                              i + self.crdsfx))) for i in self.IDs
        ])
        for fnm, path in self.molecules.items():
            if not os.path.isfile(path):
                logger.error(
                    'Coordinate file %s does not exist!\nMake sure coordinate files are in the right place\n'
                    % path)
                raise RuntimeError
        if self.subset is not None:
            subset = uncommadash(self.subset)
            self.whfe = np.array(
                [1 if i in subset else 0 for i in range(len(self.IDs))])
        else:
            self.whfe = np.ones(len(self.IDs))
示例#2
0
 def read_reference_data(self):
     """ Read the reference hydrational data from a file. """
     self.refdata = OrderedDict([(l.split()[0], float(l.split()[1])) for l in open(self.datafile).readlines()])
     self.molecules = OrderedDict([(i, os.path.abspath(os.path.join(self.root, self.tgtdir, 'molecules', i+self.crdsfx))) for i in self.refdata.keys()])
     for fnm, path in self.molecules.items():
         if not os.path.isfile(path):
             logger.error('Coordinate file %s does not exist!\nMake sure coordinate files are in the right place\n' % path)
             raise RuntimeError
     if self.subset != None:
         subset = uncommadash(self.subset)
         self.whfe = np.array([1 if i in subset else 0 for i in range(len(self.refdata.keys()))])
     else:
         self.whfe = np.ones(len(self.refdata.keys()))
示例#3
0
 def read_reference_data(self):
     """ Read the reference hydrational data from a file. """
     # Read the HFE data file.  This is a very simple file format:
     self.IDs = []
     self.expval = OrderedDict()
     self.experr = OrderedDict()
     self.nicknames = OrderedDict()
     # We don't need every single line to be the same.  This
     # indicates whether *any* molecule has a nickname for printing
     # out the nickname column.
     self.have_nicks = False
     # Again for experimental errors.  Note that we're NOT using them in the optimization at this time.
     self.have_experr = False
     for line in open(self.datafile).readlines():
         s = line.expandtabs().strip().split('#')[0].split()
         if len(s) == 0: continue
         ID = s[0]
         self.IDs.append(ID)
         # Dynamic field number for the experimental data.
         nxt = 1
         # If the next field is a string, then it's the "nickname"
         if not isfloat(s[1]):
             self.have_nicks = True
             self.nicknames[ID] = s[1]
             nxt += 1
         else:
             # We don't need nicknames on every single line.
             self.nicknames[ID] = ID
         # Read the experimental value.
         self.expval[ID] = float(s[nxt])
         # Read the experimental error bar, or use a default value of 0.6 (from Mobley).
         if len(s) > (nxt+1):
             self.have_experr = True
             self.experr[ID] = float(s[nxt+1])
         else:
             self.experr[ID] = 0.6
     
     self.molecules = OrderedDict([(i, os.path.abspath(os.path.join(self.root, self.tgtdir, 'molecules', i+self.crdsfx))) for i in self.IDs])
     for fnm, path in self.molecules.items():
         if not os.path.isfile(path):
             logger.error('Coordinate file %s does not exist!\nMake sure coordinate files are in the right place\n' % path)
             raise RuntimeError
     if self.subset != None:
         subset = uncommadash(self.subset)
         self.whfe = np.array([1 if i in subset else 0 for i in range(len(self.IDs))])
     else:
         self.whfe = np.ones(len(self.IDs))
示例#4
0
 def read_reference_data(self):
     """ Read the reference hydrational data from a file. """
     self.refdata = OrderedDict([(l.split()[0], float(l.split()[1]))
                                 for l in open(self.datafile).readlines()])
     self.molecules = OrderedDict([
         (i,
          os.path.abspath(
              os.path.join(self.root, self.tgtdir, 'molecules',
                           i + self.crdsfx))) for i in self.refdata.keys()
     ])
     for fnm, path in self.molecules.items():
         if not os.path.isfile(path):
             logger.error(
                 'Coordinate file %s does not exist!\nMake sure coordinate files are in the right place\n'
                 % path)
             raise RuntimeError
     if self.subset != None:
         subset = uncommadash(self.subset)
         self.whfe = np.array([
             1 if i in subset else 0
             for i in range(len(self.refdata.keys()))
         ])
     else:
         self.whfe = np.ones(len(self.refdata.keys()))
示例#5
0
    def __init__(self,options,tgt_opts,forcefield):
        # Initialize the SuperClass!
        super(Interaction,self).__init__(options,tgt_opts,forcefield)

        #======================================#
        # Options that are given by the parser #
        #======================================#

        ## Number of snapshots
        self.set_option(tgt_opts,'shots','ns')
        ## Do we call Q-Chem for dielectric energies? (Currently needs to be fixed)
        self.set_option(tgt_opts,'do_cosmo','do_cosmo')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts,'cauchy','cauchy')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts,'attenuate','attenuate')
        ## Divide by the number of snapshots?
        self.set_option(tgt_opts, 'normalize')
        ## What is the energy denominator?
        self.set_option(tgt_opts,'energy_denom','energy_denom')
        ## Set fragment 1
        self.set_option(tgt_opts,'fragment1','fragment1')
        if len(self.fragment1) == 0:
            logger.error('You need to define the first fragment using the fragment1 keyword\n')
            raise RuntimeError
        self.select1 = np.array(uncommadash(self.fragment1))
        ## Set fragment 2
        self.set_option(tgt_opts,'fragment2','fragment2')
        if len(self.fragment2) != 0:
            self.select2 = np.array(uncommadash(self.fragment2))
        else:
            self.select2 = None
        ## Set upper cutoff energy
        self.set_option(tgt_opts,'energy_upper','energy_upper')
        #======================================#
        #     Variables which are set here     #
        #======================================#
        ## Reference (QM) interaction energies
        self.eqm           = []
        ## Snapshot label, useful for graphing
        self.label         = []
        ## The qdata.txt file that contains the QM energies and forces
        self.qfnm = os.path.join(self.tgtdir,"qdata.txt")
        self.e_err = 0.0
        self.e_err_pct = None
        ## Read in the trajectory file
        self.mol = Molecule(os.path.join(self.root,self.tgtdir,self.coords),
                            top=(os.path.join(self.root,self.tgtdir,self.pdb) if hasattr(self, 'pdb') else None))
        if self.ns != -1:
            self.mol = self.mol[:self.ns]
        self.ns = len(self.mol)
        if self.select2 is None:
            self.select2 = [i for i in range(self.mol.na) if i not in self.select1]
            logger.info('Fragment 2 is the complement of fragment 1 : %s\n' % (commadash(self.select2)))
        ## Build keyword dictionaries to pass to engine.
        engine_args = OrderedDict(self.OptionDict.items() + options.items())
        del engine_args['name']
        self.engine = self.engine_(target=self, mol=self.mol, **engine_args)
        ## Read in the reference data
        self.read_reference_data()
        logger.info("The energy denominator is: %s kcal/mol\n"  % str(self.energy_denom))
        denom = self.energy_denom
        # Create the denominator.
        if self.cauchy:
            self.divisor = np.sqrt(self.eqm**2 + denom**2)
            if self.attenuate:
                logger.error('attenuate and cauchy are mutually exclusive\n')
                raise RuntimeError
        elif self.attenuate:
            # Attenuate only large repulsions.
            self.divisor = np.zeros(len(self.eqm))
            for i in range(len(self.eqm)):
                if self.eqm[i] < denom:
                    self.divisor[i] = denom
                else:
                    self.divisor[i] = np.sqrt(denom**2 + (self.eqm[i]-denom)**2)
        else:
            self.divisor = np.ones(len(self.eqm)) * denom

        if self.cauchy:
            logger.info("Each contribution to the interaction energy objective function will be scaled by 1.0 / ( energy_denom**2 + reference**2 )\n")
        if self.energy_upper > 0:
            ecut = self.energy_upper
            self.prefactor = 1.0 * (self.eqm < ecut)
            logger.info("Interactions more repulsive than %s will not be fitted (%i/%i excluded) \n" % (str(self.energy_upper), sum(self.eqm > ecut), len(self.eqm)))
        else:
            self.prefactor = np.ones(len(self.eqm))
        if self.normalize:
            self.prefactor /= len(self.prefactor)
示例#6
0
    def __init__(self, options, tgt_opts, forcefield):
        # Initialize the SuperClass!
        super(Interaction, self).__init__(options, tgt_opts, forcefield)

        #======================================#
        # Options that are given by the parser #
        #======================================#

        ## Number of snapshots
        self.set_option(tgt_opts, 'shots', 'ns')
        ## Do we call Q-Chem for dielectric energies? (Currently needs to be fixed)
        self.set_option(tgt_opts, 'do_cosmo', 'do_cosmo')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts, 'cauchy', 'cauchy')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts, 'attenuate', 'attenuate')
        ## Divide by the number of snapshots?
        self.set_option(tgt_opts, 'normalize')
        ## What is the energy denominator?
        self.set_option(tgt_opts, 'energy_denom', 'energy_denom')
        ## Set fragment 1
        self.set_option(tgt_opts, 'fragment1', 'fragment1')
        if len(self.fragment1) == 0:
            logger.error(
                'You need to define the first fragment using the fragment1 keyword\n'
            )
            raise RuntimeError
        self.select1 = np.array(uncommadash(self.fragment1))
        ## Set fragment 2
        self.set_option(tgt_opts, 'fragment2', 'fragment2')
        if len(self.fragment2) != 0:
            self.select2 = np.array(uncommadash(self.fragment2))
        else:
            self.select2 = None
        ## Set upper cutoff energy
        self.set_option(tgt_opts, 'energy_upper', 'energy_upper')
        #======================================#
        #     Variables which are set here     #
        #======================================#
        ## Reference (QM) interaction energies
        self.eqm = []
        ## Snapshot label, useful for graphing
        self.label = []
        ## The qdata.txt file that contains the QM energies and forces
        self.qfnm = os.path.join(self.tgtdir, "qdata.txt")
        self.e_err = 0.0
        self.e_err_pct = None
        ## Read in the trajectory file
        if self.ns == -1:
            self.mol = Molecule(
                os.path.join(self.root, self.tgtdir, self.coords))
            self.ns = len(self.mol)
        else:
            self.mol = Molecule(
                os.path.join(self.root, self.tgtdir, self.coords))[:self.ns]
        if self.select2 == None:
            self.select2 = [
                i for i in range(self.mol.na) if i not in self.select1
            ]
            logger.info('Fragment 2 is the complement of fragment 1 : %s\n' %
                        (commadash(self.select2)))
        ## Build keyword dictionaries to pass to engine.
        engine_args = OrderedDict(self.OptionDict.items() + options.items())
        del engine_args['name']
        self.engine = self.engine_(target=self, mol=self.mol, **engine_args)
        ## Read in the reference data
        self.read_reference_data()
        logger.info("The energy denominator is: %s kcal/mol\n" %
                    str(self.energy_denom))
        denom = self.energy_denom
        # Create the denominator.
        if self.cauchy:
            self.divisor = np.sqrt(self.eqm**2 + denom**2)
            if self.attenuate:
                logger.error('attenuate and cauchy are mutually exclusive\n')
                raise RuntimeError
        elif self.attenuate:
            # Attenuate only large repulsions.
            self.divisor = np.zeros(len(self.eqm))
            for i in range(len(self.eqm)):
                if self.eqm[i] < denom:
                    self.divisor[i] = denom
                else:
                    self.divisor[i] = np.sqrt(denom**2 +
                                              (self.eqm[i] - denom)**2)
        else:
            self.divisor = np.ones(len(self.eqm)) * denom

        if self.cauchy:
            logger.info(
                "Each contribution to the interaction energy objective function will be scaled by 1.0 / ( energy_denom**2 + reference**2 )\n"
            )
        if self.energy_upper > 0:
            ecut = self.energy_upper
            self.prefactor = 1.0 * (self.eqm < ecut)
            logger.info(
                "Interactions more repulsive than %s will not be fitted (%i/%i excluded) \n"
                %
                (str(self.energy_upper), sum(self.eqm > ecut), len(self.eqm)))
        else:
            self.prefactor = np.ones(len(self.eqm))
        if self.normalize:
            self.prefactor /= len(self.prefactor)
示例#7
0
    def __init__(self,options,tgt_opts,forcefield):
        # Initialize the SuperClass!
        super(Interaction,self).__init__(options,tgt_opts,forcefield)
        
        #======================================#
        # Options that are given by the parser #
        #======================================#
        
        ## Number of snapshots
        self.set_option(tgt_opts,'shots','ns')
        ## Do we call Q-Chem for dielectric energies? (Currently needs to be fixed)
        self.set_option(tgt_opts,'do_cosmo','do_cosmo')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts,'cauchy','cauchy')
        ## Do we put the reference energy into the denominator?
        self.set_option(tgt_opts,'attenuate','attenuate')
        ## What is the energy denominator?
        self.set_option(tgt_opts,'energy_denom','energy_denom')
        ## Set fragment 1
        self.set_option(tgt_opts,'fragment1','fragment1')
        if len(self.fragment1) == 0:
            raise Exception('You need to define the first fragment using the fragment1 keyword')
        self.select1 = array(uncommadash(self.fragment1))
        ## Set fragment 2
        self.set_option(tgt_opts,'fragment2','fragment2')
        if len(self.fragment2) == 0:
            raise Exception('You need to define the second fragment using the fragment2 keyword')
        self.select2 = array(uncommadash(self.fragment2))
        ## Set upper cutoff energy
        self.set_option(tgt_opts,'energy_upper','energy_upper')
        #======================================#
        #     Variables which are set here     #
        #======================================#
        ## Reference (QM) interaction energies
        self.eqm           = []
        ## Snapshot label, useful for graphing
        self.label         = []
        ## The qdata.txt file that contains the QM energies and forces
        self.qfnm = os.path.join(self.tgtdir,"qdata.txt")
        ## Qualitative Indicator: average energy error (in kJ/mol)
        self.e_err = 0.0
        self.e_err_pct = None
        ## Read in the trajectory file
        if self.ns == -1:
            self.traj = Molecule(os.path.join(self.root,self.tgtdir,self.trajfnm))
            self.ns = len(self.traj)
        else:
            self.traj = Molecule(os.path.join(self.root,self.tgtdir,self.trajfnm))[:self.ns]
        ## Read in the reference data
        self.read_reference_data()
        ## Prepare the temporary directory
        self.prepare_temp_directory(options,tgt_opts)

        logger.info("The energy denominator is: %s kcal/mol\n"  % str(self.energy_denom))
        # Internally things are handled in kJ/mol.
        denom = self.energy_denom * 4.184
        # Create the denominator.
        if self.cauchy:
            self.divisor = sqrt(self.eqm**2 + denom**2)
            if self.attenuate:
                raise Exception('attenuate and cauchy are mutually exclusive')
        elif self.attenuate:
            # Attenuate only large repulsions.
            self.divisor = zeros(len(self.eqm))
            for i in range(len(self.eqm)):
                if self.eqm[i] < denom:
                    self.divisor[i] = denom
                else:
                    self.divisor[i] = sqrt(denom**2 + (self.eqm[i]-denom)**2)
        else:
            self.divisor = ones(len(self.eqm)) * denom
        if self.cauchy:
            logger.info("Each contribution to the interaction energy objective function will be scaled by 1.0 / ( energy_denom**2 + reference**2 )\n")
        if self.energy_upper > 0:
            logger.info("Interactions more repulsive than %s will not be fitted\n" % str(self.energy_upper))
            ecut = self.energy_upper * 4.184
            self.prefactor = 1.0 * (self.eqm < ecut)
        else:
            self.prefactor = ones(len(self.eqm))
示例#8
0
    def __init__(self, options, tgt_opts, forcefield):
        # Initialize the SuperClass!
        super(Interaction, self).__init__(options, tgt_opts, forcefield)

        #======================================#
        # Options that are given by the parser #
        #======================================#

        ## Number of snapshots
        self.set_option(tgt_opts, 'shots', 'ns')
        ## Do we call Q-Chem for dielectric energies? (Currently needs to be fixed)
        self.set_option(tgt_opts, 'do_cosmo', 'do_cosmo')
        ## Attenuate weights for positive interaction energies
        self.set_option(tgt_opts, 'attenuate', 'attenuate')
        ## Divide by the number of snapshots?
        self.set_option(tgt_opts, 'normalize')
        ## What is the energy denominator?
        self.set_option(tgt_opts, 'energy_denom', 'energy_denom')
        ## Set fragment 1
        self.set_option(tgt_opts, 'fragment1', 'fragment1')
        if len(self.fragment1) == 0:
            logger.error(
                'You need to define the first fragment using the fragment1 keyword\n'
            )
            raise RuntimeError
        self.select1 = np.array(uncommadash(self.fragment1))
        ## Set fragment 2
        self.set_option(tgt_opts, 'fragment2', 'fragment2')
        if len(self.fragment2) != 0:
            self.select2 = np.array(uncommadash(self.fragment2))
        else:
            self.select2 = None
        ## Set upper cutoff energy
        self.set_option(tgt_opts, 'energy_upper', 'energy_upper')
        ## Option for how much data to write to disk.
        self.set_option(tgt_opts, 'writelevel', 'writelevel')
        #======================================#
        #     Variables which are set here     #
        #======================================#
        ## LPW 2018-02-11: This is set to True if the target calculates
        ## a single-point property over several existing snapshots.
        self.loop_over_snapshots = True
        ## Reference (QM) interaction energies
        self.eqm = []
        ## Snapshot label, useful for graphing
        self.label = []
        ## The qdata.txt file that contains the QM energies and forces
        self.qfnm = os.path.join(self.tgtdir, "qdata.txt")
        self.e_err = 0.0
        self.e_err_pct = None
        ## Read in the trajectory file
        self.mol = Molecule(
            os.path.join(self.root, self.tgtdir, self.coords),
            top=(os.path.join(self.root, self.tgtdir, self.pdb) if hasattr(
                self, 'pdb') else None),
            build_topology=False if self.coords.endswith('.pdb') else True)
        if self.ns != -1:
            self.mol = self.mol[:self.ns]
        self.ns = len(self.mol)
        if self.select2 is None:
            self.select2 = [
                i for i in range(self.mol.na) if i not in self.select1
            ]
            logger.info('Fragment 2 is the complement of fragment 1 : %s\n' %
                        (commadash(self.select2)))
        ## Build keyword dictionaries to pass to engine.
        engine_args = OrderedDict(
            list(self.OptionDict.items()) + list(options.items()))
        engine_args.pop('name', None)
        self.engine = self.engine_(target=self, mol=self.mol, **engine_args)
        ## Read in the reference data
        self.read_reference_data()
        logger.info("The energy denominator is: %s kcal/mol\n" %
                    str(self.energy_denom))
        denom = self.energy_denom
        if self.attenuate:
            # The attenuation function for weights is constant for energies up to energy_denom, then falls off smoothly in the shape of a "mesa".
            self.divisor = np.zeros(len(self.eqm))
            for i in range(len(self.eqm)):
                if self.eqm[i] < denom:
                    self.divisor[i] = denom
                else:
                    self.divisor[i] = np.sqrt(denom**2 +
                                              (self.eqm[i] - denom)**2)
            logger.info(
                "Interaction energies more positive than %.1f will have reduced weight going as: 1.0 / (%.1f^2 + (energy-%.1f)^2)\n"
                % (denom, denom, denom))
        else:
            self.divisor = np.ones(len(self.eqm)) * denom

        if self.energy_upper > 0:
            ecut = self.energy_upper
            self.prefactor = 1.0 * (self.eqm < ecut)
            logger.info(
                "Interactions more repulsive than %s will not be fitted (%i/%i excluded) \n"
                %
                (str(self.energy_upper), sum(self.eqm > ecut), len(self.eqm)))
        else:
            self.prefactor = np.ones(len(self.eqm))
        if self.normalize:
            self.prefactor /= len(self.prefactor)