Skip to content

Commit

Permalink
Renamed autoconvert to _convert_to_numeric; Tweaked MDP
Browse files Browse the repository at this point in the history
  • Loading branch information
wehs7661 committed Apr 17, 2024
1 parent aaa9c13 commit 5cddc00
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 51 deletions.
22 changes: 8 additions & 14 deletions ensemble_md/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,15 @@ def test_format_time():
assert utils.format_time(90061) == "1 day, 1 hour(s) 1 minute(s) 1 second(s)"


def test_autoconvert():
def test_convert_to_numeric():
# Test non-string input
assert utils._autoconvert(42) == 42

# Test string input that can be converted to int
assert utils._autoconvert("42") == 42

# Test string input that can be converted to float
assert utils._autoconvert("3.14159") == 3.14159

# Test string input that can be converted to a numpy array of ints
assert utils._autoconvert("1 2 3") == [1, 2, 3]

# Test string input that can be converted to a numpy array of floats
assert utils._autoconvert("1.0 2.0 3.0") == [1.0, 2.0, 3.0]
assert utils._convert_to_numeric(42) == 42
assert utils._convert_to_numeric("42") == 42
assert utils._convert_to_numeric("3.14159") == 3.14159
assert utils._convert_to_numeric("1 2 3") == [1, 2, 3]
assert utils._convert_to_numeric("1.0 2.0 3.0") == [1.0, 2.0, 3.0]
assert utils._convert_to_numeric("Hello, world!") == ['Hello,', 'world!']
assert utils._convert_to_numeric('Y Y Y') == ['Y', 'Y', 'Y']


def test_get_subplot_dimension():
Expand Down
37 changes: 17 additions & 20 deletions ensemble_md/utils/gmx_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class MDP(odict):
re.VERBOSE,
)

def __init__(self, filename=None, autoconvert=True, **kwargs):
def __init__(self, input_mdp=None, autoconvert=True, **kwargs):
"""Initialize mdp structure.
:Arguments:
Expand All @@ -213,27 +213,27 @@ def __init__(self, filename=None, autoconvert=True, **kwargs):
"""
super(MDP, self).__init__(**kwargs) # can use kwargs to set dict! (but no sanity checks!)
self.autoconvert = autoconvert
if filename is not None:
self.filename = os.path.realpath(filename)
self.read(filename)
if input_mdp is not None:
self.input_mdp = os.path.realpath(input_mdp)
self.read()

def _transform(self, value):
if self.autoconvert:
return utils._autoconvert(value)
return utils._convert_to_numeric(value)
else:
return value.rstrip()

def read(self, filename=None):
def read(self):
"""Read and parse mdp file *filename*."""
def BLANK(i):
return "B{0:04d}".format(i)
return f"B{i:04d}"

def COMMENT(i):
return "C{0:04d}".format(i)
return f"C{i:04d}"

data = odict()
iblank = icomment = 0
with open(self.filename) as mdp:
with open(self.input_mdp) as mdp:
for line in mdp:
line = line.strip()
if len(line) == 0:
Expand All @@ -245,22 +245,19 @@ def COMMENT(i):
icomment += 1
data[COMMENT(icomment)] = m.group("value")
continue
# parameter

m = self.PARAMETER.match(line)
if m:
# check for comments after parameter?? -- currently discarded
parameter = m.group("parameter")
value = self._transform(m.group("value"))
data[parameter] = value
else:
errmsg = "{filename!r}: unknown line in mdp file, {line!r}".format(
**vars()
)
raise ParseError(errmsg)
err_msg = f"{self.input_mdp!r}: unknown line in mdp file, {line!r}"
raise ParseError(err_msg)

super(MDP, self).update(data)

def write(self, filename=None, skipempty=False):
def write(self, output_mdp=None, skipempty=False):
"""Write mdp file to *filename*.
Parameters
Expand All @@ -274,19 +271,19 @@ def write(self, filename=None, skipempty=False):
# The line 'if skipempty and (v == "" or v is None):' below could possibly incur FutureWarning
warnings.simplefilter(action='ignore', category=FutureWarning)

with open(filename, "w") as mdp:
with open(output_mdp, "w") as mdp:
for k, v in self.items():
if k[0] == "B": # blank line
mdp.write("\n")
elif k[0] == "C": # comment
mdp.write("; {v!s}\n".format(**vars()))
mdp.write(f"; {v!s}\n")
else: # parameter = value
if skipempty and (v == "" or v is None):
continue
if isinstance(v, six.string_types) or not hasattr(v, "__iter__"):
mdp.write("{k!s} = {v!s}\n".format(**vars()))
mdp.write(f"{k!s} = {v!s}\n")
else:
mdp.write("{} = {}\n".format(k, " ".join(map(str, v))))
mdp.write(f"{k} = {' '.join(map(str, v))}\n")


def compare_MDPs(mdp_list, print_diff=False):
Expand Down
25 changes: 8 additions & 17 deletions ensemble_md/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,22 @@ def format_time(t):
return t_str


def _autoconvert(s):
def _convert_to_numeric(s):
"""
Converts input to a numerical type if possible. This internal function is used for the MDP parser
and was adapted from `utilities.py in GromacsWrapper <https://github.com/Becksteinlab/GromacsWrapper>`_.
Copyright (c) 2009 Oliver Beckstein <orbeckst@gmail.com>
Converts the input to a numerical type when possible. This internal function is used for the MDP parser.
Parameters
----------
s : str or any
The input value to be converted to a numerical type if possible. If :code:`s` is not a string,
it is returned as is.
s : any
The input value to be converted to a numerical type if possible. The data type of :code:`s` is
usually :code:`str` but can be any. However, if :code:`s` is not a string, it will be returned as is.
Returns
-------
numerical : int, float, numpy.ndarray, or any
numerical : any
The converted numerical value. If :code:`s` can be converted to a single numerical value,
that value is returned as an :code:`int` or :code:`float`. If :code:`s` can be converted to
multiple numerical values, a :code:`numpy.ndarray` containing those values is returned.
multiple numerical values, a list containing those values is returned.
If :code:`s` cannot be converted to a numerical value, :code:`s` is returned as is.
"""
if type(s) is not str:
Expand All @@ -157,16 +155,9 @@ def _autoconvert(s):
return s[0]
else:
return s
"""
if len(s) != 0 and type(s[0]) == str:
# For the case like pull_coord1_dim = Y Y Y
return s
else:
return np.array(s)
"""
except (ValueError, AttributeError):
pass
raise ValueError("Failed to autoconvert {0!r}".format(s))
raise ValueError(f"Failed to convert {s} to a numeric value.")


def _get_subplot_dimension(n_panels):
Expand Down

0 comments on commit 5cddc00

Please sign in to comment.