1 from __future__
import division
2 from builtins
import object
11 from collections
import OrderedDict
13 from forcebalance.output
import getLogger
14 logger = getLogger(__name__)
18 """Return mean and standard deviation of a time series ts.""" 24 """Compute the first derivatives of a set of snapshot energies with respect 25 to the force field parameters. The function calls the finite 26 difference subroutine on the energy_driver subroutine also in this 32 Use this Engine (`GMX`,`TINKER`,`OPENMM` etc.) object to get the energy 37 Mathematical parameter values. 39 Finite difference step size. 41 Number of snapshots (length of energy trajectory). 43 Switch that turns derivatives on or off; if off, return all zeros. 48 Derivative of the energy in a FF.np x length array. 51 G = np.zeros((FF.np, length))
55 def energy_driver(mvals_):
57 return engine.energy()
59 ED0 = energy_driver(mvals)
62 logger.info(
"%i %s\r" % (i, (FF.plist[i] +
" "*30)))
63 EDG, _ =
f12d3p(
fdwrap(energy_driver, mvals, i), h, f0=ED0)
70 Base class for thermodynamical quantity used for fitting. This can 71 be any experimental data that can be calculated as an ensemble 72 average from a simulation. 77 Identifier for the quantity that is specified in `quantities` in Target 80 Use this engine to extract the quantity from the simulation results. 81 At present, only `gromacs` is supported. 83 Calculate the quantity at this temperature (in K). 85 Calculate the quantity at this pressure (in bar). 88 def __init__(self, engname, temperature, pressure, name=None):
89 self.name = name
if name
is not None else "empty" 95 return "quantity is " + self.
name.capitalize() +
"." 97 def extract(self, engines, FF, mvals, h, AGrad=True):
98 """Calculate and extract the quantity from MD results. How this is done 99 depends on the quantity and the engine so this must be 100 implemented in the subclass. 105 A list of Engine objects that are requred to calculate the quantity. 109 Mathematical parameter values. 111 Finite difference step size. 113 Switch that turns derivatives on or off; if off, return all zeros. 117 result : (float, float, np.array) 118 The returned tuple is (Q, Qerr, Qgrad), where Q is the calculated 119 quantity, Qerr is the calculated standard deviation of the quantity, 120 and Qgrad is a M-array with the calculated gradients for the 121 quantity, with M being the number of force field parameters that are 125 logger.error(
"Extract method not implemented in base class.\n")
126 raise NotImplementedError
130 def __init__(self, engname, temperature, pressure, name=None):
132 super(Quantity_Density, self).
__init__(engname, temperature, pressure, name)
134 self.
name = name
if name
is not None else "density" 136 def extract(self, engines, FF, mvals, h, pgrad, AGrad=True):
141 kB = 0.008314472471220214
151 deffnm = os.path.basename(os.path.splitext(engines[0].mdene)[0])
153 energyterms = engines[0].energy_termnames(edrfile=
"%s.%s" % (deffnm,
"edr"))
155 ekeep = [
'Total-Energy',
'Potential',
'Kinetic-En.',
'Temperature']
156 ekeep += [
'Volume',
'Density']
158 ekeep_order = [key
for (key, value)
in 159 sorted(energyterms.items(), key=
lambda k_v : k_v[1])
163 engines[0].callgmx((
"g_energy " +
164 "-f %s.%s " % (deffnm,
"edr") +
165 "-o %s-energy.xvg " % deffnm +
167 stdin=
"\n".join(ekeep))
170 data = np.loadtxt(
"%s-energy.xvg" % deffnm)
171 Energy = data[:, ekeep_order.index(
"Total-Energy") + 1]
172 Potential = data[:, ekeep_order.index(
"Potential") + 1]
173 Kinetic = data[:, ekeep_order.index(
"Kinetic-En.") + 1]
174 Volume = data[:, ekeep_order.index(
"Volume") + 1]
175 Temperature = data[:, ekeep_order.index(
"Temperature") + 1]
176 Density = data[:, ekeep_order.index(
"Density") + 1]
181 logger.info((
"Calculating potential energy derivatives " +
182 "with finite difference step size: %f\n" % h))
183 printcool(
"Initializing array to length %i" % len(Energy),
193 Rho_grad = mBeta * (
flat(np.dot(G,
col(Density))) / len(Density) \
194 - np.mean(Density) * np.mean(G, axis=1))
196 return Rho_avg, Rho_err, Rho_grad
200 def __init__(self, engname, temperature, pressure, name=None):
201 """ Enthalpy of vaporization. """ 202 super(Quantity_H_vap, self).
__init__(engname, temperature, pressure, name)
204 self.
name = name
if name
is not None else "H_vap" 206 def extract(self, engines, FF, mvals, h, pgrad, AGrad=True):
211 kB = 0.008314472471220214
219 mol = Molecule(os.path.basename(os.path.splitext(engines[0].mdtraj)[0]) +
221 nmol = len(mol.molecules)
228 deffnm1 = os.path.basename(os.path.splitext(engines[0].mdene)[0])
229 deffnm2 = os.path.basename(os.path.splitext(engines[1].mdene)[0])
231 energyterms1 = engines[0].energy_termnames(edrfile=
"%s.%s" % (deffnm1,
"edr"))
232 energyterms2 = engines[1].energy_termnames(edrfile=
"%s.%s" % (deffnm2,
"edr"))
234 ekeep1 = [
'Total-Energy',
'Potential',
'Kinetic-En.',
'Temperature',
'Volume']
235 ekeep2 = [
'Total-Energy',
'Potential',
'Kinetic-En.',
'Temperature']
237 ekeep_order1 = [key
for (key, value)
238 in sorted(energyterms1.items(), key=
lambda k_v1 : k_v1[1])
240 ekeep_order2 = [key
for (key, value)
241 in sorted(energyterms2.items(), key=
lambda k_v2 : k_v2[1])
245 engines[0].callgmx((
"g_energy " +
246 "-f %s.%s " % (deffnm1,
"edr") +
247 "-o %s-energy.xvg " % deffnm1 +
249 stdin=
"\n".join(ekeep1))
250 engines[1].callgmx((
"g_energy " +
251 "-f %s.%s " % (deffnm2,
"edr") +
252 "-o %s-energy.xvg " % deffnm2 +
254 stdin=
"\n".join(ekeep2))
257 data1 = np.loadtxt(
"%s-energy.xvg" % deffnm1)
258 data2 = np.loadtxt(
"%s-energy.xvg" % deffnm2)
259 Energy = data1[:, ekeep_order1.index(
"Total-Energy") + 1]
260 Potential = data1[:, ekeep_order1.index(
"Potential") + 1]
261 Kinetic = data1[:, ekeep_order1.index(
"Kinetic-En.") + 1]
262 Temperature = data1[:, ekeep_order1.index(
"Temperature") + 1]
263 Volume = data1[:, ekeep_order1.index(
"Volume") + 1]
264 mEnergy = data2[:, ekeep_order2.index(
"Total-Energy") + 1]
265 mPotential = data2[:, ekeep_order2.index(
"Potential") + 1]
266 mKinetic = data2[:, ekeep_order2.index(
"Kinetic-En.") + 1]
271 logger.info((
"Calculating potential energy derivatives " +
272 "with finite difference step size: %f\n" % h))
273 printcool(
"Initializing arrays to lengths %d" % len(Energy),
287 Hvap_avg = Em_avg - E_avg/nmol - self.
pressure*Vol_avg/nmol/pconv + kT
288 Hvap_err = np.sqrt((E_err/nmol)**2 + Em_err**2
289 + (self.
pressure**2) * (Vol_err**2)/(float(nmol)**2)/(pconv**2))
291 Hvap_grad = np.mean(Gm, axis=1)
292 Hvap_grad += mBeta * (
flat(np.dot(Gm,
col(mEnergy))) / len(mEnergy) \
293 - np.mean(mEnergy) * np.mean(Gm, axis=1))
294 Hvap_grad -= np.mean(G, axis=1)/nmol
295 Hvap_grad += Beta * (
flat(np.dot(G,
col(Energy))) / len(Energy) \
296 - np.mean(Energy) * np.mean(G, axis=1))/nmol
297 Hvap_grad += (Beta*self.
pressure/nmol/pconv) * \
298 (
flat(np.dot(G,
col(Volume))) / len(Volume) \
299 - np.mean(Volume) * np.mean(G, axis=1))
301 return Hvap_avg, Hvap_err, Hvap_grad
Nifty functions, intended to be imported by any module within ForceBalance.
def flat(vec)
Given any list, array, or matrix, return a single-index array.
def extract(self, engines, FF, mvals, h, pgrad, AGrad=True)
def __init__(self, engname, temperature, pressure, name=None)
Density.
def statisticalInefficiency(A_n, B_n=None, fast=False, mintime=3, warn=True)
Compute the (cross) statistical inefficiency of (two) timeseries.
def mean_stderr(ts)
Return mean and standard deviation of a time series ts.
def fdwrap(func, mvals0, pidx, key=None, kwargs)
A function wrapper for finite difference designed for differentiating 'get'-type functions.
def col(vec)
Given any list, array, or matrix, return a 1-column 2D array.
def __init__(self, engname, temperature, pressure, name=None)
def extract(self, engines, FF, mvals, h, AGrad=True)
Calculate and extract the quantity from MD results.
def printcool(text, sym="#", bold=False, color=2, ansi=None, bottom='-', minwidth=50, center=True, sym2="=")
Cool-looking printout for slick formatting of output.
def f12d3p(f, h, f0=None)
A three-point finite difference stencil.
Base class for thermodynamical quantity used for fitting.
def extract(self, engines, FF, mvals, h, pgrad, AGrad=True)
def energy_derivatives(engine, FF, mvals, h, pgrad, length, AGrad=True)
Compute the first derivatives of a set of snapshot energies with respect to the force field parameter...