ForceBalance API  1.3
Automated optimization of force fields and empirical potentials
hydration.py
Go to the documentation of this file.
1 """ @package forcebalance.hydration Hydration free energy fitting module
2 
3 @author Lee-Ping Wang
4 @date 09/2014
5 """
6 from __future__ import division
7 
8 from builtins import range
9 import os
10 import shutil
11 import numpy as np
12 from copy import deepcopy
13 from forcebalance.target import Target
14 from forcebalance.molecule import Molecule
15 from re import match, sub
16 from forcebalance.finite_difference import fdwrap, f1d2p, f12d3p, in_fd
17 from collections import defaultdict, OrderedDict
18 from forcebalance.nifty import getWorkQueue, queue_up, LinkFile, printcool, link_dir_contents, lp_dump, lp_load, _exec, kb, col, flat, uncommadash, statisticalInefficiency, isfloat
19 
20 from forcebalance.output import getLogger
21 logger = getLogger(__name__)
22 
23 class Hydration(Target):
24 
25  """ Subclass of Target for fitting force fields to hydration free energies."""
26 
27  def __init__(self,options,tgt_opts,forcefield):
28  """Initialization."""
29 
30  # Initialize the SuperClass!
31  super(Hydration,self).__init__(options,tgt_opts,forcefield)
32 
33  #======================================#
34  # Options that are given by the parser #
35  #======================================#
36  self.set_option(tgt_opts,'hfedata_txt','datafile')
37  self.set_option(tgt_opts,'hfemode')
38  # Normalize the weights for molecules in this target
39  self.set_option(tgt_opts,'normalize')
40  # Energy denominator for evaluating this target
41  self.set_option(tgt_opts,'energy_denom','denom')
42  # Number of time steps in the liquid "equilibration" run
43  self.set_option(tgt_opts,'liquid_eq_steps',forceprint=True)
44  # Number of time steps in the liquid "production" run
45  self.set_option(tgt_opts,'liquid_md_steps',forceprint=True)
46  # Time step length (in fs) for the liquid production run
47  self.set_option(tgt_opts,'liquid_timestep',forceprint=True)
48  # Time interval (in ps) for writing coordinates
49  self.set_option(tgt_opts,'liquid_interval',forceprint=True)
50  # Number of time steps in the gas "equilibration" run
51  self.set_option(tgt_opts,'gas_eq_steps',forceprint=True)
52  # Number of time steps in the gas "production" run
53  self.set_option(tgt_opts,'gas_md_steps',forceprint=True)
54  # Time step length (in fs) for the gas production run
55  self.set_option(tgt_opts,'gas_timestep',forceprint=True)
56  # Time interval (in ps) for writing coordinates
57  self.set_option(tgt_opts,'gas_interval',forceprint=True)
58  # Single temperature for calculating hydration free energies
59  self.set_option(tgt_opts,'hfe_temperature',forceprint=True)
60  # Single pressure for calculating hydration free energies
61  self.set_option(tgt_opts,'hfe_pressure',forceprint=True)
62  # Whether to save trajectories (0 = never, 1 = delete after good step, 2 = keep all)
63  self.set_option(tgt_opts,'save_traj')
64  # Optimize only a subset of the
65  self.set_option(tgt_opts,'subset')
66  # List of trajectory files that may be deleted if self.save_traj == 1.
67  self.last_traj = []
68  # Extra files to be copied back at the end of a run.
69  self.extra_output = []
70 
71  #======================================#
72  # Variables which are set here #
73  #======================================#
74 
76  self.loop_over_snapshots = False
77 
78  self.datafile = os.path.join(self.tgtdir,self.datafile)
79 
80  self.scripts += ['md_ism_hfe.py']
81 
82  self.read_reference_data()
83 
85  self.OptionDict['engname'] = self.engname
86 
87  self.engine_opts = OrderedDict(list(self.OptionDict.items()) + list(options.items()))
88  del self.engine_opts['name']
89 
90  if self.hfemode.lower() in ['sp', 'single']:
91  logger.info("Hydration free energies from geometry optimization and single point energy evaluation\n")
92  self.build_engines()
93  elif self.hfemode.lower() == 'ti2':
94  logger.info("Hydration free energies from thermodynamic integration (linear response approximation)\n")
95  elif self.hfemode.lower() == 'exp_gas':
96  logger.info("Hydration free energies from exponential reweighting from the gas to the aqueous phase\n")
97  elif self.hfemode.lower() == 'exp_liq':
98  logger.info("Hydration free energies from exponential reweighting from the aqueous to the gas phase\n")
99  elif self.hfemode.lower() == 'exp_both':
100  logger.info("Hydration free energies from exponential reweighting from the aqueous to the gas phase and vice versa, taking the average\n")
101  else:
102  logger.error("Please choose hfemode from single, sp, ti2, exp_gas, exp_liq, or exp_both\n")
103  raise RuntimeError
104 
105  if self.FF.rigid_water:
106  logger.error('This class cannot be used with rigid water molecules.\n')
107  raise RuntimeError
108 
109  def read_reference_data(self):
110  """ Read the reference hydrational data from a file. """
111  # Read the HFE data file. This is a very simple file format:
112  self.IDs = []
113  self.expval = OrderedDict()
114  self.experr = OrderedDict()
115  self.nicknames = OrderedDict()
116  # We don't need every single line to be the same. This
117  # indicates whether *any* molecule has a nickname for printing
118  # out the nickname column.
119  self.have_nicks = False
120  # Again for experimental errors. Note that we're NOT using them in the optimization at this time.
121  self.have_experr = False
122  for line in open(self.datafile).readlines():
123  s = line.expandtabs().strip().split('#')[0].split()
124  if len(s) == 0: continue
125  ID = s[0]
126  self.IDs.append(ID)
127  # Dynamic field number for the experimental data.
128  nxt = 1
129  # If the next field is a string, then it's the "nickname"
130  if not isfloat(s[1]):
131  self.have_nicks = True
132  self.nicknames[ID] = s[1]
133  nxt += 1
134  else:
135  # We don't need nicknames on every single line.
136  self.nicknames[ID] = ID
137  # Read the experimental value.
138  self.expval[ID] = float(s[nxt])
139  # Read the experimental error bar, or use a default value of 0.6 (from Mobley).
140  if len(s) > (nxt+1):
141  self.have_experr = True
142  self.experr[ID] = float(s[nxt+1])
143  else:
144  self.experr[ID] = 0.6
145 
146  self.molecules = OrderedDict([(i, os.path.abspath(os.path.join(self.root, self.tgtdir, 'molecules', i+self.crdsfx))) for i in self.IDs])
147  for fnm, path in self.molecules.items():
148  if not os.path.isfile(path):
149  logger.error('Coordinate file %s does not exist!\nMake sure coordinate files are in the right place\n' % path)
150  raise RuntimeError
151  if self.subset is not None:
152  subset = uncommadash(self.subset)
153  self.whfe = np.array([1 if i in subset else 0 for i in range(len(self.IDs))])
154  else:
155  self.whfe = np.ones(len(self.IDs))
156 
157  def run_simulation(self, label, liq, AGrad=True):
158  """
159  Submit a simulation to the Work Queue or run it locally.
160 
161  Inputs:
162  label = The name of the molecule (and hopefully the folder name that you're running in)
163  liq = True/false flag indicating whether to run in liquid or gas phase
164  """
165  wq = getWorkQueue()
166 
167  # Create a dictionary of MD options that the script will read.
168  md_opts = OrderedDict()
169  md_opts['temperature'] = self.hfe_temperature
170  md_opts['pressure'] = self.hfe_pressure
171  md_opts['minimize'] = True
172  if liq:
173  sdnm = 'liq'
174  md_opts['nequil'] = self.liquid_eq_steps
175  md_opts['nsteps'] = self.liquid_md_steps
176  md_opts['timestep'] = self.liquid_timestep
177  md_opts['sample'] = self.liquid_interval
178  else:
179  sdnm = 'gas'
180  md_opts['nequil'] = self.gas_eq_steps
181  md_opts['nsteps'] = self.gas_md_steps
182  md_opts['timestep'] = self.gas_timestep
183  md_opts['sample'] = self.gas_interval
184 
185  eng_opts = deepcopy(self.engine_opts)
186  # Enforce implicit solvent in the liquid simulation.
187  # We need to be more careful with this when running explicit solvent.
188  eng_opts['implicit_solvent'] = liq
189  eng_opts['coords'] = os.path.basename(self.molecules[label])
190 
191  if not os.path.exists(sdnm):
192  os.makedirs(sdnm)
193  os.chdir(sdnm)
194  if not os.path.exists('md_result.p'):
195  # Link in a bunch of files... what were these again?
196  link_dir_contents(os.path.join(self.root,self.rundir),os.getcwd())
197  # Link in the scripts required to run the simulation
198  for f in self.scripts:
199  LinkFile(os.path.join(os.path.split(__file__)[0],"data",f),os.path.join(os.getcwd(),f))
200  # Link in the coordinate file.
201  LinkFile(self.molecules[label], './%s' % os.path.basename(self.molecules[label]))
202  # Store names of previous trajectory files.
203  self.last_traj += [os.path.join(os.getcwd(), i) for i in self.extra_output]
204  # Write target, engine and simulation options to disk.
205  lp_dump((self.OptionDict, eng_opts, md_opts), 'simulation.p')
206  # Execute the script for running molecular dynamics.
207  cmdstr = '%s python md_ism_hfe.py %s' % (self.prefix, "-g" if AGrad else "")
208  if wq is None:
209  logger.info("Running condensed phase simulation locally.\n")
210  logger.info("You may tail -f %s/npt.out in another terminal window\n" % os.getcwd())
211  _exec(cmdstr, copy_stderr=True, outfnm='md.out')
212  else:
213  queue_up(wq, command = cmdstr+' &> md.out', tag='%s:%s/%s' % (self.name, label, "liq" if liq else "gas"),
214  input_files = self.scripts + ['simulation.p', 'forcefield.p', os.path.basename(self.molecules[label])],
215  output_files = ['md_result.p', 'md.out'] + self.extra_output, tgt=self, verbose=False, print_time=3600)
216  os.chdir('..')
217 
218  def submit_liq_gas(self, mvals, AGrad=True):
219  """
220  Set up and submit/run sampling simulations in the liquid and gas phases.
221  """
222  # This routine called by Objective.stage() will run before "get".
223  # It submits the jobs to the Work Queue and the stage() function will wait for jobs to complete.
224  printcool("Target: %s - launching %i MD simulations\nTime steps (liq):"
225  "%i (eq) + %i (md)\nTime steps (g): %i (eq) + %i (md)" %
226  (self.name, 2*len(self.IDs), self.liquid_eq_steps, self.liquid_md_steps,
227  self.gas_eq_steps, self.gas_md_steps), color=0)
228  # If self.save_traj == 1, delete the trajectory files from a previous good optimization step.
229  if self.evaluated and self.goodstep and self.save_traj < 2:
230  for fn in self.last_traj:
231  if os.path.exists(fn):
232  os.remove(fn)
233  self.last_traj = []
234  # Set up and run the NPT simulations.
235  # Less fully featured than liquid simulation; NOT INCLUDED are
236  # 1) Temperature and pressure
237  # 2) Multiple initial conditions
238  for label in self.IDs:
239  if not os.path.exists(label):
240  os.makedirs(label)
241  os.chdir(label)
242  # Run liquid and gas phase simulations.
243  self.run_simulation(label, 0, AGrad)
244  self.run_simulation(label, 1, AGrad)
245  os.chdir('..')
246 
247  def submit_jobs(self, mvals, AGrad=True, AHess=True):
248  # If not calculating HFE using simulations, exit this function.
249  if self.hfemode.lower() not in ['ti2', 'exp_gas', 'exp_liq', 'exp_both']:
250  return
251  else:
252  # Prior to running simulations, write the force field pickle
253  # file which will be shared by all simulations.
254  self.serialize_ff(mvals)
255  if self.hfemode.lower() in ['ti2', 'exp_gas', 'exp_liq', 'exp_both']:
256  self.submit_liq_gas(mvals, AGrad)
257 
258  def build_engines(self):
259  """ Create a list of engines which are used to calculate HFEs using single point evaluation. """
260  self.engines = OrderedDict()
261  self.liq_engines = OrderedDict()
262  self.gas_engines = OrderedDict()
263  for mnm in self.IDs:
264  pdbfnm = os.path.abspath(os.path.join(self.root,self.tgtdir, 'molecules', mnm+'.pdb'))
265  self.liq_engines[mnm] = self.engine_(target=self, coords=pdbfnm, implicit_solvent=True, **self.engine_opts)
266  self.gas_engines[mnm] = self.engine_(target=self, coords=pdbfnm, implicit_solvent=False, **self.engine_opts)
268  def indicate(self):
269  """ Print qualitative indicator. """
270  banner = "Hydration free energies (kcal/mol)"
271  headings = ["ID"]
272  data = OrderedDict([(ID, []) for ID in self.IDs])
273  if self.have_nicks:
274  headings.append("Nickname")
275  for ID in self.IDs:
276  data[ID].append(self.nicknames[ID])
277  if self.have_experr:
278  headings.append("Reference +- StdErr")
279  for ID in self.IDs:
280  data[ID].append("% 9.3f +- %6.3f" % (self.expval[ID], self.experr[ID]))
281  else:
282  headings.append("Reference")
283  for ID in self.IDs:
284  data[ID].append("% 9.3f" % self.expval[ID])
285  if hasattr(self, 'calc_err'):
286  headings.append("Calculated +- StdErr")
287  for ID in self.IDs:
288  data[ID].append("% 10.3f +- %6.3f" % (self.calc[ID], self.calc_err[ID]))
289  else:
290  headings.append("Calculated")
291  for ID in self.IDs:
292  data[ID].append("% 10.3f" % self.calc[ID])
293  headings += ["Calc-Ref", "Weight", "Residual"]
294  for iid, ID in enumerate(self.IDs):
295  data[ID].append("% 8.3f" % (self.calc[ID] - self.expval[ID]))
296  data[ID].append("%8.3f" % (self.whfe[iid]))
297  data[ID].append("%8.3f" % (self.whfe[iid]*(self.calc[ID] - self.expval[ID])**2))
298  self.printcool_table(data, headings, banner)
299 
300  def hydration_driver_sp(self):
301  """ Calculate HFEs using single point evaluation. """
302  hfe = OrderedDict()
303  for mnm in self.IDs:
304  eliq, rmsdliq, _ = self.liq_engines[mnm].optimize()
305  egas, rmsdgas, _ = self.gas_engines[mnm].optimize()
306  hfe[mnm] = eliq - egas
307  return hfe
308 
309  def get_sp(self, mvals, AGrad=False, AHess=False):
310  """ Get the hydration free energy and first parameteric derivatives using single point energy evaluations. """
311  def get_hfe(mvals_):
312  self.FF.make(mvals_)
313  self.hfe_dict = self.hydration_driver_sp()
314  return np.array(list(self.hfe_dict.values()))
315  calc_hfe = get_hfe(mvals)
316  D = calc_hfe - np.array(list(self.expval.values()))
317  dD = np.zeros((self.FF.np,len(self.IDs)))
318  if AGrad or AHess:
319  for p in self.pgrad:
320  dD[p,:], _ = f12d3p(fdwrap(get_hfe, mvals, p), h = self.h, f0 = calc_hfe)
321  return D, dD
322 
323  def get_exp(self, mvals, AGrad=False, AHess=False):
324  """ Get the hydration free energy using the Zwanzig formula. We will obtain two different estimates along with their uncertainties. """
325  self.hfe_dict = OrderedDict()
326  self.hfe_err = OrderedDict()
327  dD = np.zeros((self.FF.np,len(self.IDs)))
328  kT = (kb * self.hfe_temperature)
329  beta = 1. / (kb * self.hfe_temperature)
330  for ilabel, label in enumerate(self.IDs):
331  os.chdir(label)
332  # This dictionary contains observables keyed by each phase.
333  data = defaultdict(dict)
334  for p in ['gas', 'liq']:
335  os.chdir(p)
336  # Load the results from molecular dynamics.
337  results = lp_load('md_result.p')
338  L = len(results['Potentials'])
339  if p == "gas":
340  Eg = results['Potentials']
341  Eaq = results['Potentials'] + results['Hydration']
342  # Mean and standard error of the exponentiated hydration energy.
343  expmbH = np.exp(-1.0*beta*results['Hydration'])
344  data[p]['Hyd'] = -kT*np.log(np.mean(expmbH))
345  # Estimate standard error by bootstrap method. We also multiply by the
346  # square root of the statistical inefficiency of the hydration energy time series.
347  data[p]['HydErr'] = np.std([-kT*np.log(np.mean(expmbH[np.random.randint(L,size=L)])) for i in range(100)]) * np.sqrt(statisticalInefficiency(results['Hydration']))
348  if AGrad:
349  dEg = results['Potential_Derivatives']
350  dEaq = results['Potential_Derivatives'] + results['Hydration_Derivatives']
351  data[p]['dHyd'] = (flat(np.dot(dEaq,col(expmbH))/L)-np.mean(dEg,axis=1)*np.mean(expmbH)) / np.mean(expmbH)
352  elif p == "liq":
353  Eg = results['Potentials'] - results['Hydration']
354  Eaq = results['Potentials']
355  # Mean and standard error of the exponentiated hydration energy.
356  exppbH = np.exp(+1.0*beta*results['Hydration'])
357  data[p]['Hyd'] = +kT*np.log(np.mean(exppbH))
358  # Estimate standard error by bootstrap method. We also multiply by the
359  # square root of the statistical inefficiency of the hydration energy time series.
360  data[p]['HydErr'] = np.std([+kT*np.log(np.mean(exppbH[np.random.randint(L,size=L)])) for i in range(100)]) * np.sqrt(statisticalInefficiency(results['Hydration']))
361  if AGrad:
362  dEg = results['Potential_Derivatives'] - results['Hydration_Derivatives']
363  dEaq = results['Potential_Derivatives']
364  data[p]['dHyd'] = -(flat(np.dot(dEg, col(exppbH))/L)-np.mean(dEaq,axis=1)*np.mean(exppbH)) / np.mean(exppbH)
365  os.chdir('..')
366  # Calculate the hydration free energy using gas phase, liquid phase or the average of both.
367  # Note that the molecular dynamics methods return energies in kJ/mol.
368  if self.hfemode == 'exp_gas':
369  self.hfe_dict[label] = data['gas']['Hyd'] / 4.184
370  self.hfe_err[label] = data['gas']['HydErr'] / 4.184
371  elif self.hfemode == 'exp_liq':
372  self.hfe_dict[label] = data['liq']['Hyd'] / 4.184
373  self.hfe_err[label] = data['liq']['HydErr'] / 4.184
374  elif self.hfemode == 'exp_both':
375  self.hfe_dict[label] = 0.5*(data['liq']['Hyd']+data['gas']['Hyd']) / 4.184
376  self.hfe_err[label] = 0.5*(data['liq']['HydErr']+data['gas']['HydErr']) / 4.184
377  if AGrad:
378  # Calculate the derivative of the hydration free energy.
379  if self.hfemode == 'exp_gas':
380  dD[:, ilabel] = self.whfe[ilabel]*data['gas']['dHyd'] / 4.184
381  elif self.hfemode == 'exp_liq':
382  dD[:, ilabel] = self.whfe[ilabel]*data['liq']['dHyd'] / 4.184
383  elif self.hfemode == 'exp_both':
384  dD[:, ilabel] = 0.5*self.whfe[ilabel]*(data['liq']['dHyd']+data['gas']['dHyd']) / 4.184
385  os.chdir('..')
386  calc_hfe = np.array(list(self.hfe_dict.values()))
387  D = self.whfe*(calc_hfe - np.array(list(self.expval.values())))
388  return D, dD
389 
390  def get_ti2(self, mvals, AGrad=False, AHess=False):
391  """ Get the hydration free energy using two-point thermodynamic integration. """
392  self.hfe_dict = OrderedDict()
393  dD = np.zeros((self.FF.np,len(self.IDs)))
394  beta = 1. / (kb * self.hfe_temperature)
395  for ilabel, label in enumerate(self.IDs):
396  os.chdir(label)
397  # This dictionary contains observables keyed by each phase.
398  data = defaultdict(dict)
399  for p in ['gas', 'liq']:
400  os.chdir(p)
401  # Load the results from molecular dynamics.
402  results = lp_load('md_result.p')
403  # Time series of hydration energies.
404  H = results['Hydration']
405  # Store the average hydration energy.
406  data[p]['Hyd'] = np.mean(H)
407  if AGrad:
408  dE = results['Potential_Derivatives']
409  dH = results['Hydration_Derivatives']
410  # Calculate the parametric derivative of the average hydration energy.
411  data[p]['dHyd'] = np.mean(dH,axis=1)-beta*(flat(np.dot(dE, col(H))/len(H))-np.mean(dE,axis=1)*np.mean(H))
412  os.chdir('..')
413  # Calculate the hydration free energy as the average of liquid and gas hydration energies.
414  # Note that the molecular dynamics methods return energies in kJ/mol.
415  self.hfe_dict[label] = 0.5*(data['liq']['Hyd']+data['gas']['Hyd']) / 4.184
416  if AGrad:
417  # Calculate the derivative of the hydration free energy.
418  dD[:, ilabel] = 0.5*self.whfe[ilabel]*(data['liq']['dHyd']+data['gas']['dHyd']) / 4.184
419  os.chdir('..')
420  calc_hfe = np.array(list(self.hfe_dict.values()))
421  D = self.whfe*(calc_hfe - np.array(list(self.expval.values())))
422  return D, dD
423 
424  def get(self, mvals, AGrad=False, AHess=False):
425  """ Evaluate objective function. """
426  Answer = {'X':0.0, 'G':np.zeros(self.FF.np), 'H':np.zeros((self.FF.np, self.FF.np))}
427  if self.hfemode.lower() == 'single' or self.hfemode.lower() == 'sp':
428  D, dD = self.get_sp(mvals, AGrad, AHess)
429  elif self.hfemode.lower() == 'ti2':
430  D, dD = self.get_ti2(mvals, AGrad, AHess)
431  elif self.hfemode.lower() in ['exp_gas', 'exp_liq', 'exp_both']:
432  D, dD = self.get_exp(mvals, AGrad, AHess)
433  Answer['X'] = np.dot(D,D) / self.denom**2 / (np.sum(self.whfe) if self.normalize else 1)
434  for p in self.pgrad:
435  Answer['G'][p] = 2*np.dot(D, dD[p,:]) / self.denom**2 / (np.sum(self.whfe) if self.normalize else 1)
436  for q in self.pgrad:
437  Answer['H'][p,q] = 2*np.dot(dD[p,:], dD[q,:]) / self.denom**2 / (np.sum(self.whfe) if self.normalize else 1)
438  if not in_fd():
439  self.calc = self.hfe_dict
440  if hasattr(self, 'hfe_err'):
441  self.calc_err = self.hfe_err
442  self.objective = Answer['X']
443  return Answer
def build_engines(self)
Create a list of engines which are used to calculate HFEs using single point evaluation.
Definition: hydration.py:266
def get_exp(self, mvals, AGrad=False, AHess=False)
Get the hydration free energy using the Zwanzig formula.
Definition: hydration.py:335
datafile
The vdata.txt file that contains the hydrations.
Definition: hydration.py:81
engine_opts
Scripts to be copied from the ForceBalance installation directory.
Definition: hydration.py:90
def read_reference_data(self)
Read the reference hydrational data from a file.
Definition: hydration.py:114
def get_sp(self, mvals, AGrad=False, AHess=False)
Get the hydration free energy and first parameteric derivatives using single point energy evaluations...
Definition: hydration.py:320
def lp_load(fnm)
Read an object from a bzipped file specified by the path.
Definition: nifty.py:836
Nifty functions, intended to be imported by any module within ForceBalance.
def submit_liq_gas(self, mvals, AGrad=True)
Set up and submit/run sampling simulations in the liquid and gas phases.
Definition: hydration.py:227
def LinkFile(src, dest, nosrcok=False)
Definition: nifty.py:1313
def flat(vec)
Given any list, array, or matrix, return a single-index array.
Definition: nifty.py:467
Subclass of Target for fitting force fields to hydration free energies.
Definition: hydration.py:26
def statisticalInefficiency(A_n, B_n=None, fast=False, mintime=3, warn=True)
Compute the (cross) statistical inefficiency of (two) timeseries.
Definition: nifty.py:740
def submit_jobs(self, mvals, AGrad=True, AHess=True)
Definition: hydration.py:253
def hydration_driver_sp(self)
Calculate HFEs using single point evaluation.
Definition: hydration.py:310
def in_fd()
Invoking this function from anywhere will tell us whether we&#39;re being called by a finite-difference f...
def fdwrap(func, mvals0, pidx, key=None, kwargs)
A function wrapper for finite difference designed for differentiating &#39;get&#39;-type functions.
def queue_up(wq, command, input_files, output_files, tag=None, tgt=None, verbose=True, print_time=60)
Submit a job to the Work Queue.
Definition: nifty.py:941
def lp_dump(obj, fnm, protocol=0)
Write an object to a zipped pickle file specified by the path.
Definition: nifty.py:817
def col(vec)
Given any list, array, or matrix, return a 1-column 2D array.
Definition: nifty.py:448
def get_ti2(self, mvals, AGrad=False, AHess=False)
Get the hydration free energy using two-point thermodynamic integration.
Definition: hydration.py:403
def link_dir_contents(abssrcdir, absdestdir)
Definition: nifty.py:1345
def printcool(text, sym="#", bold=False, color=2, ansi=None, bottom='-', minwidth=50, center=True, sym2="=")
Cool-looking printout for slick formatting of output.
Definition: nifty.py:321
def indicate(self)
Print qualitative indicator.
Definition: hydration.py:277
def get(self, mvals, AGrad=False, AHess=False)
Evaluate objective function.
Definition: hydration.py:438
def f12d3p(f, h, f0=None)
A three-point finite difference stencil.
loop_over_snapshots
LPW 2018-02-11: This is set to True if the target calculates a single-point property over several exi...
Definition: hydration.py:79
def __init__(self, options, tgt_opts, forcefield)
Initialization.
Definition: hydration.py:31
def isfloat(word)
Matches ANY number; it can be a decimal, scientific notation, integer, or what have you...
Definition: molecule.py:406
def uncommadash(s)
Definition: nifty.py:249
def getWorkQueue()
Definition: nifty.py:904
def run_simulation(self, label, liq, AGrad=True)
Submit a simulation to the Work Queue or run it locally.
Definition: hydration.py:169