def test_tracking_atom_refernces(): from pyxmolpp2 import DeadFrameAccessError frame = make_polyglycine([("A", 1)]) last_atom = frame.atoms[0] # store reference to Atom in python variable frame = None # release the reference to Frame and cause cascade deletion of everything with pytest.raises(DeadFrameAccessError): last_atom.name = "A" # access to destroyed elements is prohibited, exception raised
def test_torsional_angly_factory(): import numpy as np from pyxmolpp2 import Rotation, Translation, XYZ, Degrees, Frame, calc_alignment, TorsionAngleFactory, TorsionAngle frame = make_polyglycine([('A', 10)]) for res in frame.residues: omega = TorsionAngleFactory.omega(res) phi = TorsionAngleFactory.phi(res) psi = TorsionAngleFactory.psi(res) if res.id == 1: assert omega is None assert phi is None else: assert omega is not None assert phi is not None if res.id == 10: assert psi is None else: assert psi is not None assert TorsionAngleFactory.chi1(res) is None assert TorsionAngleFactory.chi2(res) is None assert TorsionAngleFactory.chi3(res) is None assert TorsionAngleFactory.chi4(res) is None assert TorsionAngleFactory.chi5(res) is None
def test_tracking_chain_refernces(): frame = make_polyglycine([("A", 1)]) last_chain = frame.molecules[ 0] # store reference to Atom in python variable frame = None # release the reference to Frame and cause cascade deletion of everything with pytest.raises(Exception): last_chain.name = "A" # access to destroyed elements is prohibited, exception raised
def test_selection_exceptions(): from pyxmolpp2 import DeadFrameAccessError zombie_selection = make_polyglycine([("A", 1)]).molecules with pytest.raises(DeadFrameAccessError): for a in zombie_selection: pass zombie_selection = make_polyglycine([("A", 1)]).residues with pytest.raises(DeadFrameAccessError): for a in zombie_selection: pass zombie_selection = make_polyglycine([("A", 1)]).molecules with pytest.raises(DeadFrameAccessError): for a in zombie_selection: pass
def test_iterable(): frame = make_polyglycine([("A", 10)]) assert len(list(frame.molecules)) == frame.molecules.size assert len(list(frame.residues)) == frame.residues.size assert len(list(frame.atoms)) == frame.atoms.size assert len(list(frame.coords)) == frame.atoms.size
def test_frame_buf_exceptions(): frame = make_polyglycine([("A", 20)]) with pytest.raises(TypeError): frame.to_pdb([]) with pytest.raises(TypeError): frame.to_pdb({})
def test_selection_strides(): frame = make_polyglycine([("A", 2)]) assert frame.atoms.size == 2 * 7 assert frame.atoms[::2].size == 7 # assert frame.atoms[::-2].size == 7 # todo: enable assert frame.atoms[:10].size == 10 assert frame.atoms[:-10].size == 4 assert frame.atoms[-10:].size == 10
def test_bad_selection_construction_from_list(): from pyxmolpp2 import AtomSelection, MoleculeSelection frame = make_polyglycine([("A", 20)]) with pytest.raises(Exception): AtomSelection([a for a in frame.molecules]) with pytest.raises(Exception): MoleculeSelection([a for a in frame.residues])
def test_pipe_slice(): ref = make_polyglycine([('A', 10)]) traj = Trajectory(ref) traj.extend(IotaTrajectory(natoms=ref.atoms.size, nframes=10)) for frame in (traj | AngstromsToNanometers())[:10]: assert np.allclose(frame.coords.values / 10, frame.index) assert np.isclose(frame.time, frame.index * 15)
def test_frame_copy(): from pyxmolpp2 import Frame frame = make_polyglycine([("A", 2)]) frame2 = Frame(frame) frame.atoms[0].r.x = 1 frame2.atoms[0].r.x = 2 assert frame.atoms[0].r.x != frame2.atoms[0].r.x
def test_selection_bool_indexing(): import numpy as np frame = make_polyglycine([("A", 20)]) asel = frame.atoms ind = np.array([a.name.str == "C" for a in asel]) subset = asel[ind] assert subset.size == 20
def test_Residue_setters(): from pyxmolpp2 import ResidueId frame = make_polyglycine([("A", 1)]) r = frame.residues[0] r.name = "X" assert r.name == "X" r.id = ResidueId(5) assert r.id == ResidueId(5)
def test_atom_id(): from pyxmolpp2 import aId frame = make_polyglycine([("A", 10)]) assert frame.atoms.filter(aId == 5).size == 1 assert frame.atoms.filter(aId.is_in({1,2,3})).size == 3 assert frame.atoms.filter(aId.is_in(1,2,3)).size == 3 assert frame.atoms.filter(~aId.is_in({1,2,3})).size == 70-3 assert frame.atoms.filter(~aId.is_in(1,2,3)).size == 70-3 assert frame.atoms.filter((aId == 2) | (aId == 3)).size == 2
def test_atom_name(): from pyxmolpp2 import aName frame = make_polyglycine([("A", 10)]) assert frame.atoms.filter(aName == "CA").size == 10 assert frame.atoms.filter(aName.is_in({"CA", "N"})).size == 20 assert frame.atoms.filter(aName.is_in("CA", "N")).size == 20 assert frame.atoms.filter(~aName.is_in({"CA", "N"})).size == 50 assert frame.atoms.filter(~aName.is_in("CA", "N")).size == 50 assert frame.atoms.filter((aName == "CA") | (aName == "N")).size == 20
def test_pseudo_trajectory(): ref = make_polyglycine([('A', 10)]) traj = Trajectory(ref) traj.extend(IotaTrajectory(natoms=ref.atoms.size, nframes=10)) for frame in traj: assert np.allclose(frame.coords.values, frame.index) assert np.isclose(frame.cell.volume, frame.index + 1) assert np.isclose(frame.time, frame.index * 15)
def test_AtomSelection_construction_from_list(): from pyxmolpp2 import AtomSelection frame = make_polyglycine([("A", 20)]) atom_list = [a for a in frame.atoms] asel = AtomSelection(atom_list) assert asel.size == frame.atoms.size assert asel[0] == frame.atoms[0] assert asel[frame.atoms.size - 1] == frame.atoms[frame.atoms.size - 1]
def test_str(): frame = make_polyglycine([("A", 20)]) assert "size=" in str(frame.coords[::3]) assert "size=" in str(frame.atoms[::3]) assert "size=" in str(frame.residues[::3]) assert "size=" in str(frame.molecules[::3]) assert "size=" in str(frame.atoms) assert "size=" in str(frame.residues) assert "size=" in str(frame.molecules) assert "size=" in str(frame.coords)
def test_ResidueSelection_construction_from_list(): from pyxmolpp2 import ResidueSelection frame = make_polyglycine([("A", 20)]) thelist = [a for a in frame.residues] sel = ResidueSelection(thelist) assert sel.size == frame.residues.size assert sel[0] == frame.residues[0] assert sel[frame.residues.size - 1] == frame.residues[frame.residues.size - 1]
def test_AtomSelection_transformations(): from pyxmolpp2 import Translation, XYZ frame = make_polyglycine([("A", 20)]) ats = frame.atoms for a in ats: assert (a.r - XYZ(1, 2, 3)).len() == 0 transformation = Translation(XYZ(1, 2, 3)) ats.coords.apply(transformation) for a in ats: assert (a.r - XYZ(2, 4, 6)).len() == 0
def test_coord_span_assign_values(): from pyxmolpp2 import XYZ import numpy as np frame = make_polyglycine([("A", 10)]) frame.coords.values[:] = np.array([0, 0, 0]) assert frame.coords[0].distance(XYZ(0, 0, 0)) == pytest.approx(0) assert frame.coords[frame.coords.size - 1].distance(XYZ( 0, 0, 0)) == pytest.approx(0) frame.coords.values[:] = np.array([1, 2, 3]) assert frame.coords[0].distance(XYZ(1, 2, 3)) == pytest.approx(0) assert frame.coords[frame.coords.size - 1].distance(XYZ( 1, 2, 3)) == pytest.approx(0)
def test_deleted_element_access_exceptions(): frame = make_polyglycine([("A", 1)]) sel = frame.atoms sel[0].delete() with pytest.raises(RuntimeError): for a in sel: pass frame = make_polyglycine([("A", 2)]) sel = frame.residues sel[0].delete() with pytest.raises(RuntimeError): for a in sel: pass frame = make_polyglycine([("A", 2)] * 2) sel = frame.molecules sel[0].delete() with pytest.raises(RuntimeError): for a in sel: pass
def test_Atom_setters(): from pyxmolpp2 import XYZ frame = make_polyglycine([("A", 1)]) a = frame.atoms[0] a.name = "X" assert a.name == "X" a.id = 5 assert a.id == 5 a.r = XYZ(9, 9, 9) assert (a.r - XYZ(9, 9, 9)).len() == 0
def test_selection_int_indexing(): import numpy as np from pyxmolpp2 import aName frame = make_polyglycine([("A", 20)]) asel = frame.atoms rsel = frame.residues csel = frame.molecules ind = np.array([i for i, a in enumerate(asel) if a.name == "C"]) ind2 = asel.filter(aName == "C").index assert np.allclose(ind, ind2) subset = asel[ind] assert subset.size == 20 assert asel[ind2].size == 20 # Bool array size doesn't match selection size with pytest.raises(RuntimeError): asel[np.array([True, False])] with pytest.raises(RuntimeError): rsel[np.array([True, False])] with pytest.raises(RuntimeError): csel[np.array([True, False])] # Bool array element type is not integer or bool with pytest.raises(RuntimeError): asel[np.array([1.0, 2.0])] with pytest.raises(RuntimeError): rsel[np.array([1.0, 2.0])] with pytest.raises(RuntimeError): csel[np.array([1.0, 2.0])] # Array dimension is not 1 with pytest.raises(RuntimeError): asel[np.array([[0, 2], [1, 2]])] with pytest.raises(RuntimeError): rsel[np.array([[0, 2], [1, 2]])] with pytest.raises(RuntimeError): csel[np.array([[0, 2], [1, 2]])] assert frame.residues[np.array([0, 1])].size == 2 assert frame.residues[np.array([0])].size == 1 # array index -> selection assert frame.chains[np.array( [], dtype=int)].size == 0 # array index -> selection assert frame.chains[0].size == 20 # int index -> Chain
def test_anything_to_pdb_buffer(): from io import StringIO frame = make_polyglycine([("A", 20)]) with StringIO() as output: frame.to_pdb(output) # frame.to_pdb(output, PdbFile.STANDARD_V3) frame.atoms.to_pdb(output) frame.molecules.to_pdb(output) frame.residues.to_pdb(output) frame.atoms[0].to_pdb(output) frame.molecules[0].to_pdb(output) frame.residues[0].to_pdb(output)
def test_shorthands(): import numpy as np from pyxmolpp2 import Rotation, Translation, XYZ, Degrees, Frame, calc_alignment frame = make_polyglycine([("A", 20)]) for a in frame.atoms: a.r = XYZ(*np.random.random(3)) frame2 = Frame(frame) assert frame2 != frame print(frame, frame2) asel = frame.atoms asel2 = frame2.atoms asel.coords.mean() # asel.mass_center([1.0] * asel.size) # todo: enable # asel.inertia_tensor([1.0] * asel.size) # todo: enable asel.coords.inertia_tensor() T = Translation(XYZ(1, 0, 0)) asel2.coords.apply(T) print(asel.coords.rmsd(asel2.coords)) assert np.isclose(asel.coords.rmsd(asel2.coords), 1.0) assert np.isclose(asel.coords.rmsd(asel2.coords), 1.0) asel2.coords.apply(T.inverted()) assert np.isclose(asel.coords.rmsd(asel2.coords), 0.0) T = Translation(XYZ(1, 0, 0)) * Rotation(XYZ(1, 1, 1), Degrees(45)) asel.coords.apply(asel.coords.alignment_to(asel2.coords)) assert np.isclose(asel.coords.rmsd(asel2.coords), 0) asel2.coords.apply(T) asel.align_to(asel2) assert np.isclose(asel.coords.rmsd(asel2.coords), 0) asel2.coords.apply(T) asel2.guess_mass() asel.guess_mass() asel.align_to(asel2, weighted=True) assert np.isclose(asel.rmsd(asel2), 0) assert np.isclose(asel.rmsd(asel2, weighted=True), 0) T = Translation(XYZ(1, 0, 0)) * Rotation(XYZ(1, 1, 1), Degrees(45)) asel2.coords.apply(T) assert np.allclose( T.matrix3d(), calc_alignment(asel2.coords.values, asel.coords.values).matrix3d()) assert np.allclose(T.matrix3d(), asel.alignment_to(asel2).matrix3d())
def test_lookup_after_rename(): from pyxmolpp2 import ResidueId frame = make_polyglycine([("A", 2)]) frame["A"] # does not throw frame["A"][ResidueId(2)] # does not throw frame["A"][ResidueId(2)]["CA"] # does not throw frame["A"][ResidueId(2)]["CA"].name = "CX" frame["A"][ResidueId(2)].id = ResidueId(99) frame["A"].name = "X" frame["X"] # does not throw frame["X"][ResidueId(99)] # does not throw frame["X"][ResidueId(99)]["CX"] # does not throw
def test_repr(): frame = make_polyglycine([("A", 10)]) str(frame) str(frame.molecules[0].name) str(frame.residues[0].name) str(frame.atoms[0].name) str([frame.molecules[0].name, frame.residues[0].name, frame.atoms[0].name]) str(frame.molecules[0]) str(frame.residues[0]) str(frame.atoms[0]) str(frame.molecules) str(frame.residues) str(frame.atoms)
def test_frame_file_output(): frame = make_polyglycine([("A", 20)]) output = "temp.pdb" frame.to_pdb(output) with open("temp.pdb") as output: assert output.readlines()[-1].strip() == "TER" os.unlink("temp.pdb") output = "temp.pdb" frame.to_pdb(output) with open("temp.pdb") as output: assert output.readlines()[-1].strip() == "TER" os.unlink("temp.pdb")
def test_residue_name(): from pyxmolpp2 import rName frame = make_polyglycine([("A", 10)]) assert frame.atoms.filter(rName == "GLY").size == 70 assert frame.atoms.filter(rName.is_in({"GLY", "LYS"})).size == 70 assert frame.atoms.filter(rName.is_in("GLY", "LYS")).size == 70 assert frame.atoms.filter(~rName.is_in({"GLY"})).size == 0 assert frame.atoms.filter(~rName.is_in("GLY")).size == 0 assert frame.atoms.filter((rName == "GLY") | (rName != "GLY")).size == 70 assert frame.residues.filter(rName == "GLY").size == 10 assert frame.residues.filter(rName.is_in({"GLY", "LYS"})).size == 10 assert frame.residues.filter(rName.is_in("GLY", "LYS")).size == 10 assert frame.residues.filter(~rName.is_in({"GLY"})).size == 0 assert frame.residues.filter(~rName.is_in("GLY")).size == 0 assert frame.residues.filter((rName == "GLY") | (rName != "GLY")).size == 10
def test_lookup_by_name(): from pyxmolpp2 import ResidueId frame = make_polyglycine([("A", 2)]) frame["A"] # does not throw frame["A"][ResidueId(2)] # does not throw frame["A"][ResidueId(2)]["CA"] # does not throw frame["A"][ResidueId(2)]["N"] # does not throw with pytest.raises(IndexError): frame["B"] with pytest.raises(IndexError): frame["A"][ResidueId(3)] with pytest.raises(IndexError): frame["A"][ResidueId(2)]["CX"]