Commit 51b7f9e2 authored by Robert McGibbon's avatar Robert McGibbon
Browse files

Merge master

parents 85bfd73c be0387b6
...@@ -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')
......
...@@ -45,9 +45,12 @@ class DCDReporter(object): ...@@ -45,9 +45,12 @@ class DCDReporter(object):
def __init__(self, file, reportInterval): def __init__(self, file, reportInterval):
"""Create a DCDReporter. """Create a DCDReporter.
Parameters: Parameters
- file (string) The file to write to ----------
- reportInterval (int) The interval (in time steps) at which to write frames file : string
The file to write to
reportInterval : int
The interval (in time steps) at which to write frames
""" """
self._reportInterval = reportInterval self._reportInterval = reportInterval
self._out = open(file, 'wb') self._out = open(file, 'wb')
...@@ -56,11 +59,18 @@ class DCDReporter(object): ...@@ -56,11 +59,18 @@ 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
-------
tuple
A five element tuple. The first element is the number of steps
until the next report. The remaining elements specify whether
that report will require positions, velocities, forces, and
energies respectively.
""" """
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 +78,14 @@ class DCDReporter(object): ...@@ -68,10 +78,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()
......
...@@ -46,10 +46,11 @@ class DesmondDMSFile(object): ...@@ -46,10 +46,11 @@ class DesmondDMSFile(object):
def __init__(self, file): def __init__(self, file):
"""Load a DMS file """Load a DMS file
Parameters: Parameters
- file (string) the name of the file to load ----------
file : string
the name of the file to load
""" """
# sqlite3 is included in the standard lib, but at python # sqlite3 is included in the standard lib, but at python
# compile time, you can disable support (I think), so it's # compile time, you can disable support (I think), so it's
# not *guarenteed* to be available. Doing the import here # not *guarenteed* to be available. Doing the import here
...@@ -157,16 +158,24 @@ class DesmondDMSFile(object): ...@@ -157,16 +158,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()
......
...@@ -58,11 +58,16 @@ class Element(object): ...@@ -58,11 +58,16 @@ class Element(object):
def __init__(self, number, name, symbol, mass): def __init__(self, number, name, symbol, mass):
"""Create a new element """Create a new element
Parameters: Parameters
number (int) The atomic number of the element ----------
name (string) The name of the element number : int
symbol (string) The chemical symbol of the element The atomic number of the element
mass (float) The atomic mass of the element name : string
The name of the element
symbol : string
The chemical symbol of the element
mass : float
The atomic mass of the element
""" """
## The atomic number of the element ## The atomic number of the element
self._atomic_number = number self._atomic_number = number
...@@ -115,7 +120,7 @@ class Element(object): ...@@ -115,7 +120,7 @@ class Element(object):
Returns Returns
------- -------
element : Element Element
The element whose atomic mass is closest to the input mass The element whose atomic mass is closest to the input mass
""" """
# Assume masses are in daltons if they are not units # Assume masses are in daltons if they are not units
......
...@@ -104,8 +104,10 @@ class ForceField(object): ...@@ -104,8 +104,10 @@ class ForceField(object):
def __init__(self, *files): def __init__(self, *files):
"""Load one or more XML files and create a ForceField object based on them. """Load one or more XML files and create a ForceField object based on them.
Parameters: Parameters
- files (list) A list of XML files defining the force field. Each entry may ----------
files : list
A list of XML files defining the force field. Each entry may
be an absolute file path, a path relative to the current working be an absolute file path, a path relative to the current working
directory, a path relative to this module's data subdirectory directory, a path relative to this module's data subdirectory
(for built in force fields), or an open file-like object with a (for built in force fields), or an open file-like object with a
...@@ -123,12 +125,14 @@ class ForceField(object): ...@@ -123,12 +125,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
...@@ -270,6 +274,17 @@ class ForceField(object): ...@@ -270,6 +274,17 @@ class ForceField(object):
self.impropers = [] self.impropers = []
self.atomBonds = [] self.atomBonds = []
self.isAngleConstrained = [] self.isAngleConstrained = []
self.constraints = {}
def addConstraint(self, system, atom1, atom2, distance):
"""Add a constraint to the system, avoiding duplicate constraints."""
key = (min(atom1, atom2), max(atom1, atom2))
if key in self.constraints:
if self.constraints(key) != distance:
raise ValueError('Two constraints were specified between atoms %d and %d with different distances' % (atom1, atom2))
else:
self.constraints[key] = distance
system.addConstraint(atom1, atom2, distance)
class _TemplateData: class _TemplateData:
"""Inner class used to encapsulate data about a residue template definition.""" """Inner class used to encapsulate data about a residue template definition."""
...@@ -406,20 +421,36 @@ class ForceField(object): ...@@ -406,20 +421,36 @@ class ForceField(object):
constraints=None, rigidWater=True, removeCMMotion=True, hydrogenMass=None, **args): constraints=None, rigidWater=True, removeCMMotion=True, hydrogenMass=None, **args):
"""Construct an OpenMM System representing a Topology with this force field. """Construct an OpenMM System representing a Topology with this force field.
Parameters: Parameters
- topology (Topology) The Topology for which to create a System ----------
- nonbondedMethod (object=NoCutoff) The method to use for nonbonded interactions. Allowed values are topology : Topology
The Topology for which to create a System
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
constraints : object=None
Specifies which bonds and angles should be implemented with constraints.
Allowed values are None, HBonds, AllBonds, or HAngles. Allowed values are None, HBonds, AllBonds, or HAngles.
- rigidWater (boolean=True) If true, water molecules will be fully rigid regardless of the value passed for the constraints argument rigidWater : boolean=True
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System If true, water molecules will be fully rigid regardless of the value
- hydrogenMass (mass=None) The mass to use for hydrogen atoms bound to heavy atoms. Any mass added to a hydrogen is passed for the constraints argument
subtracted from the heavy atom to keep their total mass the same. removeCMMotion : boolean=True
- args Arbitrary additional keyword arguments may also be specified. This allows extra parameters to be specified that are specific to 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.
args
Arbitrary additional keyword arguments may also be specified.
This allows extra parameters to be specified that are specific to
particular force fields. particular force fields.
Returns: the newly created System
Returns
-------
system
the newly created System
""" """
data = ForceField._SystemData() data = ForceField._SystemData()
data.atoms = list(topology.atoms()) data.atoms = list(topology.atoms())
...@@ -647,12 +678,20 @@ def _createResidueSignature(elements): ...@@ -647,12 +678,20 @@ def _createResidueSignature(elements):
def _matchResidue(res, template, bondedToAtom): def _matchResidue(res, template, bondedToAtom):
"""Determine whether a residue matches a template and return a list of corresponding atoms. """Determine whether a residue matches a template and return a list of corresponding atoms.
Parameters: Parameters
- res (Residue) The residue to check ----------
- template (_TemplateData) The template to compare it to res : Residue
- bondedToAtom (list) Enumerates which other atoms each atom is bonded to The residue to check
Returns: a list specifying which atom of the template each atom of the residue corresponds to, template : _TemplateData
or None if it does not match the template The template to compare it to
bondedToAtom : list
Enumerates which other atoms each atom is bonded to
Returns
-------
list
a list specifying which atom of the template each atom of the residue
corresponds to, or None if it does not match the template
""" """
atoms = list(res.atoms()) atoms = list(res.atoms())
if len(atoms) != len(template.atoms): if len(atoms) != len(template.atoms):
...@@ -829,7 +868,7 @@ class HarmonicBondGenerator: ...@@ -829,7 +868,7 @@ class HarmonicBondGenerator:
if (type1 in types1 and type2 in types2) or (type1 in types2 and type2 in types1): if (type1 in types1 and type2 in types2) or (type1 in types2 and type2 in types1):
bond.length = self.length[i] bond.length = self.length[i]
if bond.isConstrained: if bond.isConstrained:
sys.addConstraint(bond.atom1, bond.atom2, self.length[i]) data.addConstraint(sys, bond.atom1, bond.atom2, self.length[i])
elif self.k[i] != 0: elif self.k[i] != 0:
force.addBond(bond.atom1, bond.atom2, self.length[i], self.k[i]) force.addBond(bond.atom1, bond.atom2, self.length[i], self.k[i])
break break
...@@ -902,7 +941,7 @@ class HarmonicAngleGenerator: ...@@ -902,7 +941,7 @@ class HarmonicAngleGenerator:
l2 = data.bonds[bond2].length l2 = data.bonds[bond2].length
if l1 is not None and l2 is not None: if l1 is not None and l2 is not None:
length = sqrt(l1*l1 + l2*l2 - 2*l1*l2*cos(self.angle[i])) length = sqrt(l1*l1 + l2*l2 - 2*l1*l2*cos(self.angle[i]))
sys.addConstraint(angle[0], angle[2], length) data.addConstraint(sys, angle[0], angle[2], length)
elif self.k[i] != 0: elif self.k[i] != 0:
force.addAngle(angle[0], angle[1], angle[2], self.angle[i], self.k[i]) force.addAngle(angle[0], angle[1], angle[2], self.angle[i], self.k[i])
break break
...@@ -1990,7 +2029,7 @@ class AmoebaBondGenerator: ...@@ -1990,7 +2029,7 @@ class AmoebaBondGenerator:
if (type1 in types1 and type2 in types2) or (type1 in types2 and type2 in types1): if (type1 in types1 and type2 in types2) or (type1 in types2 and type2 in types1):
bond.length = self.length[i] bond.length = self.length[i]
if bond.isConstrained: if bond.isConstrained:
sys.addConstraint(bond.atom1, bond.atom2, self.length[i]) data.addConstraint(sys, bond.atom1, bond.atom2, self.length[i])
elif self.k[i] != 0: elif self.k[i] != 0:
force.addBond(bond.atom1, bond.atom2, self.length[i], self.k[i]) force.addBond(bond.atom1, bond.atom2, self.length[i], self.k[i])
break break
...@@ -2022,7 +2061,7 @@ def addAngleConstraint(angle, idealAngle, data, sys): ...@@ -2022,7 +2061,7 @@ def addAngleConstraint(angle, idealAngle, data, sys):
l2 = data.bonds[bond2].length l2 = data.bonds[bond2].length
if l1 is not None and l2 is not None: if l1 is not None and l2 is not None:
length = sqrt(l1*l1 + l2*l2 - 2*l1*l2*cos(idealAngle)) length = sqrt(l1*l1 + l2*l2 - 2*l1*l2*cos(idealAngle))
sys.addConstraint(angle[0], angle[2], length) data.addConstraint(sys, angle[0], angle[2], length)
return return
#============================================================================================= #=============================================================================================
......
...@@ -114,10 +114,11 @@ class GromacsGroFile(object): ...@@ -114,10 +114,11 @@ class GromacsGroFile(object):
The atom positions can be retrieved by calling getPositions(). The atom positions can be retrieved by calling getPositions().
Parameters: Parameters
- file (string) the name of the file to load ----------
file : string
the name of the file to load
""" """
xyzs = [] xyzs = []
elements = [] # The element, most useful for quantum chemistry calculations elements = [] # The element, most useful for quantum chemistry calculations
atomname = [] # The atom name, for instance 'HW1' atomname = [] # The atom name, for instance 'HW1'
...@@ -183,9 +184,13 @@ class GromacsGroFile(object): ...@@ -183,9 +184,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 +203,20 @@ class GromacsGroFile(object): ...@@ -198,16 +203,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)
......
...@@ -433,16 +433,22 @@ class GromacsTopFile(object): ...@@ -433,16 +433,22 @@ class GromacsTopFile(object):
def __init__(self, file, periodicBoxVectors=None, unitCellDimensions=None, includeDir=None, defines=None): def __init__(self, file, periodicBoxVectors=None, unitCellDimensions=None, includeDir=None, defines=None):
"""Load a top file. """Load a top file.
Parameters: Parameters
- file (string) the name of the file to load ----------
- periodicBoxVectors (tuple of Vec3=None) the vectors defining the periodic box file : str
- unitCellDimensions (Vec3=None) the dimensions of the crystallographic unit cell. For the name of the file to load
periodicBoxVectors : tuple of Vec3=None
the vectors defining the periodic box
unitCellDimensions : Vec3=None
the dimensions of the crystallographic unit cell. For
non-rectangular unit cells, specify periodicBoxVectors instead. non-rectangular unit cells, specify periodicBoxVectors instead.
- includeDir (string=None) A directory in which to look for other files includeDir : string=None
included from the top file. If not specified, we will attempt to locate a gromacs A directory in which to look for other files included from the
installation on your system. When gromacs is installed in /usr/local, this will resolve top file. If not specified, we will attempt to locate a gromacs
to /usr/local/gromacs/share/gromacs/top installation on your system. When gromacs is installed in
- defines (dict={}) preprocessor definitions that should be predefined when parsing the file /usr/local, this will resolve to /usr/local/gromacs/share/gromacs/top
defines : dict={}
preprocessor definitions that should be predefined when parsing the file
""" """
if includeDir is None: if includeDir is None:
includeDir = _defaultGromacsIncludeDir() includeDir = _defaultGromacsIncludeDir()
...@@ -539,23 +545,43 @@ class GromacsTopFile(object): ...@@ -539,23 +545,43 @@ 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
-------
System
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
......
...@@ -123,15 +123,18 @@ class PdbStructure(object): ...@@ -123,15 +123,18 @@ class PdbStructure(object):
""" """
def __init__(self, input_stream, load_all_models = False): def __init__(self, input_stream, load_all_models=False):
"""Create a PDB model from a PDB file stream. """Create a PDB model from a PDB file stream.
Parameters: Parameters
- self (PdbStructure) The new object that is created. ----------
- input_stream (stream) An input file stream, probably created with self : PdbStructure
open(). The new object that is created.
- load_all_models (bool) Whether to load every model of an NMR input_stream : stream
structure or trajectory, or just load the first model, to save memory. An input file stream, probably created with open().
load_all_models : bool
Whether to load every model of an NMR structure or trajectory, or
just load the first model, to save memory.
""" """
# initialize models # initialize models
self.load_all_models = load_all_models self.load_all_models = load_all_models
...@@ -269,8 +272,11 @@ class PdbStructure(object): ...@@ -269,8 +272,11 @@ class PdbStructure(object):
Iterate over atomic positions. Iterate over atomic positions.
Parameters Parameters
- use_all_models (bool=False) Get positions from all models or just the first one. ----------
- include_alt_loc (bool=False) Get all positions for each atom, or just the first one. use_all_models : bool=False
Get positions from all models or just the first one.
include_alt_loc : bool=False
Get all positions for each atom, or just the first one.
""" """
for model in self.iter_models(use_all_models): for model in self.iter_models(use_all_models):
for loc in model.iter_positions(include_alt_loc): for loc in model.iter_positions(include_alt_loc):
......
...@@ -64,8 +64,10 @@ class PDBFile(object): ...@@ -64,8 +64,10 @@ class PDBFile(object):
The atom positions and Topology can be retrieved by calling getPositions() and getTopology(). The atom positions and Topology can be retrieved by calling getPositions() and getTopology().
Parameters: Parameters
- file (string) the name of the file to load ----------
file : string
the name of the file to load
""" """
top = Topology() top = Topology()
## The Topology read from the PDB file ## The Topology read from the PDB file
...@@ -176,9 +178,13 @@ class PDBFile(object): ...@@ -176,9 +178,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 +240,19 @@ class PDBFile(object): ...@@ -234,13 +240,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 +262,12 @@ class PDBFile(object): ...@@ -250,9 +262,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 +281,24 @@ class PDBFile(object): ...@@ -266,15 +281,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 +355,12 @@ class PDBFile(object): ...@@ -331,9 +355,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.
......
...@@ -44,9 +44,12 @@ class PDBReporter(object): ...@@ -44,9 +44,12 @@ class PDBReporter(object):
def __init__(self, file, reportInterval): def __init__(self, file, reportInterval):
"""Create a PDBReporter. """Create a PDBReporter.
Parameters: Parameters
- file (string) The file to write to ----------
- reportInterval (int) The interval (in time steps) at which to write frames file : string
The file to write to
reportInterval : int
The interval (in time steps) at which to write frames
""" """
self._reportInterval = reportInterval self._reportInterval = reportInterval
self._out = open(file, 'w') self._out = open(file, 'w')
...@@ -56,11 +59,18 @@ class PDBReporter(object): ...@@ -56,11 +59,18 @@ 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
-------
tuple
A five element tuple. The first element is the number of steps
until the next report. The remaining elements specify whether
that report will require positions, velocities, forces, and
energies respectively.
""" """
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 +78,12 @@ class PDBReporter(object): ...@@ -68,9 +78,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 +108,12 @@ class PDBxReporter(PDBReporter): ...@@ -95,9 +108,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)
......
This diff is collapsed.
This diff is collapsed.
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