Issue 202 in mdanalysis: AtomGroup.set_resnum & set_resname

116 views
Skip to first unread message

mdana...@googlecode.com

unread,
Nov 19, 2014, 7:56:20 AM11/19/14
to mdnalys...@googlegroups.com
Status: Accepted
Owner: richardjgowers
Labels: Type-Defect Priority-Medium

New issue 202 by richardjgowers: AtomGroup.set_resnum & set_resname
https://code.google.com/p/mdanalysis/issues/detail?id=202

In [83]: u = mda.Universe('adk.psf','adk_dims.dcd')

In [84]: ag = ag[:10]

In [85]: u = mda.Universe('adk.psf','adk_dims.dcd')

In [86]: ag = u.atoms[:10]

In [87]: ag.set_resnum(10)

In [88]: ag.resnums()
Out[88]: array([1])

In [89]: ag.set_resname(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])

In [90]: ag.resnames()
Out[90]:
array(['MET'],
dtype='|S3')


This is all tied in with how residues are built in MDA. I couldn't see a
simple an easy fix, so I thought I'd open it for discussion

I've added tests for this (that currently fail) into develop.

--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

mdana...@googlecode.com

unread,
Nov 19, 2014, 11:50:19 AM11/19/14
to mdnalys...@googlegroups.com
Updates:
Blockedon: mdanalysis:193

Comment #1 on issue 202 by richardjgowers: AtomGroup.set_resnum &
set_resname
https://code.google.com/p/mdanalysis/issues/detail?id=202

Doing some reading, this might tie in with Issue 193 too, looking at more
than resids when building residues.

mdana...@googlecode.com

unread,
Nov 25, 2014, 10:15:20 AM11/25/14
to mdnalys...@googlegroups.com

Comment #2 on issue 202 by richardjgowers: AtomGroup.set_resnum &
set_resname
https://code.google.com/p/mdanalysis/issues/detail?id=202

https://code.google.com/p/mdanalysis/source/detail?r=a5f30fb67db976209e564cb7ee6d86dcf3518fb5&name=feature-residues

I've pushed a very experimental feature branch which eventually will fix
this.

Stuff that needs discussion:

Creating Residue/Segment objects now adds them to Universe, is this ugly?
or a good way of making sure that nothing gets lost. The idea here is that
everything should live in Universe.

Propagating information between levels. Does changing an Atom's residue
level information (resname, resid) indicate that the Residue should be
changed?

ie Atom.set_resname == Atom.residue.set_resname

Or should resname be read only, and the only Residue level information I
can change be resid, which actually moves the Atom into a new Residue?
To change resname instead

Atom.residue.set_resname(new)

Then if I changed an Atom's segid, does this change
1) Only the atom? (current behaviour)
2) The Residue it belongs to? Then changing all Atoms in the same Residue?
3) The entire segment and all Res & Atom within?

Or should segid be read-only from an Atom and instead only Residues can
change this as the method for moving them into new Segments?


Also, Residues/Segments now lazily built, but this should ideally be
impossible to notice!

mdana...@googlecode.com

unread,
Dec 2, 2014, 5:41:36 AM12/2/14
to mdnalys...@googlegroups.com
Updates:
Labels: Milestone-Release1.0

Comment #3 on issue 202 by richardjgowers: AtomGroup.set_resnum &
set_resname
https://code.google.com/p/mdanalysis/issues/detail?id=202

Everything is still a bit buggy, but it's getting there.

In [1]: import MDAnalysis as mda

In [2]: u = mda.Universe('adk.psf','adk_dims.dcd')

In [3]: r1 = u.residues[0]

In [4]: r2 = u.residues[1]

In [5]: ag = u.atoms[:10]

In [6]: len(r1)
Out[6]: 19

In [7]: len(r2)
Out[7]: 24

In [8]: ag.set_resid(2)

In [9]: len(r1)
Out[9]: 9

In [10]: len(r2)
Out[10]: 34

In [11]: r1.set_resid(215)

In [12]: len(r1)
Out[12]: 0

In [13]: rg = u.residues[:10]

In [14]: rg.set_segid('ABC')

In [15]: u.ABC
Out[15]: <Segment 'ABC'>

Richard Gowers

unread,
Dec 12, 2014, 5:35:33 PM12/12/14
to mdnalys...@googlegroups.com, codesite...@google.com, mdana...@googlecode.com
Hi all,

So I've got most of this working now, and I've hit a problem with the set_* methods.  Setting a series of resnums/resnames from an AtomGroup doesn't really make sense, eg if I had an AtomGroup with 3 atoms all from the same residue, then tried to set them to a series of resnames, what's the final name of the residue?

Most of the cross hierarchy set methods are problematic in the same way so they currently fail tests.  The exception to this is setting resid from AtomGroups or segid from ResidueGroups, which is how they can be merged.

The way I think makes most sense is to remove a lot of the set_* methods and only include ones that iterate over the same level of the *Group.  So for an AtomGroup you can only set_ Atom level attributes (including resids), a ResidueGroup can do resnames, resnums, resids and segids

Codewise, this would require a little work because SegmentGroup inherits from ResidueGroup and AtomGroup.  I think the neatest way to rearrange things is to make a generic Group class that defines all the base behaviour and have AtomGroup ResidueGroup and SegmentGroup all subclass this.

The branch is feature-residues

Thoughts welcome!

Oliver Beckstein

unread,
Dec 16, 2014, 9:20:03 PM12/16/14
to mdnalys...@googlegroups.com
Hi Rich,

some brief thoughts:

1) subclassing sounds good.

2) assigning different segids, for instance, is pretty much the only way to split into different segments, and I think that should work at all levels.

3) splitting residues from the atomgroup does indeed look like a bit esoteric; on the other hand, it *might* come in handy to be able to do something like this. I am also thinking of code that works on atoms to decide where they should belong (without having to make residues/residuegroups). But if the current behavior is too confusing we could disable/remove it. I did like the idea to have in principle a unified interface across all hierarch levels, reflecting the philosophy that we really only have atoms (and AtomGroups) and everything else is just a container with a special name, which makes dealing with AtomGroups more convenient.

But yeah – open for discussion!

Oliver
> You received this message because you are subscribed to the Google Groups "MDnalysis-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to mdnalysis-dev...@googlegroups.com.
> To post to this group, send email to mdnalys...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/mdnalysis-devel/d64771aa-648b-4fef-9cde-7686e1144637%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

--
Oliver Beckstein * orbe...@gmx.net
skype: orbeckst * orbe...@gmail.com

Richard Gowers

unread,
Dec 23, 2014, 5:47:57 AM12/23/14
to mdnalys...@googlegroups.com
Ok I've done a first pass at what subclassing would look like.

The old class structure was something like
AtomGroup Residue(AtomGroup) -> ResidueGroup(AtomGroup) Segment(ResidueGroup)-> SegmentGroup(ResidueGroup)

Now it's
_Group -> TopologyGroup(_Group) (todo)
            -> _GeometryGroup(_Group) -> AtomGroup(_GeometryGroup) Residue(AtomGroup)
                                                      -> ResidueGroup(_GeometryGroup) Segment(ResidueGroup)
                                                      -> SegmentGroup(_GeometryGroup)

So there's a generalised _Group class which defines how things should iter, len, getitem, getattr etc.  To use this you have to define somewhere in the subclass "_objects" which defines what the primary thing in the Group is meant to be.  This is then what is iterated over etc.  So for AtomGroup "_objects = _atoms"

For Groups which have particles inside (everything except TopologyGroup) there's _GeometryGroup which defines things like centerOfMass, centerOfGeometry.  I hate the name.

Each new Group (AtomGroup ResidueGroup SegmentGroup) now tries to do all its methods on the thing its named after, and nothing else.  The exception being moving between different hierarchy groups, so Atoms can change their resid/segid to move around.

Tests which currently don't work
  • ResidueGroup.set_mass - RG now iterates over Residues, and can't set the mass of a Residue, use RG.atoms.set_mass instead
  • SegmentGroup.set_mass - see above
  • SegmentGroup.set_resid - SG doesn't iterate over residues, use SG.residues.set_resid
I don't like the behaviour of AtomGroup.resids and resnums etc currently.  They return what is sort of a set of the resids in the AtomGroup.  I'd prefer it if they returned an array of len(self) which defines the resid per atom.  I'd also change it to a managed property, so you could set it by giving it back an array of len(self).  This would then make them behave like masses() and charges() (which I'd also like to change to managed properties).

Merry xmas!
Reply all
Reply to author
Forward
0 new messages