-
Notifications
You must be signed in to change notification settings - Fork 10
developing back end run methods #216
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
Changes from 19 commits
e71456d
6c67ec1
7bcdf49
a87cb11
7edde0d
48016c5
59c819c
fb58f27
1f7f2d1
179603f
46d3cf2
f47c806
5e02322
2fc9135
37cd1d7
0dc7e32
a0de2d9
273c1af
8212d11
653210e
7eff11f
67261cb
2f63c3a
ce02b3b
cf4bd40
f45fc6b
1a90ed8
7054bb5
19f7c84
40381aa
8870e39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -469,14 +469,14 @@ def _single_universe(self): | |
| Run on each universe in the ensemble during when | ||
| self.run in called. | ||
| """ | ||
| pass # pragma: no cover | ||
| raise NotImplementedError | ||
|
|
||
| def _single_frame(self): | ||
| """Calculate data from a single frame of trajectory | ||
|
|
||
| Called on each frame for universes in the Ensemble. | ||
| """ | ||
| pass # pragma: no cover | ||
| raise NotImplementedError | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add test that checks that this NotImplementedError is raised. If necessary by calling the method explicitly def test_single_frame_raises_NotImplementedError():
...
ea = EnsembleAnalysis(...)
with pytest.raises(NotImplementedError):
ea._single_frame()
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://github.com/Becksteinlab/MDPOW/blob/ensemble_run_update/mdpow/tests/test_dihedral.py
I am going to add explicit tests for raising NotImplementedError for _single_frame() and _single_universe() similar to pattern in your comment above, placed in test_ensemble.py, because test_run.py is for the partition coefficient calculation and test_ensemble.py deals with EnsembleAnalysis class where this run method that calls single_frame/uni is defined
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Look into https://github.com/Becksteinlab/MDPOW/pull/216/files and you see the annotation by codecov that says that the line was not covered by tests. Also check the codecov report in the checks and ultimately https://app.codecov.io/gh/Becksteinlab/MDPOW/pull/216
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your tests do not check that the base class raises NotImplementedError. |
||
|
|
||
| def _prepare_ensemble(self): | ||
| """For establishing data structures used in running | ||
|
|
@@ -505,27 +505,34 @@ def _conclude_ensemble(self): | |
| pass # pragma: no cover | ||
|
|
||
| def run(self, start=None, stop=None, step=None): | ||
| """Runs _single_universe on each system and _single_frame | ||
| """Runs _single_universe on each system or _single_frame | ||
| on each frame in the system. | ||
|
|
||
| First iterates through keys of ensemble, then runs _setup_system | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add markup :meth:`_setup_system` |
||
| which defines the system and trajectory. Then iterates over | ||
| trajectory frames. | ||
|
|
||
| NotImplementedError will detect whether _single_universe or _single_frame | ||
| should be implemented, based on which is defined in the EnsembleAnalysisClass. | ||
| Only one of the two aforementioned functions should be defined for the respective | ||
| analysis class. For verbose functionality, the analysis will currently show two | ||
| iteration bars, where only one of which will actually be iterated, while the other | ||
| will load to completion instantaneously, showing the system that is being worked on. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These implementation details are developer documentation and do not need to be in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I need to create a Read the Docs account and link my GitHub account and repository to make these changes as indicated in the Sphinx documentation, or do I make the changes to the text files (i.e. ensemble_analysis.txt) and push the changes straight to GitHub?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need an account. The CI is already using RTD. You only need to edit the docs here, namely ensemble_analysis.txt.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The CI puts an updated view of the docs for the PR at https://mdpow--216.org.readthedocs.build/en/216/
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! I think everything merged and pushed correctly, and all tests passed. I do need to modify the docs slightly after following the link above, but will wait until your review to make all necessary documentation changes in one commit. |
||
| """ | ||
| logger.info("Setting up systems") | ||
| self._prepare_ensemble() | ||
| for self._key in ProgressBar(self._ensemble.keys(), verbose=True): | ||
| self._setup_system(self._key, start=start, stop=stop, step=step) | ||
| self._prepare_universe() | ||
| self._single_universe() | ||
| for i, ts in enumerate(ProgressBar(self._trajectory[self.start:self.stop:self.step], verbose=True, | ||
| try: | ||
| self._single_universe() | ||
| except NotImplementedError: | ||
|
orbeckst marked this conversation as resolved.
|
||
| for i, ts in enumerate(ProgressBar(self._trajectory[self.start:self.stop:self.step], verbose=True, | ||
| postfix=f'running system {self._key}')): | ||
| self._frame_index = i | ||
| self._ts = ts | ||
| self.frames[i] = ts.frame | ||
| self.times[i] = ts.time | ||
| self._single_frame() | ||
| self._conclude_universe() | ||
| self._frame_index = i | ||
| self._ts = ts | ||
| self.frames[i] = ts.frame | ||
| self.times[i] = ts.time | ||
| self._single_frame() | ||
| logger.info("Moving to next universe") | ||
| logger.info("Finishing up") | ||
| self._conclude_ensemble() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,9 +23,9 @@ | |
|
|
||
| class TestDihedral(object): | ||
| DG48910_mean = -172.9849512527183 | ||
| DG491011_mean = -3.7300197060478695 | ||
| DG48910_var = 1490.6576365537262 | ||
| DG491011_var = 128.3805265432388 | ||
| DG491011_mean = 177.74725233051953 | ||
| DG48910_var = 0.20311120667628546 | ||
| DG491011_var = 0.006976126708773456 | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
|
|
||
| def setup(self): | ||
| self.tmpdir = td.TempDir() | ||
|
|
@@ -37,25 +37,25 @@ def teardown(self): | |
| self.tmpdir.dissolve() | ||
|
|
||
| def test_dataframe(self): | ||
| dh1 = self.Ens.select_atoms('name C4 or name C17 or name S2 or name N3') | ||
| dh1 = self.Ens.select_atoms('name C4', 'name C17', 'name S2', 'name N3') | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
| dh_run = DihedralAnalysis([dh1]).run(start=0, stop=4, step=1) | ||
|
|
||
| results = dh_run.results | ||
|
|
||
| assert results['selection'][0] == 'S2-N3-C4-C17' | ||
| assert results['selection'][0] == 'C4-C17-S2-N3' | ||
|
orbeckst marked this conversation as resolved.
|
||
| for s in results['solvent']: | ||
| assert s == 'water' | ||
| for i in results['interaction'][:12]: | ||
| assert i == 'Coulomb' | ||
|
|
||
| def test_selection_error(self): | ||
| dh1 = self.Ens.select_atoms('name C17 or name S2 or name N3') | ||
| dh1 = self.Ens.select_atoms('name C17', 'name S2', 'name N3') | ||
|
orbeckst marked this conversation as resolved.
|
||
| with pytest.raises(SelectionError): | ||
| dh_run = DihedralAnalysis([dh1]).run(start=0, stop=4, step=1) | ||
|
|
||
| def test_results_recursive1(self): | ||
| dh1 = self.Ens.select_atoms('name C11 or name C10 or name C9 or name C4') | ||
| dh2 = self.Ens.select_atoms('name C11 or name C10 or name C9 or name C4') | ||
| dh1 = self.Ens.select_atoms('name C11', 'name C10', 'name C9', 'name C4') | ||
| dh2 = self.Ens.select_atoms('name C11', 'name C10', 'name C9', 'name C4') | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
|
|
||
| dh_run1 = DihedralAnalysis([dh1]).run(start=0, stop=4, step=1) | ||
| dh_run2 = DihedralAnalysis([dh2]).run(start=0, stop=4, step=1) | ||
|
|
@@ -64,29 +64,34 @@ def test_results_recursive1(self): | |
| assert dh_run1.results['dihedral'][i] == dh_run2.results['dihedral'][i] | ||
|
|
||
| def test_results_recursive2(self): | ||
| dh1 = self.Ens.select_atoms('name C11 or name C10 or name C9 or name C4') | ||
| dh2 = self.Ens.select_atoms('name C8 or name C4 or name C9 or name C10') | ||
| dh1 = self.Ens.select_atoms('name C11', 'name C10', 'name C9', 'name C4') | ||
| dh2 = self.Ens.select_atoms('name C8', 'name C4', 'name C9', 'name C10') | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
|
|
||
| dh_run = DihedralAnalysis([dh1, dh2]).run(start=0, stop=4, step=1) | ||
|
|
||
| dh1_result = dh_run.results.loc[dh_run.results['selection'] == 'C4-C9-C10-C11']['dihedral'] | ||
| dh2_result = dh_run.results.loc[dh_run.results['selection'] == 'C4-C8-C9-C10']['dihedral'] | ||
| dh1_result = dh_run.results.loc[dh_run.results['selection'] == 'C11-C10-C9-C4']['dihedral'] | ||
| dh2_result = dh_run.results.loc[dh_run.results['selection'] == 'C8-C4-C9-C10']['dihedral'] | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
|
|
||
| dh1_mean = circmean(dh1_result, high=180, low=-180) | ||
| dh2_mean = circmean(dh2_result, high=180, low=-180) | ||
| dh1_var = circvar(dh1_result, high=180, low=-180) | ||
| dh2_var = circvar(dh2_result, high=180, low=-180) | ||
|
|
||
| assert_almost_equal(self.DG48910_mean, dh1_mean, 6) | ||
| assert_almost_equal(self.DG48910_var, dh1_var, 6) | ||
| assert_almost_equal(self.DG491011_mean, dh2_mean, 6) | ||
| assert_almost_equal(self.DG491011_var, dh2_var, 6) | ||
| assert_almost_equal(dh1_mean, self.DG48910_mean, 6) | ||
| assert_almost_equal(dh1_var, self.DG48910_var, 6) | ||
| assert_almost_equal(dh2_mean, self.DG491011_mean, 6) | ||
| assert_almost_equal(dh2_var, self.DG491011_var, 6) | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
|
|
||
| def test_ValueError_different_ensemble(self): | ||
| other = Ensemble(dirname=self.tmpdir.name, solvents=['water']) | ||
| dh1 = self.Ens.select_atoms('name C11 or name C10 or name C9 or name C4') | ||
| dh2 = other.select_atoms('name C8 or name C4 or name C9 or name C10') | ||
| dh1 = self.Ens.select_atoms('name C11', 'name C10', 'name C9', 'name C4') | ||
| dh2 = other.select_atoms('name C8', 'name C4', 'name C9', 'name C10') | ||
|
orbeckst marked this conversation as resolved.
Outdated
|
||
| with pytest.raises(ValueError, | ||
| match='Dihedral selections from different Ensembles, '): | ||
| DihedralAnalysis([dh1, dh2]) | ||
|
|
||
| def test_single_universe(self): | ||
| dh = self.Ens.select_atoms('name C4', 'name C17', 'name S2', 'name N3') | ||
| with pytest.raises(NotImplementedError): | ||
| DihedralAnalysis([dh])._single_universe() | ||
|
|
||
|
Comment on lines
+96
to
+100
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is not strictly necessary but we can leave it in, as a check that the DihedralAnalysis does not do something weird to |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reformat this message so that it does not contain newline/space
And we can use f-strings.