Commit 98d053d4 authored by Robert McGibbon's avatar Robert McGibbon
Browse files

Improve docstrings

Swigged python docstrings now include documented return values and type
information or their arguments. They are generated in numpydoc format.
Furthermore, all of the Python app layer docstrings have been changed
to numpydoc format. The filterPythonFiles.py script which helps to
generate the Doxygen Python API docs has been updated to reflect these
changes.
parent 596a4197
...@@ -116,11 +116,7 @@ def _strip_optunit(thing, unit): ...@@ -116,11 +116,7 @@ def _strip_optunit(thing, unit):
_resre = re.compile(r'(\d+)([a-zA-Z]*)') _resre = re.compile(r'(\d+)([a-zA-Z]*)')
class CharmmPsfFile(object): class CharmmPsfFile(object):
""" """A chemical structure instantiated from CHARMM files.
A chemical structure instantiated from CHARMM files.
Example:
>>> cs = CharmmPsfFile("testfiles/test.psf")
This structure has numerous attributes that are lists of the elements of This structure has numerous attributes that are lists of the elements of
this structure, including atoms, bonds, torsions, etc. The attributes are this structure, including atoms, bonds, torsions, etc. The attributes are
...@@ -144,7 +140,8 @@ class CharmmPsfFile(object): ...@@ -144,7 +140,8 @@ class CharmmPsfFile(object):
The lengths of each of these lists gives the pointers (e.g., natom, nres, The lengths of each of these lists gives the pointers (e.g., natom, nres,
etc.) etc.)
Example: Examples
--------
>>> cs = CharmmPsfFile("testfiles/test.psf") >>> cs = CharmmPsfFile("testfiles/test.psf")
>>> len(cs.atom_list) >>> len(cs.atom_list)
33 33
...@@ -166,14 +163,16 @@ class CharmmPsfFile(object): ...@@ -166,14 +163,16 @@ class CharmmPsfFile(object):
@_catchindexerror @_catchindexerror
def __init__(self, psf_name): def __init__(self, psf_name):
""" """Opens and parses a PSF file, then instantiates a CharmmPsfFile
Opens and parses a PSF file, then instantiates a CharmmPsfFile
instance from the data. instance from the data.
Parameters: Parameters
psf_name (str) : Name of the PSF file (it must exist) ----------
psf_name : str
Name of the PSF file (it must exist)
Exceptions Raised: Raises
------
IOError : If file "psf_name" does not exist IOError : If file "psf_name" does not exist
CharmmPSFError: If any parsing errors are encountered CharmmPSFError: If any parsing errors are encountered
""" """
...@@ -388,14 +387,17 @@ class CharmmPsfFile(object): ...@@ -388,14 +387,17 @@ class CharmmPsfFile(object):
@staticmethod @staticmethod
def _convert(string, type, message): def _convert(string, type, message):
""" """Converts a string to a specific type, making sure to raise
Converts a string to a specific type, making sure to raise
CharmmPSFError with the given message in the event of a failure. CharmmPSFError with the given message in the event of a failure.
Parameters: Parameters
- string (str) : Input string to process ----------
- type (type) : Type of data to convert to string : str
- message (str) : Error message to put in exception if failed Input string to process
type : type
Type of data to convert to
message : str
Error message to put in exception if failed
""" """
try: try:
return type(string) return type(string)
...@@ -405,23 +407,24 @@ class CharmmPsfFile(object): ...@@ -405,23 +407,24 @@ class CharmmPsfFile(object):
@staticmethod @staticmethod
def _parse_psf_section(psf): def _parse_psf_section(psf):
""" """This method parses a section of the PSF file
This method parses a section of the PSF file
Parameters
Parameters: ----------
- psf (CharmmFile) : Open file that is pointing to the first line psf : CharmmFile
of the section that is to be parsed Open file that is pointing to the first line of the section
that is to be parsed
Returns:
(title, pointers, data) Returns
--------
- title (str) : The label of the PSF section we are parsing title : str
- pointers (int/tuple of ints) : If one pointer is set, pointers is The label of the PSF section we are parsing
simply the integer that is value of that pointer. Otherwise pointers : int/tuple of ints
it is a tuple with every pointer value defined in the first If one pointer is set, pointers is simply the integer that is
line value of that pointer. Otherwise it is a tuple with every pointer
- data (list) : A list of all data in the parsed section converted value defined in the first line
to `dtype' data : list
A list of all data in the parsed section converted to `dtype'
""" """
conv = CharmmPsfFile._convert conv = CharmmPsfFile._convert
line = psf.readline() line = psf.readline()
...@@ -462,22 +465,22 @@ class CharmmPsfFile(object): ...@@ -462,22 +465,22 @@ class CharmmPsfFile(object):
return title, pointers, data return title, pointers, data
def loadParameters(self, parmset): def loadParameters(self, parmset):
""" """Loads parameters from a parameter set that was loaded via CHARMM RTF,
Loads parameters from a parameter set that was loaded via CHARMM RTF,
PAR, and STR files. PAR, and STR files.
Parameters: Parameters
- parmset (CharmmParameterSet) : List of all parameters ----------
parmset : CharmmParameterSet
List of all parameters
Notes: Notes
-----
- If any parameters that are necessary cannot be found, a - If any parameters that are necessary cannot be found, a
MissingParameter exception is raised. MissingParameter exception is raised.
- If any dihedral or improper parameters cannot be found, I will try - If any dihedral or improper parameters cannot be found, I will try
inserting wildcards (at either end for dihedrals and as the two inserting wildcards (at either end for dihedrals and as the two
central atoms in impropers) and see if that matches. Wild-cards central atoms in impropers) and see if that matches. Wild-cards
will apply ONLY if specific parameters cannot be found. will apply ONLY if specific parameters cannot be found.
- This method will expand the dihedral_parameter_list attribute by - This method will expand the dihedral_parameter_list attribute by
adding a separate Dihedral object for each term for types that adding a separate Dihedral object for each term for types that
have a multi-term expansion have a multi-term expansion
...@@ -752,52 +755,60 @@ class CharmmPsfFile(object): ...@@ -752,52 +755,60 @@ class CharmmPsfFile(object):
ewaldErrorTolerance=0.0005, ewaldErrorTolerance=0.0005,
flexibleConstraints=True, flexibleConstraints=True,
verbose=False): verbose=False):
""" """Construct an OpenMM System representing the topology described by the
Construct an OpenMM System representing the topology described by the
prmtop file. You MUST have loaded a parameter set into this PSF before prmtop file. You MUST have loaded a parameter set into this PSF before
calling createSystem. If not, AttributeError will be raised. ValueError calling createSystem. If not, AttributeError will be raised. ValueError
is raised for illegal input. is raised for illegal input.
Parameters: Parameters
- params (CharmmParameterSet) The parameter set to use to parametrize ----------
this molecule params : CharmmParameterSet
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded The parameter set to use to parametrize this molecule
interactions. Allowed values are NoCutoff, CutoffNonPeriodic, nonbondedMethod : object=NoCutoff
CutoffPeriodic, Ewald, or PME. The method to use for nonbonded interactions. Allowed values are
- nonbondedCutoff (distance=1*nanometer) The cutoff distance to use NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
for nonbonded interactions. nonbondedCutoff : distance=1*nanometer
- switchDistance (distance=0*nanometer) The distance at which the The cutoff distance to use for nonbonded interactions.
switching function is active for nonbonded interactions. If the switchDistance : distance=0*nanometer
switchDistance evaluates to boolean False (if it is 0), no The distance at which the switching function is active for nonbonded
switching function will be used. Illegal values will raise a interactions. If the switchDistance evaluates to boolean False (if
ValueError it is 0), no switching function will be used. Illegal values will
- constraints (object=None) Specifies which bonds or angles should be raise a ValueError
implemented with constraints. Allowed values are None, HBonds, constraints : object=None
AllBonds, or HAngles. Specifies which bonds or angles should be implemented with
- rigidWater (boolean=True) If true, water molecules will be fully constraints. Allowed values are None, HBonds, AllBonds, or HAngles.
rigid regardless of the value passed for the constraints argument rigidWater : boolean=True
- implicitSolvent (object=None) If not None, the implicit solvent If true, water molecules will be fully rigid regardless of the value
model to use. Allowed values are HCT, OBC1, OBC2, or GBn passed for the constraints argument
- implicitSolventKappa (float=None): Debye screening parameter to implicitSolvent : object=None
model salt concentrations in GB solvent. If not None, the implicit solvent model to use. Allowed values are
- implicitSolventSaltConc (float=0.0*u.moles/u.liter): Salt HCT, OBC1, OBC2, or GBn
concentration for GB simulations. Converted to Debye length implicitSolventKappa : float=None
Debye screening parameter to model salt concentrations in GB
solvent.
implicitSolventSaltConc : float=0.0*u.moles/u.liter
Salt concentration for GB simulations. Converted to Debye length
`kappa' `kappa'
- temperature (float=298.15*u.kelvin): Temperature used in the salt temperature : float=298.15*u.kelvin
concentration-to-kappa conversion for GB salt concentration term Temperature used in the salt concentration-to-kappa conversion for
- soluteDielectric (float=1.0) The solute dielectric constant to use GB salt concentration term
in the implicit solvent model. soluteDielectric : float=1.0
- solventDielectric (float=78.5) The solvent dielectric constant to The solute dielectric constant to use in the implicit solvent model.
use in the implicit solvent model. solventDielectric : float=78.5
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be The solvent dielectric constant to use in the implicit solvent
added to the System. model.
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to removeCMMotion : boolean=True
heavy atoms. Any mass added to a hydrogen is subtracted from the If true, a CMMotionRemover will be added to the System.
heavy atom to keep their total mass the same. hydrogenMass : mass=None
- ewaldErrorTolerance (float=0.0005) The error tolerance to use if the The mass to use for hydrogen atoms bound to heavy atoms. Any mass
nonbonded method is Ewald or PME. added to a hydrogen is subtracted from the heavy atom to keep their
- flexibleConstraints (bool=True) Are our constraints flexible or not? total mass the same.
- verbose (bool=False) Optionally prints out a running progress report ewaldErrorTolerance : float=0.0005
The error tolerance to use if the nonbonded method is Ewald or PME.
flexibleConstraints : bool=True
Are our constraints flexible or not?
verbose : bool=False
Optionally prints out a running progress report
""" """
# Load the parameter set # Load the parameter set
self.loadParameters(params.condense()) self.loadParameters(params.condense())
......
...@@ -71,10 +71,12 @@ class CheckpointReporter(object): ...@@ -71,10 +71,12 @@ class CheckpointReporter(object):
def __init__(self, file, reportInterval): def __init__(self, file, reportInterval):
"""Create a CheckpointReporter. """Create a CheckpointReporter.
Parameters: Parameters
- file (string or open file object) The file to write to. Any current ----------
contents will be overwritten. file : string or open file object
- reportInterval (int) The interval (in time steps) at which to write checkpoints The file to write to. Any current contents will be overwritten.
reportInterval : int
The interval (in time steps) at which to write checkpoints.
""" """
self._reportInterval = reportInterval self._reportInterval = reportInterval
...@@ -88,12 +90,23 @@ class CheckpointReporter(object): ...@@ -88,12 +90,23 @@ class CheckpointReporter(object):
def describeNextReport(self, simulation): def describeNextReport(self, simulation):
"""Get information about the next report this object will generate. """Get information about the next report this object will generate.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
simulation : Simulation
Returns: A five element tuple. The first element is the number of steps until the The Simulation to generate a report for
next report. The remaining elements specify whether that report will require
positions, velocities, forces, and energies respectively. Returns
-------
int
The number of steps until the
bool
Requires positions
bool
Requires velocities
bool
Requires forces
bool
Requires energies
""" """
steps = self._reportInterval - simulation.currentStep%self._reportInterval steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, False, False, False, False) return (steps, False, False, False, False)
...@@ -101,9 +114,12 @@ class CheckpointReporter(object): ...@@ -101,9 +114,12 @@ class CheckpointReporter(object):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
self._out.seek(0) self._out.seek(0)
chk = simulation.context.createCheckpoint() chk = simulation.context.createCheckpoint()
......
...@@ -55,12 +55,19 @@ class DCDFile(object): ...@@ -55,12 +55,19 @@ class DCDFile(object):
def __init__(self, file, topology, dt, firstStep=0, interval=1): def __init__(self, file, topology, dt, firstStep=0, interval=1):
"""Create a DCD file and write out the header. """Create a DCD file and write out the header.
Parameters: Parameters
- file (file) A file to write to ----------
- topology (Topology) The Topology defining the molecular system being written file : file
- dt (time) The time step used in the trajectory A file to write to
- firstStep (int=0) The index of the first step in the trajectory topology : Topology
- interval (int=1) The frequency (measured in time steps) at which states are written to the trajectory The Topology defining the molecular system being written
dt : time
The time step used in the trajectory
firstStep : int=0
The index of the first step in the trajectory
interval : int=1
The frequency (measured in time steps) at which states are written
to the trajectory
""" """
self._file = file self._file = file
self._topology = topology self._topology = topology
...@@ -83,14 +90,21 @@ class DCDFile(object): ...@@ -83,14 +90,21 @@ class DCDFile(object):
def writeModel(self, positions, unitCellDimensions=None, periodicBoxVectors=None): def writeModel(self, positions, unitCellDimensions=None, periodicBoxVectors=None):
"""Write out a model to the DCD file. """Write out a model to the DCD file.
The periodic box can be specified either by the unit cell dimensions (for a rectangular box), or the full set of box The periodic box can be specified either by the unit cell dimensions
vectors (for an arbitrary triclinic box). If neither is specified, the box vectors specified in the Topology will be (for a rectangular box), or the full set of box vectors (for an
used. Regardless of the value specified, no dimensions will be written if the Topology does not represent a periodic system. arbitrary triclinic box). If neither is specified, the box vectors
specified in the Topology will be used. Regardless of the value
Parameters: specified, no dimensions will be written if the Topology does not
- positions (list) The list of atomic positions to write represent a periodic system.
- unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell.
- periodicBoxVectors (tuple of Vec3=None) The vectors defining the periodic box. Parameters
----------
positions : list
The list of atomic positions to write
unitCellDimensions : Vec3=None
The dimensions of the crystallographic unit cell.
periodicBoxVectors : tuple of Vec3=None
The vectors defining the periodic box.
""" """
if len(list(self._topology.atoms())) != len(positions): if len(list(self._topology.atoms())) != len(positions):
raise ValueError('The number of positions must match the number of atoms') raise ValueError('The number of positions must match the number of atoms')
......
...@@ -56,11 +56,23 @@ class DCDReporter(object): ...@@ -56,11 +56,23 @@ class DCDReporter(object):
def describeNextReport(self, simulation): def describeNextReport(self, simulation):
"""Get information about the next report this object will generate. """Get information about the next report this object will generate.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
Returns: A five element tuple. The first element is the number of steps until the simulation : Simulation
next report. The remaining elements specify whether that report will require The Simulation to generate a report for
positions, velocities, forces, and energies respectively.
Returns
-------
int
The number of steps until the
bool
Requires positions
bool
Requires velocities
bool
Requires forces
bool
Requires energies
""" """
steps = self._reportInterval - simulation.currentStep%self._reportInterval steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, True, False, False, False) return (steps, True, False, False, False)
...@@ -68,10 +80,14 @@ class DCDReporter(object): ...@@ -68,10 +80,14 @@ class DCDReporter(object):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
if self._dcd is None: if self._dcd is None:
self._dcd = DCDFile(self._out, simulation.topology, simulation.integrator.getStepSize(), 0, self._reportInterval) self._dcd = DCDFile(self._out, simulation.topology, simulation.integrator.getStepSize(), 0, self._reportInterval)
a,b,c = state.getPeriodicBoxVectors() a,b,c = state.getPeriodicBoxVectors()
......
...@@ -157,16 +157,24 @@ class DesmondDMSFile(object): ...@@ -157,16 +157,24 @@ class DesmondDMSFile(object):
def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*nanometer, def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*nanometer,
ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None): ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None):
"""Construct an OpenMM System representing the topology described by this dms file """Construct an OpenMM System representing the topology described by this
DMS file
Parameters: Parameters
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are ----------
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME. NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
- nonbondedCutoff (distance=1*nanometer) The cutoff distance to use for nonbonded interactions nonbondedCutoff : distance=1*nanometer
- ewaldErrorTolerance (float=0.0005) The error tolerance to use if nonbondedMethod is Ewald or PME. The cutoff distance to use for nonbonded interactions
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System ewaldErrorTolerance : float=0.0005
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is The error tolerance to use if nonbondedMethod is Ewald or PME.
subtracted from the heavy atom to keep their total mass the same. removeCMMotion : boolean=True
If true, a CMMotionRemover will be added to the System
hydrogenMass : mass=None
The mass to use for hydrogen atoms bound to heavy atoms. Any mass
added to a hydrogen is subtracted from the heavy atom to keep their
total mass the same.
""" """
self._checkForUnsupportedTerms() self._checkForUnsupportedTerms()
sys = mm.System() sys = mm.System()
......
...@@ -123,12 +123,14 @@ class ForceField(object): ...@@ -123,12 +123,14 @@ class ForceField(object):
def loadFile(self, file): def loadFile(self, file):
"""Load an XML file and add the definitions from it to this FieldField. """Load an XML file and add the definitions from it to this FieldField.
Parameters: Parameters
- file (string or file) An XML file containing force field definitions. It may ----------
be either an absolute file path, a path relative to the current working file : string or file
directory, a path relative to this module's data subdirectory An XML file containing force field definitions. It may be either an
(for built in force fields), or an open file-like object with a absolute file path, a path relative to the current working
read() method from which the forcefield XML data can be loaded. directory, a path relative to this module's data subdirectory (for
built in force fields), or an open file-like object with a read()
method from which the forcefield XML data can be loaded.
""" """
try: try:
# this handles either filenames or open file-like objects # this handles either filenames or open file-like objects
......
...@@ -183,9 +183,13 @@ class GromacsGroFile(object): ...@@ -183,9 +183,13 @@ class GromacsGroFile(object):
def getPositions(self, asNumpy=False, frame=0): def getPositions(self, asNumpy=False, frame=0):
"""Get the atomic positions. """Get the atomic positions.
Parameters: Parameters
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s ----------
- frame (int=0) the index of the frame for which to get positions asNumpy : boolean=False
if true, the values are returned as a numpy array instead of a list
of Vec3s
frame : int=0
the index of the frame for which to get positions
""" """
if asNumpy: if asNumpy:
if self._numpyPositions is None: if self._numpyPositions is None:
...@@ -198,16 +202,20 @@ class GromacsGroFile(object): ...@@ -198,16 +202,20 @@ class GromacsGroFile(object):
def getPeriodicBoxVectors(self, frame=0): def getPeriodicBoxVectors(self, frame=0):
"""Get the vectors defining the periodic box. """Get the vectors defining the periodic box.
Parameters: Parameters
- frame (int=0) the index of the frame for which to get the box vectors ----------
frame : int=0
the index of the frame for which to get the box vectors
""" """
return self._periodicBoxVectors[frame] return self._periodicBoxVectors[frame]
def getUnitCellDimensions(self, frame=0): def getUnitCellDimensions(self, frame=0):
"""Get the dimensions of the crystallographic unit cell. """Get the dimensions of the crystallographic unit cell.
Parameters: Parameters
- frame (int=0) the index of the frame for which to get the unit cell dimensions ----------
frame : int=0
the index of the frame for which to get the unit cell dimensions
""" """
xsize = self._periodicBoxVectors[frame][0][0].value_in_unit(nanometers) xsize = self._periodicBoxVectors[frame][0][0].value_in_unit(nanometers)
ysize = self._periodicBoxVectors[frame][1][1].value_in_unit(nanometers) ysize = self._periodicBoxVectors[frame][1][1].value_in_unit(nanometers)
......
...@@ -539,23 +539,42 @@ class GromacsTopFile(object): ...@@ -539,23 +539,42 @@ class GromacsTopFile(object):
def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*unit.nanometer, def createSystem(self, nonbondedMethod=ff.NoCutoff, nonbondedCutoff=1.0*unit.nanometer,
constraints=None, rigidWater=True, implicitSolvent=None, soluteDielectric=1.0, solventDielectric=78.5, ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None): constraints=None, rigidWater=True, implicitSolvent=None, soluteDielectric=1.0, solventDielectric=78.5, ewaldErrorTolerance=0.0005, removeCMMotion=True, hydrogenMass=None):
"""Construct an OpenMM System representing the topology described by this prmtop file. """Construct an OpenMM System representing the topology described by this
prmtop file.
Parameters: Parameters
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are ----------
nonbondedMethod : object=NoCutoff
The method to use for nonbonded interactions. Allowed values are
NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME. NoCutoff, CutoffNonPeriodic, CutoffPeriodic, Ewald, or PME.
- nonbondedCutoff (distance=1*nanometer) The cutoff distance to use for nonbonded interactions nonbondedCutoff : distance=1*nanometer
- constraints (object=None) Specifies which bonds and angles should be implemented with constraints. The cutoff distance to use for nonbonded interactions
Allowed values are None, HBonds, AllBonds, or HAngles. constraints : object=None
- rigidWater (boolean=True) If true, water molecules will be fully rigid regardless of the value passed for the constraints argument Specifies which bonds and angles should be implemented with
- implicitSolvent (object=None) If not None, the implicit solvent model to use. The only allowed value is OBC2. constraints. Allowed values are None, HBonds, AllBonds, or HAngles.
- soluteDielectric (float=1.0) The solute dielectric constant to use in the implicit solvent model. rigidWater : boolean=True
- solventDielectric (float=78.5) The solvent dielectric constant to use in the implicit solvent model. If true, water molecules will be fully rigid regardless of the value
- ewaldErrorTolerance (float=0.0005) The error tolerance to use if nonbondedMethod is Ewald or PME. passed for the constraints argument
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System implicitSolvent : object=None
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is If not None, the implicit solvent model to use. The only allowed
subtracted from the heavy atom to keep their total mass the same. value is OBC2.
Returns: the newly created System soluteDielectric : float=1.0
The solute dielectric constant to use in the implicit solvent model.
solventDielectric : float=78.5
The solvent dielectric constant to use in the implicit solvent
model.
ewaldErrorTolerance : float=0.0005
The error tolerance to use if nonbondedMethod is Ewald or PME.
removeCMMotion : boolean=True
If true, a CMMotionRemover will be added to the System
hydrogenMass : mass=None
The mass to use for hydrogen atoms bound to heavy atoms. Any mass
added to a hydrogen is subtracted from the heavy atom to keep their
total mass the same.
Returns
-------
the newly created System
""" """
# Create the System. # Create the System.
......
...@@ -76,22 +76,33 @@ class AtomType(object): ...@@ -76,22 +76,33 @@ class AtomType(object):
new atom types with the "add" constructor to make sure the registry is new atom types with the "add" constructor to make sure the registry is
filled with only unique types filled with only unique types
Parameters and Attributes: Parameters
- name (str) : The name of the atom type ----------
- number (int) : The integer index of the atom type name : str
- mass (float) : The mass of the atom type The name of the atom type
- atomic_number (int) : The atomic number of the element of the atom number : int
type The integer index of the atom type
Attributes: mass : float
- name (str) : The name of the atom type The mass of the atom type
- number (int) : The integer index of the atom type atomic_number : int
- _member_number (int, private) : The order in which this atom type The atomic number of the element of the atom type
was 'added' this is used to make sure that atom types added
last have priority in assignment in the generated hash tables Attributes
- nbfix (dict) : Dictionary that maps nbfix terms with other atom types. ----------
Dict entries are (rmin, epsilon) -- precombined values name : str
for that particular atom pair The name of the atom type
Example: number : int
The integer index of the atom type
_member_number : int, private)
The order in which this atom type was 'added' this is used to make
sure that atom types added last have priority in assignment in the
generated hash tables
nbfix : dict
Dictionary that maps nbfix terms with other atom types. Dict entries
are (rmin, epsilon) -- precombined values for that particular atom pair
Examples
--------
>>> at = AtomType('HA', 1, 1.008, 1) >>> at = AtomType('HA', 1, 1.008, 1)
>>> at.name, at.number >>> at.name, at.number
('HA', 1) ('HA', 1)
...@@ -212,34 +223,59 @@ WildCard = WildCard() # Turn it into a singleton ...@@ -212,34 +223,59 @@ WildCard = WildCard() # Turn it into a singleton
class Atom(object): class Atom(object):
""" An atom in a structure. """ An atom in a structure.
Parameters: Parameters
system (str) : Name of the system this atom belongs to ----------
name (str): name of the atom system : str
type (str or int) : Type of the atom Name of the system this atom belongs to
charge (float) : Partial atomic charge (elementary charge units) name : str
mass (float) : Atomic mass (amu) name of the atom
props (list) : Other properties from the PSF type : str or int
Type of the atom
Attributes: charge : float
- attype (str) : Name of the atom type Partial atomic charge (elementary charge units)
- system (str) : The system name associated with this atom mass : float
- name (str) : Name of the atom (str) Atomic mass (amu)
- charge (float) : Partial atomic charge props : list
- mass (float) : Mass of the atom (amu) Other properties from the PSF
- idx (int) : index of the atom in the system, starting from 0
- props (list) : List of extraneous properties parsed from a PSF Attributes
- type (AtomType) : If assigned, has additional properties like the ----------
non-bonded LJ parameters. If None, it has not yet been assigned attype : str
Name of the atom type
Possible Attributes (SOA == Set of Atom instances) system : str
- bond_partners (SOA) : List of all atoms I am bonded to The system name associated with this atom
- angle_partners (SOA) : List of all atoms I am angled to name : str
- dihedral_partners (SOA) : List of all atoms I am dihedraled to Name of the atom (str)
- bonds (list of Bond's) : All bonds to which I belong charge : float
- angles (list of Angle's) : All angles to which I belong Partial atomic charge
- dihedrals (list of Dihedral's) : All dihedrals to which I belong mass : float
- impropers (list of Improper's) : All impropers to which I belong Mass of the atom (amu)
- cmaps (list of Cmap's) : All correction maps to which I belong idx : int
index of the atom in the system, starting from 0
props : list
List of extraneous properties parsed from a PSF
type : AtomType
If assigned, has additional properties like the non-bonded LJ
parameters. If None, it has not yet been assigned
Possible Attributes
-------------------
bond_partners : set of Atoms
List of all atoms I am bonded to
angle_partners set of Atoms
List of all atoms I am angled to
dihedral_partners : et of Atoms
List of all atoms I am dihedraled to
bonds : list of Bonds
All bonds to which I belong
angles : list of Angles
All angles to which I belong
dihedrals : list of Dihedrals
All dihedrals to which I belong
impropers : list of Impropers
All impropers to which I belong
cmaps : list of Cmaps
All correction maps to which I belong
""" """
def __init__(self, system, name, attype, charge, mass, props=None): def __init__(self, system, name, attype, charge, mass, props=None):
self.name = name self.name = name
...@@ -450,22 +486,33 @@ class ResidueList(list): ...@@ -450,22 +486,33 @@ class ResidueList(list):
def add_atom(self, system, resnum, resname, name, def add_atom(self, system, resnum, resname, name,
attype, charge, mass, inscode, props=None): attype, charge, mass, inscode, props=None):
""" """Adds an atom to the list of residues. If the residue is not the same as
Adds an atom to the list of residues. If the residue is not the same as the last residue that was created, a new Residue is created and added to
the last residue that was created, a new Residue is created and added this list
to this list
Parameters
Parameters: ----------
- system (str) : The system this atom belongs to system : str
- resnum (int) : Residue number The system this atom belongs to
- resname (str) : Name of the residue resnum : int
- name (str) : Name of the atom Residue number
- attype (int or str) : Type of the atom resname : str
- charge (float) : Partial atomic charge of the atom Name of the residue
- mass (float) : Mass (amu) of the atom name : str
- inscode (str) : Insertion code, if it is specified Name of the atom
attype : int or str
Returns: Type of the atom
charge : float
Partial atomic charge of the atom
mass : float
Mass (amu) of the atom
inscode : str
Insertion code, if it is specified
props : list
Other properties from the PSF
Returns
-------
The Atom instance created and added to the list of residues The Atom instance created and added to the list of residues
""" """
lr = self._last_residue lr = self._last_residue
...@@ -491,13 +538,16 @@ class ResidueList(list): ...@@ -491,13 +538,16 @@ class ResidueList(list):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Bond(object): class Bond(object):
""" """A bond object that links 2 atoms
A bond object that links 2 atoms
Parameters
Parameters: ----------
- atom1 (Atom) : First atom included in the bond atom1 : Atom
- atom2 (Atom) : Second atom included in the bond First atom included in the bond
- bond_type (BondType) : Type for the bond (None if unknown) atom2 : Atom
Second atom included in the bond
bond_type : BondType
Type for the bond (None if unknown)
""" """
def __init__(self, atom1, atom2, bond_type=None): def __init__(self, atom1, atom2, bond_type=None):
self.atom1 = atom1 self.atom1 = atom1
...@@ -519,14 +569,18 @@ class Bond(object): ...@@ -519,14 +569,18 @@ class Bond(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Angle(object): class Angle(object):
""" """An angle object that links 3 atoms
An angle object that links 3 atoms
Parameters
Parameters: ----------
- atom1 (Atom) : First atom included in the angle atom1 : Atom
- atom2 (Atom) : Central atom in the valence angle First atom included in the angle
- atom3 (Atom) : Third atom in the valence angle atom2 : Atom
- angle_type (AngleType) : Type for the angle (None if unknown) Central atom in the valence angle
atom3 : Atom
Third atom in the valence angle
angle_type : AngleType
Type for the angle (None if unknown)
""" """
def __init__(self, atom1, atom2, atom3, angle_type=None): def __init__(self, atom1, atom2, atom3, angle_type=None):
self.atom1 = atom1 self.atom1 = atom1
...@@ -554,15 +608,17 @@ class Angle(object): ...@@ -554,15 +608,17 @@ class Angle(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class UreyBradley(object): class UreyBradley(object):
""" """A harmonic restraint between two atoms separated by 2 valence bonds
A harmonic restraint between two atoms separated by 2 valence bonds (i.e., (i.e., involved in a valence angle with each other
involved in a valence angle with each other
Parameters
Parameters: ----------
- atom1 (Atom) : The first atom included in the Urey-Bradley term atom1 : Atom
- atom2 (Atom) : The second atom included in the Urey-Bradley term The first atom included in the Urey-Bradley term
- ub_type (UreyBradleyType) : The type for the Urey-Bradley term (None atom2 : Atom
if unknown) The second atom included in the Urey-Bradley term
ub_type : UreyBradleyType
The type for the Urey-Bradley term (None if unknown)
""" """
def __init__(self, atom1, atom2, ub_type=None): def __init__(self, atom1, atom2, ub_type=None):
self.atom1 = atom1 self.atom1 = atom1
...@@ -599,15 +655,20 @@ class UreyBradley(object): ...@@ -599,15 +655,20 @@ class UreyBradley(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Dihedral(object): class Dihedral(object):
""" """A torsion angle object that links 4 atoms
A torsion angle object that links 4 atoms
Parameters
Parameters: ----------
- atom1 (Atom) : First atom included in the torsion atom1 : Atom
- atom2 (Atom) : Second atom included in the torsion First atom included in the torsion
- atom3 (Atom) : Third atom included in the torsion atom2 : Atom
- atom4 (Atom) : Fourth atom included in the torsion Second atom included in the torsion
- dihedral_type (DihedralType) : Type for the torsion (None if unknown) atom3 : Atom
Third atom included in the torsion
atom4 : Atom
Fourth atom included in the torsion
dihedral_type : DihedralType
Type for the torsion (None if unknown)
""" """
def __init__(self, atom1, atom2, atom3, atom4, dihedral_type=None): def __init__(self, atom1, atom2, atom3, atom4, dihedral_type=None):
self.atom1 = atom1 self.atom1 = atom1
...@@ -648,15 +709,20 @@ class Dihedral(object): ...@@ -648,15 +709,20 @@ class Dihedral(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Improper(object): class Improper(object):
""" """An improper torsion object. The third atom is bonded to each other atom
An improper torsion object. The third atom is bonded to each other atom
Parameters
Parameters: ----------
- atom1 (Atom) : First atom included in the torsion atom1 : Atom
- atom2 (Atom) : Second atom included in the torsion First atom included in the torsion
- atom3 (Atom) : Third atom included in the torsion atom2 : Atom
- atom4 (Atom) : Fourth atom included in the torsion Second atom included in the torsion
- improper_type (ImproperType) : Type for the improper (None if unknown) atom3 : Atom
Third atom included in the torsion
atom4 : Atom
Fourth atom included in the torsion
improper_type : ImproperType
Type for the improper (None if unknown)
""" """
def __init__(self, atom1, atom2, atom3, atom4, improper_type=None): def __init__(self, atom1, atom2, atom3, atom4, improper_type=None):
self.atom1 = atom1 self.atom1 = atom1
...@@ -703,12 +769,14 @@ class Improper(object): ...@@ -703,12 +769,14 @@ class Improper(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AcceptorDonor(object): class AcceptorDonor(object):
""" """Just a holder for donors and acceptors in CHARMM speak
Just a holder for donors and acceptors in CHARMM speak
Parameters
Parameters: ----------
- atom1 (Atom) : First atom in the donor/acceptor group atom1 : Atom
- atom2 (Atom) : Second atom in the donor/acceptor group First atom in the donor/acceptor group
atom2 : Atom
Second atom in the donor/acceptor group
""" """
def __init__(self, atom1, atom2): def __init__(self, atom1, atom2):
self.atom1 = atom1 self.atom1 = atom1
...@@ -724,13 +792,16 @@ class AcceptorDonor(object): ...@@ -724,13 +792,16 @@ class AcceptorDonor(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Group(object): class Group(object):
""" """An 'interacting' group defined by the PSF.
An 'interacting' group defined by the PSF.
Parameters: Parameters
- bs (int) : ?? ----------
- type (int) : The group type bs : int
- move (int) : If the group moves ?? ??
type : int
The group type
move : int
If the group moves ??
Disclaimer: I really don't know what these numbers mean. I'm speculating Disclaimer: I really don't know what these numbers mean. I'm speculating
based on the source code of 'chamber', and this section is simply ignored based on the source code of 'chamber', and this section is simply ignored
...@@ -749,36 +820,61 @@ class Cmap(object): ...@@ -749,36 +820,61 @@ class Cmap(object):
consecutive correction maps). "Consecutive torsions" (i.e., those definable consecutive correction maps). "Consecutive torsions" (i.e., those definable
by 5 atoms) will only be recognized if the two torsions have the same order by 5 atoms) will only be recognized if the two torsions have the same order
Parameters: Parameters
- atom1 (Atom) : 1st atom of first dihedral ----------
- atom2 (Atom) : 2nd atom of first dihedral atom1 : Atom
- atom3 (Atom) : 3rd atom of first dihedral 1st atom of first dihedral
- atom4 (Atom) : 4th atom of first dihedral atom2 : Atom
- atom5 (Atom) : 1st atom of second dihedral 2nd atom of first dihedral
- atom6 (Atom) : 2nd atom of second dihedral atom3 : Atom
- atom7 (Atom) : 3rd atom of second dihedral 3rd atom of first dihedral
- atom8 (Atom) : 4th atom of second dihedral atom4 : Atom
- cmap_type (CmapType) : Cmap type for this cmap (None if unknown) 4th atom of first dihedral
atom5 : Atom
Attributes: 1st atom of second dihedral
- consecutive (bool) : Are the dihedrals consecutive? atom6 : Atom
2nd atom of second dihedral
atom7 : Atom
3rd atom of second dihedral
atom8 : Atom
4th atom of second dihedral
cmap_type : CmapType
Cmap type for this cmap (None if unknown)
Attributes
----------
consecutive : bool
Are the dihedrals consecutive?
if consecutive: if consecutive:
- atom1 (Atom) : 1st atom of 1st dihedral atom1 : Atom
- atom2 (Atom) : 2nd atom of 1st dihedral && 1st atom of 2nd dihedral 1st atom of 1st dihedral
- atom3 (Atom) : 3rd atom of 1st dihedral && 2nd atom of 2nd dihedral atom2 L Atom
- atom4 (Atom) : 4th atom of 1st dihedral && 3rd atom of 2nd dihedral 2nd atom of 1st dihedral && 1st atom of 2nd dihedral
- atom5 (Atom) : 4th atom of 2nd dihedral atom3 : Atom
3rd atom of 1st dihedral && 2nd atom of 2nd dihedral
atom4 : Atom
4th atom of 1st dihedral && 3rd atom of 2nd dihedral
atom5 : Atom
4th atom of 2nd dihedral
if not consecutive: if not consecutive:
- atom1 (Atom) : 1st atom of first dihedral atom1 : Atom
- atom2 (Atom) : 2nd atom of first dihedral 1st atom of first dihedral
- atom3 (Atom) : 3rd atom of first dihedral atom2 : Atom
- atom4 (Atom) : 4th atom of first dihedral 2nd atom of first dihedral
- atom5 (Atom) : 1st atom of second dihedral atom3 : Atom
- atom6 (Atom) : 2nd atom of second dihedral 3rd atom of first dihedral
- atom7 (Atom) : 3rd atom of second dihedral atom4 : Atom
- atom8 (Atom) : 4th atom of second dihedral 4th atom of first dihedral
atom5 : Atom
1st atom of second dihedral
atom6 : Atom
2nd atom of second dihedral
atom7 : Atom
3rd atom of second dihedral
atom8 : Atom
4th atom of second dihedral
""" """
def __init__(self, atom1, atom2, atom3, atom4, atom5, atom6, atom7, def __init__(self, atom1, atom2, atom3, atom4, atom5, atom6, atom7,
atom8, cmap_type=None): atom8, cmap_type=None):
...@@ -866,9 +962,12 @@ class BondType(object): ...@@ -866,9 +962,12 @@ class BondType(object):
A bond type with an equilibrium length (Angstroms) and force constant A bond type with an equilibrium length (Angstroms) and force constant
(kcal/mol/Angstrom^2) (kcal/mol/Angstrom^2)
Parameters: Parameters
- k (float) : Force constant (kcal/mol/A^2) ----------
- req (float) : Equilibrium distance k : float
: Force constant (kcal/mol/A^2)
req : float
: Equilibrium distance
""" """
def __init__(self, k, req): def __init__(self, k, req):
self.k = k self.k = k
...@@ -880,13 +979,15 @@ class BondType(object): ...@@ -880,13 +979,15 @@ class BondType(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AngleType(object): class AngleType(object):
""" """An angle type with an equilibrium angle (degrees) and force constant
An angle type with an equilibrium angle (degrees) and force constant
(kcal/mol/radians^2) (kcal/mol/radians^2)
Parameters: Parameters
- k (float) : Force constant (kcal/mol/radians^2) ----------
- theteq (float) : Equilibrium angle value (degrees) k : float
Force constant (kcal/mol/radians^2)
theteq : float
Equilibrium angle value (degrees)
""" """
def __init__(self, k, theteq): def __init__(self, k, theteq):
self.k = k self.k = k
...@@ -911,14 +1012,17 @@ NoUreyBradley = UreyBradleyType(None, None) ...@@ -911,14 +1012,17 @@ NoUreyBradley = UreyBradleyType(None, None)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class DihedralType(object): class DihedralType(object):
""" """A torsion angle type with a force constant (kcal/mol), periodicity
A torsion angle type with a force constant (kcal/mol), periodicity (int), (int), and phase (degrees)
and phase (degrees)
Parameters
Parameters: ----------
- phi_k (float) : Force constant (kcal/mol) phi_k : float
- per (int) : Periodicity Force constant (kcal/mol)
- phase (float): Phase of the torsion per : int
Periodicity
phase : float
Phase of the torsion
""" """
def __init__(self, phi_k, per, phase): def __init__(self, phi_k, per, phase):
self.phi_k = float(phi_k) self.phi_k = float(phi_k)
...@@ -936,13 +1040,15 @@ class DihedralType(object): ...@@ -936,13 +1040,15 @@ class DihedralType(object):
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class ImproperType(object): class ImproperType(object):
""" """An improper torsion angle type with a force constant (kcal/mol) and
An improper torsion angle type with a force constant (kcal/mol) and
equilibrium angle (degrees) equilibrium angle (degrees)
Parameters: Parameters
- k (float) : Force constant (kcal/mol) ----------
- phieq (int) : Equilibrium angle (degrees) k : float
: Force constant (kcal/mol)
phieq : int
: Equilibrium angle (degrees)
""" """
def __init__(self, k, phieq): def __init__(self, k, phieq):
self.k = k self.k = k
...@@ -960,10 +1066,13 @@ class CmapType(object): ...@@ -960,10 +1066,13 @@ class CmapType(object):
""" """
Contains a correction map interpolation grid Contains a correction map interpolation grid
Parameters: Parameters
- resolution (int) : Number of interpolation points for each dihedral ----------
- grid (list of floats) : resolution x resolution list of energy values resolution : int
(kcal/mol) for the angles with the 2nd angle changing fastest. Number of interpolation points for each dihedral
grid : list of floats
resolution x resolution list of energy values (kcal/mol) for the
angles with the 2nd angle changing fastest.
The grid object is converted to a _CmapGrid instance which can be treated The grid object is converted to a _CmapGrid instance which can be treated
like a normal list, but also has the ability to quickly return a transpose like a normal list, but also has the ability to quickly return a transpose
......
...@@ -85,12 +85,16 @@ class Modeller(object): ...@@ -85,12 +85,16 @@ class Modeller(object):
def add(self, addTopology, addPositions): def add(self, addTopology, addPositions):
"""Add chains, residues, atoms, and bonds to the model. """Add chains, residues, atoms, and bonds to the model.
Specify what to add by providing a new Topology object and the corresponding atomic positions. Specify what to add by providing a new Topology object and the
All chains, residues, atoms, and bonds contained in the Topology are added to the model. corresponding atomic positions. All chains, residues, atoms, and bonds
contained in the Topology are added to the model.
Parameters:
- addTopoology (Topology) a Topology whose contents should be added to the model Parameters
- addPositions (list) the positions of the atoms to add ----------
addTopology : Topology
a Topology whose contents should be added to the model
addPositions : list
the positions of the atoms to add
""" """
# Copy over the existing model. # Copy over the existing model.
...@@ -137,8 +141,11 @@ class Modeller(object): ...@@ -137,8 +141,11 @@ class Modeller(object):
You also can specify a bond (as a tuple of Atom objects) to delete just that bond without You also can specify a bond (as a tuple of Atom objects) to delete just that bond without
deleting the Atoms it connects. deleting the Atoms it connects.
Parameters: Parameters
- toDelete (list) a list of Atoms, Residues, Chains, and bonds (specified as tuples of Atoms) to delete ----------
toDelete : list
a list of Atoms, Residues, Chains, and bonds (specified as tuples of
Atoms) to delete
""" """
newTopology = Topology() newTopology = Topology()
newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors()) newTopology.setPeriodicBoxVectors(self.topology.getPeriodicBoxVectors())
...@@ -604,16 +611,28 @@ class Modeller(object): ...@@ -604,16 +611,28 @@ class Modeller(object):
Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load Definitions for standard amino acids and nucleotides are built in. You can call loadHydrogenDefinitions() to load
additional definitions for other residue types. additional definitions for other residue types.
Parameters: Parameters
- forcefield (ForceField=None) the ForceField to use for determining the positions of hydrogens. If this is None, ----------
positions will be picked which are generally reasonable but not optimized for any particular ForceField. forcefield : ForceField=None
- pH (float=7.0) the pH based on which to select variants the ForceField to use for determining the positions of hydrogens.
- variants (list=None) an optional list of variants to use. If this is specified, its length must equal the number If this is None, positions will be picked which are generally
of residues in the model. variants[i] is the name of the variant to use for residue i (indexed starting at 0). reasonable but not optimized for any particular ForceField.
If an element is None, the standard rules will be followed to select a variant for that residue. pH : float=7.0
- platform (Platform=None) the Platform to use when computing the hydrogen atom positions. If this is None, the pH based on which to select variants
the default Platform will be used. variants : list=None
Returns: a list of what variant was actually selected for each residue, in the same format as the variants parameter an optional list of variants to use. If this is specified, its
length must equal the number of residues in the model. variants[i]
is the name of the variant to use for residue i (indexed starting at
0). If an element is None, the standard rules will be followed to
select a variant for that residue.
platform : Platform=None
the Platform to use when computing the hydrogen atom positions. If
this is None, the default Platform will be used.
Returns
-------
a list of what variant was actually selected for each residue,
in the same format as the variants param
""" """
# Check the list of variants. # Check the list of variants.
...@@ -862,18 +881,24 @@ class Modeller(object): ...@@ -862,18 +881,24 @@ class Modeller(object):
return actualVariants return actualVariants
def addExtraParticles(self, forcefield): def addExtraParticles(self, forcefield):
"""Add missing extra particles to the model that are required by a force field. """Add missing extra particles to the model that are required by a force
field.
Some force fields use "extra particles" that do not represent actual atoms, but still need to be included in
the System. Examples include lone pairs, Drude particles, and the virtual sites used in some water models Some force fields use "extra particles" that do not represent
to adjust the charge distribution. Extra particles can be recognized by the fact that their element is None. actual atoms, but still need to be included in the System. Examples
include lone pairs, Drude particles, and the virtual sites used in some
This method is primarily used to add extra particles, but it can also remove them. It tries to match every water models to adjust the charge distribution. Extra particles can be
residue in the Topology to a template in the force field. If there is no match, it will both add and remove recognized by the fact that their element is None.
extra particles as necessary to make it match.
This method is primarily used to add extra particles, but it can also
Parameters: remove them. It tries to match every residue in the Topology to a
- forcefield (ForceField) the ForceField defining what extra particles should be present template in the force field. If there is no match, it will both add
and remove extra particles as necessary to make it match.
Parameters
----------
forcefield : ForceField
the ForceField defining what extra particles should be present
""" """
# Create copies of all residue templates that have had all extra points removed. # Create copies of all residue templates that have had all extra points removed.
......
...@@ -176,9 +176,13 @@ class PDBFile(object): ...@@ -176,9 +176,13 @@ class PDBFile(object):
def getPositions(self, asNumpy=False, frame=0): def getPositions(self, asNumpy=False, frame=0):
"""Get the atomic positions. """Get the atomic positions.
Parameters: Parameters
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s ----------
- frame (int=0) the index of the frame for which to get positions asNumpy : boolean=False
if true, the values are returned as a numpy array instead of a list
of Vec3s
frame : int=0
the index of the frame for which to get positions
""" """
if asNumpy: if asNumpy:
if self._numpyPositions is None: if self._numpyPositions is None:
...@@ -234,13 +238,19 @@ class PDBFile(object): ...@@ -234,13 +238,19 @@ class PDBFile(object):
def writeFile(topology, positions, file=sys.stdout, keepIds=False): def writeFile(topology, positions, file=sys.stdout, keepIds=False):
"""Write a PDB file containing a single model. """Write a PDB file containing a single model.
Parameters: Parameters
- topology (Topology) The Topology defining the model to write ----------
- positions (list) The list of atomic positions to write topology : Topology
- file (file=stdout) A file to write to The Topology defining the model to write
- keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating positions : list
new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of The list of atomic positions to write
the PDB format. Otherwise, the output file will be invalid. file : file=stdout
A file to write to
keepIds : bool=False
If True, keep the residue and chain IDs specified in the Topology
rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the
PDB format. Otherwise, the output file will be invalid.
""" """
PDBFile.writeHeader(topology, file) PDBFile.writeHeader(topology, file)
PDBFile.writeModel(topology, positions, file, keepIds=keepIds) PDBFile.writeModel(topology, positions, file, keepIds=keepIds)
...@@ -250,9 +260,12 @@ class PDBFile(object): ...@@ -250,9 +260,12 @@ class PDBFile(object):
def writeHeader(topology, file=sys.stdout): def writeHeader(topology, file=sys.stdout):
"""Write out the header for a PDB file. """Write out the header for a PDB file.
Parameters: Parameters
- topology (Topology) The Topology defining the molecular system being written ----------
- file (file=stdout) A file to write the file to topology : Topology
The Topology defining the molecular system being written
file : file=stdout
A file to write the file to
""" """
print("REMARK 1 CREATED WITH OPENMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) print("REMARK 1 CREATED WITH OPENMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file)
vectors = topology.getPeriodicBoxVectors() vectors = topology.getPeriodicBoxVectors()
...@@ -266,15 +279,24 @@ class PDBFile(object): ...@@ -266,15 +279,24 @@ class PDBFile(object):
def writeModel(topology, positions, file=sys.stdout, modelIndex=None, keepIds=False): def writeModel(topology, positions, file=sys.stdout, modelIndex=None, keepIds=False):
"""Write out a model to a PDB file. """Write out a model to a PDB file.
Parameters: Parameters
- topology (Topology) The Topology defining the model to write ----------
- positions (list) The list of atomic positions to write topology : Topology
- file (file=stdout) A file to write the model to The Topology defining the model to write
- modelIndex (int=None) If not None, the model will be surrounded by MODEL/ENDMDL records with this index positions : list
- keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating The list of atomic positions to write
new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of file : file=stdout
the PDB format. Otherwise, the output file will be invalid. A file to write the model to
modelIndex : int=None
If not None, the model will be surrounded by MODEL/ENDMDL records
with this index
keepIds : bool=False
If True, keep the residue and chain IDs specified in the Topology
rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the
PDB format. Otherwise, the output file will be invalid.
""" """
if len(list(topology.atoms())) != len(positions): if len(list(topology.atoms())) != len(positions):
raise ValueError('The number of positions must match the number of atoms') raise ValueError('The number of positions must match the number of atoms')
if is_quantity(positions): if is_quantity(positions):
...@@ -331,9 +353,12 @@ class PDBFile(object): ...@@ -331,9 +353,12 @@ class PDBFile(object):
def writeFooter(topology, file=sys.stdout): def writeFooter(topology, file=sys.stdout):
"""Write out the footer for a PDB file. """Write out the footer for a PDB file.
Parameters: Parameters
- topology (Topology) The Topology defining the molecular system being written ----------
- file (file=stdout) A file to write the file to topology : Topology
The Topology defining the molecular system being written
file : file=stdout
A file to write the file to
""" """
# Identify bonds that should be listed as CONECT records. # Identify bonds that should be listed as CONECT records.
......
...@@ -56,11 +56,23 @@ class PDBReporter(object): ...@@ -56,11 +56,23 @@ class PDBReporter(object):
def describeNextReport(self, simulation): def describeNextReport(self, simulation):
"""Get information about the next report this object will generate. """Get information about the next report this object will generate.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
Returns: A five element tuple. The first element is the number of steps until the simulation : Simulation
next report. The remaining elements specify whether that report will require The Simulation to generate a report for
positions, velocities, forces, and energies respectively.
Returns
-------
int
The number of steps until the
bool
Requires positions
bool
Requires velocities
bool
Requires forces
bool
Requires energies
""" """
steps = self._reportInterval - simulation.currentStep%self._reportInterval steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, True, False, False, False) return (steps, True, False, False, False)
...@@ -68,9 +80,12 @@ class PDBReporter(object): ...@@ -68,9 +80,12 @@ class PDBReporter(object):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
if self._nextModel == 0: if self._nextModel == 0:
PDBFile.writeHeader(simulation.topology, self._out) PDBFile.writeHeader(simulation.topology, self._out)
...@@ -95,9 +110,12 @@ class PDBxReporter(PDBReporter): ...@@ -95,9 +110,12 @@ class PDBxReporter(PDBReporter):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
if self._nextModel == 0: if self._nextModel == 0:
PDBxFile.writeHeader(simulation.topology, self._out) PDBxFile.writeHeader(simulation.topology, self._out)
......
...@@ -193,9 +193,13 @@ class PDBxFile(object): ...@@ -193,9 +193,13 @@ class PDBxFile(object):
def getPositions(self, asNumpy=False, frame=0): def getPositions(self, asNumpy=False, frame=0):
"""Get the atomic positions. """Get the atomic positions.
Parameters: Parameters
- asNumpy (boolean=False) if true, the values are returned as a numpy array instead of a list of Vec3s ----------
- frame (int=0) the index of the frame for which to get positions asNumpy : bool=False
if true, the values are returned as a numpy array instead of a list
of Vec3s
frame : int=0
the index of the frame for which to get positions
""" """
if asNumpy: if asNumpy:
if self._numpyPositions is None: if self._numpyPositions is None:
...@@ -210,14 +214,21 @@ class PDBxFile(object): ...@@ -210,14 +214,21 @@ class PDBxFile(object):
entry=None): entry=None):
"""Write a PDBx/mmCIF file containing a single model. """Write a PDBx/mmCIF file containing a single model.
Parameters: Parameters
- topology (Topology) The Topology defining the model to write ----------
- positions (list) The list of atomic positions to write topology : Topology
- file (file=stdout) A file to write to The Topology defining the model to write
- keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating positions : list
new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of The list of atomic positions to write
the PDBx/mmCIF format. Otherwise, the output file will be invalid. file : file=stdout
- entry (str=None) The entry ID to assign to the CIF file A file to write to
keepIds : bool=False
If True, keep the residue and chain IDs specified in the Topology
rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the
PDBx/mmCIF format. Otherwise, the output file will be invalid.
entry : str=None
The entry ID to assign to the CIF file
""" """
PDBxFile.writeHeader(topology, file, entry) PDBxFile.writeHeader(topology, file, entry)
PDBxFile.writeModel(topology, positions, file, keepIds=keepIds) PDBxFile.writeModel(topology, positions, file, keepIds=keepIds)
...@@ -226,10 +237,14 @@ class PDBxFile(object): ...@@ -226,10 +237,14 @@ class PDBxFile(object):
def writeHeader(topology, file=sys.stdout, entry=None): def writeHeader(topology, file=sys.stdout, entry=None):
"""Write out the header for a PDBx/mmCIF file. """Write out the header for a PDBx/mmCIF file.
Parameters: Parameters
- topology (Topology) The Topology defining the molecular system being written ----------
- file (file=stdout) A file to write the file to topology : Topology
- entry (str=None) The entry ID to assign to the CIF file The Topology defining the molecular system being written
file : file=stdout
A file to write the file to
entry : str=None
The entry ID to assign to the CIF file
""" """
if entry is not None: if entry is not None:
print('data_%s' % entry, file=file) print('data_%s' % entry, file=file)
...@@ -280,14 +295,21 @@ class PDBxFile(object): ...@@ -280,14 +295,21 @@ class PDBxFile(object):
def writeModel(topology, positions, file=sys.stdout, modelIndex=1, keepIds=False): def writeModel(topology, positions, file=sys.stdout, modelIndex=1, keepIds=False):
"""Write out a model to a PDBx/mmCIF file. """Write out a model to a PDBx/mmCIF file.
Parameters: Parameters
- topology (Topology) The Topology defining the model to write ----------
- positions (list) The list of atomic positions to write topology : Topology
- file (file=stdout) A file to write the model to The Topology defining the model to write
- modelIndex (int=1) The model number of this frame positions : list
- keepIds (bool=False) If True, keep the residue and chain IDs specified in the Topology rather than generating The list of atomic positions to write
new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of file : file=stdout
the PDBx/mmCIF format. Otherwise, the output file will be invalid. A file to write the model to
modelIndex : int=1
The model number of this frame
keepIds : bool=False
If True, keep the residue and chain IDs specified in the Topology
rather than generating new ones. Warning: It is up to the caller to
make sure these are valid IDs that satisfy the requirements of the
PDBx/mmCIF format. Otherwise, the output file will be invalid.
""" """
if len(list(topology.atoms())) != len(positions): if len(list(topology.atoms())) != len(positions):
raise ValueError('The number of positions must match the number of atoms') raise ValueError('The number of positions must match the number of atoms')
......
...@@ -84,10 +84,14 @@ class Simulation(object): ...@@ -84,10 +84,14 @@ class Simulation(object):
def minimizeEnergy(self, tolerance=10*unit.kilojoule/unit.mole, maxIterations=0): def minimizeEnergy(self, tolerance=10*unit.kilojoule/unit.mole, maxIterations=0):
"""Perform a local energy minimization on the system. """Perform a local energy minimization on the system.
Parameters: Parameters
- tolerance (energy=10*kilojoules/mole) The energy tolerance to which the system should be minimized ----------
- maxIterations (int=0) The maximum number of iterations to perform. If this is 0, minimization is continued tolerance : energy=10*kilojoules/mole
until the results converge without regard to how many iterations it takes. The energy tolerance to which the system should be minimized
maxIterations : int=0
The maximum number of iterations to perform. If this is 0,
minimization is continued until the results converge without regard
to how many iterations it takes.
""" """
mm.LocalEnergyMinimizer.minimize(self.context, tolerance, maxIterations) mm.LocalEnergyMinimizer.minimize(self.context, tolerance, maxIterations)
...@@ -104,15 +108,24 @@ class Simulation(object): ...@@ -104,15 +108,24 @@ class Simulation(object):
later resume the simulation. Another option allows it to write checkpoints or states at regular intervals, so later resume the simulation. Another option allows it to write checkpoints or states at regular intervals, so
you can resume even if the simulation is interrupted before the time limit is reached. you can resume even if the simulation is interrupted before the time limit is reached.
Parameters: Parameters
- time (time) the amount of time to run for. If no units are specified, it is assumed to be a number of hours. ----------
- checkpointFile (string or file=None) if specified, a checkpoint file will be written at the end of the time : time
simulation (and optionally at regular intervals before then) by passing this to saveCheckpoint(). the amount of time to run for. If no units are specified, it is
- stateFile (string or file=None) if specified, a state file will be written at the end of the assumed to be a number of hours.
simulation (and optionally at regular intervals before then) by passing this to saveState(). checkpointFile : string or file=None
- checkpointInterval (time=None) if specified, checkpoints and/or states will be written at regular intervals if specified, a checkpoint file will be written at the end of the
during the simulation, in addition to writing a final version at the end. If no units are specified, this is simulation (and optionally at regular intervals before then) by
assumed to be in hours. passing this to saveCheckpoint().
stateFile : string or file=None
if specified, a state file will be written at the end of the
simulation (and optionally at regular intervals before then) by
passing this to saveState().
checkpointInterval : time=None
if specified, checkpoints and/or states will be written at regular
intervals during the simulation, in addition to writing a final
version at the end. If no units are specified, this is assumed to
be in hours.
""" """
if unit.is_quantity(time): if unit.is_quantity(time):
time = time.value_in_unit(unit.hours) time = time.value_in_unit(unit.hours)
...@@ -184,8 +197,11 @@ class Simulation(object): ...@@ -184,8 +197,11 @@ class Simulation(object):
another Simulation that has an identical System, uses the same Platform and OpenMM version, and is running on another Simulation that has an identical System, uses the same Platform and OpenMM version, and is running on
identical hardware. If you need a more portable way to resume simulations, consider using saveState() instead. identical hardware. If you need a more portable way to resume simulations, consider using saveState() instead.
Parameters: Parameters
- file (string or file) a File-like object to write the checkpoint to, or alternatively a filename ----------
file : string or file
a File-like object to write the checkpoint to, or alternatively a
filename
""" """
if isinstance(file, str): if isinstance(file, str):
with open(file, 'wb') as f: with open(file, 'wb') as f:
...@@ -196,8 +212,11 @@ class Simulation(object): ...@@ -196,8 +212,11 @@ class Simulation(object):
def loadCheckpoint(self, file): def loadCheckpoint(self, file):
"""Load a checkpoint file that was created with saveCheckpoint(). """Load a checkpoint file that was created with saveCheckpoint().
Parameters: Parameters
- file (string or file) a File-like object to load the checkpoint from, or alternatively a filename ----------
file : string or file
a File-like object to load the checkpoint from, or alternatively a
filename
""" """
if isinstance(file, str): if isinstance(file, str):
with open(file, 'rb') as f: with open(file, 'rb') as f:
...@@ -217,8 +236,11 @@ class Simulation(object): ...@@ -217,8 +236,11 @@ class Simulation(object):
with the original Simulation. On the other hand, this means it is portable across different Platforms or with the original Simulation. On the other hand, this means it is portable across different Platforms or
hardware. hardware.
Parameters: Parameters
- file (string or file) a File-like object to write the state to, or alternatively a filename ----------
file : string or file
a File-like object to write the state to, or alternatively a
filename
""" """
state = self.context.getState(getPositions=True, getVelocities=True, getParameters=True) state = self.context.getState(getPositions=True, getVelocities=True, getParameters=True)
xml = mm.XmlSerializer.serialize(state) xml = mm.XmlSerializer.serialize(state)
...@@ -231,8 +253,11 @@ class Simulation(object): ...@@ -231,8 +253,11 @@ class Simulation(object):
def loadState(self, file): def loadState(self, file):
"""Load a State file that was created with saveState(). """Load a State file that was created with saveState().
Parameters: Parameters
- file (string or file) a File-like object to load the state from, or alternatively a filename ----------
file : string or file
a File-like object to load the state from, or alternatively a
filename
""" """
if isinstance(file, str): if isinstance(file, str):
with open(file, 'r') as f: with open(file, 'r') as f:
......
...@@ -129,11 +129,23 @@ class StateDataReporter(object): ...@@ -129,11 +129,23 @@ class StateDataReporter(object):
def describeNextReport(self, simulation): def describeNextReport(self, simulation):
"""Get information about the next report this object will generate. """Get information about the next report this object will generate.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
Returns: A five element tuple. The first element is the number of steps until the simulation : Simulation
next report. The remaining elements specify whether that report will require The Simulation to generate a report for
positions, velocities, forces, and energies respectively.
Returns
-------
int
The number of steps until the
bool
Requires positions
bool
Requires velocities
bool
Requires forces
bool
Requires energies
""" """
steps = self._reportInterval - simulation.currentStep%self._reportInterval steps = self._reportInterval - simulation.currentStep%self._reportInterval
return (steps, self._needsPositions, self._needsVelocities, self._needsForces, self._needEnergy) return (steps, self._needsPositions, self._needsVelocities, self._needsForces, self._needEnergy)
...@@ -141,9 +153,12 @@ class StateDataReporter(object): ...@@ -141,9 +153,12 @@ class StateDataReporter(object):
def report(self, simulation, state): def report(self, simulation, state):
"""Generate a report. """Generate a report.
Parameters: Parameters
- simulation (Simulation) The Simulation to generate a report for ----------
- state (State) The current state of the simulation simulation : Simulation
The Simulation to generate a report for
state : State
The current state of the simulation
""" """
if not self._hasInitialized: if not self._hasInitialized:
self._initializeConstants(simulation) self._initializeConstants(simulation)
......
...@@ -89,10 +89,15 @@ class Topology(object): ...@@ -89,10 +89,15 @@ class Topology(object):
def addChain(self, id=None): def addChain(self, id=None):
"""Create a new Chain and add it to the Topology. """Create a new Chain and add it to the Topology.
Parameters: Parameters
- id (string=None) An optional identifier for the chain. If this is omitted, an id ----------
is generated based on the chain index. id : string=None
Returns: the newly created Chain An optional identifier for the chain. If this is omitted, an id is
generated based on the chain index.
Returns
-------
the newly created Chain
""" """
if id is None: if id is None:
id = str(len(self._chains)+1) id = str(len(self._chains)+1)
...@@ -103,12 +108,19 @@ class Topology(object): ...@@ -103,12 +108,19 @@ class Topology(object):
def addResidue(self, name, chain, id=None): def addResidue(self, name, chain, id=None):
"""Create a new Residue and add it to the Topology. """Create a new Residue and add it to the Topology.
Parameters: Parameters
- name (string) The name of the residue to add ----------
- chain (Chain) The Chain to add it to name : string
- id (string=None) An optional identifier for the residue. If this is omitted, an id The name of the residue to add
chain : Chain
The Chain to add it to
id : string=None
An optional identifier for the residue. If this is omitted, an id
is generated based on the residue index. is generated based on the residue index.
Returns: the newly created Residue
Returns
-------
the newly created Resid
""" """
if id is None: if id is None:
id = str(self._numResidues+1) id = str(self._numResidues+1)
...@@ -120,13 +132,21 @@ class Topology(object): ...@@ -120,13 +132,21 @@ class Topology(object):
def addAtom(self, name, element, residue, id=None): def addAtom(self, name, element, residue, id=None):
"""Create a new Atom and add it to the Topology. """Create a new Atom and add it to the Topology.
Parameters: Parameters
- name (string) The name of the atom to add ----------
- element (Element) The element of the atom to add name : string
- residue (Residue) The Residue to add it to The name of the atom to add
- id (string=None) An optional identifier for the atom. If this is omitted, an id element : Element
is generated based on the atom index. The element of the atom to add
Returns: the newly created Atom residue : Residue
The Residue to add it to
id : string=None
An optional identifier for the atom. If this is omitted, an id is
generated based on the atom index.
Returns
-------
the newly created Atom
""" """
if id is None: if id is None:
id = str(self._numAtoms+1) id = str(self._numAtoms+1)
...@@ -138,9 +158,12 @@ class Topology(object): ...@@ -138,9 +158,12 @@ class Topology(object):
def addBond(self, atom1, atom2): def addBond(self, atom1, atom2):
"""Create a new bond and add it to the Topology. """Create a new bond and add it to the Topology.
Parameters: Parameters
- atom1 (Atom) The first Atom connected by the bond ----------
- atom2 (Atom) The second Atom connected by the bond atom1 : Atom
The first Atom connected by the bond
atom2 : Atom
The second Atom connected by the bond
""" """
self._bonds.append((atom1, atom2)) self._bonds.append((atom1, atom2))
...@@ -274,10 +297,13 @@ class Topology(object): ...@@ -274,10 +297,13 @@ class Topology(object):
self.addBond(atomMaps[fromResidue][fromAtom], atomMaps[toResidue][toAtom]) self.addBond(atomMaps[fromResidue][fromAtom], atomMaps[toResidue][toAtom])
def createDisulfideBonds(self, positions): def createDisulfideBonds(self, positions):
"""Identify disulfide bonds based on proximity and add them to the Topology. """Identify disulfide bonds based on proximity and add them to the
Topology.
Parameters: Parameters
- positions (list) The list of atomic positions based on which to identify bonded atoms ----------
positions : list
The list of atomic positions based on which to identify bonded atoms
""" """
def isCyx(res): def isCyx(res):
names = [atom.name for atom in res._atoms] names = [atom.name for atom in res._atoms]
......
...@@ -54,9 +54,12 @@ class Unit(object): ...@@ -54,9 +54,12 @@ class Unit(object):
def __init__(self, base_or_scaled_units): def __init__(self, base_or_scaled_units):
"""Create a new Unit. """Create a new Unit.
Parameters: Parameters
- self (Unit) The newly created Unit. ----------
- base_or_scaled_units (dict) Keys are BaseUnits or ScaledUnits. Values are exponents (numbers). self : Unit
The newly created Unit.
base_or_scaled_units : dict
Keys are BaseUnits or ScaledUnits. Values are exponents (numbers).
""" """
# Unit contents are of two types: BaseUnits and ScaledUnits # Unit contents are of two types: BaseUnits and ScaledUnits
self._top_base_units = {} self._top_base_units = {}
...@@ -389,7 +392,8 @@ class Unit(object): ...@@ -389,7 +392,8 @@ class Unit(object):
Strips off any ScaledUnits in the Unit, leaving only BaseUnits. Strips off any ScaledUnits in the Unit, leaving only BaseUnits.
Parameters Parameters
- system: a dictionary of (BaseDimension, BaseUnit) pairs ----------
system : a dictionary of (BaseDimension, BaseUnit) pairs
""" """
return system.express_unit(self) return system.express_unit(self)
...@@ -583,7 +587,7 @@ class UnitSystem(object): ...@@ -583,7 +587,7 @@ class UnitSystem(object):
Parameters Parameters
---------- ----------
units: ``list`` units : list
List of base units from which to construct the unit system List of base units from which to construct the unit system
""" """
def __init__(self, units): def __init__(self, units):
...@@ -678,7 +682,7 @@ def is_unit(x): ...@@ -678,7 +682,7 @@ def is_unit(x):
Returns True if x is a Unit, False otherwise. Returns True if x is a Unit, False otherwise.
Examples Examples
--------
>>> is_unit(16) >>> is_unit(16)
False False
""" """
......
...@@ -45,7 +45,7 @@ using namespace OpenMM; ...@@ -45,7 +45,7 @@ using namespace OpenMM;
%} %}
%feature("autodoc", "1"); %feature("autodoc", "0");
%nodefaultctor; %nodefaultctor;
%include features.i %include features.i
......
...@@ -146,6 +146,20 @@ def getClassMethodList(classNode, skipMethods): ...@@ -146,6 +146,20 @@ def getClassMethodList(classNode, skipMethods):
return methodList return methodList
def docstringTypemap(cpptype):
"""Translate a C++ type to Python for inclusion in the Python docstrings.
This doesn't need to be perfectly accurate -- it's not used for generating
the actual swig wrapper code. It's only used for generating the docstrings.
"""
pytype = cpptype
if pytype.startswith('const '):
pytype = pytype[6:]
if pytype.startswith('std::'):
pytype = pytype[5:]
pytype = pytype.strip('&')
return pytype.strip()
class SwigInputBuilder: class SwigInputBuilder:
def __init__(self, def __init__(self,
inputDirname, inputDirname,
...@@ -563,32 +577,58 @@ class SwigInputBuilder: ...@@ -563,32 +577,58 @@ class SwigInputBuilder:
(shortClassName, memberNode, (shortClassName, memberNode,
shortMethDefinition, methName, shortMethDefinition, methName,
isConstructors, isDestructor, templateType, templateName ) = items isConstructors, isDestructor, templateType, templateName ) = items
if self.fOutDocstring: if self.fOutDocstring:
for dNode in findNodes(memberNode, 'detaileddescription'): signatureParams = findNodes(memberNode, 'param')
dString="" assert len(findNodes(memberNode, 'detaileddescription')) == 1
dNode = findNodes(memberNode, 'detaileddescription')[0]
try: try:
description=getText('para', dNode) description=getText('para', dNode)
description.strip() description.strip()
if description:
dString=description
except IndexError: except IndexError:
pass description = ''
params = findNodes(dNode, 'para/parameterlist/parameteritem') params = findNodes(dNode, 'para/parameterlist/parameteritem')
paramString = ['Parameters', '----------']
returnString = ['Returns', '-------']
if len(params) > 0: if len(params) > 0:
dString="%s\n Parameters:" % dString if len(signatureParams) != len(params):
for pNode in params: raise ValueError('docstring in %s.%s does not match the signature' % (shortClassName, methName))
argName = getText('parameternamelist/parametername', pNode)
for pNode, pSignatureNode in zip(params, signatureParams):
parameterNameNode = findNodes(pNode, 'parameternamelist/parametername')[0]
argDoc = getText('parameterdescription/para', pNode) argDoc = getText('parameterdescription/para', pNode)
dString="%s\n - %s %s" % (dString, argName, argDoc) argName = getNodeText(parameterNameNode)
dString.strip() argType = docstringTypemap(getText('type', pSignatureNode))
isOutput = parameterNameNode.get('direction') == 'out'
if isOutput:
returnString.extend(['%s : %s' % (argName, argType), ' %s' % argDoc])
else:
paramString.extend(['%s : %s' % (argName, argType), ' %s' % argDoc])
returnSection = findNodes(dNode, 'para/simplesect')
if len(returnSection) > 0:
returnNode = returnSection[0]
if returnNode.get('kind') == 'return':
argType = getNodeText(findNodes(memberNode, 'type')[0])
argType = docstringTypemap(argType)
returnString.extend([argType, ' %s' % getNodeText(returnNode).strip()])
dString = '\n'.join(
([description] + [''] if len(description) > 0 else []) +
(paramString + [''] if len(paramString) > 2 else []) +
(returnString if len(returnString) > 2 else [])).strip()
if dString: if dString:
dString=re.sub(r'([^\\])"', r'\g<1>\"', dString) dString = re.sub(r'([^\\])"', r'\g<1>\"', dString)
s = '%%feature("docstring") OpenMM::%s::%s "%s";' \ s = '%%feature("docstring") OpenMM::%s::%s "%s";' \
% (shortClassName, methName, dString) % (shortClassName, methName, dString)
self.fOutDocstring.write("%s\n" % s) self.fOutDocstring.write("%s\n" % s)
self.fOutDocstring.write("\n\n")
#print "Done write Docstring info\n"
self.fOutDocstring.write("\n\n")
def writeSwigFile(self): def writeSwigFile(self):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment