From 5cddc001cb74a6d4f4fa0207a23b9eade5b3880d Mon Sep 17 00:00:00 2001 From: Wei-Tse Hsu Date: Wed, 17 Apr 2024 23:09:21 +0800 Subject: [PATCH] Renamed autoconvert to _convert_to_numeric; Tweaked MDP --- ensemble_md/tests/test_utils.py | 22 +++++++------------- ensemble_md/utils/gmx_parser.py | 37 +++++++++++++++------------------ ensemble_md/utils/utils.py | 25 +++++++--------------- 3 files changed, 33 insertions(+), 51 deletions(-) diff --git a/ensemble_md/tests/test_utils.py b/ensemble_md/tests/test_utils.py index 495fc68d..f130e1ca 100644 --- a/ensemble_md/tests/test_utils.py +++ b/ensemble_md/tests/test_utils.py @@ -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(): diff --git a/ensemble_md/utils/gmx_parser.py b/ensemble_md/utils/gmx_parser.py index 1e573af9..1d317a8d 100644 --- a/ensemble_md/utils/gmx_parser.py +++ b/ensemble_md/utils/gmx_parser.py @@ -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: @@ -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: @@ -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 @@ -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): diff --git a/ensemble_md/utils/utils.py b/ensemble_md/utils/utils.py index 078cbc4d..f072c8ae 100644 --- a/ensemble_md/utils/utils.py +++ b/ensemble_md/utils/utils.py @@ -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 `_. - Copyright (c) 2009 Oliver Beckstein + 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: @@ -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):