Skip to content
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

distopia 0.3.0 compatibility changes #4734

Open
wants to merge 34 commits into
base: develop
Choose a base branch
from

Conversation

hmacdope
Copy link
Member

@hmacdope hmacdope commented Oct 15, 2024

Test implementation of distopia-0.3.0 distances API.

Changes made in this Pull Request:

  • Adds support for distopia 0.3.0 API

PR Checklist

  • Tests?
  • Docs?
  • CHANGELOG updated?
  • Issue raised/referenced?

Developers certificate of origin


📚 Documentation preview 📚: https://mdanalysis--4734.org.readthedocs.build/en/4734/

@pep8speaks
Copy link

pep8speaks commented Oct 15, 2024

Hello @hmacdope! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 64:80: E501 line too long (82 > 79 characters)
Line 90:80: E501 line too long (86 > 79 characters)
Line 96:80: E501 line too long (103 > 79 characters)
Line 98:80: E501 line too long (83 > 79 characters)
Line 102:80: E501 line too long (103 > 79 characters)
Line 105:80: E501 line too long (83 > 79 characters)
Line 109:80: E501 line too long (107 > 79 characters)
Line 111:80: E501 line too long (87 > 79 characters)
Line 113:1: E302 expected 2 blank lines, found 1
Line 114:80: E501 line too long (124 > 79 characters)
Line 116:80: E501 line too long (95 > 79 characters)
Line 118:1: E302 expected 2 blank lines, found 1
Line 119:80: E501 line too long (124 > 79 characters)
Line 121:80: E501 line too long (95 > 79 characters)
Line 123:1: E302 expected 2 blank lines, found 1
Line 130:80: E501 line too long (82 > 79 characters)
Line 132:80: E501 line too long (82 > 79 characters)
Line 134:1: E302 expected 2 blank lines, found 1
Line 135:80: E501 line too long (82 > 79 characters)
Line 137:80: E501 line too long (82 > 79 characters)
Line 139:1: E302 expected 2 blank lines, found 1
Line 144:1: E302 expected 2 blank lines, found 1
Line 149:1: E302 expected 2 blank lines, found 1
Line 153:1: W391 blank line at end of file

Line 77:53: W291 trailing whitespace
Line 344:1: W293 blank line contains whitespace
Line 348:44: W291 trailing whitespace
Line 374:80: E501 line too long (80 > 79 characters)
Line 457:44: W291 trailing whitespace
Line 483:80: E501 line too long (80 > 79 characters)
Line 1677:44: W291 trailing whitespace
Line 1703:80: E501 line too long (80 > 79 characters)
Line 1800:44: W291 trailing whitespace
Line 1827:80: E501 line too long (80 > 79 characters)
Line 1939:44: W291 trailing whitespace
Line 1963:80: E501 line too long (80 > 79 characters)

Line 1095:32: E222 multiple spaces after operator
Line 1099:5: E303 too many blank lines (2)
Line 1106:32: E222 multiple spaces after operator

Comment last updated at 2025-01-02 07:42:51 UTC

Copy link

Linter Bot Results:

Hi @hmacdope! Thanks for making this PR. We linted your code and found the following:

Some issues were found with the formatting of your code.

Code Location Outcome
main package ⚠️ Possible failure
testsuite ✅ Passed

Please have a look at the darker-main-code and darker-test-code steps here for more details: https://github.com/MDAnalysis/mdanalysis/actions/runs/11344140762/job/31548247192


Please note: The black linter is purely informational, you can safely ignore these outcomes if there are no flake8 failures!

Copy link

codecov bot commented Oct 15, 2024

Codecov Report

Attention: Patch coverage is 90.14085% with 7 lines in your changes missing coverage. Please review.

Project coverage is 93.62%. Comparing base (b8fe34b) to head (730cee9).

Files with missing lines Patch % Lines
package/MDAnalysis/lib/distances.py 88.57% 2 Missing and 2 partials ⚠️
package/MDAnalysis/lib/_distopia.py 91.66% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4734      +/-   ##
===========================================
- Coverage    93.66%   93.62%   -0.04%     
===========================================
  Files          177      189      +12     
  Lines        21787    22909    +1122     
  Branches      3067     3079      +12     
===========================================
+ Hits         20406    21448    +1042     
- Misses         929     1007      +78     
- Partials       452      454       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hmacdope hmacdope marked this pull request as ready for review October 17, 2024 03:26
@hmacdope
Copy link
Member Author

@orbeckst @richardjgowers this is ready for a first look over. The failing tests are for a 180 degree dihedral where numpy returns np.pi and distopia returns -np.pi (equivalent in polar coordinates). Are we ok to change the test to account for this? There are also options for changing in distopia but at the cost of a lot of performance improvement.

@orbeckst
Copy link
Member

I'd be ok with changing tests but adding a note to docs.

Copy link
Member

@orbeckst orbeckst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if the tests are actually run — if we can confirm that they run then I have no blockers.

ALso updated CHANGELOG, please.

package/MDAnalysis/lib/distances.py Outdated Show resolved Hide resolved
package/MDAnalysis/lib/_distopia.py Show resolved Hide resolved
@orbeckst
Copy link
Member

FYI, upstream distopia 0.3.0 release is currently breaking all tests, see #4739 .

@orbeckst orbeckst mentioned this pull request Oct 18, 2024
5 tasks
@orbeckst orbeckst mentioned this pull request Oct 18, 2024
8 tasks
Copy link
Member

@orbeckst orbeckst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome to also have support for distance_array/self_distance_array!

I have a few comments on the docs (see inline) and minor suggestion for the test.

My major issue at the moment is that codecov does not mark the distance_array functions as tested. Given that it sees the bonds and angles, I wonder if we are really testing distopia-accelerated distance_array. Can you please double check? Thanks!

package/MDAnalysis/lib/distances.py Outdated Show resolved Hide resolved
package/MDAnalysis/lib/distances.py Outdated Show resolved Hide resolved
package/CHANGELOG Outdated Show resolved Hide resolved
import MDAnalysis.lib._distopia
assert not MDAnalysis.lib._distopia.HAS_DISTOPIA
sys.modules.pop("MDAnalysis.lib._distopia", None)
if HAS_DISTOPIA:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the test I'd ignore HAS_DISTOPIA and not add the conditional. In principle we always want to test explicitly that the version check is working. By using the conditional you implicitly assume that HAS_DISTOPIA was set to False because of the version check.

assert not MDAnalysis.lib._distopia.HAS_DISTOPIA
sys.modules.pop("MDAnalysis.lib._distopia", None)
if HAS_DISTOPIA:
with patch('distopia.__version__', '0.1.0'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works if we can actually import distopia so I now understand why you need the conditional.

I'd prefer the test to work regardless of distopia being present, which can be achieved with the previous approach of creating a mocked module.

background on patch()

(I had to read up on patch to understand how it does its magic so in case anyone else is interested, here's the background.)

The docs for patch() say

unittest.mock.patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
...
target should be a string in the form 'package.module.ClassName'. The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch() from.

(my emphasis).

Just to confirm: patch needs an importable module if one relies on the default behavior:

In [2]: from unittest.mock import patch

In [3]: import distopia
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[3], line 1
----> 1 import distopia

ModuleNotFoundError: No module named 'distopia'

In [4]: with patch('distopia.__version__', '0.1.0'):
   ...:     import distopia
   ...:     print(distopa.__version__)
   ...:

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[4], line 1
----> 1 with patch('distopia.__version__', '0.1.0'):
      2     import distopia
      3     print(distopa.__version__)
...
ModuleNotFoundError: No module named 'distopia'

package/MDAnalysis/lib/_distopia.py Show resolved Hide resolved
) -> None:
distopia.calc_self_distance_array_no_box(coords, results=results)

def calc_self_distance_array_ortho(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not tested + docs of self_distance_array

package/MDAnalysis/lib/_distopia.py Show resolved Hide resolved
package/MDAnalysis/lib/_distopia.py Outdated Show resolved Hide resolved
package/MDAnalysis/lib/distances.py Show resolved Hide resolved
@@ -946,6 +939,19 @@ def test_bonds(self, box, backend, dtype, pos, request):
assert_almost_equal(dists_pbc[3], 3.46410072, self.prec,
err_msg="PBC check #w with box")

@pytest.mark.parametrize("dtype", (np.float32, np.float64))
@pytest.mark.parametrize("backend", distopia_conditional_backend())
def test_results_inplace_all_backends(self, backend, dtype,):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problematic test here.

# distopia requires that all the input arrays are the same type,
# while MDAnalysis allows for mixed types, this should be changed
# pre 0.3.0 release see issue #3707
distances = distances.astype(np.float32)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may create a copy.

Copy link
Member

@orbeckst orbeckst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the astype required for distopia you may be creating a copy so that the top-level in-place operation is not actually in-place anymore. ... I think.

if backend == 'distopia':
# mda expects the result to be in float64, so we need to convert it back
# to float64, change for 3.0, see #3707
distances = distances.astype(np.float64)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may create a copy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may have to instead put the numbers back into the original array to make in-place work.

result[:] = distances

...

return result

or something of that kind.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used this strategy

@orbeckst
Copy link
Member

@hmacdope did you look further into the copy vs in-place issue?

@orbeckst orbeckst self-assigned this Nov 21, 2024
@hmacdope
Copy link
Member Author

hmacdope commented Dec 2, 2024

@orbeckst I'll try get back to this over holidays, sorry for delay.

@orbeckst
Copy link
Member

Ok! I think getting this one working will be important for a MDA paper.

@orbeckst
Copy link
Member

@hmacdope I resolved the merge conflicts but please double-check that I didn't miss anything.

@orbeckst orbeckst added this to the Release 3.0 milestone Dec 12, 2024
@hmacdope hmacdope requested a review from orbeckst January 2, 2025 07:43
@hmacdope
Copy link
Member Author

hmacdope commented Jan 2, 2025

@orbeckst this is probably ready for another look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants