From d1c75390aa9d9279d0dc6a05ecd8b4b8d35d08a9 Mon Sep 17 00:00:00 2001 From: "David W.H. Swenson" Date: Sun, 25 Aug 2024 13:52:37 +0200 Subject: [PATCH 1/3] Convert output of INIT_CONDS parameter to trajs --- paths_cli/parameters.py | 26 +++++++++++++++++++++++++- paths_cli/tests/test_parameters.py | 13 ++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/paths_cli/parameters.py b/paths_cli/parameters.py index e8fbc581..0e047097 100644 --- a/paths_cli/parameters.py +++ b/paths_cli/parameters.py @@ -18,7 +18,31 @@ store='schemes', ) -INIT_CONDS = OPSStorageLoadMultiple( +class InitCondsLoader(OPSStorageLoadMultiple): + def _extract_trajectories(self, obj): + import openpathsampling as paths + if isinstance(obj, paths.SampleSet): + yield from (s.trajectory for s in obj) + elif isinstance(obj, paths.Sample): + yield obj.trajectory + elif isinstance(obj, paths.Trajectory): + yield obj + elif isinstance(obj, paths.BaseSnapshot): + yield paths.Trajectory([obj]) + elif isinstance(obj, list): + for o in obj: + yield from self._extract_trajectories(o) + else: + raise RuntimeError("Unknown initial conditions type: " + f"{obj} (type: {type(obj)}") + + def get(self, storage, names): + results = super().get(storage, names) + final_results = list(self._extract_trajectories(results)) + return final_results + + +INIT_CONDS = InitCondsLoader( param=Option('-t', '--init-conds', multiple=True, help=("identifier for initial conditions " + "(sample set or trajectory)" + HELP_MULTIPLE)), diff --git a/paths_cli/tests/test_parameters.py b/paths_cli/tests/test_parameters.py index b748fbe6..c9531e12 100644 --- a/paths_cli/tests/test_parameters.py +++ b/paths_cli/tests/test_parameters.py @@ -243,8 +243,8 @@ def test_get(self, getter): storage = paths.Storage(filename, mode='r') get_type, getter_style = self._parse_getter(getter) expected = { - 'sset': self.sample_set, - 'traj': self.traj + 'sset': [s.trajectory for s in self.sample_set], + 'traj': [self.traj] }[get_type] get_arg = { 'name': 'traj', @@ -277,7 +277,14 @@ def test_get_none(self, num_in_file): st = paths.Storage(filename, mode='r') obj = INIT_CONDS.get(st, None) - assert obj == stored_things[num_in_file - 1] + # TODO: fix this for all being trajectories + expected = [ + [self.traj], + [s.trajectory for s in self.sample_set], + [s.trajectory for s in self.other_sample_set], + [s.trajectory for s in self.other_sample_set], + ] + assert obj == expected[num_in_file - 1] def test_get_multiple(self): filename = self.create_file('number-traj') From 06db15a379c853661e92451cfc5c31fec12385f5 Mon Sep 17 00:00:00 2001 From: "David W.H. Swenson" Date: Sun, 25 Aug 2024 14:50:38 +0200 Subject: [PATCH 2/3] Cleanup after switching init conds behavior --- paths_cli/tests/commands/test_equilibrate.py | 8 +++++--- paths_cli/tests/commands/test_pathsampling.py | 5 +++-- paths_cli/tests/test_parameters.py | 1 - 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/paths_cli/tests/commands/test_equilibrate.py b/paths_cli/tests/commands/test_equilibrate.py index c57a8b8f..01c36891 100644 --- a/paths_cli/tests/commands/test_equilibrate.py +++ b/paths_cli/tests/commands/test_equilibrate.py @@ -11,7 +11,7 @@ def print_test(output_storage, scheme, init_conds, multiplier, extra_steps): print(isinstance(output_storage, paths.Storage)) print(scheme.__uuid__) - print(init_conds.__uuid__) + print([o.__uuid__ for o in init_conds]) print(multiplier, extra_steps) @@ -31,8 +31,10 @@ def test_equilibrate(tps_fixture): ["setup.nc", "-o", "foo.nc"] ) out_str = "True\n{schemeid}\n{condsid}\n1 0\n" - expected_output = out_str.format(schemeid=scheme.__uuid__, - condsid=init_conds.__uuid__) + expected_output = out_str.format( + schemeid=scheme.__uuid__, + condsid=[o.trajectory.__uuid__ for o in init_conds], + ) assert results.exit_code == 0 assert results.output == expected_output diff --git a/paths_cli/tests/commands/test_pathsampling.py b/paths_cli/tests/commands/test_pathsampling.py index dc5034a5..08d7db3b 100644 --- a/paths_cli/tests/commands/test_pathsampling.py +++ b/paths_cli/tests/commands/test_pathsampling.py @@ -11,7 +11,7 @@ def print_test(output_storage, scheme, init_conds, n_steps): print(isinstance(output_storage, paths.Storage)) print(scheme.__uuid__) - print(init_conds.__uuid__) + print([traj.__uuid__ for traj in init_conds]) print(n_steps) @patch('paths_cli.commands.pathsampling.pathsampling_main', print_test) @@ -26,7 +26,8 @@ def test_pathsampling(tps_fixture): results = runner.invoke(pathsampling, ['setup.nc', '-o', 'foo.nc', '-n', '1000']) - expected_output = (f"True\n{scheme.__uuid__}\n{init_conds.__uuid__}" + initcondsid = [samp.trajectory.__uuid__ for samp in init_conds] + expected_output = (f"True\n{scheme.__uuid__}\n{initcondsid}" "\n1000\n") assert results.output == expected_output diff --git a/paths_cli/tests/test_parameters.py b/paths_cli/tests/test_parameters.py index c9531e12..ecc82a3b 100644 --- a/paths_cli/tests/test_parameters.py +++ b/paths_cli/tests/test_parameters.py @@ -277,7 +277,6 @@ def test_get_none(self, num_in_file): st = paths.Storage(filename, mode='r') obj = INIT_CONDS.get(st, None) - # TODO: fix this for all being trajectories expected = [ [self.traj], [s.trajectory for s in self.sample_set], From ff15749584c829f86d4d482b56943ff124e79d8b Mon Sep 17 00:00:00 2001 From: "David W.H. Swenson" Date: Sun, 25 Aug 2024 16:32:15 +0200 Subject: [PATCH 3/3] add some test coverage --- paths_cli/parameters.py | 2 -- paths_cli/tests/test_parameters.py | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/paths_cli/parameters.py b/paths_cli/parameters.py index 0e047097..574b17da 100644 --- a/paths_cli/parameters.py +++ b/paths_cli/parameters.py @@ -27,8 +27,6 @@ def _extract_trajectories(self, obj): yield obj.trajectory elif isinstance(obj, paths.Trajectory): yield obj - elif isinstance(obj, paths.BaseSnapshot): - yield paths.Trajectory([obj]) elif isinstance(obj, list): for o in obj: yield from self._extract_trajectories(o) diff --git a/paths_cli/tests/test_parameters.py b/paths_cli/tests/test_parameters.py index ecc82a3b..e4cc9f12 100644 --- a/paths_cli/tests/test_parameters.py +++ b/paths_cli/tests/test_parameters.py @@ -214,8 +214,12 @@ def create_file(self, getter): get_type, getter_style = self._parse_getter(getter) main, other = { 'traj': (self.traj, self.other_traj), - 'sset': (self.sample_set, self.other_sample_set) + 'sset': (self.sample_set, self.other_sample_set), + 'samp': (self.sample_set[0], self.other_sample_set[0]), }[get_type] + if get_type == 'samp': + storage.save(main) + storage.save(other) if get_type == 'sset': storage.save(self.sample_set) storage.save(self.other_sample_set) @@ -231,12 +235,14 @@ def create_file(self, getter): if other_tag: storage.tags[other_tag] = other + storage.close() return filename @pytest.mark.parametrize("getter", [ 'name-traj', 'number-traj', 'tag-final-traj', 'tag-initial-traj', - 'name-sset', 'number-sset', 'tag-final-sset', 'tag-initial-sset' + 'name-sset', 'number-sset', 'tag-final-sset', 'tag-initial-sset', + 'name-samp', 'number-samp', ]) def test_get(self, getter): filename = self.create_file(getter) @@ -244,7 +250,8 @@ def test_get(self, getter): get_type, getter_style = self._parse_getter(getter) expected = { 'sset': [s.trajectory for s in self.sample_set], - 'traj': [self.traj] + 'traj': [self.traj], + 'samp': [self.sample_set[0].trajectory], }[get_type] get_arg = { 'name': 'traj', @@ -303,6 +310,18 @@ def test_cannot_guess(self): with pytest.raises(RuntimeError): self.PARAMETER.get(storage, None) + def test_get_bad_name(self): + filename = self._filename("bad_tag") + storage = paths.Storage(filename, 'w') + storage.save(self.traj) + storage.save(self.other_traj) + storage.tags['bad_tag'] = "foo" + storage.close() + + storage = paths.Storage(filename, 'r') + with pytest.raises(RuntimeError, match="initial conditions type"): + self.PARAMETER.get(storage, "bad_tag") + class TestINIT_SNAP(ParamInstanceTest): PARAMETER = INIT_SNAP