Skip to content

LinearDensity now working with residues/segments #3572

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

Merged
merged 15 commits into from
Apr 8, 2022

Conversation

BFedder
Copy link
Contributor

@BFedder BFedder commented Mar 24, 2022

Fixes #3571

LinearDensity did not work with grouping='residues' and grouping='segments'.
This is now fixed, and more tests have been added.

Changes made:
MDAnalysis/analysis/lineardensity.py:

  • in _prepare(self):

    • try/except statement replaced by if statements checking the grouping
      specified for LinearDensity.
    • masses and charges are obtained in a way appropriate for each case.
  • in _single_frame(self):

    • 'positions' variable assignment changed from elem.centroid() to
      elem.atoms.centroid() so it works for residues/segments
  • in _conclude(self):

    • Floating point arithmetic issues could lead to negative radicands. A check
      was implemented to set numbers which are close to zero to precisely zero
      before the square root (for standard deviation) is calculated.

MDAnalysisTests/analysis/test_lineardensity.py:

  • renamed previous test function and added expected masses and charges
  • added test functions for the other groupings with their respective expected
    masses and charges

Regarding my suggested change to _conclude(self):
I stuck with binsize=5 for the new tests for the other groupings for internal
consistency in the tests. With this bin size, the positions of the centres of
geometry are invariant, yielding standard deviations equal to zero. Floating point
imprecision made it possible for negative values on the order of e-13 to e-14 to
appear and cause a warning from np.sqrt() though, and that is why I added the
extra step of calculating the radicand and editing it where appropriate beforehand.
Other solutions are to just ignore this and accept nan values in the result arrays,
or change the bin size for the tests. I was hesitant to do the later to stay consistent
with the established test, but I'm happy to change this of course if that's the consensus.

PR Checklist

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

LinearDensity did not work with grouping='residues' and grouping='segments'.
This is now fixed, and more tests have been added.

Changes made:
MDAnalysis/analysis/lineardensity.py:
  - in _prepare(self):
    - try/except statement replaced by if statements checking the grouping
      specified for LinearDensity.
    - masses and charges are obtained in a way appropriate for each case.

  - in _single_frame(self):
    - 'positions' variable assignment changed from elem.centroid() to
      elem.atoms.centroid() so it works for residues/segments

  - in _conclude(self):
    - Floating point arithmetic issues could lead to negative radicands. A check
      was implemented to set numbers which are close to zero to precisely zero
      before the square root (for standard deviation) is calculated.

MDAnalysisTests/analysis/test_lineardensity.py:
  - renamed previous test function and added expected masses and charges
  - added test functions for the other groupings with their respective expected
    masses and charges
@pep8speaks
Copy link

pep8speaks commented Mar 24, 2022

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

Line 84:80: E501 line too long (86 > 79 characters)
Line 85:80: E501 line too long (86 > 79 characters)
Line 87:1: W293 blank line contains whitespace

Line 79:80: E501 line too long (104 > 79 characters)

Comment last updated at 2022-04-08 21:38:30 UTC

@codecov
Copy link

codecov bot commented Mar 24, 2022

Codecov Report

Merging #3572 (565bd4d) into develop (e940bd1) will increase coverage by 0.05%.
The diff coverage is 100.00%.

❗ Current head 565bd4d differs from pull request most recent head 0352033. Consider uploading reports for the commit 0352033 to get more accurate results

@@             Coverage Diff             @@
##           develop    #3572      +/-   ##
===========================================
+ Coverage    94.17%   94.22%   +0.05%     
===========================================
  Files          190      190              
  Lines        24686    24729      +43     
  Branches      3330     3320      -10     
===========================================
+ Hits         23247    23301      +54     
+ Misses        1391     1380      -11     
  Partials        48       48              
Impacted Files Coverage Δ
package/MDAnalysis/analysis/lineardensity.py 87.65% <100.00%> (+3.23%) ⬆️
package/MDAnalysis/topology/MOL2Parser.py 98.90% <0.00%> (-0.23%) ⬇️
package/MDAnalysis/coordinates/MOL2.py 97.63% <0.00%> (ø)
MDAnalysisTests/coordinates/base.py 95.35% <0.00%> (+0.25%) ⬆️
MDAnalysisTests/auxiliary/base.py 91.31% <0.00%> (+0.56%) ⬆️
package/MDAnalysis/due.py 76.66% <0.00%> (+29.99%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 993770f...0352033. Read the comment docs.

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

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

Couple of quick comments on the first half of the code (didn't get pass _conclude for now)

@BFedder
Copy link
Contributor Author

BFedder commented Mar 24, 2022

Hi, and thanks for the feedback!
First off, I'll be better about checking PEP8 compliance before opening a PR next time... Sorry!

I could change the code you mention above to the following to have if/elif/else, raise an exception in the case of unknown groupings, and use the same logic for residues, segments and fragments?

# Get masses and charges for the selection
if self.grouping == "atoms":
    self.masses = self._ags[0].masses
    self.charges = self._ags[0].charges

elif self.grouping in ["residues", "segments", "fragments"]:
    self.masses = np.array([elem.atoms.total_mass() for elem in group])
    self.charges = np.array(
        [elem.atoms.total_charge() for elem in group])

else:
    raise RuntimeError(
        f"{self.grouping} is not a valid value for grouping.")

@IAlibay
Copy link
Member

IAlibay commented Mar 24, 2022

First off, I'll be better about checking PEP8 compliance before opening a PR next time... Sorry!

Flake8 can be really useful here, especially if combined with something like VS code. That being said, even of the coredevs are terrible at keeping up with pep8 🙄

I could change the code you mention above to the following to have if/elif/else, raise an exception in the case of unknown groupings, and use the same logic for residues, segments and fragments?

Sure, at a quick glance that seems reasonable, although you might want to use an AttributeError instead of a RuntimeError here.

@IAlibay
Copy link
Member

IAlibay commented Mar 24, 2022

I'm going to cycle the PR (opening and closing it), I'm not sure why gh actions is being silly today...

@IAlibay IAlibay closed this Mar 24, 2022
@IAlibay IAlibay reopened this Mar 24, 2022
@IAlibay
Copy link
Member

IAlibay commented Mar 24, 2022

well at least the webhooks got triggered, that should be enough for now until actions comes back (another day another gh service issue... https://www.githubstatus.com/)

Changed the if/if/if for reading masses and charges
to if/elif/else.
Will now raise an AttributeError if invalid grouping is chosen.
'residues', 'segments' and 'fragments' now use the same logic
(elem.atoms.total_mass()).
IAlibay and others added 2 commits March 30, 2022 13:45
 Updated check of radicands in _conclude(self).
@orbeckst orbeckst requested a review from PicoCentauri April 2, 2022 00:23
Copy link
Contributor

@PicoCentauri PicoCentauri left a comment

Choose a reason for hiding this comment

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

Good work to fix this!

I have some code simplifications and one physical question/addition. For me the center of geometry does not make sense to use as a reference point. It has no physical meaning.

BFedder and others added 2 commits April 4, 2022 15:23
* Changed test of radicand to only convert negative numbers to 0
* Now uses CoM rather than CoG for density calculations
* Changed Class docstring to reflect change to CoM
* Now uses parameter for compound instead of list comprehension when
  calculating masses, charges, and CoM
* refactored test_lineardensity.py, make use of pytest functionality
  better
* Added test for case of invalid grouping selection
Copy link
Contributor

@PicoCentauri PicoCentauri left a comment

Choose a reason for hiding this comment

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

Very well. LGTM

Added second example to class docstring
@orbeckst
Copy link
Member

orbeckst commented Apr 5, 2022

@BFedder can you please resolve the conflicts?

@orbeckst
Copy link
Member

orbeckst commented Apr 5, 2022

@IAlibay can you please check if your comments were addressed?

@orbeckst orbeckst removed their assignment Apr 5, 2022
Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

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

Just two small suggested changes - I'm directly suggesting them here since they are more "my style" than anything. Feel free to say no, I'll approve after.

@BFedder
Copy link
Contributor Author

BFedder commented Apr 8, 2022

Thanks, I have taken the suggestions on board

Copy link
Member

@IAlibay IAlibay left a comment

Choose a reason for hiding this comment

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

Thanks @BFedder

@MDAnalysis/gsoc-mentors - I can't merge this as a GSoC PR due to conflicts of interest. Can someone please take over the responsibility of merging this?

@orbeckst
Copy link
Member

orbeckst commented Apr 8, 2022

@PicoCentauri can you please have a final look and then squash-merge? Thanks.

@PicoCentauri PicoCentauri merged commit 7c166c0 into MDAnalysis:develop Apr 8, 2022
@PicoCentauri
Copy link
Contributor

Thanks @BFedder for your fix!

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

Successfully merging this pull request may close these issues.

LinearDensity does not work on residues or segments
6 participants