Пример #1
0
    def getEffectiveEnergy(self, totalEnergy, groupEnergy):
        """Given the actual potential energy of the system, return the value of the effective potential.

        Parameters
        ----------
        totalEnergy : energy
            the actual potential energy of the whole system
        groupEnergy : energy
            the actual potential energy of the boosted force group

        Returns
        -------
        energy
            the value of the effective potential
        """
        alphaTotal = self.getAlphaTotal()
        ETotal = self.getETotal()
        alphaGroup = self.getAlphaGroup()
        EGroup = self.getEGroup()
        if not is_quantity(totalEnergy):
            totalEnergy = totalEnergy * kilojoules_per_mole  # Assume kJ/mole
        if not is_quantity(groupEnergy):
            groupEnergy = groupEnergy * kilojoules_per_mole  # Assume kJ/mole
        dE = 0.0 * kilojoules_per_mole
        if (totalEnergy < ETotal):
            dE = dE + (ETotal - totalEnergy) * (ETotal - totalEnergy) / (
                alphaTotal + ETotal - totalEnergy)
        if (groupEnergy < EGroup):
            dE = dE + (EGroup - groupEnergy) * (EGroup - groupEnergy) / (
                alphaGroup + EGroup - groupEnergy)
        return totalEnergy + dE
Пример #2
0
 def testCollectionQuantityOperations(self):
     """ Tests that Quantity collections behave correctly """
     # Tests that __getitem__ returns a unit
     s = [1, 2, 3, 4] * u.angstroms
     self.assertTrue(u.is_quantity(s[0]))
     for i, val in enumerate(s):
         self.assertTrue(u.is_quantity(val))
         self.assertEqual(val, (i+1) * u.angstroms)
     # Tests that __setitem__ fails when an incompatible type is added
     def fail(s): s[0] = 5
     self.assertRaises(AttributeError, lambda: fail(s))
     def fail(s): s[0] = 5 * u.joules
     self.assertRaises(TypeError, lambda: fail(s))
     def fail(s): s[0] /= 10 * u.meters
     self.assertRaises(AttributeError, lambda: fail(s))
     # Tests that __setitem__ converts to the unit of the container
     s[0] = 1 * u.nanometers
     self.assertEqual(s[0]._value, 10)
     # Tests standard unit conversions
     x = [1, 2, 3] * u.centimeters
     self.assertEqual(x / u.millimeters, [10, 20, 30])
     # Test the construction of a container in which each element is a
     # Quantity, passed to the Quantity constructor
     x = u.Quantity([1*u.angstrom, 2*u.nanometer, 3*u.angstrom])
     self.assertEqual(x._value, [1, 20, 3])
     self.assertEqual(x.unit, u.angstrom)
     x = u.Quantity((1, 2, 3))
     self.assertTrue(u.is_quantity(x))
     self.assertTrue(x.unit.is_dimensionless())
     x = u.Quantity(([1*u.angstrom, 2*u.nanometer, 3*u.angstrom],
                     [1*u.angstrom, 4*u.nanometer, 3*u.angstrom]))
     self.assertEqual(x._value, ([1, 20, 3], [1, 40, 3]))
     self.assertEqual(x.unit, u.angstrom)
     self.assertTrue(u.is_quantity(u.Quantity([])))
Пример #3
0
 def testNumpyDeepCopy(self):
     """ Check that deepcopy on numpy array does not strip units """
     x = u.Quantity(np.zeros((2, 3)), u.nanometer)
     y = copy.deepcopy(x)
     self.assertTrue(np.all(x == y))
     self.assertTrue(u.is_quantity(x))
     self.assertTrue(u.is_quantity(y))
Пример #4
0
    def getEffectiveEnergy(self, totalEnergy, groupEnergy):
        """Given the actual potential energy of the system, return the value of the effective potential.

        Parameters
        ----------
        totalEnergy : energy
            the actual potential energy of the whole system
        groupEnergy : energy
            the actual potential energy of the boosted force group

        Returns
        -------
        energy
            the value of the effective potential
        """
        alphaTotal = self.getAlphaTotal()
        ETotal = self.getETotal()
        alphaGroup = self.getAlphaGroup()
        EGroup = self.getEGroup()
        if not is_quantity(totalEnergy):
            totalEnergy = totalEnergy*kilojoules_per_mole # Assume kJ/mole
        if not is_quantity(groupEnergy):
            groupEnergy = groupEnergy*kilojoules_per_mole # Assume kJ/mole
        dE = 0.0*kilojoules_per_mole
        if (totalEnergy < ETotal):
            dE = dE + (ETotal-totalEnergy)*(ETotal-totalEnergy)/(alphaTotal+ETotal-totalEnergy)
        if (groupEnergy < EGroup):
            dE = dE + (EGroup-groupEnergy)*(EGroup-groupEnergy)/(alphaGroup+EGroup-groupEnergy)
        return totalEnergy+dE
Пример #5
0
 def testScalarQuantityConstructor(self):
     """ Tests creating a Quantity using the Quantity constructor """
     self.assertTrue(u.is_quantity(u.Quantity(5, u.centimeters)))
     self.assertTrue(u.is_quantity(u.Quantity(5, u.centimeters**-1)))
     x = u.Quantity(value=5.0, unit=100.0*u.meters)
     self.assertTrue(u.is_quantity(x))
     self.assertEqual(x, 500*u.meters)
Пример #6
0
 def testCollectionQuantities(self):
     """ Tests the use of collections as Quantity values """
     s = [1, 2, 3] * u.centimeters
     self.assertEqual(str(s), '[1, 2, 3] cm')
     self.assertTrue(u.is_quantity(s))
     s2 = s / u.millimeters
     self.assertEqual(s2, [10.0, 20.0, 30.0])
     self.assertEqual(s2, s.value_in_unit(u.millimeters))
     # Test 2-D list
     s = [[1, 2, 3], [4, 5, 6]]
     s *= u.centimeters
     self.assertTrue(u.is_quantity(s))
     s2 = s / u.millimeters
     self.assertEqual(s2, [[10.0, 20.0, 30.0], [40.0, 50.0, 60.0]])
     self.assertEqual(s.value_in_unit(u.millimeters), s2)
     # Test tuples
     s = (1, 2, 3) * u.centimeters
     self.assertTrue(u.is_quantity(s))
     self.assertEqual(str(s), '(1, 2, 3) cm')
     s2 = s / u.millimeters
     self.assertEqual(s2, (10, 20, 30))
     self.assertIsInstance(s2, tuple)
     self.assertEqual(s.value_in_unit(u.millimeters), s2)
     self.assertIsInstance(s.value_in_unit(u.millimeters), tuple)
     x = [1, 2, 3] * u.centimeters
     x *= u.meters
     self.assertEqual(x, [100, 200, 300] * u.centimeters**2)
Пример #7
0
    def writeModel(self, positions, unitCellDimensions=None, periodicBoxVectors=None):
        """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
        vectors (for an arbitrary triclinic box).  If neither is specified, the box vectors specified in the Topology will be
        used.  Regardless of the value specified, no dimensions will be written if the Topology does not represent a periodic system.

        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):
            raise ValueError('The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(nanometers)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        file = self._file

        # Update the header.

        self._modelCount += 1
        file.seek(8, os.SEEK_SET)
        file.write(struct.pack('<i', self._modelCount))
        file.seek(20, os.SEEK_SET)
        file.write(struct.pack('<i', self._firstStep+self._modelCount*self._interval))

        # Write the data.

        file.seek(0, os.SEEK_END)
        boxVectors = self._topology.getPeriodicBoxVectors()
        if boxVectors is not None:
            if periodicBoxVectors is not None:
                boxVectors = periodicBoxVectors
            elif unitCellDimensions is not None:
                if is_quantity(unitCellDimensions):
                    unitCellDimensions = unitCellDimensions.value_in_unit(nanometers)
                boxVectors = (Vec3(unitCellDimensions[0], 0, 0), Vec3(0, unitCellDimensions[1], 0), Vec3(0, 0, unitCellDimensions[2]))*nanometers
            (a_length, b_length, c_length, alpha, beta, gamma) = computeLengthsAndAngles(boxVectors)
            a_length = a_length * 10.  # computeLengthsAndAngles returns unitless nanometers, but need angstroms here.
            b_length = b_length * 10.  # computeLengthsAndAngles returns unitless nanometers, but need angstroms here.
            c_length = c_length * 10.  # computeLengthsAndAngles returns unitless nanometers, but need angstroms here.
            angle1 = math.sin(math.pi/2-gamma)
            angle2 = math.sin(math.pi/2-beta)
            angle3 = math.sin(math.pi/2-alpha)
            file.write(struct.pack('<i6di', 48, a_length, angle1, b_length, angle2, angle3, c_length, 48))
        length = struct.pack('<i', 4*len(positions))
        for i in range(3):
            file.write(length)
            data = array.array('f', (10*x[i] for x in positions))
            data.tofile(file)
            file.write(length)
Пример #8
0
 def testAngleQuantities(self):
     """ Tests angle measurements """
     self.assertEqual(1.0*u.radians / u.degrees, 180 / math.pi)
     self.assertTrue(u.is_quantity(1.0*u.radians))
     self.assertTrue(u.is_quantity(1.0*u.degrees))
     self.assertEqual((1.0*u.radians).in_units_of(u.degrees),
                      (180 / math.pi)*u.degrees)
     self.assertEqual(90*u.degrees/u.radians, math.pi/2)
     q = 90 * u.degrees + 0.3 * u.radians
     self.assertEqual(q._value, 90 + 180*0.3/math.pi)
     self.assertEqual(q.unit, u.degrees)
Пример #9
0
    def _writeModel(topology,
                    positions,
                    file=sys.stdout,
                    subset=None,
                    velocities=None):
        """Write out a model to a PDB file.

        Parameters
        ----------
        topology : Topology
            The Topology defining the model to write
        positions : list
            The list of atomic positions to write
        file : file=stdout
            A file to write the model to
        subset : list(int)=None
            If not None, only the selected atoms will be written
        """

        atoms = list(topology.atoms())
        if len(atoms) != len(positions):
            raise ValueError(
                'The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(nanometer)
        if velocities is not None:
            if len(atoms) != len(velocities):
                raise ValueError(
                    'The number of velocities must match the number of atoms')
            if is_quantity(velocities):
                velocities = velocities.value_in_unit(nanometer / picosecond)

        if subset is None:
            subset = list(range(len(atoms)))

        print('%i' % len(subset), file=file)
        for ii, i in enumerate(subset):
            atom = atoms[i]
            residue = atom.residue
            coords = positions[i]
            # writing atom symbol instead of name makes visualization easier
            if atom.element is not None:
                name = atom.element.symbol
            else:
                name = ''.join(i for i in atom.name if not i.isdigit())
            line = '%5i%5s%5s%5i%8.3f%8.3f%8.3f' % (
                (residue.index + 1) % 100000, residue.name[:5], name[:5],
                (atom.index + 1) % 100000, coords[0], coords[1], coords[2])
            if velocities is not None:
                vel = velocities[i]
                line += '%8.4f%8.4f%8.4f' % (vel[0], vel[1], vel[2])
            print(line, file=file)
Пример #10
0
    def runForClockTime(self,
                        time,
                        checkpointFile=None,
                        stateFile=None,
                        checkpointInterval=None):
        """Advance the simulation by integrating time steps until a fixed amount of clock time has elapsed.

        This is useful when you have a limited amount of computer time available, and want to run the longest simulation
        possible in that time.  This method will continue taking time steps until the specified clock time has elapsed,
        then return.  It also can automatically write out a checkpoint and/or state file before returning, so you can
        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.

        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
            simulation (and optionally at regular intervals before then) by
            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):
            time = time.value_in_unit(unit.hours)
        if unit.is_quantity(checkpointInterval):
            checkpointInterval = checkpointInterval.value_in_unit(unit.hours)
        endTime = datetime.now() + timedelta(hours=time)
        while (datetime.now() < endTime):
            if checkpointInterval is None:
                nextTime = endTime
            else:
                nextTime = datetime.now() + timedelta(hours=checkpointInterval)
                if nextTime > endTime:
                    nextTime = endTime
            self._simulate(endTime=nextTime)
            if checkpointFile is not None:
                self.saveCheckpoint(checkpointFile)
            if stateFile is not None:
                self.saveState(stateFile)
Пример #11
0
 def testDimensionless(self):
     """ Tests the properties of unit.dimensionless """
     x = 5 * u.dimensionless
     y = u.Quantity(5, u.dimensionless)
     self.assertTrue(u.is_quantity(x))
     self.assertTrue(u.is_quantity(y))
     self.assertNotEqual(x, 5)
     self.assertNotEqual(y, 5)
     self.assertEqual(x, y)
     self.assertEqual(x.value_in_unit_system(u.si_unit_system), 5)
     self.assertEqual(x.value_in_unit_system(u.cgs_unit_system), 5)
     self.assertEqual(x.value_in_unit_system(u.md_unit_system), 5)
     x = u.Quantity(1.0, u.dimensionless)
     y = u.Quantity(1.0, u.dimensionless)
     self.assertIsNot(x, y)
     self.assertEqual(x, y)
Пример #12
0
    def _initializeConstants(self, context_state):
        """Initialize a set of constants required for the reports

        Parameters
        ----------
        context_state : :class:`openmm.State`
            The current state of the context
        """
        system = context_state.system
        if self._temperature:
            # Compute the number of degrees of freedom.
            dof = 0
            for i in range(system.getNumParticles()):
                if system.getParticleMass(i) > 0 * unit.dalton:
                    dof += 3
            dof -= system.getNumConstraints()
            if any(
                    type(system.getForce(i)) == openmm.CMMotionRemover
                    for i in range(system.getNumForces())):
                dof -= 3
            self._dof = dof
        if self._density:
            if self._totalMass is None:
                # Compute the total system mass.
                self._totalMass = 0 * unit.dalton
                for i in range(system.getNumParticles()):
                    self._totalMass += system.getParticleMass(i)
            elif not unit.is_quantity(self._totalMass):
                self._totalMass = self._totalMass * unit.dalton
Пример #13
0
    def __init__(self, file, topology, dt, firstStep=0, interval=1):
        """Create a DCD file and write out the header.

        Parameters:
         - file (file) A file to write to
         - topology (Topology) 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._topology = topology
        self._firstStep = firstStep
        self._interval = interval
        self._modelCount = 0
        if is_quantity(dt):
            dt = dt.value_in_unit(picoseconds)
        dt /= 0.04888821
        boxFlag = 0
        if topology.getUnitCellDimensions() is not None:
            boxFlag = 1
        header = struct.pack('<i4c9if', 84, 'C', 'O', 'R', 'D', 0, firstStep,
                             interval, 0, 0, 0, 0, 0, 0, dt)
        header += struct.pack('<13i', boxFlag, 0, 0, 0, 0, 0, 0, 0, 0, 24, 84,
                              164, 2)
        header += struct.pack('<80s', 'Created by OpenMM')
        header += struct.pack(
            '<80s', 'Created ' + time.asctime(time.localtime(time.time())))
        header += struct.pack('<4i', 164, 4, len(list(topology.atoms())), 4)
        file.write(header)
Пример #14
0
    def __init__(self, file, topology, dt, firstStep=0, interval=1):
        """Create a DCD file and write out the header.

        Parameters:
         - file (file) A file to write to
         - topology (Topology) 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._topology = topology
        self._firstStep = firstStep
        self._interval = interval
        self._modelCount = 0
        if is_quantity(dt):
            dt = dt.value_in_unit(picoseconds)
        dt /= 0.04888821
        boxFlag = 0
        if topology.getUnitCellDimensions() is not None:
            boxFlag = 1
        header = struct.pack('<i4c9if', 84, b'C', b'O', b'R', b'D', 0, firstStep, interval, 0, 0, 0, 0, 0, 0, dt)
        header += struct.pack('<13i', boxFlag, 0, 0, 0, 0, 0, 0, 0, 0, 24, 84, 164, 2)
        header += struct.pack('<80s', b'Created by OpenMM')
        header += struct.pack('<80s', b'Created '+time.asctime(time.localtime(time.time())).encode('ascii'))
        header += struct.pack('<4i', 164, 4, len(list(topology.atoms())), 4)
        file.write(header)
Пример #15
0
    def _initializeConstants(self, simulation):
        """Initialize a set of constants required for the reports

        Parameters
        - simulation (Simulation) The simulation to generate a report for
        """
        system = simulation.system
        if self._temperature:
            # Compute the number of degrees of freedom.
            dof = 0
            for i in range(system.getNumParticles()):
                if system.getParticleMass(i) > 0*unit.dalton:
                    dof += 3
            dof -= system.getNumConstraints()
            if any(type(system.getForce(i)) == mm.CMMotionRemover for i in range(system.getNumForces())):
                dof -= 3
            self._dof = dof
        if self._density:
            if self._totalMass is None:
                # Compute the total system mass.
                self._totalMass = 0*unit.dalton
                for i in range(system.getNumParticles()):
                    self._totalMass += system.getParticleMass(i)
            elif not unit.is_quantity(self._totalMass):
                self._totalMass = self._totalMass*unit.dalton
Пример #16
0
    def writeModel(topology,
                   positions,
                   file=sys.stdout,
                   modelIndex=1,
                   keepIds=False):
        """Write out a model to a PDBx/mmCIF file.

        Parameters
        ----------
        topology : Topology
            The Topology defining the model to write
        positions : list
            The list of atomic positions to write
        file : file=stdout
            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):
            raise ValueError(
                'The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(angstroms)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        atomIndex = 1
        posIndex = 0
        for (chainIndex, chain) in enumerate(topology.chains()):
            if keepIds:
                chainName = chain.id
            else:
                chainName = chr(ord('A') + chainIndex % 26)
            residues = list(chain.residues())
            for (resIndex, res) in enumerate(residues):
                if keepIds:
                    resId = res.id
                else:
                    resId = resIndex + 1
                for atom in res.atoms():
                    coords = positions[posIndex]
                    if atom.element is not None:
                        symbol = atom.element.symbol
                    else:
                        symbol = '?'
                    line = "ATOM  %5d %-3s %-4s . %-4s %s ? %5s . %10.4f %10.4f %10.4f  0.0  0.0  ?  ?  ?  ?  ?  .  %5s %4s %s %4s %5d"
                    print(line %
                          (atomIndex, symbol, atom.name, res.name, chainName,
                           resId, coords[0], coords[1], coords[2], resId,
                           res.name, chainName, atom.name, modelIndex),
                          file=file)
                    posIndex += 1
                    atomIndex += 1
Пример #17
0
def _strip_optunit(thing, unit):
    """
    Strips optional units, converting to specified unit type. If no unit
    present, it just returns the number
    """
    if u.is_quantity(thing):
        return thing.value_in_unit(unit)
    return thing
Пример #18
0
def _strip_optunit(thing, unit):
    """
    Strips optional units, converting to specified unit type. If no unit
    present, it just returns the number
    """
    if u.is_quantity(thing):
        return thing.value_in_unit(unit)
    return thing
Пример #19
0
    def writeModel(topology, positions, file=sys.stdout, modelIndex=None):
        """Write out a model to a PDB file.

        Parameters:
         - topology (Topology) The Topology defining the model to write
         - positions (list) The list of atomic positions to write
         - file (file=stdout) 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
        """
        if len(list(topology.atoms())) != len(positions):
            raise ValueError(
                'The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(angstroms)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        atomIndex = 1
        posIndex = 0
        if modelIndex is not None:
            print >> file, "MODEL     %4d" % modelIndex
        for (chainIndex, chain) in enumerate(topology.chains()):
            chainName = chr(ord('A') + chainIndex % 26)
            residues = list(chain.residues())
            for (resIndex, res) in enumerate(residues):
                if len(res.name) > 3:
                    resName = res.name[:3]
                else:
                    resName = res.name
                for atom in res.atoms():
                    if len(atom.name) < 4 and atom.name[:1].isalpha() and (
                            atom.element is None
                            or len(atom.element.symbol) < 2):
                        atomName = ' ' + atom.name
                    elif len(atom.name) > 4:
                        atomName = atom.name[:4]
                    else:
                        atomName = atom.name
                    coords = positions[posIndex]
                    if atom.element is not None:
                        symbol = atom.element.symbol
                    else:
                        symbol = ' '
                    line = "ATOM  %5d %-4s %3s %s%4d    %s%s%s  1.00  0.00          %2s  " % (
                        atomIndex % 100000, atomName, resName, chainName,
                        (resIndex + 1) % 10000, _format_83(coords[0]),
                        _format_83(coords[1]), _format_83(coords[2]), symbol)
                    assert len(line) == 80, 'Fixed width overflow detected'
                    print >> file, line
                    posIndex += 1
                    atomIndex += 1
                if resIndex == len(residues) - 1:
                    print >> file, "TER   %5d      %3s %s%4d" % (
                        atomIndex, resName, chainName, resIndex + 1)
                    atomIndex += 1
        if modelIndex is not None:
            print >> file, "ENDMDL"
Пример #20
0
    def __init__(self,
                 file,
                 topology,
                 dt,
                 firstStep=0,
                 interval=1,
                 append=False):
        """Create a DCD file and write out the header, or open an existing file to append.

        Parameters
        ----------
        file : file
            A file to write to
        topology : Topology
            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
        append : bool=False
            If True, open an existing DCD file to append to.  If False, create a new file.
        """
        self._file = file
        self._topology = topology
        self._firstStep = firstStep
        self._interval = interval
        self._modelCount = 0
        if is_quantity(dt):
            dt = dt.value_in_unit(picoseconds)
        dt /= 0.04888821
        self._dt = dt
        boxFlag = 0
        if topology.getUnitCellDimensions() is not None:
            boxFlag = 1
        if append:
            file.seek(8, os.SEEK_SET)
            self._modelCount = struct.unpack('<i', file.read(4))[0]
            file.seek(268, os.SEEK_SET)
            numAtoms = struct.unpack('<i', file.read(4))[0]
            if numAtoms != len(list(topology.atoms())):
                raise ValueError(
                    'Cannot append to a DCD file that contains a different number of atoms'
                )
        else:
            header = struct.pack('<i4c9if', 84, b'C', b'O', b'R', b'D', 0,
                                 firstStep, interval, 0, 0, 0, 0, 0, 0, dt)
            header += struct.pack('<13i', boxFlag, 0, 0, 0, 0, 0, 0, 0, 0, 24,
                                  84, 164, 2)
            header += struct.pack('<80s', b'Created by OpenMM')
            header += struct.pack(
                '<80s', b'Created ' +
                time.asctime(time.localtime(time.time())).encode('ascii'))
            header += struct.pack('<4i', 164, 4, len(list(topology.atoms())),
                                  4)
            file.write(header)
Пример #21
0
    def runForClockTime(self, time, checkpointFile=None, stateFile=None, checkpointInterval=None):
        """Advance the simulation by integrating time steps until a fixed amount of clock time has elapsed.

        This is useful when you have a limited amount of computer time available, and want to run the longest simulation
        possible in that time.  This method will continue taking time steps until the specified clock time has elapsed,
        then return.  It also can automatically write out a checkpoint and/or state file before returning, so you can
        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.

        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
            simulation (and optionally at regular intervals before then) by
            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):
            time = time.value_in_unit(unit.hours)
        if unit.is_quantity(checkpointInterval):
            checkpointInterval = checkpointInterval.value_in_unit(unit.hours)
        endTime = datetime.now()+timedelta(hours=time)
        while (datetime.now() < endTime):
            if checkpointInterval is None:
                nextTime = endTime
            else:
                nextTime = datetime.now()+timedelta(hours=checkpointInterval)
                if nextTime > endTime:
                    nextTime = endTime
            self._simulate(endTime=nextTime)
            if checkpointFile is not None:
                self.saveCheckpoint(checkpointFile)
            if stateFile is not None:
                self.saveState(stateFile)
Пример #22
0
 def getEffectiveEnergy(self, energy):
     """Given the actual potential energy of the system, return the value of the effective potential."""
     alpha = self.getAlpha()
     E = self.getE()
     if not is_quantity(energy):
         energy = energy*kilojoules_per_mole # Assume kJ/mole
     if (energy > E):
         return energy
     return energy+(E-energy)*(E-energy)/(alpha+E-energy)
Пример #23
0
 def getEffectiveEnergy(self, energy):
     """Given the actual potential energy of the system, return the value of the effective potential."""
     alpha = self.getAlpha()
     E = self.getE()
     if not is_quantity(energy):
         energy = energy * kilojoules_per_mole  # Assume kJ/mole
     if (energy > E):
         return energy
     return energy + (E - energy) * (E - energy) / (alpha + E - energy)
Пример #24
0
 def testNumpyDivision(self):
     """ Tests that division of numpy Quantities works correctly """
     x = u.Quantity(np.asarray([1., 2.]), u.nanometers)
     y = u.Quantity(np.asarray([3., 4.]), u.picoseconds)
     xy = x / y
     self.assertTrue(u.is_quantity(xy))
     self.assertEqual(xy.unit, u.nanometers/u.picoseconds)
     self.assertEqual(xy[0].value_in_unit(u.nanometers/u.picoseconds), 1/3)
     self.assertEqual(xy[1].value_in_unit(u.nanometers/u.picoseconds), 0.5)
Пример #25
0
 def testNumpyFunctions(self):
     """ Tests various numpy attributes that they result in Quantities """
     a = u.Quantity(np.arange(10), u.seconds)
     self.assertEqual(a.max(), 9*u.seconds)
     self.assertEqual(a.min(), 0*u.seconds)
     self.assertEqual(a.mean(), 4.5*u.seconds)
     self.assertAlmostEqualQuantities(a.std(), 2.8722813232690143*u.seconds)
     b = a.reshape((5, 2))
     self.assertTrue(u.is_quantity(b))
Пример #26
0
    def setUnitCellDimensions(self, dimensions):
        """Set the dimensions of the crystallographic unit cell.

        This method is an alternative to setPeriodicBoxVectors() for the case of a rectangular box.  It sets
        the box vectors to be orthogonal to each other and to have the specified lengths."""
        if dimensions is None:
            self._periodicBoxVectors = None
        else:
            if is_quantity(dimensions):
                dimensions = dimensions.value_in_unit(nanometers)
            self._periodicBoxVectors = (Vec3(dimensions[0], 0, 0), Vec3(0, dimensions[1], 0), Vec3(0, 0, dimensions[2]))*nanometers
Пример #27
0
    def writeModel(topology, positions, file=sys.stdout, modelIndex=None):
        """Write out a model to a PDB file.

        Parameters:
         - topology (Topology) The Topology defining the model to write
         - positions (list) The list of atomic positions to write
         - file (file=stdout) 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
        """
        if len(list(topology.atoms())) != len(positions):
            raise ValueError('The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(angstroms)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        atomIndex = 1
        posIndex = 0
        if modelIndex is not None:
            print >>file, "MODEL     %4d" % modelIndex
        for (chainIndex, chain) in enumerate(topology.chains()):
            chainName = chr(ord('A')+chainIndex%26)
            residues = list(chain.residues())
            for (resIndex, res) in enumerate(residues):
                if len(res.name) > 3:
                    resName = res.name[:3]
                else:
                    resName = res.name
                for atom in res.atoms():
                    if len(atom.name) < 4 and atom.name[:1].isalpha() and (atom.element is None or len(atom.element.symbol) < 2):
                        atomName = ' '+atom.name
                    elif len(atom.name) > 4:
                        atomName = atom.name[:4]
                    else:
                        atomName = atom.name
                    coords = positions[posIndex]
                    if atom.element is not None:
                        symbol = atom.element.symbol
                    else:
                        symbol = ' '
                    line = "ATOM  %5d %-4s %3s %s%4d    %s%s%s  1.00  0.00          %2s  " % (
                        atomIndex%100000, atomName, resName, chainName,
                        (resIndex+1)%10000, _format_83(coords[0]),
                        _format_83(coords[1]), _format_83(coords[2]), symbol)
                    assert len(line) == 80, 'Fixed width overflow detected'
                    print >>file, line
                    posIndex += 1
                    atomIndex += 1
                if resIndex == len(residues)-1:
                    print >>file, "TER   %5d      %3s %s%4d" % (atomIndex, resName, chainName, resIndex+1)
                    atomIndex += 1
        if modelIndex is not None:
            print >>file, "ENDMDL"
Пример #28
0
def _standardized(quantity):
    """
    Returns the numerical value of a quantity in a unit of measurement compatible with the
    Molecular Dynamics unit system (mass in Da, distance in nm, time in ps, temperature in K,
    energy in kJ/mol, angle in rad).

    """
    if unit.is_quantity(quantity):
        return quantity.value_in_unit_system(unit.md_unit_system)
    else:
        return quantity
Пример #29
0
    def setUnitCellDimensions(self, dimensions):
        """Set the dimensions of the crystallographic unit cell.

        This method is an alternative to setPeriodicBoxVectors() for the case of a rectangular box.  It sets
        the box vectors to be orthogonal to each other and to have the specified lengths."""
        if dimensions is None:
            self._periodicBoxVectors = None
        else:
            if is_quantity(dimensions):
                dimensions = dimensions.value_in_unit(nanometers)
            self._periodicBoxVectors = (Vec3(dimensions[0], 0, 0), Vec3(0, dimensions[1], 0), Vec3(0, 0, dimensions[2]))*nanometers
Пример #30
0
 def setPeriodicBoxVectors(self, vectors):
     """Set the vectors defining the periodic box."""
     if vectors is not None:
         if not is_quantity(vectors[0][0]):
             vectors = vectors*nanometers
         if vectors[0][1] != 0*nanometers or vectors[0][2] != 0*nanometers:
             raise ValueError("First periodic box vector must be parallel to x.");
         if vectors[1][2] != 0*nanometers:
             raise ValueError("Second periodic box vector must be in the x-y plane.");
         if vectors[0][0] <= 0*nanometers or vectors[1][1] <= 0*nanometers or vectors[2][2] <= 0*nanometers or vectors[0][0] < 2*abs(vectors[1][0]) or vectors[0][0] < 2*abs(vectors[2][0]) or vectors[1][1] < 2*abs(vectors[2][1]):
             raise ValueError("Periodic box vectors must be in reduced form.");
     self._periodicBoxVectors = deepcopy(vectors)
Пример #31
0
    def writeModel(topology, positions, file=sys.stdout, modelIndex=1, keepIds=False):
        """Write out a model to a PDBx/mmCIF file.

        Parameters
        ----------
        topology : Topology
            The Topology defining the model to write
        positions : list
            The list of atomic positions to write
        file : file=stdout
            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):
            raise ValueError('The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(angstroms)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        atomIndex = 1
        posIndex = 0
        for (chainIndex, chain) in enumerate(topology.chains()):
            if keepIds:
                chainName = chain.id
            else:
                chainName = chr(ord('A')+chainIndex%26)
            residues = list(chain.residues())
            for (resIndex, res) in enumerate(residues):
                if keepIds:
                    resId = res.id
                    resIC = (res.insertionCode if len(res.insertionCode) > 0 else '.')
                else:
                    resId = resIndex + 1
                    resIC = '.'
                for atom in res.atoms():
                    coords = positions[posIndex]
                    if atom.element is not None:
                        symbol = atom.element.symbol
                    else:
                        symbol = '?'
                    line = "ATOM  %5d %-3s %-4s . %-4s %s ? %5s %s %10.4f %10.4f %10.4f  0.0  0.0  ?  ?  ?  ?  ?  .  %5s %4s %s %4s %5d"
                    print(line % (atomIndex, symbol, atom.name, res.name, chainName, resId, resIC, coords[0], coords[1], coords[2],
                                  resId, res.name, chainName, atom.name, modelIndex), file=file)
                    posIndex += 1
                    atomIndex += 1
Пример #32
0
 def setPeriodicBoxVectors(self, vectors):
     """Set the vectors defining the periodic box."""
     if vectors is not None:
         if not is_quantity(vectors[0][0]):
             vectors = vectors*nanometers
         if vectors[0][1] != 0*nanometers or vectors[0][2] != 0*nanometers:
             raise ValueError("First periodic box vector must be parallel to x.");
         if vectors[1][2] != 0*nanometers:
             raise ValueError("Second periodic box vector must be in the x-y plane.");
         if vectors[0][0] <= 0*nanometers or vectors[1][1] <= 0*nanometers or vectors[2][2] <= 0*nanometers or vectors[0][0] < 2*abs(vectors[1][0]) or vectors[0][0] < 2*abs(vectors[2][0]) or vectors[1][1] < 2*abs(vectors[2][1]):
             raise ValueError("Periodic box vectors must be in reduced form.");
     self._periodicBoxVectors = deepcopy(vectors)
Пример #33
0
    def __init__(self, topology, positions):
        """Create a new Modeller object

        Parameters:
         - topology (Topology) the initial Topology of the model
         - positions (list) the initial atomic positions
        """
        ## The Topology describing the structure of the system
        self.topology = topology
        if not is_quantity(positions):
            positions = positions*nanometer
        ## The list of atom positions
        self.positions = positions
Пример #34
0
 def testUnitMathModule(self):
     """ Tests the unit_math functions on Quantity objects """
     self.assertEqual(u.sqrt(1.0*u.kilogram*u.joule),
                      1.0*u.kilogram*u.meter/u.second)
     self.assertEqual(u.sqrt(1.0*u.kilogram*u.calorie),
                      math.sqrt(4.184)*u.kilogram*u.meter/u.second)
     self.assertEqual(u.sqrt(9), 3) # Test on a scalar
     self.assertEqual(u.sin(90*u.degrees), 1)
     self.assertEqual(u.sin(math.pi/2*u.radians), 1)
     self.assertEqual(u.sin(math.pi/2), 1)
     self.assertEqual(u.cos(180*u.degrees), -1)
     self.assertEqual(u.cos(math.pi*u.radians), -1)
     self.assertEqual(u.cos(math.pi), -1)
     self.assertAlmostEqual(u.tan(45*u.degrees), 1)
     self.assertAlmostEqual(u.tan(math.pi/4*u.radians), 1)
     self.assertAlmostEqual(u.tan(math.pi/4), 1)
     acos = u.acos(1.0)
     asin = u.asin(1.0)
     atan = u.atan(1.0)
     self.assertTrue(u.is_quantity(acos))
     self.assertTrue(u.is_quantity(asin))
     self.assertTrue(u.is_quantity(atan))
     self.assertEqual(acos.unit, u.radians)
     self.assertEqual(asin.unit, u.radians)
     self.assertEqual(atan.unit, u.radians)
     self.assertEqual(acos.value_in_unit(u.degrees), 0)
     self.assertEqual(acos / u.radians, 0)
     self.assertEqual(asin.value_in_unit(u.degrees), 90)
     self.assertEqual(asin / u.radians, math.pi/2)
     self.assertAlmostEqual(atan.value_in_unit(u.degrees), 45)
     self.assertAlmostEqual(atan / u.radians, math.pi/4)
     # Check some sequence maths
     seq = [1, 2, 3, 4] * u.meters
     self.assertEqual(u.sum(seq), 10*u.meters)
     self.assertEqual(u.dot(seq, seq), (1+4+9+16)*u.meters**2)
     self.assertEqual(u.norm(seq), math.sqrt(30)*u.meters)
Пример #35
0
 def getEffectiveEnergy(self, groupEnergy):
     """Given the actual group energy of the system, return the value of the effective potential.
     
     Parameters:
       - groupEnergy (energy): the actual potential energy of the boosted force group
     Returns: the value of the effective potential
     """
     alphaGroup = self.getAlphaGroup()
     EGroup = self.getEGroup()
     if not is_quantity(groupEnergy):
         groupEnergy = groupEnergy*kilojoules_per_mole # Assume kJ/mole
     dE = 0.0*kilojoules_per_mole
     if (groupEnergy < EGroup):
         dE = dE + (EGroup-groupEnergy)*(EGroup-groupEnergy)/(alphaGroup+EGroup-groupEnergy)
     return groupEnergy+dE
Пример #36
0
    def writeModel(topology, positions, file=sys.stdout):
        """Write out a model to a PDB file.

        Parameters
        ----------
        topology : Topology
            The Topology defining the model to write
        positions : list
            The list of atomic positions to write
        file : file=stdout
            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.  No guarantees are made about what will happen if they
            are not, and the output file could be invalid.
        extraParticleIdentifier : string=' '
            String to write in the element column of the ATOM records for atoms whose element is None (extra particles)
        """

        if len(list(topology.atoms())) != len(positions):
            raise ValueError(
                'The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(nanometer)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        print('%i' % len(positions), file=file)
        atomIndex = 1
        for (chainIndex, chain) in enumerate(topology.chains()):
            residues = list(chain.residues())
            for (resIndex, res) in enumerate(residues):
                resName = res.name[:4]
                resId = res.id
                for atom in res.atoms():
                    atomName = atom.name[:5]
                    coords = positions[atomIndex - 1]
                    line = '%5i%5s%5s%5i%8.3f%8.3f%8.3f' % (
                        int(resId), resName, atomName, atomIndex, coords[0],
                        coords[1], coords[2])
                    print(line, file=file)
                    atomIndex += 1
Пример #37
0
    def _writeHeader(time=None, file=sys.stdout):
        """Write out the header for a PDB file.

        Parameters
        ----------
        topology : Topology
            The Topology defining the molecular system being written
        file : file=stdout
            A file to write the file to
        """
        if time is None:
            time = 0.0
        elif is_quantity(time):
            time = time.value_in_unit(picosecond)

        print("written by openmm t = %.3f ps" % time, file=file)
Пример #38
0
def computeLengthsAndAngles(periodicBoxVectors):
    """Convert periodic box vectors to lengths and angles.

    Lengths are returned in nanometers and angles in radians.
    """
    if is_quantity(periodicBoxVectors):
        (a, b, c) = periodicBoxVectors.value_in_unit(nanometers)
    else:
        a, b, c = periodicBoxVectors
    a_length = norm(a)
    b_length = norm(b)
    c_length = norm(c)
    alpha = math.acos(dot(b, c) / (b_length * c_length))
    beta = math.acos(dot(c, a) / (c_length * a_length))
    gamma = math.acos(dot(a, b) / (a_length * b_length))
    return (a_length, b_length, c_length, alpha, beta, gamma)
Пример #39
0
 def getEffectiveEnergy(self, groupEnergy):
     """Given the actual group energy of the system, return the value of the effective potential.
     
     Parameters:
       - groupEnergy (energy): the actual potential energy of the boosted force group
     Returns: the value of the effective potential
     """
     alphaGroup = self.getAlphaGroup()
     EGroup = self.getEGroup()
     if not is_quantity(groupEnergy):
         groupEnergy = groupEnergy * kilojoules_per_mole  # Assume kJ/mole
     dE = 0.0 * kilojoules_per_mole
     if (groupEnergy < EGroup):
         dE = dE + (EGroup - groupEnergy) * (EGroup - groupEnergy) / (
             alphaGroup + EGroup - groupEnergy)
     return groupEnergy + dE
Пример #40
0
def computeLengthsAndAngles(periodicBoxVectors):
    """Convert periodic box vectors to lengths and angles.

    Lengths are returned in nanometers and angles in radians.
    """
    if is_quantity(periodicBoxVectors):
        (a, b, c) = periodicBoxVectors.value_in_unit(nanometers)
    else:
        a, b, c = periodicBoxVectors
    a_length = norm(a)
    b_length = norm(b)
    c_length = norm(c)
    alpha = math.acos(dot(b, c)/(b_length*c_length))
    beta = math.acos(dot(c, a)/(c_length*a_length))
    gamma = math.acos(dot(a, b)/(a_length*b_length))
    return (a_length, b_length, c_length, alpha, beta, gamma)
Пример #41
0
    def writeModel(self, positions, unitCellDimensions=None):
        """Write out a model to the DCD file.

        Parameters:
         - positions (list) The list of atomic positions to write
         - unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell.  If None, the dimensions specified in
           the Topology will be used.  Regardless of the value specified, no dimensions will be written if the Topology does not
           represent a periodic system.
        """
        if len(list(self._topology.atoms())) != len(positions):
            raise ValueError(
                'The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(nanometers)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        file = self._file

        # Update the header.

        self._modelCount += 1
        file.seek(8, os.SEEK_SET)
        file.write(struct.pack('<i', self._modelCount))
        file.seek(20, os.SEEK_SET)
        file.write(
            struct.pack('<i',
                        self._firstStep + self._modelCount * self._interval))

        # Write the data.

        file.seek(0, os.SEEK_END)
        boxSize = self._topology.getUnitCellDimensions()
        if boxSize is not None:
            if unitCellDimensions is not None:
                boxSize = unitCellDimensions
            size = boxSize.value_in_unit(angstroms)
            file.write(
                struct.pack('<i6di', 48, size[0], 0, size[1], 0, 0, size[2],
                            48))
        length = struct.pack('<i', 4 * len(positions))
        for i in range(3):
            file.write(length)
            data = array.array('f', (10 * x[i] for x in positions))
            data.tofile(file)
            file.write(length)
Пример #42
0
 def testQuantityMaths(self):
     """ Tests dimensional analysis & maths on and b/w Quantity objects """
     x = 1.3 * u.meters
     y = 75.2 * u.centimeters
     self.assertEqual((x + y) / u.meters, 2.052)
     self.assertEqual((x - y) / u.meters, 0.548)
     self.assertEqual(x / y, 1.3 / 0.752)
     self.assertEqual(x * y, 1.3 * 0.752 * u.meters**2)
     d1 = 2.0 * u.meters
     d2 = 2.0 * u.nanometers
     self.assertEqual(d1 + d2, (2 + 2e-9) * u.meters)
     self.assertAlmostEqual((d2 + d1 - (2e9 + 2) * u.nanometers)._value,
                            0,
                            places=6)
     self.assertEqual(d1 + d1, 4.0 * u.meters)
     self.assertEqual(d1 - d1, 0.0 * u.meters)
     self.assertEqual(d1 / d1, 1.0)
     self.assertEqual(d1 * u.meters, 2.0 * u.meters**2)
     self.assertEqual(u.kilograms * (d1 / u.seconds) * (d1 / u.seconds),
                      4 * u.kilograms * u.meters**2 / u.seconds**2)
     self.assertEqual(u.kilograms * (d1 / u.seconds)**2,
                      4 * u.kilograms * u.meters**2 / u.seconds**2)
     self.assertEqual(d1**3, 8.0 * u.meters**3)
     x = d1**(3 / 2)
     self.assertAlmostEqual(x._value, math.sqrt(2)**3)
     self.assertEqual(x.unit, u.meters**(3 / 2))
     self.assertAlmostEqual((d1**0.5)._value, math.sqrt(2))
     self.assertEqual((d1**0.5).unit, u.meters**0.5)
     comp = (3.0 + 4.0j) * u.meters
     self.assertTrue(u.is_quantity(comp))
     self.assertEqual(comp.unit, u.meters)
     self.assertEqual(str(comp), '(3+4j) m')
     self.assertEqual(comp + comp, (6.0 + 8.0j) * u.meters)
     self.assertEqual(comp - comp, 0 * u.meters)
     self.assertEqual(comp * comp, (3.0 + 4.0j)**2 * u.meters**2)
     self.assertAlmostEqual(comp / comp, 1)
     self.assertAlmostEqual(1.5 * u.nanometers / u.meters,
                            1.5e-9,
                            places=15)
     self.assertEqual((2.3 * u.meters)**2, 2.3**2 * u.meters**2)
     x = 4.3 * u.meters
     self.assertEqual(x / u.centimeters, 430)
     self.assertEqual(str(x / u.seconds), '4.3 m/s')
     self.assertEqual(str(8.4 / (4.2 * u.centimeters)), '2.0 /cm')
     x = 1.2 * u.meters
     self.assertEqual(x * 5, u.Quantity(6.0, u.meters))
Пример #43
0
def reducePeriodicBoxVectors(periodicBoxVectors):
    """ Reduces the representation of the PBC. periodicBoxVectors is expected to
    be an unpackable iterable of length-3 iterables
    """
    if is_quantity(periodicBoxVectors):
        a, b, c = periodicBoxVectors.value_in_unit(nanometers)
    else:
        a, b, c = periodicBoxVectors
    a = Vec3(*a)
    b = Vec3(*b)
    c = Vec3(*c)

    c = c - b * round(c[1] / b[1])
    c = c - a * round(c[0] / a[0])
    b = b - a * round(b[0] / a[0])

    return (a, b, c) * nanometers
Пример #44
0
def reducePeriodicBoxVectors(periodicBoxVectors):
    """ Reduces the representation of the PBC. periodicBoxVectors is expected to
    be an unpackable iterable of length-3 iterables
    """
    if is_quantity(periodicBoxVectors):
        a, b, c = periodicBoxVectors.value_in_unit(nanometers)
    else:
        a, b, c = periodicBoxVectors
    a = Vec3(*a)
    b = Vec3(*b)
    c = Vec3(*c)

    c = c - b*round(c[1]/b[1])
    c = c - a*round(c[0]/a[0])
    b = b - a*round(b[0]/a[0])

    return (a, b, c) * nanometers
Пример #45
0
    def __init__(self, file, topology, dt, firstStep=0, interval=1, append=False):
        """Create a DCD file and write out the header, or open an existing file to append.

        Parameters
        ----------
        file : file
            A file to write to
        topology : Topology
            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
        append : bool=False
            If True, open an existing DCD file to append to.  If False, create a new file.
        """
        self._file = file
        self._topology = topology
        self._firstStep = firstStep
        self._interval = interval
        self._modelCount = 0
        if is_quantity(dt):
            dt = dt.value_in_unit(picoseconds)
        dt /= 0.04888821
        self._dt = dt
        boxFlag = 0
        if topology.getUnitCellDimensions() is not None:
            boxFlag = 1
        if append:
            file.seek(8, os.SEEK_SET)
            self._modelCount = struct.unpack('<i', file.read(4))[0]
            file.seek(268, os.SEEK_SET)
            numAtoms = struct.unpack('<i', file.read(4))[0]
            if numAtoms != len(list(topology.atoms())):
                raise ValueError('Cannot append to a DCD file that contains a different number of atoms')
        else:
            header = struct.pack('<i4c9if', 84, b'C', b'O', b'R', b'D', 0, firstStep, interval, 0, 0, 0, 0, 0, 0, dt)
            header += struct.pack('<13i', boxFlag, 0, 0, 0, 0, 0, 0, 0, 0, 24, 84, 164, 2)
            header += struct.pack('<80s', b'Created by OpenMM')
            header += struct.pack('<80s', b'Created '+time.asctime(time.localtime(time.time())).encode('ascii'))
            header += struct.pack('<4i', 164, 4, len(list(topology.atoms())), 4)
            file.write(header)
Пример #46
0
    def getByMass(mass):
        """
        Get the element whose mass is CLOSEST to the requested mass. This method
        should not be used for repartitioned masses

        Parameters
        ----------
        mass : float or Quantity
            Mass of the atom to find the element for. Units assumed to be
            daltons if not specified

        Returns
        -------
        element : Element
            The element whose atomic mass is closest to the input mass
        """
        # Assume masses are in daltons if they are not units
        if is_quantity(mass):
            mass = mass.value_in_unit(daltons)
        if mass < 0:
            raise ValueError('Invalid Higgs field')
        # If this is our first time calling getByMass (or we added an element
        # since the last call), re-generate the ordered by-mass dict cache
        if Element._elements_by_mass is None:
            Element._elements_by_mass = OrderedDict()
            for elem in sorted(Element._elements_by_symbol.values(),
                               key=lambda x: x.mass):
                Element._elements_by_mass[elem.mass.value_in_unit(daltons)] = elem

        diff = mass
        best_guess = None

        for elemmass, element in _iteritems(Element._elements_by_mass):
            massdiff = abs(elemmass - mass)
            if massdiff < diff:
                best_guess = element
                diff = massdiff
            if elemmass > mass:
                # Elements are only getting heavier, so bail out early
                return best_guess

        # This really should only happen if we wanted ununoctium or something
        # bigger... won't really happen but still make sure we return an Element
        return best_guess
Пример #47
0
def _box_vectors_from_lengths_angles(a, b, c, alpha, beta, gamma):
    """
    This method takes the lengths and angles from a unit cell and creates unit
    cell vectors.

    Parameters:
        - a (unit, dimension length): Length of the first vector
        - b (unit, dimension length): Length of the second vector
        - c (unit, dimension length): Length of the third vector
        - alpha (float): Angle between b and c in degrees
        - beta (float): Angle between a and c in degrees
        - gamma (float): Angle between a and b in degrees

    Returns:
        Tuple of box vectors (as Vec3 instances)
    """
    if not (u.is_quantity(a) and u.is_quantity(b) and u.is_quantity(c)):
        raise TypeError('a, b, and c must be units of dimension length')
    if u.is_quantity(alpha): alpha = alpha.value_in_unit(u.degree)
    if u.is_quantity(beta): beta = beta.value_in_unit(u.degree)
    if u.is_quantity(gamma): gamma = gamma.value_in_unit(u.degree)
    a = a.value_in_unit(u.angstrom)
    b = b.value_in_unit(u.angstrom)
    c = c.value_in_unit(u.angstrom)

    if alpha <= 2 * pi and beta <= 2 * pi and gamma <= 2 * pi:
        raise ValueError('box angles must be given in degrees')

    alpha *= pi / 180
    beta *= pi / 180
    gamma *= pi / 180

    av = Vec3(a, 0.0, 0.0) * u.angstrom
    bx = b * cos(gamma)
    by = b * sin(gamma)
    bz = 0.0
    cx = c * cos(beta)
    cy = c * (cos(alpha) - cos(beta) * cos(gamma))
    cz = sqrt(c * c - cx * cx - cy * cy)
   
    # Make sure any components that are close to zero are set to zero exactly
    if abs(bx) < TINY: bx = 0.0
    if abs(by) < TINY: by = 0.0
    if abs(cx) < TINY: cx = 0.0
    if abs(cy) < TINY: cy = 0.0
    if abs(cz) < TINY: cz = 0.0

    bv = Vec3(bx, by, bz) * u.angstrom
    cv = Vec3(cx, cy, cz) * u.angstrom

    return (av, bv, cv)
Пример #48
0
    def getByMass(mass):
        """
        Get the element whose mass is CLOSEST to the requested mass. This method
        should not be used for repartitioned masses
        """
        # Assume masses are in daltons if they are not units
        if not is_quantity(mass):
            mass = mass * daltons
        diff = mass
        best_guess = None

        for key in Element._elements_by_atomic_number:
            element = Element._elements_by_atomic_number[key]
            massdiff = abs(element.mass - mass)
            if massdiff < diff:
                best_guess = element
                diff = massdiff

        return best_guess
Пример #49
0
 def testQuantityMaths(self):
     """ Tests dimensional analysis & maths on and b/w Quantity objects """
     x = 1.3 * u.meters
     y = 75.2 * u.centimeters
     self.assertEqual((x + y) / u.meters, 2.052)
     self.assertEqual((x - y) / u.meters, 0.548)
     self.assertEqual(x / y, 1.3 / 0.752)
     self.assertEqual(x * y, 1.3*0.752*u.meters**2)
     d1 = 2.0*u.meters
     d2 = 2.0*u.nanometers
     self.assertEqual(d1 + d2, (2+2e-9)*u.meters)
     self.assertAlmostEqual((d2+d1-(2e9+2)*u.nanometers)._value, 0, places=6)
     self.assertEqual(d1 + d1, 4.0*u.meters)
     self.assertEqual(d1 - d1, 0.0*u.meters)
     self.assertEqual(d1 / d1, 1.0)
     self.assertEqual(d1 * u.meters, 2.0*u.meters**2)
     self.assertEqual(u.kilograms*(d1/u.seconds)*(d1/u.seconds),
                      4*u.kilograms*u.meters**2/u.seconds**2)
     self.assertEqual(u.kilograms*(d1/u.seconds)**2,
                      4*u.kilograms*u.meters**2/u.seconds**2)
     self.assertEqual(d1**3, 8.0*u.meters**3)
     x = d1**(3/2)
     self.assertAlmostEqual(x._value, math.sqrt(2)**3)
     self.assertEqual(x.unit, u.meters**(3/2))
     self.assertAlmostEqual((d1**0.5)._value, math.sqrt(2))
     self.assertEqual((d1**0.5).unit, u.meters**0.5)
     comp = (3.0 + 4.0j) * u.meters
     self.assertTrue(u.is_quantity(comp))
     self.assertEqual(comp.unit, u.meters)
     self.assertEqual(str(comp), '(3+4j) m')
     self.assertEqual(comp + comp, (6.0 + 8.0j)*u.meters)
     self.assertEqual(comp - comp, 0*u.meters)
     self.assertEqual(comp * comp, (3.0 + 4.0j)**2 * u.meters**2)
     self.assertAlmostEqual(comp / comp, 1)
     self.assertAlmostEqual(1.5*u.nanometers / u.meters, 1.5e-9, places=15)
     self.assertEqual((2.3*u.meters)**2, 2.3**2*u.meters**2)
     x = 4.3 * u.meters
     self.assertEqual(x / u.centimeters, 430)
     self.assertEqual(str(x / u.seconds), '4.3 m/s')
     self.assertEqual(str(8.4 / (4.2*u.centimeters)), '2.0 /cm')
     x = 1.2 * u.meters
     self.assertEqual(x * 5, u.Quantity(6.0, u.meters))
Пример #50
0
    def writeModel(self, positions, unitCellDimensions=None):
        """Write out a model to the DCD file.

        Parameters:
         - positions (list) The list of atomic positions to write
         - unitCellDimensions (Vec3=None) The dimensions of the crystallographic unit cell.  If None, the dimensions specified in
           the Topology will be used.  Regardless of the value specified, no dimensions will be written if the Topology does not
           represent a periodic system.
        """
        if len(list(self._topology.atoms())) != len(positions):
            raise ValueError('The number of positions must match the number of atoms')
        if is_quantity(positions):
            positions = positions.value_in_unit(nanometers)
        if any(math.isnan(norm(pos)) for pos in positions):
            raise ValueError('Particle position is NaN')
        if any(math.isinf(norm(pos)) for pos in positions):
            raise ValueError('Particle position is infinite')
        file = self._file

        # Update the header.

        self._modelCount += 1
        file.seek(8, os.SEEK_SET)
        file.write(struct.pack('<i', self._modelCount))
        file.seek(20, os.SEEK_SET)
        file.write(struct.pack('<i', self._firstStep+self._modelCount*self._interval))

        # Write the data.

        file.seek(0, os.SEEK_END)
        boxSize = self._topology.getUnitCellDimensions()
        if boxSize is not None:
            if unitCellDimensions is not None:
                boxSize = unitCellDimensions
            size = boxSize.value_in_unit(angstroms)
            file.write(struct.pack('<i6di', 48, size[0], 0, size[1], 0, 0, size[2], 48))
        length = struct.pack('<i', 4*len(positions))
        for i in range(3):
            file.write(length)
            data = array.array('f', (10*x[i] for x in positions))
            data.tofile(file)
            file.write(length)