Package specific_fns :: Module consistency_tests
[hide private]
[frames] | no frames]

Source Code for Module specific_fns.consistency_tests

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2012 Edward d'Auvergne                                   # 
  4  # Copyright (C) 2007-2009 Sebastien Morin                                     # 
  5  #                                                                             # 
  6  # This file is part of the program relax.                                     # 
  7  #                                                                             # 
  8  # relax 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 2 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # relax 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 relax; if not, write to the Free Software                        # 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 21  #                                                                             # 
 22  ############################################################################### 
 23   
 24  # Python module imports. 
 25  from re import search 
 26  from warnings import warn 
 27   
 28  # relax module imports. 
 29  from api_base import API_base 
 30  from api_common import API_common 
 31  from generic_fns.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop 
 32  from generic_fns import pipes 
 33  from maths_fns.consistency_tests import Consistency 
 34  from physical_constants import N15_CSA, NH_BOND_LENGTH, h_bar, mu0, return_gyromagnetic_ratio 
 35  from relax_errors import RelaxError, RelaxFuncSetupError, RelaxNoSequenceError, RelaxNoValueError, RelaxProtonTypeError, RelaxSpinTypeError 
 36  from relax_warnings import RelaxDeselectWarning 
 37  import specific_fns 
 38   
 39   
40 -class Consistency_tests(API_base, API_common):
41 """Class containing functions specific to consistency testing.""" 42
43 - def __init__(self):
44 """Initialise the class by placing API_common methods into the API.""" 45 46 # Execute the base class __init__ method. 47 super(Consistency_tests, self).__init__() 48 49 # Place methods into the API. 50 self.base_data_loop = self._base_data_loop_spin 51 self.create_mc_data = self._create_mc_relax_data 52 self.model_loop = self._model_loop_spin 53 self.return_conversion_factor = self._return_no_conversion_factor 54 self.return_error = self._return_error_relax_data 55 self.return_value = self._return_value_general 56 self.set_param_values = self._set_param_values_spin 57 self.set_selected_sim = self._set_selected_sim_spin 58 self.sim_pack_data = self._sim_pack_relax_data 59 60 # Set up the spin parameters. 61 self.PARAMS.add('j0', scope='spin', desc='Spectral density value at 0 MHz (from Farrow et al. (1995) JBNMR, 6: 153-162)', py_type=float, grace_string='\\qJ(0)\\Q', err=True, sim=True) 62 self.PARAMS.add('f_eta', scope='spin', desc='Eta-test (from Fushman et al. (1998) JACS, 120: 10947-10952)', py_type=float, grace_string='\\qF\\s\\xh\\Q', err=True, sim=True) 63 self.PARAMS.add('f_r2', scope='spin', desc='R2-test (from Fushman et al. (1998) JACS, 120: 10947-10952)', py_type=float, grace_string='\\qF\\sR2\\Q', err=True, sim=True) 64 self.PARAMS.add('r', scope='spin', default=NH_BOND_LENGTH, units='Angstrom', desc='Bond length', py_type=float, grace_string='Bond length') 65 self.PARAMS.add('csa', scope='spin', default=N15_CSA, units='ppm', desc='CSA value', py_type=float, grace_string='\\qCSA\\Q') 66 self.PARAMS.add('heteronuc_type', scope='spin', default='15N', desc='The heteronucleus type', py_type=str) 67 self.PARAMS.add('proton_type', scope='spin', default='1H', desc='The proton type', py_type=str) 68 self.PARAMS.add('orientation', scope='spin', default=15.7, units='degrees', desc="Angle between the 15N-1H vector and the principal axis of the 15N chemical shift tensor", py_type=float, grace_string='\\q\\xq\\Q') 69 self.PARAMS.add('tc', scope='spin', default=13 * 1e-9, units='ns', desc="Correlation time", py_type=float, grace_string='\\q\\xt\\f{}c\\Q')
70 71
72 - def _set_frq(self, frq=None):
73 """Function for selecting which relaxation data to use in the consistency tests.""" 74 75 # Test if the current pipe exists. 76 pipes.test() 77 78 # Test if the pipe type is set to 'ct'. 79 function_type = cdp.pipe_type 80 if function_type != 'ct': 81 raise RelaxFuncSetupError(specific_fns.setup.get_string(function_type)) 82 83 # Test if the frequency has been set. 84 if hasattr(cdp, 'ct_frq'): 85 raise RelaxError("The frequency for the run has already been set.") 86 87 # Create the data structure if it doesn't exist. 88 if not hasattr(cdp, 'ct_frq'): 89 cdp.ct_frq = {} 90 91 # Set the frequency. 92 cdp.ct_frq = frq
93 94
95 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
96 """Calculation of the consistency functions. 97 98 @keyword spin_id: The spin identification string. 99 @type spin_id: None or str 100 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity. 101 @type verbosity: int 102 @keyword sim_index: The optional MC simulation index. 103 @type sim_index: None or int 104 """ 105 106 # Test if the frequency has been set. 107 if not hasattr(cdp, 'ct_frq') or not isinstance(cdp.ct_frq, float): 108 raise RelaxError("The frequency has not been set up.") 109 110 # Test if the sequence data is loaded. 111 if not exists_mol_res_spin_data(): 112 raise RelaxNoSequenceError 113 114 # Test if the CSA, bond length, angle Theta and correlation time values have been set. 115 for spin in spin_loop(spin_id): 116 # Skip deselected spins. 117 if not spin.select: 118 continue 119 120 # Test if the CSA value has been set. 121 if not hasattr(spin, 'csa') or spin.csa == None: 122 raise RelaxNoValueError("CSA") 123 124 # Test if the bond length has been set. 125 if not hasattr(spin, 'r') or spin.r == None: 126 raise RelaxNoValueError("bond length") 127 128 # Test if the angle Theta has been set. 129 if not hasattr(spin, 'orientation') or spin.orientation == None: 130 raise RelaxNoValueError("angle Theta") 131 132 # Test if the correlation time has been set. 133 if not hasattr(spin, 'tc') or spin.tc == None: 134 raise RelaxNoValueError("correlation time") 135 136 # Test if the spin type has been set. 137 if not hasattr(spin, 'heteronuc_type'): 138 raise RelaxSpinTypeError 139 140 # Test if the type attached proton has been set. 141 if not hasattr(spin, 'proton_type'): 142 raise RelaxProtonTypeError 143 144 # Frequency index. 145 if cdp.ct_frq not in cdp.frq.values(): 146 raise RelaxError("No relaxation data corresponding to the frequency %s has been loaded." % cdp.ct_frq) 147 148 # Consistency testing. 149 for spin in spin_loop(spin_id): 150 # Skip deselected spins. 151 if not spin.select: 152 continue 153 154 # Set the r1, r2, and NOE to None. 155 r1 = None 156 r2 = None 157 noe = None 158 159 # Get the R1, R2, and NOE values corresponding to the set frequency. 160 for ri_id in cdp.ri_ids: 161 # The frequency does not match. 162 if cdp.frq[ri_id] != cdp.ct_frq: 163 continue 164 165 # R1. 166 if cdp.ri_type[ri_id] == 'R1': 167 if sim_index == None: 168 r1 = spin.ri_data[ri_id] 169 else: 170 r1 = spin.ri_data_sim[ri_id][sim_index] 171 172 # R2. 173 if cdp.ri_type[ri_id] == 'R2': 174 if sim_index == None: 175 r2 = spin.ri_data[ri_id] 176 else: 177 r2 = spin.ri_data_sim[ri_id][sim_index] 178 179 # NOE. 180 if cdp.ri_type[ri_id] == 'NOE': 181 if sim_index == None: 182 noe = spin.ri_data[ri_id] 183 else: 184 noe = spin.ri_data_sim[ri_id][sim_index] 185 186 # Skip the spin if not all of the three value exist. 187 if r1 == None or r2 == None or noe == None: 188 continue 189 190 # Initialise the function to calculate. 191 self.ct = Consistency(frq=cdp.ct_frq, gx=return_gyromagnetic_ratio(spin.heteronuc_type), gh=return_gyromagnetic_ratio(spin.proton_type), mu0=mu0, h_bar=h_bar) 192 193 # Calculate the consistency tests values. 194 j0, f_eta, f_r2 = self.ct.func(orientation=spin.orientation, tc=spin.tc, r=spin.r, csa=spin.csa, r1=r1, r2=r2, noe=noe) 195 196 # Consistency tests values. 197 if sim_index == None: 198 spin.j0 = j0 199 spin.f_eta = f_eta 200 spin.f_r2 = f_r2 201 202 # Monte Carlo simulated consistency tests values. 203 else: 204 # Initialise the simulation data structures. 205 self.data_init(spin, sim=1) 206 if spin.j0_sim == None: 207 spin.j0_sim = [] 208 spin.f_eta_sim = [] 209 spin.f_r2_sim = [] 210 211 # Consistency tests values. 212 spin.j0_sim.append(j0) 213 spin.f_eta_sim.append(f_eta) 214 spin.f_r2_sim.append(f_r2)
215 216 217
218 - def data_init(self, data_cont, sim=False):
219 """Initialise the data structures. 220 221 @param data_cont: The data container. 222 @type data_cont: instance 223 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure. 224 @type sim: bool 225 """ 226 227 # Get the data names. 228 data_names = self.data_names() 229 230 # Loop over the data structure names. 231 for name in data_names: 232 # Simulation data structures. 233 if sim: 234 # Add '_sim' to the names. 235 name = name + '_sim' 236 237 # If the name is not in 'data_cont', add it. 238 if not hasattr(data_cont, name): 239 # Set the attribute. 240 setattr(data_cont, name, None)
241 242 243 default_value_doc = """ 244 Consistency testing default values 245 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 246 These default values are found in the file 'physical_constants.py'. 247 248 ______________________________________________________________________________________ 249 | | | | 250 | Data type | Object name | Value | 251 |_______________________________________|____________________|_________________________| 252 | | | | 253 | Bond length | 'r' | 1.02 * 1e-10 | 254 | | | | 255 | CSA | 'csa' | -172 * 1e-6 | 256 | | | | 257 | Heteronucleus type | 'heteronuc_type' | '15N' | 258 | | | | 259 | Proton type | 'proton_type' | '1H' | 260 | | | | 261 | Angle Theta | 'orientation' | 15.7 | 262 | | | | 263 | Correlation time | 'tc' | 13 * 1e-9 | 264 |_______________________________________|____________________|_________________________| 265 266 """ 267 268
269 - def overfit_deselect(self):
270 """Deselect spins which have insufficient data to support calculation.""" 271 272 # Print out. 273 print("\n\nOver-fit spin deselection.\n") 274 275 # Test the sequence data exists. 276 if not exists_mol_res_spin_data(): 277 raise RelaxNoSequenceError 278 279 # Loop over spin data. 280 for spin, spin_id in spin_loop(return_id=True): 281 # Skip deselected spins. 282 if not spin.select: 283 continue 284 285 # Check if data exists. 286 if not hasattr(spin, 'ri_data'): 287 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data')) 288 spin.select = False 289 290 # Require 3 or more data points. 291 else: 292 # Count the points. 293 data_points = 0 294 for id in cdp.ri_ids: 295 if spin.ri_data.has_key(id) and spin.ri_data[id] != None: 296 data_points += 1 297 298 # Not enough. 299 if data_points < 3: 300 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required')) 301 spin.select = False
302 303 304 return_data_name_doc = """ 305 Consistency testing data type string matching patterns 306 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307 308 ___________________________________________ 309 | | | 310 | Data type | Object name | 311 |_______________________|__________________| 312 | | | 313 | J(0) | 'j0' | 314 | | | 315 | F_eta | 'f_eta' | 316 | | | 317 | F_R2 | 'f_r2' | 318 | | | 319 | Bond length | 'r' | 320 | | | 321 | CSA | 'csa' | 322 | | | 323 | Heteronucleus type | 'heteronuc_type' | 324 | | | 325 | Proton type | 'proton_type' | 326 | | | 327 | Angle Theta | 'orientation' | 328 | | | 329 | Correlation time | 'tc' | 330 |_______________________|__________________| 331 """ 332 333 334 set_doc = """ 335 Consistency testing set details 336 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 337 338 In consistency testing, only four values can be set, the bond length, CSA, angle 339 Theta ('orientation') and correlation time values. These must be set prior to the 340 calculation of consistency functions. 341 342 """ 343 344
345 - def set_error(self, model_info, index, error):
346 """Set the parameter errors. 347 348 @param model_info: The spin container originating from model_loop(). 349 @type model_info: SpinContainer instance 350 @param index: The index of the parameter to set the errors for. 351 @type index: int 352 @param error: The error value. 353 @type error: float 354 """ 355 356 # Alias. 357 spin = model_info 358 359 # Return J(0) sim data. 360 if index == 0: 361 spin.j0_err = error 362 363 # Return F_eta sim data. 364 if index == 1: 365 spin.f_eta_err = error 366 367 # Return F_R2 sim data. 368 if index == 2: 369 spin.f_r2_err = error
370 371
372 - def sim_return_param(self, model_info, index):
373 """Return the array of simulation parameter values. 374 375 @param model_info: The spin container originating from model_loop(). 376 @type model_info: SpinContainer instance 377 @param index: The index of the parameter to return the array of values for. 378 @type index: int 379 @return: The array of simulation parameter values. 380 @rtype: list of float 381 """ 382 383 # Alias. 384 spin = model_info 385 386 # Skip deselected spins. 387 if not spin.select: 388 return 389 390 # Return J(0) sim data. 391 if index == 0: 392 return spin.j0_sim 393 394 # Return F_eta sim data. 395 if index == 1: 396 return spin.f_eta_sim 397 398 # Return F_R2 sim data. 399 if index == 2: 400 return spin.f_r2_sim
401 402
403 - def sim_return_selected(self, model_info):
404 """Return the array of selected simulation flags. 405 406 @param model_info: The spin container originating from model_loop(). 407 @type model_info: SpinContainer instance 408 @return: The array of selected simulation flags. 409 @rtype: list of int 410 """ 411 412 # Alias. 413 spin = model_info 414 415 # Multiple spins. 416 return spin.select_sim
417