Hi Troels, This is quite a flexible user function! I'd recommend copying and pasting the list of allowed operators from this docstring into the user function description to improve the user interface and to make it clearer. If you want the ultimate flexibility, consider adding the boolean operator as in the deselect.spin and select.spin user functions.
Regards, Edward On 7 December 2014 at 12:27, <tlin...@nmr-relax.com> wrote: > Author: tlinnet > Date: Sun Dec 7 12:27:32 2014 > New Revision: 26983 > > URL: http://svn.gna.org/viewcvs/relax?rev=26983&view=rev > Log: > Added function in pipe_control.spectrum.sn_ratio_deselection(), a function to > deselect spins according to the Signal to Noise ration. > > The function is flexible, since it possible to use different comparison > operators. > And the function can be switched, so a selection is made instead. > > Modified: > trunk/pipe_control/spectrum.py > > Modified: trunk/pipe_control/spectrum.py > URL: > http://svn.gna.org/viewcvs/relax/trunk/pipe_control/spectrum.py?rev=26983&r1=26982&r2=26983&view=diff > ============================================================================== > --- trunk/pipe_control/spectrum.py (original) > +++ trunk/pipe_control/spectrum.py Sun Dec 7 12:27:32 2014 > @@ -27,18 +27,21 @@ > > # Python module imports. > from math import sqrt > +from numpy import asarray > +import operator > import sys > from warnings import warn > > # relax module imports. > from lib.errors import RelaxError, RelaxImplementError, RelaxNoSpectraError > from lib.io import sort_filenames, write_data > -from lib.text.sectioning import section > +from lib.text.sectioning import section, subsection > from lib.spectrum.peak_list import read_peak_list > from lib.statistics import std > from lib.warnings import RelaxWarning, RelaxNoSpinWarning > from pipe_control.mol_res_spin import check_mol_res_spin_data, create_spin, > generate_spin_id_unique, return_spin, spin_loop > from pipe_control.pipes import check_pipe > +from pipe_control.selection import desel_spin, sel_spin > > > def __errors_height_no_repl(): > @@ -935,3 +938,143 @@ > if verbose: > section(file=sys.stdout, text="Signal to noise ratio for spin ID > '%s'"%spin_id, prespace=1) > write_data(out=sys.stdout, headings=["Spectrum ID", "Signal", > "Noise", "S/N"], data=data_i) > + > + > +def sn_ratio_deselection(ratio=1.0, operation='<', all_sn=False, > select=False, verbose=True): > + """Use user function deselect.spin on spins with signal to noise ratio > higher or lower than ratio. The operation determines the selection operation. > + > + @keyword ratio: The ratio to compare to. > + @type ratio: float > + @keyword operation: The comparison operation by which to select the > spins. Of the operation(sn_ratio, ratio), where operation can either be: > '<', '<=', '>', '>=', '==', '!='. > + @type operation: str > + @keyword all_sn: A flag specifying if all the signal to noise > ratios per spin should match the comparison operator, of if just a single > comparison match is enough. > + @type all_sn: bool > + @keyword select: A flag specifying if the user function > select.spin should be used instead. > + @type select: bool > + @keyword verbose: A flag which if True will print additional > information out. > + @type verbose: bool > + """ > + > + # Tests. > + check_pipe() > + check_mol_res_spin_data() > + > + # Test if spectra have been loaded. > + if not hasattr(cdp, 'spectrum_ids'): > + raise RelaxError("No spectra have been loaded.") > + > + # Assign the comparison operator. > + # "'<' : strictly less than" > + if operation == '<': > + op = operator.lt > + > + # "'<=' : less than or equal" > + elif operation == '<=': > + op = operator.le > + > + # "'>' : strictly greater than" > + elif operation == '>': > + op = operator.gt > + > + # "'>=' : greater than or equal" > + elif operation == '>=': > + op = operator.ge > + > + # "'==' : equal" > + elif operation == '==': > + op = operator.eq > + > + # "'!=' : not equal", > + elif operation == '!=': > + op = operator.ne > + > + # If not assigned, raise error. > + else: > + raise RelaxError("The compare operation does not belong to the > allowed list of methods: ['<', '<=', '>', '>=', '==', '!=']") > + > + # Assign text for print out. > + if all_sn: > + text_all_sn = "all" > + else: > + text_all_sn = "any" > + > + if select: > + text_sel = "selected" > + sel_func = sel_spin > + else: > + text_sel = "deselected" > + sel_func = desel_spin > + > + # Print > + section(file=sys.stdout, text="Signal to noise ratio comparison > selection", prespace=1, postspace=0) > + print("For the comparion test: S/N %s %1.1f"%(operation, ratio)) > + > + # Loop over the spins. > + spin_ids = [] > + for spin, spin_id in spin_loop(return_id=True): > + # Skip spins missing sn_ratio. > + if not hasattr(spin, 'sn_ratio'): > + # Skip warning for deselected spins. > + if spin.select: > + warn(RelaxWarning("Spin '%s' does not contain Signal to > Noise calculations. Perform the user function 'spectrum.sn_ratio'. This spin > is skipped." % spin_id)) > + continue > + > + # Loop over the ID, collect and sort. > + ids = [] > + for id in spin.peak_intensity: > + # Append the ID to the list. > + ids.append(id) > + > + # Sort the ids alphanumeric. > + ids = sort_filenames(filenames=ids, rev=False) > + > + # Loop over the sorted ids. > + sn_val = [] > + for id in ids: > + # Append the Signal to Noise in the list. > + sn_val.append(spin.sn_ratio[id]) > + > + # Convert the list to array. > + sn_val = asarray(sn_val) > + > + # Make the comparison for the whole array. > + test_arr = op(sn_val, ratio) > + > + # Determine how the test should evaluate. > + if all_sn: > + test = test_arr.all() > + else: > + test = test_arr.any() > + > + # Make an numpy array for the ids, an extract id which failed the > test. > + ids_arr = asarray(ids) > + ids_test_arr = ids_arr[test_arr] > + > + # Make inversion of bool > + test_arr_inv = test_arr == False > + ids_test_arr_inv = ids_arr[test_arr_inv] > + > + # print > + if verbose: > + subsection(file=sys.stdout, text="Signal to noise ratio > comparison for spin ID '%s'"%spin_id, prespace=1, postspace=0) > + print("Following spectra ID evaluated to True: %s"%ids_test_arr) > + print("Following spectra ID evaluated to False: > %s"%ids_test_arr_inv) > + print("'%s' comparisons have been used for evaluation, which > evaluated to: %s"%(text_all_sn, test)) > + if test: > + print("The spin ID '%s' is %s"%(spin_id, text_sel)) > + else: > + print("The spin ID '%s' is skipped"%spin_id) > + > + # If the test evaluates to True, then do selection action. > + if test: > + # Select/Deselect the spin. > + sel_func(spin_id=spin_id) > + > + # Assign spin_id to list, for printing. > + spin_ids.append(spin_id) > + > + # Make summary > + if verbose: > + if len(spin_ids) > 0: > + subsection(file=sys.stdout, text="For all of the S/N comparion > test, the following spin ID's was %s"%text_sel, prespace=1, postspace=0) > + print(spin_ids) > > > _______________________________________________ > relax (http://www.nmr-relax.com) > > This is the relax-commits mailing list > relax-comm...@gna.org > > 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://www.nmr-relax.com) This is the relax-devel mailing list relax-devel@gna.org 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