From c98cec977a5d917cfd95c2d9235f258b2d9f4509 Mon Sep 17 00:00:00 2001 From: braniii Date: Thu, 9 Nov 2023 19:26:59 +0100 Subject: [PATCH 1/6] Test for immutability. --- src/msmhelper/statetraj.py | 22 ++++++++++++---------- test/test_statetraj.py | 10 ++++++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/msmhelper/statetraj.py b/src/msmhelper/statetraj.py index dfc83ad..4c82e80 100644 --- a/src/msmhelper/statetraj.py +++ b/src/msmhelper/statetraj.py @@ -80,7 +80,7 @@ def states(self): Numpy array holding active set of states. """ - return self._states + return self._states.copy() @property def nstates(self): @@ -108,7 +108,7 @@ def ntrajs(self): @property def nframes(self): - """Return cummulative length of all trajectories. + """Return cumulative length of all trajectories. Returns ------- @@ -131,7 +131,7 @@ def trajs(self): if np.array_equal(self.states, np.arange(1, self.nstates + 1)): return [traj + 1 for traj in self._trajs] if np.array_equal(self.states, np.arange(self.nstates)): - return self._trajs + return self.index_trajs return mh.shift_data( self._trajs, np.arange(self.nstates), @@ -160,7 +160,7 @@ def index_trajs(self): List of ndarrays holding the input data. """ - return self._trajs + return [traj.copy() for traj in self._trajs] @property def index_trajs_flatten(self): @@ -338,7 +338,7 @@ def states(self): Numpy array holding active set of states. """ - return self._macrostates + return self._macrostates.copy() @property def nstates(self): @@ -362,8 +362,10 @@ def microstate_trajs(self): List of ndarrays holding the input data. """ - if np.array_equal(self.microstates, np.arange(self.nmicrostates)): - return self._trajs + if np.array_equal(self.microstates, np.arange(1, self.nstates + 1)): + return [traj + 1 for traj in self._trajs] + elif np.array_equal(self.microstates, np.arange(self.nmicrostates)): + return self.microstate_index_trajs return mh.shift_data( self._trajs, np.arange(self.nmicrostates), @@ -392,7 +394,7 @@ def microstate_index_trajs(self): List of ndarrays holding the microstate index trajectory. """ - return self._trajs + return [traj.copy() for traj in self._trajs] @property def microstate_index_trajs_flatten(self): @@ -448,7 +450,7 @@ def microstates(self): Numpy array holding active set of states. """ - return self._states + return self._states.copy() @property def nmicrostates(self): @@ -472,7 +474,7 @@ def state_assignment(self): Micro to macrostate assignment vector. """ - return self._state_assignment + return self._state_assignment.copy() @property def _state_assignment_idx(self): diff --git a/test/test_statetraj.py b/test/test_statetraj.py index 09202b7..d098184 100644 --- a/test/test_statetraj.py +++ b/test/test_statetraj.py @@ -127,6 +127,16 @@ def test_nstates(state_traj, statetraj, macro_traj, macrotraj): state_traj.nstates = 5 +def test_states(state_traj): + """Test immutability of states property.""" + states = state_traj.states + states += 2 + assert np.testing.assert_array_almost_equal(states - 2, state_traj.states) + + with pytest.raises(AttributeError): + state_traj.states = states + + def test_nframes(state_traj): """Test nframes property.""" assert state_traj.nframes == len(state_traj[0]) From c61195445d76862d448e6592c2da8012007dcae0 Mon Sep 17 00:00:00 2001 From: braniii Date: Thu, 9 Nov 2023 19:40:40 +0100 Subject: [PATCH 2/6] Fix immutable comaprison of states property. --- CHANGELOG.md | 5 +++++ test/test_statetraj.py | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa682cf..97282e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Bugfix 🐛: +- Fix mutable properties of `mh.StateTraj` and `mh.LumpedStateTraj`, #43 + +### Other changes: +- Improved performance of `mh.LumpedStateTraj.microtrajs` ## [1.1.0] - 2023-11-03 diff --git a/test/test_statetraj.py b/test/test_statetraj.py index d098184..1224528 100644 --- a/test/test_statetraj.py +++ b/test/test_statetraj.py @@ -129,12 +129,10 @@ def test_nstates(state_traj, statetraj, macro_traj, macrotraj): def test_states(state_traj): """Test immutability of states property.""" - states = state_traj.states - states += 2 - assert np.testing.assert_array_almost_equal(states - 2, state_traj.states) + assert state_traj.states is not state_traj.states with pytest.raises(AttributeError): - state_traj.states = states + state_traj.states = state_traj.states def test_nframes(state_traj): From 781e9640ec0fa610430e2fa23a4ce72b6210a31d Mon Sep 17 00:00:00 2001 From: braniii Date: Thu, 9 Nov 2023 19:47:53 +0100 Subject: [PATCH 3/6] Test for immutable traj properties. --- test/test_statetraj.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_statetraj.py b/test/test_statetraj.py index 1224528..172b1bf 100644 --- a/test/test_statetraj.py +++ b/test/test_statetraj.py @@ -96,6 +96,14 @@ def test_StateTraj_constructor(statetraj): lumpedTraj = LumpedStateTraj(statetraj, statetraj) assert lumpedTraj is StateTraj(lumpedTraj) + # check that immutable + assert traj._trajs[0] is not StateTraj(traj.trajs)._trajs[0] + # check for index trajs + assert ( + StateTraj(traj.index_trajs)._trajs[0] is not + StateTraj(traj.index_trajs)._trajs[0] + ) + def test_LumpedStateTraj_constructor(macrotraj, statetraj): """Test construction of object.""" From fb902dd7ea0b1c69955b8780cde641416a344606 Mon Sep 17 00:00:00 2001 From: braniii Date: Thu, 9 Nov 2023 19:56:03 +0100 Subject: [PATCH 4/6] Enforce true copy on mh.StateTraj creation. --- src/msmhelper/statetraj.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/msmhelper/statetraj.py b/src/msmhelper/statetraj.py index 4c82e80..d820f03 100644 --- a/src/msmhelper/statetraj.py +++ b/src/msmhelper/statetraj.py @@ -60,11 +60,14 @@ def __init__(self, trajs): # get number of states self._states = mh.utils.unique(self._trajs) + # enforce true copy of trajs + if np.array_equal(self._states, np.arange(self.nstates)): + self._trajs = [traj.copy() for traj in self._trajs] # shift to indices - if np.array_equal(self._states, np.arange(1, self.nstates + 1)): + elif np.array_equal(self._states, np.arange(1, self.nstates + 1)): self._states = np.arange(1, self.nstates + 1) self._trajs = [traj - 1 for traj in self._trajs] - elif not np.array_equal(self._states, np.arange(self.nstates)): + else: # not np.array_equal(self._states, np.arange(self.nstates)): self._trajs, self._states = mh.utils.rename_by_index( self._trajs, return_permutation=True, From 9c287579ca3862b2a31813e74a1c239ba01bba2f Mon Sep 17 00:00:00 2001 From: braniii Date: Fri, 10 Nov 2023 09:13:01 +0100 Subject: [PATCH 5/6] Bump v1.1.1 --- CHANGELOG.md | 6 +++++- setup.py | 2 +- src/msmhelper/__init__.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97282e0..3bb3ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] + + +## [1.1.1] - 2023-11-10 ### Bugfix 🐛: - Fix mutable properties of `mh.StateTraj` and `mh.LumpedStateTraj`, #43 @@ -188,7 +191,8 @@ Chapman-Kolmogorov test - Initial release -[Unreleased]: https://github.com/moldyn/msmhelper/compare/v1.1.0...main +[Unreleased]: https://github.com/moldyn/msmhelper/compare/v1.1.1...main +[1.1.1]: https://github.com/moldyn/msmhelper/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/moldyn/msmhelper/compare/v1.0.4...v1.1.0 [1.0.4]: https://github.com/moldyn/msmhelper/compare/v1.0.3...v1.0.4 [1.0.3]: https://github.com/moldyn/msmhelper/compare/v1.0.2...v1.0.3 diff --git a/setup.py b/setup.py index 25b3dce..a56d672 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ def remove_gh_dark_mode_only_tags(text, tag='#gh-dark-mode-only'): # This call to setup() does all the work setuptools.setup( name='msmhelper', - version='1.1.0', + version='1.1.1', description='Helper functions for Markov State Models.', long_description=README, long_description_content_type='text/markdown', diff --git a/src/msmhelper/__init__.py b/src/msmhelper/__init__.py index 951434a..e73734c 100644 --- a/src/msmhelper/__init__.py +++ b/src/msmhelper/__init__.py @@ -30,4 +30,4 @@ unique, ) -__version__ = '1.1.0' +__version__ = '1.1.1' From ace64c81dec88191d3147f32d4e90807d3cb34cc Mon Sep 17 00:00:00 2001 From: braniii Date: Fri, 10 Nov 2023 10:22:42 +0100 Subject: [PATCH 6/6] Hide external link icon from badges. --- docs/css/extra.css | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/css/extra.css b/docs/css/extra.css index a84b75e..b11ffbb 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -65,6 +65,7 @@ a[href^="https://"]::after a[href^="https://github.com/moldyn/msmhelper"]::after, a[href^="https://moldyn.github.io/msmhelper"]::after, +a[href^="https://joss.theoj.org"]::after, a[href^="https://github.com/wemake-services"]::after, a[href^="https://pypi.org"]::after, a[href^="https://anaconda.org"]::after,