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.
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? 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: <[EMAIL PROTECTED]>) doesn't work with the mol-res-spin data structure of a data pipe. Cheers, Edward On 3/30/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> 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: ':[EMAIL PROTECTED] | :[EMAIL PROTECTED],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 [email protected] 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
_______________________________________________ relax (http://nmr-relax.com) This is the relax-devel mailing list [email protected] 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-devel

