def to_string(self): """ Write all settings in this object to a format which can be provided to NAMD in an input file. """ my_string = "\n# Pressure Control\n" my_string += add_string_buffer("useGroupPressure", self.useGroupPressure) my_string += add_string_buffer("useFlexibleCell", self.useFlexibleCell) my_string += add_string_buffer("useConstantArea", self.useConstantArea) if self.langevinPistonTarget is not None: my_string += add_string_buffer("langevinPiston", "yes") assert self.langevinPistonTarget >= 0.0 my_string += add_string_buffer("langevinPistonTarget", str(self.langevinPistonTarget)) assert self.langevinPistonPeriod >= 0.0 langevinPistonPeriod_in_ps = unit.Quantity( self.langevinPistonPeriod, unit.picoseconds) langevinPistonPeriod_in_fs = \ langevinPistonPeriod_in_ps.value_in_unit(unit.femtoseconds) my_string += add_string_buffer("langevinPistonPeriod", str(langevinPistonPeriod_in_fs)) assert self.langevinPistonDecay >= 0.0 langevinPistonDecay_in_ps = unit.Quantity(self.langevinPistonDecay, unit.picoseconds) langevinPistonDecay_in_fs = langevinPistonDecay_in_ps.value_in_unit( unit.femtoseconds) my_string += add_string_buffer("langevinPistonDecay", str(langevinPistonDecay_in_fs)) assert self.langevinPistonTemp >= 0.0 my_string += add_string_buffer("langevinPistonTemp", str(self.langevinPistonTemp)) return my_string
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)
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)
def to_string(self): """ Write all settings in this object to a format which can be provided to NAMD in an input file. """ my_string = "\n# Integrator Parameters\n" assert self.timestep > 0.0 timestep_in_ps = unit.Quantity(self.timestep, unit.picoseconds) timestep_in_fs = timestep_in_ps.value_in_unit(unit.femtoseconds) my_string += add_string_buffer("timestep", str(timestep_in_fs)) assert self.nonbondedFreq > 0 my_string += add_string_buffer("nonbondedFreq", str(self.nonbondedFreq)) assert self.fullElectFrequency > 0 my_string += add_string_buffer("fullElectFrequency", str(self.fullElectFrequency)) assert self.stepspercycle > 0 my_string += add_string_buffer("stepspercycle", str(self.stepspercycle)) if self.langevinTemp is not None: my_string += add_string_buffer("langevin", "yes") assert self.langevinTemp >= 0.0 my_string += add_string_buffer("langevinTemp", str(self.langevinTemp)) assert self.langevinDamping >= 0.0 my_string += add_string_buffer("langevinDamping", str(self.langevinDamping)) my_string += add_string_buffer("langevinHydrogen", self.langevinHydrogen) return my_string
def write_extended_system_file(filename, box_vectors, origin_vector=None): """ Make a NAMD extended system file for this system """ step = "0" box_vectors_unitless = box_vectors.value_in_unit(unit.angstrom) ax = "{:.3f}".format(box_vectors_unitless[0][0]) ay = "{:.3f}".format(box_vectors_unitless[0][1]) az = "{:.3f}".format(box_vectors_unitless[0][2]) bx = "{:.3f}".format(box_vectors_unitless[1][0]) by = "{:.3f}".format(box_vectors_unitless[1][1]) bz = "{:.3f}".format(box_vectors_unitless[1][2]) cx = "{:.3f}".format(box_vectors_unitless[2][0]) cy = "{:.3f}".format(box_vectors_unitless[2][1]) cz = "{:.3f}".format(box_vectors_unitless[2][2]) if origin_vector is None: origin_vector = unit.Quantity([0.0, 0.0, 0.0], unit.angstrom) origin_unitless = origin_vector.value_in_unit(unit.angstrom) ox = "{:.3f}".format(origin_unitless[0]) oy = "{:.3f}".format(origin_unitless[1]) oz = "{:.3f}".format(origin_unitless[2]) box_list = [step, ax, ay, az, bx, by, bz, cx, cy, cz, ox, oy, oz] with open(filename, "w") as f: f.write("# NAMD extended system configuration output file\n") f.write("#$LABELS step a_x a_y a_z b_x b_y b_z c_x c_y c_z o_x o_y "\ "o_z\n") f.write(" ".join(box_list)) return
def test_box_vectors(): box_vector_q = unit.Quantity( [[64.0, 0.0, 0.0], [-21.0, 61.0, 0.0], [-21.0, -30.0, 53.0]], unit=unit.angstrom) box_vector = base.Box_vectors() box_vector.from_quantity(box_vector_q) assert np.isclose(box_vector.ax, 6.4) assert np.isclose(box_vector.ay, 0.0) assert np.isclose(box_vector.az, 0.0) assert np.isclose(box_vector.bx, -2.1) assert np.isclose(box_vector.by, 6.1) assert np.isclose(box_vector.bz, 0.0) assert np.isclose(box_vector.cx, -2.1) assert np.isclose(box_vector.cy, -3.0) assert np.isclose(box_vector.cz, 5.3) box_vector_q2 = box_vector.to_quantity() assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][0], 6.4) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][1], 0.0) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[0][2], 0.0) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][0], -2.1) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][1], 6.1) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[1][2], 0.0) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][0], -2.1) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][1], -3.0) assert np.isclose(box_vector_q2.value_in_unit(unit.nanometers)[2][2], 5.3)
def to_string(self): """ Write all settings in this object to a format which can be provided to NAMD in an input file. """ my_string = "\n# Periodic Boundary Conditions (PBC)\n" if self.PMEGridSpacing is not None: my_string += add_string_buffer("PME", "yes") assert self.PMEGridSpacing > 0.0 PMEGridSpacing_in_nm = unit.Quantity(self.PMEGridSpacing, unit.nanometers) PMEGridSpacing_in_A = PMEGridSpacing_in_nm.value_in_unit( unit.angstroms) my_string += add_string_buffer("PMEGridSpacing", str(PMEGridSpacing_in_A)) my_string += add_string_buffer("wrapWater", self.wrapWater) my_string += add_string_buffer("wrapAll", self.wrapAll) my_string += add_string_buffer("wrapNearest", self.wrapNearest) if self.cellBasisVector1 is not None: assert self.cellBasisVector2 is not None assert self.cellBasisVector3 is not None my_string += add_string_buffer("cellBasisVector1", self.cellBasisVector1) my_string += add_string_buffer("cellBasisVector2", self.cellBasisVector2) my_string += add_string_buffer("cellBasisVector3", self.cellBasisVector3) if self.cellOrigin is not None: cellOrig_str = ','.join(map(str, self.cellOrigin)) my_string += add_string_buffer("cellOrigin", cellOrig_str) else: assert self.cellBasisVector2 is None assert self.cellBasisVector3 is None return my_string
def energy_forces(as_numpy=False): """ Returns the energies and forces of the current conformation with the current Hamiltonian. Parameters ---------- as_numpy : bool, optional If True, the forces will be returned as a natom*3-length numpy array. If False (default), they will be returned as a natom*3-length Python list. Returns ------- energy, forces : EnergyTerms, array of float The energies returned in an EnergyTerms container, and the forces are returned as a natom*3-length list (or numpy array if requested). If sander.APPLY_UNITS is True, the energies will have the units kilocalories_per_mole applied, and forces will have the units kilocalories_per_mole/u.angstroms """ global APPLY_UNITS e, f = _pys.energy_forces() if as_numpy: f = _np.asarray(f) if APPLY_UNITS: return (_apply_units_to_struct(e, u.kilocalories_per_mole), u.Quantity(f, u.kilocalories_per_mole/u.angstroms)) return e, f
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))
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)
def testReduceUnit(self): """ Tests the reduce_unit functionality """ x = u.nanometer**2 / u.angstrom**2 self.assertEqual(str(x), 'nanometer**2/(angstrom**2)') self.assertTrue(x.is_dimensionless()) q = u.Quantity(2.0, x) self.assertEqual(str(q), '2.0 nm**2/(A**2)') self.assertEqual(q.reduce_unit(), 200)
def testMutableQuantityOperations(self): " Tests that mutable Quantity objects do not get unexpectedly changed " # This used to be a bug -- t and s._value were the same object, so # changing t would also change s silently s = [1, 2, 3, 4] * u.angstroms t = s / u.angstroms self.assertEqual(t, [1, 2, 3, 4]) self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) t[0] = 2 self.assertEqual(t, [2, 2, 3, 4]) if not utils.openmm_version or utils.openmm_version > (6, 2): self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) else: t[0] = 1 t = s.value_in_unit(u.angstroms) self.assertEqual(t, [1, 2, 3, 4]) self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) t[0] = 2 self.assertEqual(t, [2, 2, 3, 4]) self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.angstroms)) s = [1, 2, 3, 4] * u.nanometers self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.nanometers)) t = s.in_units_of(u.nanometers) self.assertEqual(s, t) t[0] = 1 * u.meters self.assertAlmostEqualQuantities( t, u.Quantity([1e9, 2, 3, 4], u.nanometers)) self.assertEqual(s, u.Quantity([1, 2, 3, 4], u.nanometers))
def test_get_box_vectors_from_pdb(): expected_box_vectors = unit.Quantity( [[40.142, 0.0, 0.0], [0.0, 40.329, 0.0], [0.0, 0.0, 32.472]], unit=unit.angstrom) test_pdb_filename = os.path.join( TEST_DIRECTORY, "../data/hostguest_files/hostguest_at0.5.pdb") result = base.get_box_vectors_from_pdb(test_pdb_filename) assert np.isclose(expected_box_vectors.value_in_unit(unit.angstroms), result.value_in_unit(unit.angstroms)).all()
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))
def to_quantity(self): """ Convert this object to a Quantity object that could be used in OpenMM or parmed. """ box_vector = unit.Quantity( [[self.ax, self.ay, self.az], [self.bx, self.by, self.bz], [self.cx, self.cy, self.cz]], unit=unit.nanometer) return box_vector
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([])))
def to_string(self): """ Write these settings to a string to be used as direct input into a NAMD input script. """ my_string = "\n# Simulation Parameters\n" if self.temperature is not None: assert self.temperature >= 0.0 my_string += add_string_buffer("temperature", str(self.temperature)) if self.watermodel: my_string += add_string_buffer("watermodel", self.watermodel) assert self.cutoff >= 0.0 cutoff_in_nm = unit.Quantity(self.cutoff, unit.nanometers) cutoff_in_A = cutoff_in_nm.value_in_unit(unit.angstroms) my_string += add_string_buffer("cutoff", str(cutoff_in_A)) my_string += add_string_buffer("switching", self.switching) assert self.margin >= 0.0 margin_in_nm = unit.Quantity(self.margin, unit.nanometers) margin_in_A = margin_in_nm.value_in_unit(unit.angstroms) my_string += add_string_buffer("margin", str(margin_in_A)) my_string += add_string_buffer("zeroMomentum", self.zeroMomentum) my_string += add_string_buffer("ljCorrection", self.ljCorrection) if self.rigidBonds: my_string += add_string_buffer("rigidBonds", self.rigidBonds) assert self.rigidTolerance > 0.0 my_string += add_string_buffer("rigidTolerance", str(self.rigidTolerance)) assert self.rigidIterations > 0 my_string += add_string_buffer("rigidIterations", str(self.rigidIterations)) my_string += add_string_buffer("useSettle", self.useSettle) if self.seed is not None and self.seed != 0: my_string += add_string_buffer("seed", str(self.seed)) my_string += add_string_buffer("firsttimestep", str(self.firsttimestep)) return my_string
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(abs(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))
def get_positions(as_numpy=False): """ Returns the current atomic positions loaded in the sander API Parameters ---------- as_numpy : bool, optional If True, the positions will be returned as a natom*3-length numpy array. If False (default), it will be returned as a natom*3-length Python list. Returns ------- positions : array of float The atomic positions as a list (or numpy array if requested). If sander.APPLY_UNITS is True, the return object will be a Quantity with the units chemistry.unit.angstroms """ global APPLY_UNITS positions = _pys.get_positions() if as_numpy: positions = _np.asarray(positions) if APPLY_UNITS: return u.Quantity(positions, u.angstrom) return positions
def testNumpyQuantity(self): """ Tests that numpy arrays can form Quantity values """ q = u.Quantity(np.array([1, 2, 3]), u.centimeters) self.assertTrue(u.is_quantity(q)) self.assertIsInstance(q._value, np.ndarray) self.assertTrue(np.all(q / u.millimeters == np.array([1, 2, 3]) * 10))
def testString(self): """ Tests unit handling with strings, which should be dimensionless """ s = u.Quantity("string") self.assertEqual(s.value_in_unit_system(u.md_unit_system), "string")
def testUnaryOperators(self): """ Tests unary operators on units """ self.assertEqual(-(2.3 * u.meters), u.Quantity(-2.3, u.meters)) self.assertEqual(-(2.3 * u.meters), -u.Quantity(2.3, u.meters)) self.assertEqual(+(2.3 * u.meters), u.Quantity(2.3, u.meters)) self.assertEqual(2.3 * u.meters, +u.Quantity(2.3, u.meters))
def __rmul__(self, other): """Multiply a Vec3 by a constant.""" if unit.is_unit(other): return unit.Quantity(self, other) return Vec3(other * self[0], other * self[1], other * self[2])