plane and axis centering transformations#1973
plane and axis centering transformations#1973davidercruz wants to merge 22 commits intoMDAnalysis:developfrom
Conversation
jbarnoud
left a comment
There was a problem hiding this comment.
Oops! I forgot to click "submit". I am very sorry about that. It is great that Github saves pending reviews!!!!!
|
|
||
| Returns | ||
| ------- | ||
| :class:`~MDAnalysis.coordinates.base.Timestep` object |
There was a problem hiding this comment.
This line could be just MDAnalysis.coordinates.base.Timestep without the :class: and "object". See https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard.
| is centered on an axis. This axis can only be parallel to the x, y or z planes. | ||
|
|
||
| Example | ||
| ------- |
There was a problem hiding this comment.
You need to tell what your example is doing, or I just see random code.
There was a problem hiding this comment.
Also, the example is aimed at the user which is not really supposed to use the function directly on a TimeStep. Your example should probably use the transformation feature.
| center = np.asarray([_origin[0], ag_center[1], _origin[2]], np.float32) | ||
| if axis == 'z': | ||
| center = np.asarray([_origin[0], _origin[1], ag_center[2]], np.float32) | ||
| vector = center - ag_center |
There was a problem hiding this comment.
Are we guaranteed that the dtype of vector will be float32?
There was a problem hiding this comment.
center_of_mass and center_of_geometry output an array of dtype float32. I can typecast it again, but it isn't really necessary.
ps - unless someone changes the center_of functions in the future. If that changes than tests will likely fail.
There was a problem hiding this comment.
There is no need to typecast again. Though, it would be good to have a test for each transformation to make sure the coordinates have the correct dtype.
| ---------- | ||
| ag: AtomGroup | ||
| atom group to be centered on the unit cell. | ||
| plane: str |
There was a problem hiding this comment.
'x', 'y', and 'z' are not planes so your explanation is unclear. I guess if I want to center on the 'XY' plane, I need to provide 'z'; but I am not really sure. This makes for an unclear API.
There was a problem hiding this comment.
Centering on xz,xy and yz planes is not trivial. Since these planes cross more than 1 axis, the center of these planes is the center of the cross-section area formed by these planes in the unit cell.
Currently, the code only works with planes that are parallel to x=0, y=0 or z=0.
There was a problem hiding this comment.
The way I see it, assuming a orthogonal box, centering on XY means you do not change the Z coordinate. It is always tricky to have a mental picture of an arbitrary triclinic box, but assuming the lower triangle of the box matrix is 0, then it should work the same. If the triangle is not 0, then it is trickier as you do have to change Z; but we can make sure it is not the case and fail if it is.
There was a problem hiding this comment.
okay I see I was confused, sorry. XY is the same as z=0, XZ is y=0 and YZ is x=0. I was talking about non-perpendicular planes, sorry. I will simply change the strings to match.
|
No newline at end of file |
||
|
|
||
|
|
||
| def center_in_plane(ag, plane, coordinate=0, origin=None, center='geometry', wrap=False): |
There was a problem hiding this comment.
Why defaulting 'origin' to None and not its value?
|
|
||
| """ | ||
|
|
||
| if isinstance(plane, string_types): |
There was a problem hiding this comment.
You do not need to test the type. You just need to test is it is not None and not in 'xyz'. In general, testing on type should be avoided. Python is keen on duck-typing. If I write an object that pretends to be 'x', you should not discriminate against it if you can avoid it.
| if plane == 'z': | ||
| shift = _origin[2]+coordinate | ||
| position = [boxcenter[0], boxcenter[1], shift] | ||
| ts = center_in_box(ag, center=center, point=position, wrap=wrap)(ts) |
There was a problem hiding this comment.
You are doing for every frame all the checks that you removed from the wrapped function in center_in_box. This does not seem very efficient.
jbarnoud
left a comment
There was a problem hiding this comment.
Some more comments on top of the previous ones that are still valid.
package/CHANGELOG
Outdated
|
|
||
| Enhancements | ||
|
|
||
| * Added box/axis/plane centering trajectory transformations |
There was a problem hiding this comment.
Instead of adding this line to the changelog, you can update the other line about centering method by listing this PR next to the other one.
| Returns | ||
| ------- | ||
| :class:`~MDAnalysis.coordinates.base.Timestep` object | ||
| `~MDAnalysis.coordinates.base.Timestep` |
There was a problem hiding this comment.
Just the type, no back-tick nor tilde.
| .. code-block:: python | ||
|
|
||
| ag = u.residues[1].atoms | ||
| ts = MDAnalysis.transformations.center_in_axis(ag,'x', [0,0,1], center='mass')(ts) |
There was a problem hiding this comment.
My previous comment on the example applies here as well.
| center = np.asarray([_origin[0], ag_center[1], _origin[2]], np.float32) | ||
| if axis == 'z': | ||
| center = np.asarray([_origin[0], _origin[1], ag_center[2]], np.float32) | ||
| vector = center - ag_center |
There was a problem hiding this comment.
There is no need to typecast again. Though, it would be good to have a test for each transformation to make sure the coordinates have the correct dtype.
Codecov Report
@@ Coverage Diff @@
## develop #1973 +/- ##
===========================================
+ Coverage 89.44% 89.48% +0.03%
===========================================
Files 157 157
Lines 18775 18857 +82
Branches 2713 2722 +9
===========================================
+ Hits 16794 16874 +80
- Misses 1378 1379 +1
- Partials 603 604 +1
Continue to review full report at Codecov.
|
|
@davidercruz My comments on the API still stand:
At this point, I think these are the main issues. The rest looks OK, but depends on the API. For |
… changed some options names to something clearer; updated tests
jbarnoud
left a comment
There was a problem hiding this comment.
Could you:
- remove the
dargument. The name is bad (it is not explicit at all), and it triger a behaviour that is out of the scope of the function; - avoid the succesion of ifs with the dict trick I showed you;
- rename
center_fromtocenter_to, one of my earlier comment was confusing.
jbarnoud
left a comment
There was a problem hiding this comment.
I have connection issues so I am reviewing from my phone. It is less than optimal so I expect I missed some stuff...
|
|
||
| def wrapped(ts): | ||
| if isinstance(center_from, string_types) and center_from == 'center': | ||
| if isinstance(center_to, string_types) and center_to == 'center': |
There was a problem hiding this comment.
You do not need to test for the type. Testing for the value is enough.
| used to define the plane on which the given AtomGroup will be centered. Suported | ||
| planes are yz, xz and xy planes. | ||
| center_to: array-like or str | ||
| coordinate from which the axes are centered. Can be an array of three coordinate |
| """ | ||
|
|
||
| pbc_arg = wrap | ||
| if plane is not None: |
There was a problem hiding this comment.
Can 'plane' be None? What would it mean?
| if center_to != 'center': | ||
| _origin = center_to | ||
| position[plane] = _origin[plane] | ||
| vector = np.asarray(position, np.float32) - center_method() |
There was a problem hiding this comment.
Are you really working in 2D there? From what I read you are centering in the box, not the plane.
| raise ValueError('{} is not a valid "center_to"'.format(center_to)) | ||
| else: | ||
| center_to = np.asarray(center_to, np.float32) | ||
| if center_to.shape != (3, ) and center_to.shape != (1, 3): |
There was a problem hiding this comment.
Does it actually work with a (1, 3) vector ? Did you try?
kain88-de
left a comment
There was a problem hiding this comment.
Looks nice. I mainly would like the center calculations to make use of the flexibility in MDAnalysis that we expose in the encore module
| raise ValueError('{} is not a valid point'.format(point)) | ||
| try: | ||
| if center == 'geometry': | ||
| if center_of == 'geometry': |
There was a problem hiding this comment.
why do we have center_of here all the time? Can't you make use of the generic center as well? it allows to center with respect to arbitrary weights. People will want to do this. Think of IDP proteins where you want to calculate a center with respect to the flexibility of residues.
There was a problem hiding this comment.
You could have an argument weights='mass' like we have for the encore methods. The argument would accept mass and centroid as string arguments or an array-like object or None.
| axis = axes[axis] | ||
| if center_to is not None: | ||
| if isinstance(center_to, string_types): | ||
| if not center_to == 'center': |
There was a problem hiding this comment.
unnecessary check and nesting of if clauses. You can leave out the isinstance check in the first place. Here you also have an unnecessary nesting of the if clause. It would be better to write the two tests into the same if-clause.
| which sets [0, 0, 0] as the origin of the axis. | ||
| center_of: str, optional | ||
| used to choose the method of centering on the given atom group. Can be 'geometry' | ||
| or 'mass' |
There was a problem hiding this comment.
I would like to be able to give this arbitrary weights to calculate the center. This is for all your methods in all PRs you have so far. It's a useful addition and makes MDAnalysis more flexible. I actually ran across an issue where I would like to calculate the center with respect to arbitrary weights several times. I'm not aware that any other tool besides MDAnalysis allows to do this.
| .. code-block:: python | ||
|
|
||
| ag = u.residues[1].atoms | ||
| transform = MDAnalysis.transformations.center_in_axis(ag, 'x', [0,0,1], center_of='mass') |
…analysis into more-translations
|
looks like there are some python 2.7 specific errors left |
|
apparently bytes from strings ( |
|
which line fails?
…On Sun, Jul 22, 2018 at 3:31 PM Davide Cruz ***@***.***> wrote:
apparently bytes from strings behave differently in python 2 and python 3.
While in python 3 the functions fails as expected, in python 2 it doesn't.
What should I do? Should I remove this type from the tests?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1973 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AEGnVj7PmGZRuTQdhG0r9r2BXyoeTZK2ks5uJH7KgaJpZM4VGKdl>
.
|
|
@kain88-de I think I had already faced this problem in the groupby PR months ago. Python 2 doesn't have a |
| except (KeyError, TypeError): | ||
| raise ValueError('{} is not a valid plane'.format(plane)) | ||
|
|
||
| if isinstance(center_to, string_types): |
There was a problem hiding this comment.
did you remove the import of string_types?
|
@davidercruz Can yuu elaborate why you have to use such a weird workflow to reach your goal? You should only need transformations = (mda.transformations.unwrap(prot))
mda.transformations.center_in_box(prot, wrap=False),)Is your notebook visible somewhere? If no, could you share it as a github gist? |
|
@jbarnoud That is fine for a protein in solution, in a trajectory without solvent. |
|
@davidercruz And what does the unwrap option of the centering methods (I did not have time to catch up yet). |
|
What we need is a function which chooses the image closest to a given
reference coordinate. Ie translate box lengths to minimise the distance
from AG to point. This exists in the wrap method currently, but can be
moved out.
…On Thu, Aug 2, 2018 at 8:28 AM, Davide Cruz ***@***.***> wrote:
@jbarnoud <https://github.com/jbarnoud> It runs make_whole for the
atomgroup that needs to be centered. If #2012
<#2012> is merged,
make_whole will be called directly from atoms.center() just for the
calculation, but without changes to the actual AtomGroup.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1973 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AI0jBzZrghRZoIJ2QCzTWOpBtU-ZWxypks5uMv6LgaJpZM4VGKdl>
.
|
|
The unwrap argument is a good idea, though I would not encourage it in a transformation workflow as would will end up unwrapping the same molecules multiple times. For transformations, a function that puts things back in the expected image would be better. It would combine the two last steps in your workflow, hopefully in a most efficient way. About the unwrap argument: what happens if I say |
|
@jbarnoud It raises a ValueError. My inital thought was to simply give priority to unwrap and if both were True, then wrap would become False, but now I think an error is better. |
|
@richardjgowers @jbarnoud Thus the workflow could be ag = u.atoms
prot = u.select_atoms('protein')
transformations = (mda.transformations.unwrap(ag))
mda.transformations.center_in_box(prot),
mda.transformations.clean(ag)) |
why not add the compound keyword to the wrap transformation? Can't you simply pass all kwargs along? |
A colleague has asked about exactly that problem and if the transformations can help with it. |
|
Could someone knowledgeable with the discussion (@davidercruz @jbarnoud @richardjgowers @kain88-de ) please summarize with a view towards:
Thanks. |
|
It will be finished. There is not much work left but I did not have time to finish the review so far. On 14 Dec 2018 21:46, Oliver Beckstein <notifications@github.com> wrote:Could someone knowledgeable with the discussion (@davidercruz @jbarnoud @richardjgowers @kain88-de ) please summarize with a view towards:
Is there a chance that this PR will get finished?What are the major hurdles that would have to be overcome to make it work? (In case someone else might want to pick up the PR.)
Thanks.
—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or mute the thread.
|
|
Thanks!
… On Dec 14, 2018, at 1:59 PM, Jonathan Barnoud ***@***.***> wrote:
It will be finished. There is not much work left but I did not have time to finish the review so far.
|
|
As soon as @jbarnoud submits his review I'll make the changes necessary :D |
|
@jbarnoud @richardjgowers @davidercruz any chance that this gets into 0.20.0 #2240 (as we had promised in the 0.19.x blog post)? |
- fix #13 - needs MDAnalysisData >= 0.7.0 for the "membrane peptide" dataset - needs MDAnalysis >= 0.20.0 for the transformations (currently PRs MDAnalysis/mdanalysis#2038 , MDAnalysis/mdanalysis#1991 , and MDAnalysis/mdanalysis#1973 ) - updated text in notebook - adde a few more empty lines for clarity
- fix #13 - needs MDAnalysisData >= 0.7.0 for the "membrane peptide" dataset - needs MDAnalysis >= 0.20.0 for the transformations (currently PRs MDAnalysis/mdanalysis#2038 , MDAnalysis/mdanalysis#1991 , and MDAnalysis/mdanalysis#1973 ) - updated text in notebook - adde a few more empty lines for clarity
|
@jbarnoud @kain88-de – sorry to ping you both but you both have open review requests on this PR. Can you provide a quick note if these requests still stand or if they have been addressed? Thanks! |
|
Closing as stale, feel free to re-open if you want to continue. |
Adds plane and axis centering transformations
PR Checklist