Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

raise warning if geometry is out of bounds #270

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions polyply/src/build_file_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ def _molecule(self, line, lineno=0):
self.current_molidxs = np.arange(float(tokens[1]), float(tokens[2]), 1., dtype=int)
for idx in self.current_molidxs:
if idx not in self.topology.mol_idx_by_name[tokens[0]]:
LOGGER.warning("parsing build file: could not find molecule with name {name} and index {index}.",
**{"index": idx, "name": tokens[0]})
msg = ("parsing build file: could not find molecule with "
"name {name} and index {index}.")
LOGGER.warning(msg, **{"index": idx, "name": tokens[0]})
fgrunewald marked this conversation as resolved.
Show resolved Hide resolved

@SectionLineParser.section_parser('molecule', 'cylinder', geom_type="cylinder")
@SectionLineParser.section_parser('molecule', 'sphere', geom_type="sphere")
Expand Down Expand Up @@ -231,18 +232,17 @@ def _tag_nodes(molecule, keyword, option, molname=""):
[option['parameters']]
# broadcast warning if we find the resid but it doesn't match the resname
elif molecule.nodes[node]["resid"] in resids and not\
molecule.nodes[node]["resname"] == resname:
msg = "parsing build file: could not find resid {resid} with resname {resname} in molecule {molname}."
LOGGER.warning(msg, **{"resid": molecule.nodes[node]["resid"], "resname": resname,
"molname": molname})
molecule.nodes[node]["resname"] == resname:
msg = "parsing build file: could not find resid {resid} with resname {resname} in molecule {molname}."
LOGGER.warning(msg, **{"resid": molecule.nodes[node]["resid"], "resname": resname,
"molname": molname})
fgrunewald marked this conversation as resolved.
Show resolved Hide resolved

# broadcast warning if we find the resname but it doesn't match the resid
elif molecule.nodes[node]["resname"] == resname and not\
molecule.nodes[node]["resid"]:
msg = "parsing build file: could not find residue {resname} with resid {resid} in molecule {molname}."
LOGGER.warning(msg, **{"resid": molecule.nodes[node]["resid"], "resname": resname,
"molname": molname})

molecule.nodes[node]["resid"]:
msg = "parsing build file: could not find residue {resname} with resid {resid} in molecule {molname}."
LOGGER.warning(msg, **{"resid": molecule.nodes[node]["resid"], "resname": resname,
"molname": molname})
fgrunewald marked this conversation as resolved.
Show resolved Hide resolved
@staticmethod
def _base_parser_geometry(tokens, _type):
geometry_def = {}
Expand All @@ -258,8 +258,44 @@ def _base_parser_geometry(tokens, _type):

parameters.append(_type)
geometry_def["parameters"] = parameters

_check_geometry_def(geometry_def, _type)
return geometry_def

def _check_geometry_def(geom_def, geom_type):
fgrunewald marked this conversation as resolved.
Show resolved Hide resolved
"""
Raise a warning if the point of reference
for the geometry type is too close to the
origin.

Parameters
----------
geom_def: dict
dict with entries: resname, start, stop, point, parameters
geom_type: str
one of sphere, cylinder, rectangle
"""
Comment on lines +276 to +287
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring needs updating

msg = ("Geometry restriction {geom_def} extends beyond definite "
"positive coordiantes relative to the center point "
fgrunewald marked this conversation as resolved.
Show resolved Hide resolved
"{x:.3f} {y:.3f} {z:.3f}. Be aware polyply only builds "
"in positive coordinate space.")

point = geom_def['parameters'][1]
if geom_type == "sphere":
radius = geom_def['parameters'][2]
if any( i < j for i, j in zip([radius, radius, radius], point)):
LOGGER.warning(msg, geom_def=geom_def, x=point[0], y=point[1], z=point[2])

if geom_type == "rectangle":
a, b, c = geom_def['parameters'][2:5]
if any( i < j for i, j in zip([a, b, c], point)):
LOGGER.warning(msg, geom_def=geom_def, x=point[0], y=point[1], z=point[2])

if geom_type == "cylinder":
z, r = geom_def['parameters'][2:4]
if z < point[2] or r < np.linalg.norm(point[:2]):
LOGGER.warning(msg, geom_def=geom_def, x=point[0], y=point[1], z=point[2])

def read_build_file(lines, molecules, topology):
"""
Parses `lines` of itp format and adds the
Expand Down
24 changes: 24 additions & 0 deletions polyply/tests/test_build_file_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""
Test that build files are properly read.
"""
import logging
import textwrap
import pytest
import numpy as np
Expand Down Expand Up @@ -51,6 +52,29 @@ def test_base_parser_geometry(tokens, _type, expected):
for result_param, expected_param in zip(result[key][2:], expected[key][2:]):
assert result_param == expected_param

@pytest.mark.parametrize('tokens, _type', (
# for cylinder z is not covered
(["PEO", "63", "154", "in", "8", "8", "6", "6", "7"],
"cylinder",),
# for cylinder z is not covered
(["PEO", "63", "154", "in", "2", "2", "8", "6", "7"],
"cylinder",),
# for recangle one of the sides is out
(["PEO", "0", "10", "out", "11", "0", "13", "1", "2", "3"],
"rectangle",),
# for sphere radius is to large/small
(["PEO", "0", "10", "in", "0", "12", "13", "5"],
"sphere",),
))
def test_base_parser_geometry_warning(caplog, tokens, _type):
with caplog.at_level(logging.WARNING):
result = polyply.src.build_file_parser.BuildDirector._base_parser_geometry(tokens, _type)
for record in caplog.records:
assert record.levelname == "WARNING"
break
else:
assert False
Comment on lines +82 to +88
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to test len(records)?


@pytest.fixture
def test_molecule():
# dummy vermouth force-field
Expand Down