Skip to content

corrected rotateby transformation calculation#2000

Merged
jbarnoud merged 7 commits intoMDAnalysis:developfrom
davidercruz:rotation-transform
Aug 5, 2018
Merged

corrected rotateby transformation calculation#2000
jbarnoud merged 7 commits intoMDAnalysis:developfrom
davidercruz:rotation-transform

Conversation

@davidercruz
Copy link
Contributor

Changes made in this Pull Request:

  • when rotating a given atomgroup from a different point than the origin, the rotation calculation is wrong

PR Checklist

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

@codecov
Copy link

codecov bot commented Jul 21, 2018

Codecov Report

Merging #2000 into develop will increase coverage by 0.04%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2000      +/-   ##
===========================================
+ Coverage    88.48%   88.52%   +0.04%     
===========================================
  Files          142      143       +1     
  Lines        17203    17259      +56     
  Branches      2635     2644       +9     
===========================================
+ Hits         15222    15279      +57     
+ Misses        1385     1383       -2     
- Partials       596      597       +1
Impacted Files Coverage Δ
package/MDAnalysis/transformations/rotate.py 100% <100%> (ø) ⬆️
package/MDAnalysis/analysis/dihedrals.py 97.82% <0%> (ø)
package/MDAnalysis/lib/util.py 86.86% <0%> (+0.33%) ⬆️

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 238904d...e60b268. Read the comment docs.

matrix = rotation_matrix(np.deg2rad(angle), vector, center_pos)
rotation = matrix[:3, :3]
translation = matrix[:3, 3]
ref.positions = np.dot(ref.positions, rotation) + translation
Copy link
Member

@kain88-de kain88-de Jul 21, 2018

Choose a reason for hiding this comment

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

Can you use ag.transform(matrix) for the test. It’s an atom group method that accepts the 4x4 matrix for translation and rotation.

Copy link
Contributor Author

@davidercruz davidercruz Jul 21, 2018

Choose a reason for hiding this comment

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

You're right. I used/looked at it in another transform (the fitting one), I thought " I could use this in the rotation transformation. Then I completely forgot.

I have a question though. Why do we use the inverse of the rotation matrix (the transpose) in atoms.transform and atoms.rotate? Is it related to the direction of the rotation (clockwise or counter-cockwise)?

Copy link
Member

Choose a reason for hiding this comment

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

Really it does that? I never use the combined method much myself. Did you check visually if the alignment is correct like this now or before?

If a float array of the same length as `ag` is provided, use each element of
the `array_like` as a weight for the corresponding atom in `ag`. Default is
None.
wrap: bool, optional
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this follow the atomgroup convention to call it pbc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@richardjgowers proposed the change to wrap in #1946. The argument is explained in #1185 (comment) and I agree with it. Since there's no code built upon these transformations yet, there's no risk of breaking things.

Copy link
Member

Choose a reason for hiding this comment

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

yes, there is a risk of breaking user expectation. As a newbie using MDAnalysis I would be confusing why the transformation has a wrap argument and the corresponding atomgroup method a pbc argument. This is not an intuitive design.

Besides the comment also mentions to deprecate the pbc keyword argument. Is anyone on that yet?

Copy link
Member

Choose a reason for hiding this comment

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

@davidercruz did you start work on introducing the wrap keyword in the other atomgroup functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kain88-de not yet

Copy link
Member

Choose a reason for hiding this comment

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

Yeah sorry, I didn't want to propagate the pbc keyword any more. I've started looking at the unwrap keyword. Adding the wrap keyword should just be deprecating pbc and aliasing it to wrap

matrix = rotation_matrix(np.deg2rad(angle), vector, center_pos)
rotation = matrix[:3, :3]
translation = matrix[:3, 3]
ref.positions = np.dot(ref.positions, rotation) + translation
Copy link
Member

Choose a reason for hiding this comment

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

Really it does that? I never use the combined method much myself. Did you check visually if the alignment is correct like this now or before?

@davidercruz
Copy link
Contributor Author

@kain88-de In theory, using the transposed of the matrix for a 45 degree rotation would result in a -45 degree rotation. There must be a reason for this being the default behaviour. I don't have a molecular viewer in this computer, but I'll try it tomorrow at work to see the difference.
Anyway, I have changed rotateby to be consistent with what's already implemented in the API

@kain88-de
Copy link
Member

kain88-de commented Jul 22, 2018 via email

@davidercruz
Copy link
Contributor Author

@kain88-de I tested it on a molecule. I understand now. The rotations follow the right-hand rule.

center: str, optional
used to choose the method of centering on the given atom group. Can be 'geometry'
or 'mass'
use the eighted center of an AtomGroup as the point from where the rotation axis
Copy link
Member

Choose a reason for hiding this comment

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

weighted

@orbeckst
Copy link
Member

orbeckst commented Jul 28, 2018

General comment to @davidercruz : If you find an actual bug such as this one then please first raise an actual issue and then put in the PR. Fixing the bug is awesome but for keeping track of serious issues, it is much more convenient to have an actual issue to refer to (e.g., in discussions and in the CHANGELOG) – An issue is preferred over a PR number because one might actually need multiple PRs for fixing a complex issuesand conceptually it makes more sense to re-open an issue if necessary than to re-open a PR.

You can also raise an issue after the PR and edit the PR to refer to it...

@kain88-de
Copy link
Member

If you find an actual bug such as this one then please first raise an actual issue and then put in the PR.

even better is to fix it in a separate PR. It gives more overview and less code to review. This makes the whole process easier for us and faster for you!

Copy link
Member

@kain88-de kain88-de left a comment

Choose a reason for hiding this comment

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

There are some issues left with the documentation. Did you also render it locally and check that it looks OK?

@@ -69,11 +76,14 @@ def rotateby(angle, direction, point=None, center="geometry", wrap=False, ag=Non
vector that will define the direction of a custom axis of rotation from the
Copy link
Member

Choose a reason for hiding this comment

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

I would mention the expected shapes already in the docs.

angle = np.deg2rad(angle)
try:
direction = np.asarray(direction, np.float32)
if direction.shape != (3, ) and direction.shape != (1, 3):
Copy link
Member

Choose a reason for hiding this comment

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

did you check the (1, 3) shape? I can't see it in the tests.

@@ -69,11 +76,14 @@ def rotateby(angle, direction, point=None, center="geometry", wrap=False, ag=Non
vector that will define the direction of a custom axis of rotation from the
provided point.
ag: AtomGroup, optional
Copy link
Member

Choose a reason for hiding this comment

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

what happens if this is None? I find no mention in the documentation

@davidercruz
Copy link
Contributor Author

@kain88-de Yes, I built the docs using sphinx and it looks ok now. I also updated the docs of my other PRs.

@kain88-de
Copy link
Member

I think @jbarnoud should be back to give this a final look

@jbarnoud jbarnoud added this to the 0.19.0 milestone Aug 5, 2018
@jbarnoud jbarnoud self-assigned this Aug 5, 2018
@jbarnoud jbarnoud added the Component-Transformations On-the-fly transformations label Aug 5, 2018
@jbarnoud jbarnoud merged commit bf424a5 into MDAnalysis:develop Aug 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component-Transformations On-the-fly transformations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants