Skip to content

Commit

Permalink
Added deprecations for Residue, Segment plural residue, segment props…
Browse files Browse the repository at this point in the history
… respectively

Since Residues are an AtomGroup subclass here, a Residue has e.g. `resids`,
which gives per-atom resids (all the same, *hopefully*). This doesn't
exist in #363, so added proper deprecations. Ditto for segment
properties that spit out per-residue results.

Also, since we don't want our own recommendations for setters using the
deprecated setters internally, did simple copy-paste of setter code to
appropriate property.

Also deprecated Residue.id, Residue.name, and added Residue.resid and
Residue.resname as the proper alternatives.

Still getting deprecation warnings on loading a PSF+DCD Universe. Next
up is checking all the readers for internal use of deprecated
properties/methods.
  • Loading branch information
dotsdl committed Apr 1, 2016
1 parent da6e888 commit b399e18
Showing 1 changed file with 112 additions and 35 deletions.
147 changes: 112 additions & 35 deletions package/MDAnalysis/core/AtomGroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,12 @@ def outfunc(self, *args):
elif isinstance(self, ResidueGroup):
pass
elif isinstance(self, Residue):
pass
elif isinstance(self, AtomGroup):
warnings.warn(warnstring.format('atomgroup', func.__name__),
warnings.warn("In version 0.16.0, Use 'residue.atoms.{}' instead.".format(func.__name__),
DeprecationWarning)
elif isinstance(self, AtomGroup):
pass
elif isinstance(self, Atom):
warnings.warn(warnstring_sing.format('atom', func.__name__),
DeprecationWarning)
pass

return func(self, *args)

Expand All @@ -518,6 +517,8 @@ def outfunc(self, *args):
if isinstance(self, SegmentGroup):
pass
elif isinstance(self, Segment):
warnings.warn("In version 0.16.0, Use 'segment.residues.{}' instead.".format(func.__name__),
DeprecationWarning)
pass
elif isinstance(self, ResidueGroup):
warnings.warn(warnstring.format('residuegroup', func.__name__),
Expand Down Expand Up @@ -1265,7 +1266,7 @@ def masses(self):
@warn_atom_property
def masses(self, new):
self._clear_caches('masses')
self.set_masses(new)
self.set("mass", mass, conversion=float, cache="masses")

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


def total_mass(self):
"""Total mass of the selection (masses are taken from the topology or guessed)."""
Expand Down Expand Up @@ -1318,7 +1319,7 @@ def charges(self):
@charges.setter
@warn_atom_property
def charges(self, new):
self.set_charges(new)
self.set("charge", charge, conversion=float)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


def total_charge(self):
"""Sum of all partial charges (must be defined in topology)."""
Expand All @@ -1344,7 +1345,7 @@ def names(self):
@names.setter
@warn_atom_property
def names(self, new):
self.set_names(new)
self.set("name", name, conversion=str)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


@property
@warn_atom_property
Expand All @@ -1360,7 +1361,7 @@ def types(self):
@types.setter
@warn_atom_property
def types(self, new):
self.set_types(new)
self.set("type", atype)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


@property
@warn_atom_property
Expand All @@ -1375,7 +1376,7 @@ def radii(self):
@radii.setter
@warn_atom_property
def radii(self, new):
self.set_radii(new)
self.set("radius", radius, conversion=float)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


@property
@warn_atom_property
Expand All @@ -1387,7 +1388,7 @@ def bfactors(self):
@bfactors.setter
@warn_atom_property
def bfactors(self, new):
self.set_bfactors(new)
self.set("bfactor", bfactor, conversion=float)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

change new to bfactor to match your code


@property
@warn_atom_property
Expand All @@ -1401,7 +1402,7 @@ def altLocs(self):
@altLocs.setter
@warn_atom_property
def altLocs(self, new):
self.set_altlocs(new)
self.set("altLoc", altLoc, conversion=str)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

change new to altLoc to match your code


@property
@deprecate(message="{}; use `ids` property instead".format(_SIXTEEN_DEPRECATION))
Expand All @@ -1415,7 +1416,7 @@ def serials(self):
@serials.setter
@deprecate(message="{}; use `ids` property instead".format(_SIXTEEN_DEPRECATION))
def serials(self, new):
self.set_serials(new)
self.set("serial", serial, conversion=int)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

change new to serial to match your code


@property
def ids(self):
Expand All @@ -1435,7 +1436,7 @@ def ids(self):

@ids.setter
def ids(self, new):
self.set_serials(new)
self.set("serial", serial, conversion=int)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

change new to serial to match your code


@property
@cached('residues')
Expand Down Expand Up @@ -1482,6 +1483,7 @@ def segments(self):
return SegmentGroup(segments)

@property
@warn_residue_property
def resids(self):
"""Returns an array of residue numbers.
Expand All @@ -1495,9 +1497,22 @@ def resids(self):
@resids.setter
@warn_residue_property
def resids(self, new):
self.set_resids(new)
from MDAnalysis.topology.core import build_residues

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix: argument contains new but you use resid


self.set("resid", resid, conversion=int)
# Note that this also automagically updates THIS AtomGroup;
# the side effect of build_residues(self.atoms) is to update all Atoms!!!!
self._fill_cache('residues', ResidueGroup(build_residues(self.atoms)))

# make sure to update the whole universe: the Atoms are shared but
# ResidueGroups are not
if self.atoms is not self.universe.atoms:
self.universe.atoms._fill_cache(
'residues',
ResidueGroup(build_residues(self.universe.atoms)))

@property
@warn_residue_property
def resnames(self):
"""Returns an array of residue names.
Expand All @@ -1511,9 +1526,10 @@ def resnames(self):
@resnames.setter
@warn_residue_property
def resnames(self, new):
self.set_resnames(new)
self.set("resname", resname, conversion=str)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


@property
@warn_residue_property
def resnums(self):
"""Returns an array of canonical residue numbers.
Expand All @@ -1528,9 +1544,10 @@ def resnums(self):
@resnums.setter
@warn_residue_property
def resnums(self, new):
self.set_resnums(new)
self.set("resnum", resnum)

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix... new!


@property
@warn_segment_property
def segids(self):
"""Returns an array of segment names.
Expand All @@ -1544,7 +1561,23 @@ def segids(self):
@segids.setter
@warn_segment_property
def segids(self, new):
self.set_segids(new)
from MDAnalysis.topology.core import build_segments

This comment has been minimized.

Copy link
@orbeckst

orbeckst Apr 1, 2016

Member

fix: new vs segid


self.set("segid", segid, conversion=str)

# also updates convenience handles for segments in universe
segments = self.universe._build_segments()

# Note that this also automagically updates THIS AtomGroup;
# the side effect of build_residues(self.atoms) is to update all Atoms!!!!
self._fill_cache('segments', SegmentGroup(segments))

# make sure to update the whole universe: the Atoms are shared but
# ResidueGroups are not
if self.atoms is not self.universe.atoms:
self.universe.atoms._fill_cache(
'segments',
SegmentGroup(segments))

def sequence(self, **kwargs):
"""Returns the amino acid sequence.
Expand Down Expand Up @@ -3484,12 +3517,12 @@ class Residue(AtomGroup):

def __init__(self, name, id, atoms, resnum=None):
super(Residue, self).__init__(atoms)
self.name = name
self.id = id
self._resname = name
self._resid = id
if resnum is not None:
self.resnum = resnum
self._resnum = resnum
else:
self.resnum = self.id # TODO: get resnum from topologies that support it
self._resnum = self._resid # TODO: get resnum from topologies that support it
self.segment = None
for a in atoms:
a.resnum = self.resnum
Expand All @@ -3502,6 +3535,50 @@ def __init__(self, name, id, atoms, resnum=None):
##if not Residue._cache.has_key(name):
## Residue._cache[name] = dict([(a.name, i) for i, a in enumerate(self._atoms)])

@property
@deprecate(message="{}; use `resname` property instead".format(_SIXTEEN_DEPRECATION))
def name(self):
return self._resname

@name.setter
@deprecate(message="{}; use `resname` property instead".format(_SIXTEEN_DEPRECATION))
def name(self, value):
self._resname = value

@property
def resname(self):
return self._resname

@resname.setter
def resname(self, value):
self._resname = value

@property
@deprecate(message="{}; use `resid` property instead".format(_SIXTEEN_DEPRECATION))
def id(self):
return self._resid

@id.setter
@deprecate(message="{}; use `resid` property instead".format(_SIXTEEN_DEPRECATION))
def id(self, value):
self._resid = value

@property
def resid(self):
return self._resid

@resid.setter
def resid(self, value):
self._resid = value

@property
def resnum(self):
return self._resnum

@resnum.setter
def resnum(self, value):
self._resnum = value

def phi_selection(self):
"""AtomGroup corresponding to the phi protein backbone dihedral C'-N-CA-C.
Expand All @@ -3510,7 +3587,7 @@ def phi_selection(self):
method returns ``None``.
"""
sel = self.universe.select_atoms(
'segid {0!s} and resid {1:d} and name C'.format(self.segment.id, self.id - 1)) + \
'segid {0!s} and resid {1:d} and name C'.format(self.segment.segid, self.resid - 1)) + \
self['N'] + self['CA'] + self['C']
if len(sel) == 4: # select_atoms doesnt raise errors if nothing found, so check size
return sel
Expand All @@ -3526,7 +3603,7 @@ def psi_selection(self):
"""
sel = self['N'] + self['CA'] + self['C'] + \
self.universe.select_atoms(
'segid {0!s} and resid {1:d} and name N'.format(self.segment.id, self.id + 1))
'segid {0!s} and resid {1:d} and name N'.format(self.segment.segid, self.resid + 1))
if len(sel) == 4:
return sel
else:
Expand All @@ -3544,7 +3621,7 @@ def omega_selection(self):
method returns ``None``.
"""
nextres = self.id + 1
nextres = self.resid + 1
segid = self.segment.id
sel = self['CA'] + self['C'] + \
self.universe.select_atoms(
Expand All @@ -3570,7 +3647,7 @@ def chi1_selection(self):

def __repr__(self):
return "<Residue {name}, {id}>".format(
name=self.name, id=self.id)
name=self.name, id=self.resid)


class ResidueGroup(AtomGroup):
Expand Down Expand Up @@ -3646,7 +3723,7 @@ def resids(self):
.. versionchanged:: 0.11.0
Now a property and returns array of length `len(self)`
"""
return np.array([r.id for r in self.residues])
return np.array([r.resid for r in self.residues])

@property
@warn_residue_property
Expand Down Expand Up @@ -3824,7 +3901,7 @@ class Segment(ResidueGroup):
def __init__(self, name, residues):
"""Initialize a Segment with segid *name* from a list of :class:`Residue` instances."""
super(Segment, self).__init__(residues)
self._name = name
self._segid = name
for res in self.residues:
res.segment = self
for atom in res:
Expand All @@ -3835,31 +3912,31 @@ def __init__(self, name, residues):
@deprecate(message="{}; use `segid` property instead".format(_SIXTEEN_DEPRECATION))
def id(self):
"""Segment id (alias for :attr:`Segment.name`)"""
return self.name
return self._segid

@id.setter
@deprecate(message="{}; use `segid` property instead".format(_SIXTEEN_DEPRECATION))
def id(self, x):
self.name = x
self._segid = x

@property
def segid(self):
"""Segment id (alias for :attr:`Segment.name`)"""
return self.name
return self._segid

@id.setter
def segid(self, x):
self.name = x
self._segid = x

@property
@deprecate(message="{}; use `segid` property instead".format(_SIXTEEN_DEPRECATION))
def name(self):
return self._name
return self._segid

@name.setter
@deprecate(message="{}; use `segid` property instead".format(_SIXTEEN_DEPRECATION))
def name(self, x):
self._name = x
self._segid = x

def __getattr__(self, attr):
if attr[0] == 'r':
Expand Down Expand Up @@ -3945,7 +4022,7 @@ def segids(self):
.. versionchanged:: 0.11.0
Now a property and returns array of length `len(self)`
"""
return np.array([s.name for s in self.segments])
return np.array([s.segid for s in self.segments])

@deprecate(message="{}; use `segids` property instead".format(_SIXTEEN_DEPRECATION))
def set_segids(self, segid):
Expand Down

1 comment on commit b399e18

@dotsdl
Copy link
Member Author

@dotsdl dotsdl commented on b399e18 Apr 1, 2016

Choose a reason for hiding this comment

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

Thanks @orbeckst! Hadn't waited for the Travis check to finish before I wrote my comment; went through and fixed all these.

Please sign in to comment.