Package specific_analyses :: Package consistency_tests :: Module api
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.consistency_tests.api

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2014 Edward d'Auvergne                                   # 
  4  # Copyright (C) 2007-2009 Sebastien Morin                                     # 
  5  #                                                                             # 
  6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  7  #                                                                             # 
  8  # This program is free software: you can redistribute it and/or modify        # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation, either version 3 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # This program is distributed in the hope that it will be useful,             # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """The consistency testing analysis API object.""" 
 25   
 26  # Python module imports. 
 27  from warnings import warn 
 28   
 29  # relax module imports. 
 30  from lib.errors import RelaxError, RelaxNoSequenceError, RelaxNoValueError, RelaxSpinTypeError 
 31  from lib.float import isInf 
 32  from lib.physical_constants import h_bar, mu0, return_gyromagnetic_ratio 
 33  from lib.warnings import RelaxDeselectWarning 
 34  from pipe_control.interatomic import return_interatom_list 
 35  from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop 
 36  from specific_analyses.api_base import API_base 
 37  from specific_analyses.api_common import API_common 
 38  from specific_analyses.consistency_tests.parameter_object import Consistency_tests_params 
 39  from target_functions.consistency_tests import Consistency 
 40   
 41   
42 -class Consistency_tests(API_base, API_common):
43 """Class containing functions specific to consistency testing.""" 44 45 # Class variable for storing the class instance (for the singleton design pattern). 46 instance = None 47
48 - def __init__(self):
49 """Initialise the class by placing API_common methods into the API.""" 50 51 # Place methods into the API. 52 self.base_data_loop = self._base_data_loop_spin 53 self.create_mc_data = self._create_mc_relax_data 54 self.model_loop = self._model_loop_spin 55 self.return_conversion_factor = self._return_no_conversion_factor 56 self.return_error = self._return_error_relax_data 57 self.return_value = self._return_value_general 58 self.set_param_values = self._set_param_values_spin 59 self.set_selected_sim = self._set_selected_sim_spin 60 self.sim_pack_data = self._sim_pack_relax_data 61 62 # Place a copy of the parameter list object in the instance namespace. 63 self._PARAMS = Consistency_tests_params()
64 65
66 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
67 """Calculation of the consistency functions. 68 69 @keyword spin_id: The spin identification string. 70 @type spin_id: None or str 71 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity. 72 @type verbosity: int 73 @keyword sim_index: The optional MC simulation index. 74 @type sim_index: None or int 75 """ 76 77 # Test if the frequency has been set. 78 if not hasattr(cdp, 'ct_frq') or not isinstance(cdp.ct_frq, float): 79 raise RelaxError("The frequency has not been set up.") 80 81 # Test if the sequence data is loaded. 82 if not exists_mol_res_spin_data(): 83 raise RelaxNoSequenceError 84 85 # Test if the spin data has been set. 86 for spin, id in spin_loop(spin_id, return_id=True): 87 # Skip deselected spins. 88 if not spin.select: 89 continue 90 91 # Test if the nuclear isotope type has been set. 92 if not hasattr(spin, 'isotope'): 93 raise RelaxSpinTypeError 94 95 # Test if the CSA value has been set. 96 if not hasattr(spin, 'csa') or spin.csa == None: 97 raise RelaxNoValueError("CSA") 98 99 # Test if the angle Theta has been set. 100 if not hasattr(spin, 'orientation') or spin.orientation == None: 101 raise RelaxNoValueError("angle Theta") 102 103 # Test if the correlation time has been set. 104 if not hasattr(spin, 'tc') or spin.tc == None: 105 raise RelaxNoValueError("correlation time") 106 107 # Test the interatomic data. 108 interatoms = return_interatom_list(id) 109 for interatom in interatoms: 110 # No relaxation mechanism. 111 if not interatom.dipole_pair: 112 continue 113 114 # The interacting spin. 115 if id != interatom.spin_id1: 116 spin_id2 = interatom.spin_id1 117 else: 118 spin_id2 = interatom.spin_id2 119 spin2 = return_spin(spin_id2) 120 121 # Test if the nuclear isotope type has been set. 122 if not hasattr(spin2, 'isotope'): 123 raise RelaxSpinTypeError 124 125 # Test if the interatomic distance has been set. 126 if not hasattr(interatom, 'r') or interatom.r == None: 127 raise RelaxNoValueError("interatomic distance", spin_id=spin_id, spin_id2=spin_id2) 128 129 # Frequency index. 130 if cdp.ct_frq not in cdp.spectrometer_frq.values(): 131 raise RelaxError("No relaxation data corresponding to the frequency %s has been loaded." % cdp.ct_frq) 132 133 # Consistency testing. 134 for spin, id in spin_loop(spin_id, return_id=True): 135 # Skip deselected spins. 136 if not spin.select: 137 continue 138 139 # Set the r1, r2, and NOE to None. 140 r1 = None 141 r2 = None 142 noe = None 143 144 # Get the R1, R2, and NOE values corresponding to the set frequency. 145 for ri_id in cdp.ri_ids: 146 # The frequency does not match. 147 if cdp.spectrometer_frq[ri_id] != cdp.ct_frq: 148 continue 149 150 # R1. 151 if cdp.ri_type[ri_id] == 'R1': 152 if sim_index == None: 153 r1 = spin.ri_data[ri_id] 154 else: 155 r1 = spin.ri_data_sim[ri_id][sim_index] 156 157 # R2. 158 if cdp.ri_type[ri_id] == 'R2': 159 if sim_index == None: 160 r2 = spin.ri_data[ri_id] 161 else: 162 r2 = spin.ri_data_sim[ri_id][sim_index] 163 164 # NOE. 165 if cdp.ri_type[ri_id] == 'NOE': 166 if sim_index == None: 167 noe = spin.ri_data[ri_id] 168 else: 169 noe = spin.ri_data_sim[ri_id][sim_index] 170 171 # Skip the spin if not all of the three value exist. 172 if r1 == None or r2 == None or noe == None: 173 continue 174 175 # Loop over the interatomic data. 176 interatoms = return_interatom_list(id) 177 for i in range(len(interatoms)): 178 # No relaxation mechanism. 179 if not interatoms[i].dipole_pair: 180 continue 181 182 # The surrounding spins. 183 if id != interatoms[i].spin_id1: 184 spin_id2 = interatoms[i].spin_id1 185 else: 186 spin_id2 = interatoms[i].spin_id2 187 spin2 = return_spin(spin_id2) 188 189 # Gyromagnetic ratios. 190 gx = return_gyromagnetic_ratio(spin.isotope) 191 gh = return_gyromagnetic_ratio(spin2.isotope) 192 193 # The interatomic distance. 194 r = interatoms[i].r 195 196 # Initialise the function to calculate. 197 ct = Consistency(frq=cdp.ct_frq, gx=gx, gh=gh, mu0=mu0, h_bar=h_bar) 198 199 # Calculate the consistency tests values. 200 j0, f_eta, f_r2 = ct.func(orientation=spin.orientation, tc=spin.tc, r=r, csa=spin.csa, r1=r1, r2=r2, noe=noe) 201 202 # Consistency tests values. 203 if sim_index == None: 204 spin.j0 = j0 205 spin.f_eta = f_eta 206 spin.f_r2 = f_r2 207 208 # Monte Carlo simulated consistency tests values. 209 else: 210 # Initialise the simulation data structures. 211 self.data_init(spin, sim=1) 212 if spin.j0_sim == None: 213 spin.j0_sim = [] 214 spin.f_eta_sim = [] 215 spin.f_r2_sim = [] 216 217 # Consistency tests values. 218 spin.j0_sim.append(j0) 219 spin.f_eta_sim.append(f_eta) 220 spin.f_r2_sim.append(f_r2)
221 222
223 - def data_init(self, data_cont, sim=False):
224 """Initialise the data structures. 225 226 @param data_cont: The data container. 227 @type data_cont: instance 228 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure. 229 @type sim: bool 230 """ 231 232 # Get the data names. 233 data_names = self.data_names() 234 235 # Loop over the data structure names. 236 for name in data_names: 237 # Simulation data structures. 238 if sim: 239 # Add '_sim' to the names. 240 name = name + '_sim' 241 242 # If the name is not in 'data_cont', add it. 243 if not hasattr(data_cont, name): 244 # Set the attribute. 245 setattr(data_cont, name, None)
246 247
248 - def overfit_deselect(self, data_check=True, verbose=True):
249 """Deselect spins which have insufficient data to support calculation. 250 251 @keyword data_check: A flag to signal if the presence of base data is to be checked for. 252 @type data_check: bool 253 @keyword verbose: A flag which if True will allow printouts. 254 @type verbose: bool 255 """ 256 257 # Print out. 258 if verbose: 259 print("\nOver-fit spin deselection:") 260 261 # Test the sequence data exists. 262 if not exists_mol_res_spin_data(): 263 raise RelaxNoSequenceError 264 265 # Loop over spin data. 266 deselect_flag = False 267 spin_count = 0 268 for spin, spin_id in spin_loop(return_id=True): 269 # Skip deselected spins. 270 if not spin.select: 271 continue 272 273 # The interatomic data. 274 interatoms = return_interatom_list(spin_id) 275 276 # Loop over the interatomic data. 277 dipole_relax = False 278 for i in range(len(interatoms)): 279 # No dipolar relaxation mechanism. 280 if not interatoms[i].dipole_pair: 281 continue 282 283 # The surrounding spins. 284 if spin_id != interatoms[i].spin_id1: 285 spin_id2 = interatoms[i].spin_id1 286 else: 287 spin_id2 = interatoms[i].spin_id2 288 spin2 = return_spin(spin_id2) 289 290 # Dipolar relaxation flag. 291 dipole_relax = True 292 293 # No relaxation mechanism. 294 if not dipole_relax or not hasattr(spin, 'csa') or spin.csa == None: 295 warn(RelaxDeselectWarning(spin_id, 'an absence of relaxation mechanisms')) 296 spin.select = False 297 deselect_flag = True 298 continue 299 300 # Data checks. 301 if data_check: 302 # The number of relaxation data points (and for infinite data). 303 data_points = 0 304 inf_data = False 305 if hasattr(cdp, 'ri_ids') and hasattr(spin, 'ri_data'): 306 for id in cdp.ri_ids: 307 if id in spin.ri_data and spin.ri_data[id] != None: 308 data_points += 1 309 310 # Infinite data! 311 if isInf(spin.ri_data[id]): 312 inf_data = True 313 314 # Infinite data. 315 if inf_data: 316 warn(RelaxDeselectWarning(spin_id, 'infinite relaxation data')) 317 spin.select = False 318 deselect_flag = True 319 continue 320 321 # Relaxation data must exist! 322 if not hasattr(spin, 'ri_data'): 323 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data')) 324 spin.select = False 325 deselect_flag = True 326 continue 327 328 # Require 3 or more relaxation data points. 329 if data_points < 3: 330 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required')) 331 spin.select = False 332 deselect_flag = True 333 continue 334 335 # Increment the spin number. 336 spin_count += 1 337 338 # No spins selected, so fail hard to prevent the user from going any further. 339 if spin_count == 0: 340 warn(RelaxWarning("No spins are selected therefore the optimisation or calculation cannot proceed.")) 341 342 # Final printout. 343 if verbose and not deselect_flag: 344 print("No spins have been deselected.")
345 346
347 - def set_error(self, model_info, index, error):
348 """Set the parameter errors. 349 350 @param model_info: The spin container originating from model_loop(). 351 @type model_info: SpinContainer instance 352 @param index: The index of the parameter to set the errors for. 353 @type index: int 354 @param error: The error value. 355 @type error: float 356 """ 357 358 # Alias. 359 spin = model_info 360 361 # Return J(0) sim data. 362 if index == 0: 363 spin.j0_err = error 364 365 # Return F_eta sim data. 366 if index == 1: 367 spin.f_eta_err = error 368 369 # Return F_R2 sim data. 370 if index == 2: 371 spin.f_r2_err = error
372 373
374 - def sim_return_param(self, model_info, index):
375 """Return the array of simulation parameter values. 376 377 @param model_info: The spin container originating from model_loop(). 378 @type model_info: SpinContainer instance 379 @param index: The index of the parameter to return the array of values for. 380 @type index: int 381 @return: The array of simulation parameter values. 382 @rtype: list of float 383 """ 384 385 # Alias. 386 spin = model_info 387 388 # Skip deselected spins. 389 if not spin.select: 390 return 391 392 # Return J(0) sim data. 393 if index == 0: 394 return spin.j0_sim 395 396 # Return F_eta sim data. 397 if index == 1: 398 return spin.f_eta_sim 399 400 # Return F_R2 sim data. 401 if index == 2: 402 return spin.f_r2_sim
403 404
405 - def sim_return_selected(self, model_info):
406 """Return the array of selected simulation flags. 407 408 @param model_info: The spin container originating from model_loop(). 409 @type model_info: SpinContainer instance 410 @return: The array of selected simulation flags. 411 @rtype: list of int 412 """ 413 414 # Alias. 415 spin = model_info 416 417 # Multiple spins. 418 return spin.select_sim
419