-
Notifications
You must be signed in to change notification settings - Fork 670
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
Add pbc kwarg to Contacts #2646
Conversation
@@ -424,18 +424,28 @@ def __init__(self, u, select, refgroup, method="hard_cut", radius=4.5, | |||
self.select = select | |||
self.grA = u.select_atoms(select[0]) | |||
self.grB = u.select_atoms(select[1]) | |||
|
|||
self.is_box = self.fraction_kwargs.get('is_box') |
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.
The name is_box
isn't particularly intuitive; something like pbc
would be better.
Also, since it is only used in __init__
and not in the fraction_contacts methods where fraction_kwargs
is passed, it'd make more sense to directly include as an argument of __init__
rather than through kwargs
. This would also make it easier to include in the docs here.
sel1 = "(resname ARG LYS) and (name NH* NZ)" | ||
sel2 = "(resname ASP GLU) and (name OE* OD*)" | ||
acidic = u.select_atoms(sel2) | ||
basic = u.select_atoms(sel1) |
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.
You could focus the test on a particular pair we know is split across the periodic boundary, to make it easier to directly check the distances measured are what we expect given PBC.
|
||
q.r0 = np.array(q.r0).squeeze() | ||
r.r0 = np.array(r.r0).squeeze() | ||
assert_array_equal(q.r0,r.r0) |
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.
We expect the distance to be different with or without consideration of the periodic boundaries, so this test is currently failing; maybe you could compare directly with what we expect the values to be instead?
@fiona-naughton @orbeckst can you please review these changes? |
Just FYI, |
@lilyminium I didn't get this. Can you please clarify :) |
Codecov Report
@@ Coverage Diff @@
## develop #2646 +/- ##
===========================================
- Coverage 91.01% 90.96% -0.05%
===========================================
Files 174 174
Lines 23595 23314 -281
Branches 3082 3083 +1
===========================================
- Hits 21474 21207 -267
+ Misses 1498 1487 -11
+ Partials 623 620 -3
Continue to review full report at Codecov.
|
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.
A couple comments.
Following @lilyminium's comment, you could set a value box
based on pbc
(ie. None
or dimensions, as appropriate) and run distance_array
with that, rather than needing an if/else every time.
@@ -392,6 +392,9 @@ def __init__(self, u, select, refgroup, method="hard_cut", radius=4.5, | |||
method : string | callable (optional) | |||
Can either be one of ``['hard_cut' , 'soft_cut', 'radius_cut']`` or a callable | |||
with call signature ``func(r, r0, **kwargs)`` (the "Contacts API"). | |||
pbc : bool (optional) | |||
Uses periodic boundary conditions to calculate distances if set to ``True``; the | |||
default is ``False``. |
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.
I would set the default to True
instead, since this is probably what most users would expect the behaviour to be
@@ -461,7 +479,8 @@ def _new_selections(u_orig, selections, frame): | |||
"""create stand alone AGs from selections at frame""" | |||
u = MDAnalysis.Universe(u_orig.filename, u_orig.trajectory.filename) | |||
u.trajectory[frame] | |||
return [u.select_atoms(s) for s in selections] | |||
temp_u = u.copy() |
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.
The idea of using copy()
here would be to avoid having to reload a universe from the filenames - you can copy u_orig
directly.
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.
can I fix this in another pull request?
average_contacts_r = np.mean(r.timeseries[:, 1]) | ||
average_contacts_q = np.mean(q.timeseries[:, 1]) | ||
|
||
assert not average_contacts_q == average_contacts_r |
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.
A test like this isn't ideal as inequality could be due to any number of things going wrong. I'd find a specific value(s) you expect to be returned and check against that - say by measuring the expected distances with and without PBC in another program or directly using distance_array
Yep, thanks for clarifying @fiona-naughton. However the box dimensions will change for every frame in an NPT ensemble so it might be better to set a box getting function to use in if pbc:
self._get_box = lambda ts: ts.dimensions
else:
self._get_box = lambda ts: None and call it with |
@lilyminium thanks for clarifying and providing better way to implement this :) |
@fiona-naughton any other changes needed? |
@lilyminium can you please review this. |
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.
Please also update CHANGELOG and add a .. versionchanged
to the docstring of Contacts
.
refgroup=(acidic, basic), radius=6.0, pbc=pbc) | ||
r.run() | ||
if pbc: | ||
expected = [1., 0.43138152, 0.3989021, 0.43824337, 0.41948765, |
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.
Looks good @ss62171 -- personally I would change the test so that the expected values are also part of parametrize
, e.g.
@pytest.mark.parametrize("pbc,expected", [
(True, [1., 0.43138152, 0.3989021, 0.43824337, 0.41948765,
0.42223239, 0.41354071, 0.43641354, 0.41216834, 0.38334858]),
(False, [1., 0.42327791, 0.39192399, 0.40950119, 0.40902613,
0.42470309, 0.41140143, 0.42897862, 0.41472684, 0.38574822])
])
A new push would also restart the Appveyor tests, which as far as I can tell have failed due to running out of time. I can't seem to restart these jobs individually without a commit -- @MDAnalysis/coredevs have any insight?
@@ -373,6 +373,8 @@ class Contacts(AnalysisBase): | |||
.. versionchanged:: 1.0.0 | |||
``save()`` method has been removed. Use ``np.savetxt()`` on | |||
:attr:`Contacts.timeseries` instead. | |||
.. versionchanged:: 2.0.0 |
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.
Thanks @ss62171, just one final thing -- this should be for version 1.0.0 which hasn't been released yet.
Thanks @ss62171, looks good to me! Are you happy with this @fiona-naughton? |
@lilyminium any updates on this? |
Sorry for the delay @ss62171, I've been busy. I've requested another review from @fiona-naughton and if she doesn't do so within 24 hours I'll presume that she is too and merge the PR. |
Fiona's comments re: pbc=True kwarg name and default, and the test equality have been addressed; the copy() comment refers to now-removed code.
Thanks for your patience @ss62171, this will make Contacts analysis much nicer to use. |
Fixes #2368
Changes made in this Pull Request:
PR Checklist