def testIAdd(self): """ Tests in-place addition of two Structure instances """ s1 = create_random_structure(parametrized=True) s2 = create_random_structure(parametrized=True) s1cp = copy(s1) s1 += s2 self._check_sum(s1, s1cp, s2)
def testAddParametrized(self): """ Tests addition of two parametrized Structure instances """ s1 = create_random_structure(parametrized=True) s2 = create_random_structure(parametrized=True) self.assertTrue(bool(s1.bond_types)) self.assertTrue(bool(s2.bond_types)) s = s1 + s2 self._check_sum(s, s1, s2)
def test_ub_select(self): """ Tests selection when "blank" Urey-Bradley terms present """ struct = utils.create_random_structure(parametrized=True) struct.urey_bradleys[0].type = pmd.NoUreyBradley s = struct[:] self.assertEqual(len(s.urey_bradleys), len(struct.urey_bradleys)) self.assertIs(s.urey_bradleys[0].type, pmd.NoUreyBradley)
def testBoxHandling(self): """ Tests that Structure.box is always the expected type """ s = create_random_structure(parametrized=False) self.assertIs(s.box, None) s.box = [10, 10, 10, 90, 90, 90] self.assertIsInstance(s.box, np.ndarray) self.assertEqual(s.box[0], 10) self.assertEqual(s.box[1], 10) self.assertEqual(s.box[2], 10) self.assertEqual(s.box[3], 90) self.assertEqual(s.box[4], 90) self.assertEqual(s.box[5], 90) s.box = np.array([10, 10, 10, 90, 90, 90], dtype=np.float64) self.assertIsInstance(s.box, np.ndarray) self.assertEqual(s.box[0], 10) self.assertEqual(s.box[1], 10) self.assertEqual(s.box[2], 10) self.assertEqual(s.box[3], 90) self.assertEqual(s.box[4], 90) self.assertEqual(s.box[5], 90) s.box = [10*u.angstroms, 10*u.angstroms, 10*u.angstroms, 90*u.degrees, 90*u.degrees, 90*u.degrees] self.assertIsInstance(s.box, np.ndarray) self.assertEqual(s.box[0], 10) self.assertEqual(s.box[1], 10) self.assertEqual(s.box[2], 10) self.assertEqual(s.box[3], 90) self.assertEqual(s.box[4], 90) self.assertEqual(s.box[5], 90)
def testMultiplyNotParametrized(self): """ Tests replicating a non-parametrized Structure instance """ s1 = create_random_structure(parametrized=False) multfac = random.randint(2, 5) s2 = s1 * multfac self.assertIsNot(s1, s2) self.assertEqual(len(s2.atoms), len(s1.atoms) * multfac) self._check_mult(s2, s1, multfac)
def test_bond_serialization(self): """ Tests the serialization of Bond """ struct = utils.create_random_structure(True) bond = struct.bonds[0] fobj = BytesIO() pickle.dump(bond, fobj) fobj.seek(0) unpickled = pickle.load(fobj) self.assertIsInstance(bond, pmd.Bond)
def testCoordinates(self): """ Tests coordinate handling in Structure """ s = create_random_structure(parametrized=False) self.assertIs(s.coordinates, None) natom = len(s.atoms) # Make sure coordinates will be generated from Atom.xx, xy, xz if not # otherwise generated xyz = np.random.random((natom, 3)) for a, x in zip(s.atoms, xyz): a.xx, a.xy, a.xz = x self.assertEqual(s.coordinates.shape, (natom, 3)) np.testing.assert_equal(s.coordinates, xyz[:,:]) self.assertIs(s._coordinates, None) # Now set multiple frames xyz = np.random.random((5, natom, 3)).tolist() s.coordinates = xyz self.assertIsInstance(s.coordinates, np.ndarray) self.assertEqual(s.coordinates.shape, (natom, 3)) for a, x in zip(s.atoms, xyz[0]): self.assertEqual(a.xx, x[0]) self.assertEqual(a.xy, x[1]) self.assertEqual(a.xz, x[2]) np.testing.assert_equal(s.get_coordinates('all'), xyz) for i in range(5): np.testing.assert_equal(s.get_coordinates(i), xyz[i]) # Now try setting with units xyz = u.Quantity(np.random.random((3, natom, 3)), u.nanometers) s.coordinates = xyz self.assertIsInstance(s.coordinates, np.ndarray) self.assertEqual(s.coordinates.shape, (natom, 3)) for a, x in zip(s.atoms, xyz[0]._value): self.assertEqual(a.xx, x[0]*10) self.assertEqual(a.xy, x[1]*10) self.assertEqual(a.xz, x[2]*10) # Now check setting None s.coordinates = None for a in s.atoms: self.assertFalse(hasattr(a, 'xx')) self.assertFalse(hasattr(a, 'xy')) self.assertFalse(hasattr(a, 'xz')) self.assertIs(s.coordinates, None) # Now check setting flattened arrays s.coordinates = np.random.random((natom, 3)) self.assertEqual(s.coordinates.shape, (natom, 3)) s.coordinates = np.random.random(natom*3) self.assertEqual(s.coordinates.shape, (natom, 3)) s.coordinates = np.random.random(natom*3*10) self.assertEqual(s.coordinates.shape, (natom, 3)) # Now check other iterables old_crds = s.coordinates s.coordinates = (random.random() for i in range(3*len(s.atoms))) self.assertEqual(s.coordinates.shape, (natom, 3)) diff = (old_crds - s.coordinates).ravel()**2 self.assertGreater(diff.sum(), 0.01)
def test_structure_serialization(self): """ Tests the serialization of Structure """ structure = utils.create_random_structure(parametrized=True) # Make sure we copy over exclusions structure.atoms[0].exclude(structure.atoms[10]) fobj = BytesIO() pickle.dump(structure, fobj) fobj.seek(0) unpickled = pickle.load(fobj) self._compare_structures(unpickled, structure)
def testLoadDataFrameStructureView(self): """ Tests the load_dataframe method on StructureView """ struct = create_random_structure(parametrized=True).view[:10, :] charges = [a.charge for a in struct.atoms] self.assertTrue(not all(x == 0 for x in charges)) df = struct.to_dataframe() # First zero-out all of the charges struct.load_dataframe(dict(charge=[0 for a in struct.atoms])) self.assertTrue(all(a.charge == 0 for a in struct.atoms)) # Now re-load the dataframe to restore the original charges struct.load_dataframe(df) self.assertTrue( all(a.charge == x for a, x in zip(struct.atoms, charges))) # Change the first atomic properties of *everything* now to # make sure that they all get updated df_orig = df.copy() df.loc[0, 'number'] = 1 df.loc[0, 'name'] = 'HAHA' df.loc[0, 'type'] = 'FUNY' df.loc[0, 'atomic_number'] = 92 # uranium df.loc[0, 'charge'] *= 2 df.loc[0, 'mass'] *= 10 df.loc[0, 'nb_idx'] = 10 df.loc[0, 'solvent_radius'] *= 2 df.loc[0, 'screen'] = 0.5 df.loc[0, 'occupancy'] = 0.1 df.loc[0, 'bfactor'] = 0.5 df.loc[0, 'altloc'] = 'X' df.loc[0, 'tree'] = 'BLU' df.loc[0, 'join'] = 1.0 df.loc[0, 'irotat'] = 2.0 df.loc[0, 'rmin'] *= 2 df.loc[0, 'epsilon'] /= 2 struct.load_dataframe(df) atom = struct.atoms[0] self.assertEqual(atom.number, 1) self.assertEqual(atom.name, 'HAHA') self.assertEqual(atom.type, 'FUNY') self.assertEqual(atom.atomic_number, 92) self.assertEqual(atom.charge, charges[0] * 2) self.assertEqual(atom.mass, 10 * df_orig.loc[0, 'mass']) self.assertEqual(atom.nb_idx, 10) self.assertEqual(atom.solvent_radius, 2 * df_orig.loc[0, 'solvent_radius']) self.assertEqual(atom.screen, 0.5) self.assertEqual(atom.occupancy, 0.1) self.assertEqual(atom.bfactor, 0.5) self.assertEqual(atom.altloc, 'X') self.assertEqual(atom.tree, 'BLU') self.assertEqual(atom.join, 1.0) self.assertEqual(atom.irotat, 2.0) self.assertEqual(atom.rmin, 2 * df_orig.loc[0, 'rmin']) self.assertEqual(atom.epsilon, df_orig.loc[0, 'epsilon'] / 2)
def test_residue_serialization(self): """ Tests the serialization of Residue """ struct = utils.create_random_structure(parametrized=True) res = struct.residues[0] fobj = BytesIO() pickle.dump(res, fobj) fobj.seek(0) unpickled = pickle.load(fobj) self.assertEqual(len(res.atoms), len(unpickled.atoms)) for a1, a2 in zip(res, unpickled): self._equal_atoms(a1, a2)
def test_bondtype_serialization(self): """ Tests the serialization of BondType """ struct = utils.create_random_structure(True) bt = struct.bond_types[0] fobj = BytesIO() pickle.dump(bt, fobj) fobj.seek(0) unpickled = pickle.load(fobj) self.assertEqual(unpickled, bt) self.assertIsNot(unpickled, bt)
def test_structure_view_coordinates(self): """ Tests handling of coordinates on a StructureView """ s = utils.create_random_structure(parametrized=True) self.assertIs(s.view[:len(s.atoms)//2].coordinates, None) self.assertIs(s.view[:len(s.atoms)//2].positions, None) # Make sure it's an even number of atoms if len(s.atoms) % 2 == 1: s.strip('@1') x = np.random.rand(len(s.atoms)//2, 3) s.coordinates = np.vstack([x.flatten(), x.flatten()]) np.testing.assert_equal(s.view[:len(s.atoms)//2].coordinates, x) np.testing.assert_equal( s.view[:len(s.atoms)//2].positions.value_in_unit(u.angstroms), x)
def testLoadDataFrameStructureView(self): """ Tests the load_dataframe method on StructureView """ struct = create_random_structure(parametrized=True).view[:10,:] charges = [a.charge for a in struct.atoms] self.assertTrue(not all(x == 0 for x in charges)) df = struct.to_dataframe() # First zero-out all of the charges struct.load_dataframe(dict(charge=[0 for a in struct.atoms])) self.assertTrue(all(a.charge == 0 for a in struct.atoms)) # Now re-load the dataframe to restore the original charges struct.load_dataframe(df) self.assertTrue(all(a.charge == x for a, x in zip(struct.atoms, charges))) # Change the first atomic properties of *everything* now to # make sure that they all get updated df_orig = df.copy() df.loc[0, 'number'] = 1 df.loc[0, 'name'] = 'HAHA' df.loc[0, 'type'] = 'FUNY' df.loc[0, 'atomic_number'] = 92 # uranium df.loc[0, 'charge'] *= 2 df.loc[0, 'mass'] *= 10 df.loc[0, 'nb_idx'] = 10 df.loc[0, 'radii'] *= 2 df.loc[0, 'screen'] = 0.5 df.loc[0, 'occupancy'] = 0.1 df.loc[0, 'bfactor'] = 0.5 df.loc[0, 'altloc'] = 'X' df.loc[0, 'tree'] = 'BLU' df.loc[0, 'join'] = 1.0 df.loc[0, 'irotat'] = 2.0 df.loc[0, 'rmin'] *= 2 df.loc[0, 'epsilon'] /= 2 struct.load_dataframe(df) atom = struct.atoms[0] self.assertEqual(atom.number, 1) self.assertEqual(atom.name, 'HAHA') self.assertEqual(atom.type, 'FUNY') self.assertEqual(atom.atomic_number, 92) self.assertEqual(atom.charge, charges[0]*2) self.assertEqual(atom.mass, 10*df_orig.loc[0, 'mass']) self.assertEqual(atom.nb_idx, 10) self.assertEqual(atom.radii, 2*df_orig.loc[0, 'radii']) self.assertEqual(atom.screen, 0.5) self.assertEqual(atom.occupancy, 0.1) self.assertEqual(atom.bfactor, 0.5) self.assertEqual(atom.altloc, 'X') self.assertEqual(atom.tree, 'BLU') self.assertEqual(atom.join, 1.0) self.assertEqual(atom.irotat, 2.0) self.assertEqual(atom.rmin, 2*df_orig.loc[0, 'rmin']) self.assertEqual(atom.epsilon, df_orig.loc[0, 'epsilon']/2)
def testAddNoValence(self): """ Tests addition of two minimal Structure instances """ s1 = create_random_structure(parametrized=False, novalence=True) s2 = create_random_structure(parametrized=False, novalence=True) s = s1 + s2 self.assertIsNot(s, s1) self.assertIsNot(s, s2) # Make sure that s is really the sum of s1 and s2 self.assertEqual(len(s.atoms), len(s1.atoms) + len(s2.atoms)) self.assertEqual(len(s.residues), len(s1.residues) + len(s2.residues)) def cmp_atoms(a1, a2): self.assertIsNot(a1, a2) self.assertEqual(a1.name, a2.name) self.assertEqual(a1.type, a2.type) self.assertEqual(a1.atom_type, a2.atom_type) self.assertEqual(a1.mass, a2.mass) self.assertEqual(a1.charge, a2.charge) self.assertEqual(a1.atomic_number, a2.atomic_number) self.assertEqual(a1.radii, a2.radii) self.assertEqual(a1.screen, a2.screen) self.assertEqual(a1.residue.name, a2.residue.name) self.assertEqual(a1.residue.insertion_code, a2.residue.insertion_code) self.assertEqual(len(a1.bond_partners), len(a2.bond_partners)) self.assertEqual(len(a1.angle_partners), len(a2.angle_partners)) self.assertEqual(len(a1.dihedral_partners), len(a2.dihedral_partners)) self.assertEqual(len(a1.bonds), len(a2.bonds)) self.assertEqual(len(a1.angles), len(a2.angles)) self.assertEqual(len(a1.dihedrals), len(a2.dihedrals)) self.assertEqual(len(a1.impropers), len(a2.impropers)) for a1, a2 in zip(s.atoms, s1.atoms + s2.atoms): cmp_atoms(a1, a2) for r1, r2 in zip(s.residues, s1.residues + s2.residues): self.assertEqual(len(r1), len(r2)) self.assertEqual(r1.name, r2.name) self.assertEqual(r1.chain, r2.chain) self.assertEqual(r1.insertion_code, r2.insertion_code)
def test_residue_serialization(self): """ Tests the serialization of Residue """ struct = utils.create_random_structure(parametrized=True) res = struct.residues[0] fobj = BytesIO() pickle.dump(res, fobj) fobj.seek(0) unpickled = pickle.load(fobj) self.assertEqual(len(res.atoms), len(unpickled.atoms)) for a1, a2 in zip(res, unpickled): self._equal_atoms(a1, a2) self.assertIs(a1.residue, res) self.assertIs(a2.residue, unpickled)
def testBadBoxHandling(self): """ Tests error handling when Structure.box is improperly assigned """ s = create_random_structure(parametrized=True) def wrong_number_of_args(): s.box = [0, 1, 2, 3, 4] def wrong_number_of_args2(): s.box = [0, 1, 2, 3, 4, 5, 6] self.assertRaises(ValueError, wrong_number_of_args) self.assertRaises(ValueError, wrong_number_of_args2) try: wrong_number_of_args() except ValueError as err: self.assertIn('6', str(err)) # Try wrong units for i in range(6): box = [10, 10, 10, 90, 90, 90] box[i] *= u.liters def func(): s.box = box self.assertRaises(TypeError, func)
def testAddToEmptyStructure(self): """ Tests addition to empty Structure """ s1 = create_random_structure(parametrized=True) s2 = structure.Structure() s2 += s1 self._check_sum(s2, structure.Structure(), s1)
def testAddNotParametrized(self): """ Tests addition of two non-parametrized Structure instances """ s1 = create_random_structure(parametrized=False) s2 = create_random_structure(parametrized=False) self.assertFalse(bool(s1.bond_types)) self.assertFalse(bool(s2.bond_types)) s = s1 + s2 self.assertIsNot(s, s1) self.assertIsNot(s, s2) # Make sure that s is really the sum of s1 and s2 self.assertEqual(len(s.atoms), len(s1.atoms) + len(s2.atoms)) self.assertEqual(len(s.residues), len(s1.residues) + len(s2.residues)) def cmp_atoms(a1, a2): self.assertIsNot(a1, a2) self.assertEqual(a1.name, a2.name) self.assertEqual(a1.type, a2.type) self.assertEqual(a1.atom_type, a2.atom_type) self.assertEqual(a1.mass, a2.mass) self.assertEqual(a1.charge, a2.charge) self.assertEqual(a1.atomic_number, a2.atomic_number) self.assertEqual(a1.radii, a2.radii) self.assertEqual(a1.screen, a2.screen) self.assertEqual(a1.residue.name, a2.residue.name) self.assertEqual(a1.residue.insertion_code, a2.residue.insertion_code) self.assertEqual(len(a1.bond_partners), len(a2.bond_partners)) self.assertEqual(len(a1.angle_partners), len(a2.angle_partners)) self.assertEqual(len(a1.dihedral_partners), len(a2.dihedral_partners)) self.assertEqual(len(a1.bonds), len(a2.bonds)) self.assertEqual(len(a1.angles), len(a2.angles)) self.assertEqual(len(a1.dihedrals), len(a2.dihedrals)) self.assertEqual(len(a1.impropers), len(a2.impropers)) for a1, a2 in zip(s.atoms, s1.atoms + s2.atoms): cmp_atoms(a1, a2) for r1, r2 in zip(s.residues, s1.residues + s2.residues): self.assertEqual(len(r1), len(r2)) self.assertEqual(r1.name, r2.name) self.assertEqual(r1.chain, r2.chain) self.assertEqual(r1.insertion_code, r2.insertion_code) self.assertEqual(len(s.bonds), len(s1.bonds)+len(s2.bonds)) self.assertEqual(len(s.angles), len(s1.angles)+len(s2.angles)) self.assertEqual(len(s.dihedrals), len(s1.dihedrals)+len(s2.dihedrals)) self.assertEqual(len(s.urey_bradleys), len(s1.urey_bradleys)+len(s2.urey_bradleys)) self.assertEqual(len(s.impropers), len(s1.impropers)+len(s2.impropers)) self.assertEqual(len(s.rb_torsions), len(s1.rb_torsions)+len(s2.rb_torsions)) self.assertEqual(len(s.cmaps), len(s1.cmaps)+len(s2.cmaps)) self.assertEqual(len(s.stretch_bends), len(s1.stretch_bends)+len(s2.stretch_bends)) self.assertEqual(len(s.trigonal_angles), len(s1.trigonal_angles)+len(s2.trigonal_angles)) self.assertEqual(len(s.out_of_plane_bends), len(s1.out_of_plane_bends)+len(s2.out_of_plane_bends)) self.assertEqual(len(s.torsion_torsions), len(s1.torsion_torsions)+len(s2.torsion_torsions)) self.assertEqual(len(s.acceptors), len(s1.acceptors)+len(s2.acceptors)) self.assertEqual(len(s.donors), len(s1.donors)+len(s2.donors)) self.assertEqual(len(s.pi_torsions), len(s1.pi_torsions)+len(s2.pi_torsions)) self.assertEqual(len(s.chiral_frames), len(s1.chiral_frames)+len(s2.chiral_frames)) self.assertEqual(len(s.multipole_frames), len(s1.multipole_frames)+len(s2.multipole_frames)) self.assertEqual(len(s.groups), len(s1.groups)+len(s2.groups)) self.assertEqual(len(s.adjusts), len(s1.adjusts)+len(s2.adjusts)) self.assertEqual(len(s.adjust_types), len(s1.adjust_types)+len(s2.adjust_types)) # Check all valence terms def chk_valence(val1, val2): self.assertIs(type(val1[0]), type(val2[0])) self.assertEqual(len(val1), len(val2)) attrs = [attr for attr in dir(val1[0]) if attr.startswith('atom')] for v1, v2 in zip(val1, val2): at1 = [getattr(v1, attr) for attr in attrs] at2 = [getattr(v2, attr) for attr in attrs] self.assertIsNot(v1, v2) for a1, a2 in zip(at1, at2): cmp_atoms(a1, a2) chk_valence(s.bonds, s1.bonds+s2.bonds) chk_valence(s.angles, s1.angles+s2.angles) chk_valence(s.dihedrals, s1.dihedrals+s2.dihedrals) chk_valence(s.rb_torsions, s1.rb_torsions+s2.rb_torsions) chk_valence(s.urey_bradleys, s1.urey_bradleys+s2.urey_bradleys) chk_valence(s.impropers, s1.impropers+s2.impropers) chk_valence(s.cmaps, s1.cmaps+s2.cmaps) chk_valence(s.trigonal_angles, s1.trigonal_angles+s2.trigonal_angles) chk_valence(s.out_of_plane_bends, s1.out_of_plane_bends+s2.out_of_plane_bends) chk_valence(s.pi_torsions, s1.pi_torsions+s2.pi_torsions) chk_valence(s.torsion_torsions, s1.torsion_torsions+s2.torsion_torsions) chk_valence(s.stretch_bends, s1.stretch_bends+s2.stretch_bends) chk_valence(s.chiral_frames, s1.chiral_frames+s2.chiral_frames) chk_valence(s.multipole_frames, s1.multipole_frames+s2.multipole_frames) chk_valence(s.donors, s1.donors+s2.donors) chk_valence(s.acceptors, s1.acceptors+s2.acceptors) chk_valence(s.groups, s1.groups+s2.groups)