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)