mailRe: r3245 - /1.3/generic_fns/selection.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Chris MacRaild on March 30, 2007 - 11:57:
On Fri, 2007-03-30 at 17:01 +1000, Edward d'Auvergne wrote:
Chris,

Would you like to add a few unit tests to check that all possibilities
of boolean usage (and misusage) in the spin_id selection string
function correctly?  These are very easy to write using Gary's unit
test framework.  Unit tests for the Selection class and corresponding
object and methods would also be very useful.  Thanks.


Will try to get to these today. Ran out of time yesterday, and figured
it was worth getting the idea out for comment before putting too much
more effort into it.


I was also wondering if the approach used by the
Selection.__contains__() method was efficient.  Do the changes affect
the speed of the looping over the spin_loop() generator function?


Undoubtably Selection.__contains__() will be slower than a simple "x in
list" operation. Whether or not this will be noticable when used in
anger I'm not sure. I've given this implimentation a little thought, but
its far from the final word. If a better idea exists that gives similar
flexibility with respect to booleans, wildcards, etc. I'd be glad to
give it a shot.

If efficiency proves a major problem, there are a few alternatives:

1) We could cache selections in some way eg. as boolean lists which map
onto the current mol-res-spin data structure. Then the selections would
only need to be re-calculated every time the molecular structure is
changed. Gary tells me this is a very common way of dealing with
molecule selections in other programs.

2) We might decide that booleans, wildcards, etc. are not worth the
costs, and go back to a simpler implimentation

Unfortunately I was unable to implement all of the ideas surrounding
the spin loop.  Specifically your idea Chris at
https://mail.gna.org/public/relax-devel/2007-01/msg00036.html
(Message-ID: <1168883717.7569.511.camel@mrspell>) doesn't work with
the mol-res-spin data structure of a data pipe.

Indeed. There are some basic conceptual deficiencies in that idea (ie.
it makes very little sense at all)


Chris


Cheers,

Edward


On 3/30/07, c.a.macraild@xxxxxxxxxxx <c.a.macraild@xxxxxxxxxxx> wrote:
Author: macraild
Date: Thu Mar 29 18:46:15 2007
New Revision: 3245

URL: http://svn.gna.org/viewcvs/relax?rev=3245&view=rev
Log:
A proposal for a modified mol-res-spin selection mechanism.

This simple modification, based on a selection object, permits
the use of booleans in selection strings, eg:

':leu@xxxxxxx | :val@CG1,CG2'

selects leucine and valine methyls.

Also, modification of Selection.__contains__() will allow for
wildcards, regex, etc as desired.


Modified:
    1.3/generic_fns/selection.py

Modified: 1.3/generic_fns/selection.py
URL: 
http://svn.gna.org/viewcvs/relax/1.3/generic_fns/selection.py?rev=3245&r1=3244&r2=3245&view=diff
==============================================================================
--- 1.3/generic_fns/selection.py (original)
+++ 1.3/generic_fns/selection.py Thu Mar 29 18:46:15 2007
@@ -28,6 +28,7 @@

 # relax module imports.
 from data import Data as relax_data_store
+from data.mol_res_spin import MoleculeContainer, ResidueContainer, 
SpinContainer
 from relax_errors import RelaxError, RelaxNoRunError, 
RelaxNoSequenceError, RelaxRegExpError, RelaxResSelectDisallowError, 
RelaxSpinSelectDisallowError


@@ -55,6 +56,67 @@
 id_string_doc = string


+
+class Selection(object):
+    """An object containing mol-res-spin selections"""
+
+    def __init__(self, selectString):
+
+        self._union = None
+        self._intersect = None
+
+        self.molecules = None
+        self.residues = None
+        self.spins = None
+
+        if not selectString:
+            return
+
+        if '&' in selectString:
+            and_split = selectString.split('&')
+            part0 = Selection(and_split[0])
+            part1 = Selection(and_split[1])
+            return part0.intersection(part1)
+
+        elif '|' in selectString:
+            and_split = selectString.split('|')
+            part0 = Selection(and_split[0])
+            part1 = Selection(and_split[1])
+            return part0.union(part1)
+
+        else:
+            mol_token, res_token, spin_token = tokenise(selectString)
+            self.molecules = parse_token(mol_token)
+            self.residues = parse_token(res_token)
+            self.spins = parse_token(spin_token)
+
+    def __contains__(self, obj):
+
+        in_self = False
+        if isinstance(obj, MoleculeContainer) and obj.name in 
self.molecules:
+            in_self = True
+        elif isinstance(obj, ResidueContainer) and obj.name in 
self.residues:
+            in_self = True
+        elif isinstance(obj, SpinContainer) and obj.name in self.spins:
+            in_self = True
+        if self._union:
+            return in_self or (obj in self._union)
+        if self._intersect:
+            return in_self and (obj in self._union)
+        else:
+            return in_self
+
+    def intersection(self, selectObj):
+
+        if self._union or self._intersect:
+            raise RelaxError, "Cannot define multiple Boolean 
relationships between Selection objects"
+        self._intersect = selectObj
+
+    def union(self, selectObj):
+
+        if self._union or self._intersect:
+            raise RelaxError, "Cannot define multiple Boolean 
relationships between Selection objects"
+        self._union = selectObj


 def desel_all(self, run=None):
@@ -216,22 +278,19 @@
     @rtype:             instance of the MoleculeContainer class.
     """

-    # Split up the selection string.
-    mol_token, res_token, spin_token = tokenise(selection)
+    # Parse the selection string.
+    selectObj = Selection(selection)

     # Disallowed selections.
-    if res_token:
+    if selectObj.residues:
         raise RelaxResSelectDisallowError
-    if spin_token:
+    if selectObj.spins:
         raise RelaxSpinSelectDisallowError
-
-    # Parse the token.
-    molecules = parse_token(mol_token)

     # Loop over the molecules.
     for mol in relax_data_store[relax_data_store.current_pipe].mol:
         # Skip the molecule if there is no match to the selection.
-        if mol_token and mol.name not in molecules:
+        if selectObj.molecules and mol.name not in selectObj:
             continue

         # Yield the molecule data container.
@@ -320,27 +379,23 @@
     @rtype:             instance of the MoleculeContainer class.
     """

-    # Split up the selection string.
-    mol_token, res_token, spin_token = tokenise(selection)
-
+    # Parse the selection string.
+    selectObj = Selection(selection)
+
     # Disallowed selections.
-    if spin_token:
+    if selectObj.spins:
         raise RelaxSpinSelectDisallowError
-
-    # Parse the tokens.
-    molecules = parse_token(mol_token)
-    residues = parse_token(res_token)

     # Loop over the molecules.
     for mol in relax_data_store[relax_data_store.current_pipe].mol:
         # Skip the molecule if there is no match to the selection.
-        if mol_token and mol.name not in molecules:
+        if selectObj.molecules and mol.name not in selectObj:
             continue

         # Loop over the residues.
         for res in mol.res:
             # Skip the residue if there is no match to the selection.
-            if res_token and res.name not in residues:
+            if selectObj.residues and res.name not in selectObj:
                 continue

             # Yield the residue data container.
@@ -575,30 +630,25 @@
     @rtype:             instance of the SpinContainer class.
     """

-    # Split up the selection string.
-    mol_token, res_token, spin_token = tokenise(selection)
-
-    # Parse the tokens.
-    molecules = parse_token(mol_token)
-    residues = parse_token(res_token)
-    spins = parse_token(spin_token)
+    # Parse the selection string.
+    selectObj = Selection(selection)

     # Loop over the molecules.
     for mol in relax_data_store[relax_data_store.current_pipe].mol:
         # Skip the molecule if there is no match to the selection.
-        if mol_token and mol.name not in molecules:
+        if selectObj.molecules and mol.name not in selectObj:
             continue

         # Loop over the residues.
         for res in mol.res:
             # Skip the residue if there is no match to the selection.
-            if res_token and res.name not in residues:
+            if selectObj.residues and res.name not in selectObj:
                 continue

             # Loop over the spins.
             for spin in res.spin:
                 # Skip the spin if there is no match to the selection.
-                if spin_token and spin.name not in spins:
+                if selectObj.spins and spin.name not in selectObj:
                     continue

                 # Yield the spin system data container.
@@ -697,3 +747,4 @@

     # Return the three tokens.
     return mol_token, res_token, spin_token
+


_______________________________________________
relax (http://nmr-relax.com)

This is the relax-commits mailing list
relax-commits@xxxxxxx

To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-commits






Related Messages


Powered by MHonArc, Updated Tue Apr 03 19:40:18 2007