Skip to content

Commit

Permalink
Merge pull request #321 from marrink-lab/box_from_coords
Browse files Browse the repository at this point in the history
Box from coords
  • Loading branch information
fgrunewald committed Sep 28, 2023
2 parents 84d0c25 + f7334a2 commit 2fc4b16
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 5 deletions.
16 changes: 16 additions & 0 deletions polyply/src/gen_coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@ def gen_coords(toppath,
LOGGER.info("loading grid", type="step")
grid = np.loadtxt(grid)

# where to get the box size from
if box is not None and not np.array_equal(topology.box, box):
msg = ("A box is provided via the -box command line "
"and the starting coordinates. We consider the "
"the box of starting coordinates as correct. ")
LOGGER.warning(msg, type="warning")
box = topology.box
elif topology.box is not None:
box = topology.box
if density is not None:
msg = ("A density is provided via the command line, "
"but the starting coordinates define a box."
"Will try to pack all molecules in the box "
"provided with starting coordinates.")
LOGGER.warning(msg, type="warning")

# do a sanity check
LOGGER.info("checking residue integrity", type="step")
check_residue_equivalence(topology)
Expand Down
9 changes: 7 additions & 2 deletions polyply/src/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ def _coord_parser(path, extension):
molecule.merge_molecule(new_mol)
else:
molecule = molecules

box = molecule.box
positions = np.array(list(nx.get_node_attributes(molecule, "position").values()))
return positions
return positions, box


def replace_defined_interaction(interaction, defines):
Expand Down Expand Up @@ -213,6 +215,8 @@ class Topology(System):
A dictionary of all typed parameter
defines: list
A list of everything that is defined
box: np.array(3,1)
Box vectors as a, b, c in nanometers
"""

def __init__(self, force_field, name=None):
Expand All @@ -228,6 +232,7 @@ def __init__(self, force_field, name=None):
self.persistences = []
self.distance_restraints = defaultdict(dict)
self.volumes = {}
self.box = None

def preprocess(self):
"""
Expand Down Expand Up @@ -425,7 +430,7 @@ def add_positions_from_file(self, path, skip_res=[], resolution='mol'):
"""
path = Path(path)
extension = path.suffix.casefold()[1:]
positions = _coord_parser(path, extension)
positions, self.box = _coord_parser(path, extension)
max_coords = len(positions)
total = 0
for meta_mol in self.molecules:
Expand Down
2 changes: 1 addition & 1 deletion polyply/tests/test_data/topology_test/meta.gro
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ PMMA test file
2
1PMMA C1 1 -0.024 -0.125 0.104
1PMMA C2 2 -0.089 -0.100 -0.028
10.00000 10.00000 10.00000
10.00000 11.00000 12.00000
2 changes: 1 addition & 1 deletion polyply/tests/test_data/topology_test/test.gro
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ PMMA test file
2PMMA O1 12 4.482 6.483 9.965
2PMMA O2 13 4.579 6.512 9.772
2PMMA C5 14 4.632 6.624 9.842
10.00000 10.00000 10.00000
10.00000 11.00000 12.00000
1 change: 1 addition & 0 deletions polyply/tests/test_data/topology_test/test.pdb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CRYST1 118.249 120.688 110.944 90.00 90.00 90.00 P 1 1
ATOM 1 BB MET A 1 17.193 61.796 62.315 1.00 0.00
ATOM 2 SC1 MET A 1 20.670 62.642 62.148 1.00 0.00
ATOM 3 BB TYR A 2 16.691 62.571 65.956 1.00 0.00
Expand Down
47 changes: 47 additions & 0 deletions polyply/tests/test_gen_coords_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,53 @@ def test_no_positions_generated(tmp_path, monkeypatch):
assert np.all(molecule_out.nodes[node]['position'] ==
molecule_in.nodes[node]['position'])

@pytest.mark.parametrize('box_input, box_ref, density, warning', [
# box from input coordinates
(None, np.array([11.0, 11.0, 11.0]), None, None),
# box from input coordinates overwrites
(np.array([5.0, 5.0, 5.0]), np.array([11.0, 11.0, 11.0]), None, "warn1"),
# box from input coordinates and density from CLI
(None, np.array([11.0, 11.0, 11.0]), 1000, "warn2"),
])
def test_box_input(tmp_path, caplog, box_input, box_ref, density, warning):
"""
Here we test that the correct box is chosen, in case there
are conflicting inputs.
"""
warnings = {"warn1": ("A box is provided via the -box command line "
"and the starting coordinates. We consider the "
"the box of starting coordinates as correct. "),
"warn2": ("A density is provided via the command line, "
"but the starting coordinates define a box."
"Will try to pack all molecules in the box "
"provided with starting coordinates."),}

top_file = TEST_DATA + "/topology_test/system.top"
pos_file = TEST_DATA + "/topology_test/complete.gro"
out_file = tmp_path / "out.gro"

with caplog.at_level(logging.WARNING):
gen_coords(toppath=top_file,
coordpath=pos_file,
outpath=out_file,
name="test",
box=box_input,
density=density,)

molecule_out = read_gro(out_file, exclude=())
assert np.array_equal(molecule_out.box, box_ref)
if warning:
for record in caplog.records:
if record.levelname == "WARNING":
assert str(record.msg) == warnings[warning]
break
else:
assert False
else:
for record in caplog.records:
if record.levelname == "WARNING":
assert False

def test_backmap_only(tmp_path, monkeypatch):
"""
Only meta_mol positions are defined so others have to be backmapped.
Expand Down
11 changes: 11 additions & 0 deletions polyply/tests/test_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def test_add_positions_from_gro():
"""
top = Topology.from_gmx_topfile(TEST_DATA + "/topology_test/system.top", "test")
top.add_positions_from_file(TEST_DATA + "/topology_test/test.gro")

# check that the box is correctly read
assert np.allclose(top.box, np.array([10.0, 11.0, 12.0]))

for node in top.molecules[0].molecule.nodes:
if node < 14:
assert "position" in top.molecules[0].molecule.nodes[node].keys()
Expand All @@ -70,6 +74,10 @@ def test_add_meta_positions_from_gro():
"""
top = Topology.from_gmx_topfile(TEST_DATA + "/topology_test/system.top", "test")
top.add_positions_from_file(TEST_DATA + "/topology_test/meta.gro", resolution="meta_mol")

# check that the box is correctly read
assert np.allclose(top.box, np.array([10.0, 11.0, 12.0]))

for node in top.molecules[0].nodes:
if node != 2:
assert "position" in top.molecules[0].nodes[node].keys()
Expand All @@ -90,6 +98,9 @@ def test_add_positions_from_pdb():
top = Topology.from_gmx_topfile(TEST_DATA + "/topology_test/pdb.top", "test")
top.add_positions_from_file(TEST_DATA + "/topology_test/test.pdb")

# check that the box is correctly read
assert np.allclose(top.box, np.array([11.8249, 12.0688, 11.0944]))

pdb_mols = read_pdb(TEST_DATA + "/topology_test/test.pdb")
for idx, meta_mol in enumerate(top.molecules):
for node in meta_mol.molecule.nodes:
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ install-requires = # ?? requires-dist?
numpy
decorator == 4.4.2
networkx ~= 2.0
vermouth >= 0.9.1
vermouth >= 0.9.6
scipy >= 1.6.0
tqdm
zip-safe = False
Expand Down

0 comments on commit 2fc4b16

Please sign in to comment.