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