Package specific_analyses :: Package noe :: Module main
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.noe.main

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2014 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The main methods of the analysis specific API for the steady-state heteronuclear NOE calculation.""" 
 24   
 25  # Python module imports. 
 26  from math import sqrt 
 27  from warnings import warn 
 28   
 29  # relax module imports. 
 30  from lib.errors import RelaxError, RelaxNoSequenceError 
 31  from lib.warnings import RelaxDeselectWarning 
 32  from pipe_control import pipes 
 33  from pipe_control.mol_res_spin import exists_mol_res_spin_data, spin_loop 
 34  from user_functions.data import Uf_tables; uf_tables = Uf_tables() 
 35  from user_functions.objects import Desc_container 
 36   
 37   
38 -class Noe_main:
39 """Class containing functions for relaxation data.""" 40
41 - def _assign_function(self, spin=None, intensity=None, spectrum_type=None):
42 """Place the peak intensity data into the spin container. 43 44 The intensity data can be either that of the reference or saturated spectrum. 45 46 @keyword spin: The spin container. 47 @type spin: SpinContainer instance 48 @keyword intensity: The intensity value. 49 @type intensity: float 50 @keyword spectrum_type: The type of spectrum, one of 'ref' or 'sat'. 51 @type spectrum_type: str 52 """ 53 54 # Add the data. 55 if spectrum_type == 'ref': 56 spin.ref = intensity 57 elif spectrum_type == 'sat': 58 spin.sat = intensity 59 else: 60 raise RelaxError("The spectrum type '%s' is unknown." % spectrum_type)
61 62
63 - def _spectrum_type(self, spectrum_type=None, spectrum_id=None):
64 """Set the spectrum type corresponding to the spectrum_id. 65 66 @keyword spectrum_type: The type of NOE spectrum, one of 'ref' or 'sat'. 67 @type spectrum_type: str 68 @keyword spectrum_id: The spectrum id string. 69 @type spectrum_id: str 70 """ 71 72 # Test if the current pipe exists 73 pipes.test() 74 75 # Test the spectrum id string. 76 if spectrum_id not in cdp.spectrum_ids: 77 raise RelaxError("The peak intensities corresponding to the spectrum id '%s' does not exist." % spectrum_id) 78 79 # Initialise or update the spectrum_type data structure as necessary. 80 if not hasattr(cdp, 'spectrum_type'): 81 cdp.spectrum_type = {} 82 83 # Set the error. 84 cdp.spectrum_type[spectrum_id] = spectrum_type
85 86
87 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
88 """Calculate the NOE and its error. 89 90 The error for each peak is calculated using the formula:: 91 ___________________________________________ 92 \/ {sd(sat)*I(unsat)}^2 + {sd(unsat)*I(sat)}^2 93 sd(NOE) = ----------------------------------------------- 94 I(unsat)^2 95 96 @keyword spin_id: The spin identification string. 97 @type spin_id: None or str 98 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity. 99 @type verbosity: int 100 @keyword sim_index: The MC simulation index (unused). 101 @type sim_index: None 102 """ 103 104 # Test if the current pipe exists. 105 pipes.test() 106 107 # The spectrum types have not been set. 108 if not hasattr(cdp, 'spectrum_type'): 109 raise RelaxError("The spectrum types have not been set.") 110 111 # Test if the 2 spectra types 'ref' and 'sat' exist. 112 if not 'ref' in cdp.spectrum_type.values() or not 'sat' in cdp.spectrum_type.values(): 113 raise RelaxError("The reference and saturated NOE spectra have not been loaded.") 114 115 # Loop over the spins. 116 for spin in spin_loop(): 117 # Skip deselected spins. 118 if not spin.select: 119 continue 120 121 # Average intensities and squared errors (if required). 122 sat = 0.0 123 sat_err2 = 0.0 124 sat_count = 0 125 ref = 0.0 126 ref_err2 = 0.0 127 ref_count = 0 128 for id in cdp.spectrum_ids: 129 # Sat spectra. 130 if cdp.spectrum_type[id] == 'sat': 131 sat += spin.intensities[id] 132 sat_err2 += spin.intensity_err[id]**2 133 sat_count += 1 134 135 # Ref spectra. 136 if cdp.spectrum_type[id] == 'ref': 137 ref += spin.intensities[id] 138 ref_err2 += spin.intensity_err[id]**2 139 ref_count += 1 140 141 # Average the values and errors (variance averaging). 142 sat = sat / sat_count 143 sat_err2 = sat_err2 / sat_count 144 ref = ref / ref_count 145 ref_err2 = ref_err2 / ref_count 146 147 # Calculate the NOE. 148 spin.noe = sat / ref 149 150 # Calculate the error. 151 spin.noe_err = sqrt(sat_err2 * ref**2 + ref_err2 * sat**2) / ref**2
152 153
154 - def overfit_deselect(self, data_check=True, verbose=True):
155 """Deselect spins which have insufficient data to support calculation. 156 157 @keyword data_check: A flag to signal if the presence of base data is to be checked for. 158 @type data_check: bool 159 @keyword verbose: A flag which if True will allow printouts. 160 @type verbose: bool 161 """ 162 163 # Print out. 164 if verbose: 165 print("\nOver-fit spin deselection:") 166 167 # Test the sequence data exists. 168 if not exists_mol_res_spin_data(): 169 raise RelaxNoSequenceError 170 171 # Loop over spin data. 172 deselect_flag = False 173 all_desel = True 174 for spin, spin_id in spin_loop(return_id=True): 175 # Skip deselected spins. 176 if not spin.select: 177 continue 178 179 # No intensity data. 180 if not hasattr(spin, 'intensities'): 181 warn(RelaxDeselectWarning(spin_id, 'the absence of intensity data')) 182 spin.select = False 183 deselect_flag = True 184 continue 185 186 # Check for sufficient data. 187 if not len(spin.intensities) >= 2: 188 warn(RelaxDeselectWarning(spin_id, 'insufficient data (less than two data points)')) 189 spin.select = False 190 deselect_flag = True 191 continue 192 193 # No error data. 194 if not hasattr(spin, 'intensity_err'): 195 warn(RelaxDeselectWarning(spin_id, 'the absence of errors')) 196 spin.select = False 197 deselect_flag = True 198 continue 199 200 # Check for sufficient errors. 201 if not len(spin.intensity_err) >= 2: 202 warn(RelaxDeselectWarning(spin_id, 'missing errors (less than two error points)')) 203 spin.select = False 204 deselect_flag = True 205 continue 206 207 # Not all spins have been deselected. 208 all_desel = False 209 210 # Final printout. 211 if verbose and not deselect_flag: 212 print("No spins have been deselected.") 213 214 # Catch complete failures - i.e. no spins are selected. 215 if all_desel: 216 raise RelaxError("All spins have been deselected.")
217 218 219 return_data_name_doc = Desc_container("NOE calculation data type string matching patterns") 220 _table = uf_tables.add_table(label="table: NOE data type patterns", caption="NOE data type string matching patterns.") 221 _table.add_headings(["Data type", "Object name"]) 222 _table.add_row(["Reference intensity", "'ref'"]) 223 _table.add_row(["Saturated intensity", "'sat'"]) 224 _table.add_row(["NOE", "'noe'"]) 225 return_data_name_doc.add_table(_table.label) 226 227
228 - def return_units(self, param):
229 """Dummy function which returns None as the stats have no units. 230 231 @param param: The name of the parameter to return the units string for. 232 @type param: str 233 @return: Nothing. 234 @rtype: None 235 """ 236 237 return None
238