######################################################################
# BioSimSpace: Making biomolecular simulation a breeze!
#
# Copyright: 2017-2024
#
# Authors: Lester Hedges <lester.hedges@gmail.com>
#
# BioSimSpace is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BioSimSpace is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BioSimSpace. If not, see <http://www.gnu.org/licenses/>.
#####################################################################
"""Functionality for a production alchecmical free-energy protocol."""
__author__ = "Lester Hedges"
__email__ = "lester.hedges@gmail.com"
__all__ = ["FreeEnergy", "FreeEnergyProduction"]
from ._free_energy_mixin import _FreeEnergyMixin
from ._production import Production as _Production
from .. import Types as _Types
from .. import Units as _Units
[docs]
class FreeEnergyProduction(_Production, _FreeEnergyMixin):
"""A class for storing free energy production protocols."""
[docs]
def __init__(
self,
lam=0.0,
lam_vals=None,
min_lam=0.0,
max_lam=1.0,
num_lam=11,
timestep=_Types.Time(2, "femtosecond"),
runtime=_Types.Time(4, "nanosecond"),
temperature=_Types.Temperature(300, "kelvin"),
pressure=_Types.Pressure(1, "atmosphere"),
thermostat_time_constant=_Types.Time(1, "picosecond"),
report_interval=200,
restart_interval=1000,
restart=False,
perturbation_type="full",
restraint=None,
force_constant=10 * _Units.Energy.kcal_per_mol / _Units.Area.angstrom2,
):
"""Constructor.
Parameters
----------
lam : float
The perturbation parameter: [0.0, 1.0]
lam_vals : [float]
The list of lambda parameters.
min_lam : float
The minimum lambda value.
max_lam : float
The maximum lambda value.
num_lam : int
The number of lambda values.
timestep : :class:`Time <BioSimSpace.Types.Time>`
The integration timestep.
runtime : :class:`Time <BioSimSpace.Types.Time>`
The running time.
temperature : :class:`Temperature <BioSimSpace.Types.Temperature>`
The temperature.
pressure : :class:`Pressure <BioSimSpace.Types.Pressure>`
The pressure. Pass pressure=None to use the NVT ensemble.
thermostat_time_constant : :class:`Time <BioSimSpace.Types.Time>`
Time constant for thermostat coupling.
report_interval : int
The frequency at which statistics are recorded. (In integration steps.)
restart_interval : int
The frequency at which restart configurations and trajectory
restart : bool
Whether this is a continuation of a previous simulation.
perturbation_type : str
The type of perturbation to perform. Options are:
"full" : A full perturbation of all terms (default option).
"discharge_soft" : Perturb all discharging soft atom charge terms (i.e. value->0.0).
"vanish_soft" : Perturb all vanishing soft atom LJ terms (i.e. value->0.0).
"flip" : Perturb all hard atom terms as well as bonds/angles.
"grow_soft" : Perturb all growing soft atom LJ terms (i.e. 0.0->value).
"charge_soft" : Perturb all charging soft atom LJ terms (i.e. 0.0->value).
Currently perturubation_type != "full" is only supported by
BioSimSpace.Process.Somd.
restraint : str, [int]
The type of restraint to perform. This should be one of the
following options:
"backbone"
Protein backbone atoms. The matching is done by a name
template, so is unreliable on conversion between
molecular file formats.
"heavy"
All non-hydrogen atoms that aren't part of water
molecules or free ions.
"all"
All atoms that aren't part of water molecules or free
ions.
Alternatively, the user can pass a list of atom indices for
more fine-grained control. If None, then no restraints are used.
force_constant : :class:`GeneralUnit <BioSimSpace.Types._GeneralUnit>`, float
The force constant for the restraint potential. If a 'float' is
passed, then default units of 'kcal_per_mol / angstrom**2' will
be used.
"""
# Call the base class constructors.
_Production.__init__(
self,
timestep=timestep,
runtime=runtime,
temperature=temperature,
pressure=pressure,
thermostat_time_constant=thermostat_time_constant,
report_interval=report_interval,
restart_interval=restart_interval,
restart=restart,
restraint=restraint,
force_constant=force_constant,
)
_FreeEnergyMixin.__init__(
self,
lam=lam,
lam_vals=lam_vals,
min_lam=min_lam,
max_lam=max_lam,
num_lam=num_lam,
perturbation_type=perturbation_type,
)
def _get_parm(self):
"""Return a string representation of the parameters."""
return ", ".join(
[_Production._get_parm(self), _FreeEnergyMixin._get_parm(self)]
)
def __str__(self):
"""Return a human readable string representation of the object."""
if self._is_customised:
return "<BioSimSpace.Protocol.Custom>"
else:
return f"<BioSimSpace.Protocol.FreeEnergyProduction: {self._get_parm()}>"
def __repr__(self):
"""Return a string showing how to instantiate the object."""
if self._is_customised:
return "BioSimSpace.Protocol.Custom"
else:
return f"BioSimSpace.Protocol.FreeEnergyProduction({self._get_parm()})"
def __eq__(self, other):
"""Equality operator."""
if not isinstance(other, FreeEnergyProduction):
return False
if self._is_customised or other._is_customised:
return False
return _Production.__eq__(self, other) and _FreeEnergyMixin.__eq__(self, other)
# Alias the class for consistency with the old API.
FreeEnergy = FreeEnergyProduction