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: <[EMAIL PROTECTED]>) 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, [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

