Package specific_fns :: Package model_free :: Module main
[hide private]
[frames] | no frames]

Source Code for Module specific_fns.model_free.main

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2003-2012 Edward d'Auvergne                                   # 
   4  #                                                                             # 
   5  # This file is part of the program relax.                                     # 
   6  #                                                                             # 
   7  # relax 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 2 of the License, or           # 
  10  # (at your option) any later version.                                         # 
  11  #                                                                             # 
  12  # relax 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 relax; if not, write to the Free Software                        # 
  19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
  20  #                                                                             # 
  21  ############################################################################### 
  22   
  23  # Python module imports. 
  24  from copy import deepcopy 
  25  from math import pi 
  26  from numpy import float64, array, identity, transpose, zeros 
  27  from re import match, search 
  28  from string import replace, split 
  29  import sys 
  30  from warnings import warn 
  31   
  32  # relax module imports. 
  33  import arg_check 
  34  from data.diff_tensor import DiffTensorSimList 
  35  from float import isNaN, isInf 
  36  from generic_fns import diffusion_tensor, pipes, relax_data, sequence 
  37  from generic_fns.mol_res_spin import convert_from_global_index, count_spins, exists_mol_res_spin_data, find_index, return_spin, return_spin_from_index, spin_index_loop, spin_loop 
  38  from maths_fns.mf import Mf 
  39  from minfx.generic import generic_minimise 
  40  import specific_fns 
  41  from relax_errors import RelaxError, RelaxFuncSetupError, RelaxInfError, RelaxInvalidDataError, RelaxLenError, RelaxNaNError, RelaxNoModelError, RelaxNoPdbError, RelaxNoResError, RelaxNoSequenceError, RelaxNoSpinSpecError, RelaxNoTensorError, RelaxNoValueError, RelaxNoVectorsError, RelaxNucleusError, RelaxTensorError 
  42  from relax_warnings import RelaxDeselectWarning 
  43   
  44   
  45   
46 -class Model_free_main:
47 """Class containing functions specific to model-free analysis.""" 48
49 - def _are_mf_params_set(self, spin):
50 """Test if the model-free parameter values are set. 51 52 @param spin: The spin container object. 53 @type spin: SpinContainer instance 54 @return: The name of the first parameter in the parameter list in which the 55 corresponding parameter value is None. If all parameters are set, then None 56 is returned. 57 @rtype: str or None 58 """ 59 60 # Deselected residue. 61 if spin.select == 0: 62 return 63 64 # Loop over the model-free parameters. 65 for j in xrange(len(spin.params)): 66 # Local tm. 67 if spin.params[j] == 'local_tm' and spin.local_tm == None: 68 return spin.params[j] 69 70 # S2. 71 elif spin.params[j] == 's2' and spin.s2 == None: 72 return spin.params[j] 73 74 # S2f. 75 elif spin.params[j] == 's2f' and spin.s2f == None: 76 return spin.params[j] 77 78 # S2s. 79 elif spin.params[j] == 's2s' and spin.s2s == None: 80 return spin.params[j] 81 82 # te. 83 elif spin.params[j] == 'te' and spin.te == None: 84 return spin.params[j] 85 86 # tf. 87 elif spin.params[j] == 'tf' and spin.tf == None: 88 return spin.params[j] 89 90 # ts. 91 elif spin.params[j] == 'ts' and spin.ts == None: 92 return spin.params[j] 93 94 # Rex. 95 elif spin.params[j] == 'rex' and spin.rex == None: 96 return spin.params[j] 97 98 # r. 99 elif spin.params[j] == 'r' and spin.r == None: 100 return spin.params[j] 101 102 # CSA. 103 elif spin.params[j] == 'csa' and spin.csa == None: 104 return spin.params[j]
105 106
107 - def _assemble_param_names(self, model_type, spin_id=None):
108 """Function for assembling a list of all the model parameter names. 109 110 @param model_type: The model-free model type. This must be one of 'mf', 'local_tm', 111 'diff', or 'all'. 112 @type model_type: str 113 @param spin_id: The spin identification string. 114 @type spin_id: str 115 @return: A list containing all the parameters of the model-free model. 116 @rtype: list of str 117 """ 118 119 # Initialise. 120 param_names = [] 121 122 # Diffusion tensor parameters. 123 if model_type == 'diff' or model_type == 'all': 124 # Spherical diffusion. 125 if cdp.diff_tensor.type == 'sphere': 126 param_names.append('tm') 127 128 # Spheroidal diffusion. 129 elif cdp.diff_tensor.type == 'spheroid': 130 param_names.append('tm') 131 param_names.append('Da') 132 param_names.append('theta') 133 param_names.append('phi') 134 135 # Ellipsoidal diffusion. 136 elif cdp.diff_tensor.type == 'ellipsoid': 137 param_names.append('tm') 138 param_names.append('Da') 139 param_names.append('Dr') 140 param_names.append('alpha') 141 param_names.append('beta') 142 param_names.append('gamma') 143 144 # Model-free parameters (spin specific parameters). 145 if model_type != 'diff': 146 # Loop over the spins. 147 for spin in spin_loop(spin_id): 148 # Skip deselected spins. 149 if not spin.select: 150 continue 151 152 # Add the spin specific model-free parameters. 153 param_names = param_names + spin.params 154 155 # Return the parameter names. 156 return param_names
157 158
159 - def _assemble_param_vector(self, spin=None, spin_id=None, sim_index=None, model_type=None):
160 """Assemble the model-free parameter vector (as numpy array). 161 162 If the spin argument is supplied, then the spin_id argument will be ignored. 163 164 @keyword spin: The spin data container. 165 @type spin: SpinContainer instance 166 @keyword spin_id: The spin identification string. 167 @type spin_id: str 168 @keyword sim_index: The optional MC simulation index. 169 @type sim_index: int 170 @keyword model_type: The optional model type, one of 'all', 'diff', 'mf', or 'local_tm'. 171 @type model_type: str or None 172 @return: An array of the parameter values of the model-free model. 173 @rtype: numpy array 174 """ 175 176 # Initialise. 177 param_vector = [] 178 179 # Determine the model type. 180 if not model_type: 181 model_type = self._determine_model_type() 182 183 # Diffusion tensor parameters. 184 if model_type == 'diff' or model_type == 'all': 185 # Normal parameters. 186 if sim_index == None: 187 # Spherical diffusion. 188 if cdp.diff_tensor.type == 'sphere': 189 param_vector.append(cdp.diff_tensor.tm) 190 191 # Spheroidal diffusion. 192 elif cdp.diff_tensor.type == 'spheroid': 193 param_vector.append(cdp.diff_tensor.tm) 194 param_vector.append(cdp.diff_tensor.Da) 195 param_vector.append(cdp.diff_tensor.theta) 196 param_vector.append(cdp.diff_tensor.phi) 197 198 # Ellipsoidal diffusion. 199 elif cdp.diff_tensor.type == 'ellipsoid': 200 param_vector.append(cdp.diff_tensor.tm) 201 param_vector.append(cdp.diff_tensor.Da) 202 param_vector.append(cdp.diff_tensor.Dr) 203 param_vector.append(cdp.diff_tensor.alpha) 204 param_vector.append(cdp.diff_tensor.beta) 205 param_vector.append(cdp.diff_tensor.gamma) 206 207 # Monte Carlo diffusion tensor parameters. 208 else: 209 # Spherical diffusion. 210 if cdp.diff_tensor.type == 'sphere': 211 param_vector.append(cdp.diff_tensor.tm_sim[sim_index]) 212 213 # Spheroidal diffusion. 214 elif cdp.diff_tensor.type == 'spheroid': 215 param_vector.append(cdp.diff_tensor.tm_sim[sim_index]) 216 param_vector.append(cdp.diff_tensor.Da_sim[sim_index]) 217 param_vector.append(cdp.diff_tensor.theta_sim[sim_index]) 218 param_vector.append(cdp.diff_tensor.phi_sim[sim_index]) 219 220 # Ellipsoidal diffusion. 221 elif cdp.diff_tensor.type == 'ellipsoid': 222 param_vector.append(cdp.diff_tensor.tm_sim[sim_index]) 223 param_vector.append(cdp.diff_tensor.Da_sim[sim_index]) 224 param_vector.append(cdp.diff_tensor.Dr_sim[sim_index]) 225 param_vector.append(cdp.diff_tensor.alpha_sim[sim_index]) 226 param_vector.append(cdp.diff_tensor.beta_sim[sim_index]) 227 param_vector.append(cdp.diff_tensor.gamma_sim[sim_index]) 228 229 # Model-free parameters (residue specific parameters). 230 if model_type != 'diff': 231 # The loop. 232 if spin: 233 loop = [spin] 234 else: 235 loop = spin_loop(spin_id) 236 237 # Loop over the spins. 238 for spin in loop: 239 # Skip deselected residues. 240 if not spin.select: 241 continue 242 243 # Loop over the model-free parameters. 244 for i in xrange(len(spin.params)): 245 # local tm. 246 if spin.params[i] == 'local_tm': 247 if sim_index == None: 248 param_vector.append(spin.local_tm) 249 else: 250 param_vector.append(spin.local_tm_sim[sim_index]) 251 252 # S2. 253 elif spin.params[i] == 's2': 254 if sim_index == None: 255 param_vector.append(spin.s2) 256 else: 257 param_vector.append(spin.s2_sim[sim_index]) 258 259 # S2f. 260 elif spin.params[i] == 's2f': 261 if sim_index == None: 262 param_vector.append(spin.s2f) 263 else: 264 param_vector.append(spin.s2f_sim[sim_index]) 265 266 # S2s. 267 elif spin.params[i] == 's2s': 268 if sim_index == None: 269 param_vector.append(spin.s2s) 270 else: 271 param_vector.append(spin.s2s_sim[sim_index]) 272 273 # te. 274 elif spin.params[i] == 'te': 275 if sim_index == None: 276 param_vector.append(spin.te) 277 else: 278 param_vector.append(spin.te_sim[sim_index]) 279 280 # tf. 281 elif spin.params[i] == 'tf': 282 if sim_index == None: 283 param_vector.append(spin.tf) 284 else: 285 param_vector.append(spin.tf_sim[sim_index]) 286 287 # ts. 288 elif spin.params[i] == 'ts': 289 if sim_index == None: 290 param_vector.append(spin.ts) 291 else: 292 param_vector.append(spin.ts_sim[sim_index]) 293 294 # Rex. 295 elif spin.params[i] == 'rex': 296 if sim_index == None: 297 param_vector.append(spin.rex) 298 else: 299 param_vector.append(spin.rex_sim[sim_index]) 300 301 # r. 302 elif spin.params[i] == 'r': 303 if sim_index == None: 304 param_vector.append(spin.r) 305 else: 306 param_vector.append(spin.r_sim[sim_index]) 307 308 # CSA. 309 elif spin.params[i] == 'csa': 310 if sim_index == None: 311 param_vector.append(spin.csa) 312 else: 313 param_vector.append(spin.csa_sim[sim_index]) 314 315 # Unknown parameter. 316 else: 317 raise RelaxError("Unknown parameter.") 318 319 # Replace all instances of None with 0.0 to allow the list to be converted to a numpy array. 320 for i in xrange(len(param_vector)): 321 if param_vector[i] == None: 322 param_vector[i] = 0.0 323 324 # Return a numpy array. 325 return array(param_vector, float64)
326 327
328 - def _assemble_scaling_matrix(self, num_params, model_type=None, spin=None, spin_id=None, scaling=True):
329 """Create and return the scaling matrix. 330 331 If the spin argument is supplied, then the spin_id argument will be ignored. 332 333 @param num_params: The number of parameters in the model. 334 @type num_params: int 335 @keyword model_type: The model type, one of 'all', 'diff', 'mf', or 'local_tm'. 336 @type model_type: str 337 @keyword spin: The spin data container. 338 @type spin: SpinContainer instance 339 @keyword spin_id: The spin identification string. 340 @type spin_id: str 341 @return: The diagonal and square scaling matrix. 342 @rtype: numpy diagonal matrix 343 """ 344 345 # Initialise. 346 if num_params == 0: 347 scaling_matrix = zeros((0, 0), float64) 348 else: 349 scaling_matrix = identity(num_params, float64) 350 i = 0 351 352 # No diagonal scaling, so return the identity matrix. 353 if not scaling: 354 return scaling_matrix 355 356 # tm, te, tf, and ts (must all be the same for diagonal scaling!). 357 ti_scaling = 1e-12 358 359 # Diffusion tensor parameters. 360 if model_type == 'diff' or model_type == 'all': 361 # Spherical diffusion. 362 if cdp.diff_tensor.type == 'sphere': 363 # tm. 364 scaling_matrix[i, i] = ti_scaling 365 366 # Increment i. 367 i = i + 1 368 369 # Spheroidal diffusion. 370 elif cdp.diff_tensor.type == 'spheroid': 371 # tm, Da, theta, phi 372 scaling_matrix[i, i] = ti_scaling 373 scaling_matrix[i+1, i+1] = 1e7 374 scaling_matrix[i+2, i+2] = 1.0 375 scaling_matrix[i+3, i+3] = 1.0 376 377 # Increment i. 378 i = i + 4 379 380 # Ellipsoidal diffusion. 381 elif cdp.diff_tensor.type == 'ellipsoid': 382 # tm, Da, Dr, alpha, beta, gamma. 383 scaling_matrix[i, i] = ti_scaling 384 scaling_matrix[i+1, i+1] = 1e7 385 scaling_matrix[i+2, i+2] = 1.0 386 scaling_matrix[i+3, i+3] = 1.0 387 scaling_matrix[i+4, i+4] = 1.0 388 scaling_matrix[i+5, i+5] = 1.0 389 390 # Increment i. 391 i = i + 6 392 393 # Model-free parameters. 394 if model_type != 'diff': 395 # The loop. 396 if spin: 397 loop = [spin] 398 else: 399 loop = spin_loop(spin_id) 400 401 # Loop over the spins. 402 for spin in loop: 403 # Skip deselected spins. 404 if not spin.select: 405 continue 406 407 # Loop over the model-free parameters. 408 for k in xrange(len(spin.params)): 409 # Local tm, te, tf, and ts (must all be the same for diagonal scaling!). 410 if spin.params[k] == 'local_tm' or search('^t', spin.params[k]): 411 scaling_matrix[i, i] = ti_scaling 412 413 # Rex. 414 elif spin.params[k] == 'rex': 415 scaling_matrix[i, i] = 1.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]]) ** 2 416 417 # Bond length. 418 elif spin.params[k] == 'r': 419 scaling_matrix[i, i] = 1e-10 420 421 # CSA. 422 elif spin.params[k] == 'csa': 423 scaling_matrix[i, i] = 1e-4 424 425 # Increment i. 426 i = i + 1 427 428 # Return the scaling matrix. 429 return scaling_matrix
430 431
432 - def back_calc_ri(self, spin_index=None, ri_id=None, ri_type=None, frq=None):
433 """Back-calculation of relaxation data from the model-free parameter values. 434 435 @keyword spin_index: The global spin index. 436 @type spin_index: int 437 @keyword ri_id: The relaxation data ID string. 438 @type ri_id: str 439 @keyword ri_type: The relaxation data type. 440 @type ri_type: str 441 @keyword frq: The field strength. 442 @type frq: float 443 @return: The back calculated relaxation data value corresponding to the index. 444 @rtype: float 445 """ 446 447 # Get the spin container. 448 spin, spin_id = return_spin_from_index(global_index=spin_index, return_spin_id=True) 449 450 # Missing structural data. 451 if hasattr(cdp, 'diff_tensor') and (cdp.diff_tensor.type == 'spheroid' or cdp.diff_tensor.type == 'ellipsoid') and (not hasattr(spin, 'xh_vect') or spin.xh_vect == None): 452 warn(RelaxDeselectWarning(spin_id, 'missing structural data')) 453 return 454 455 # Get the relaxation value from the minimise function. 456 value = self.minimise(min_algor='back_calc', min_options=(spin_index, ri_id, ri_type, frq)) 457 458 # Return the relaxation value. 459 return value
460 461
462 - def _compare_objects(self, object_from, object_to, pipe_from, pipe_to):
463 """Compare the contents of the two objects and raise RelaxErrors if they are not the same. 464 465 @param object_from: The first object. 466 @type object_from: any object 467 @param object_to: The second object. 468 @type object_to: any object 469 @param pipe_from: The name of the data pipe containing the first object. 470 @type pipe_from: str 471 @param pipe_to: The name of the data pipe containing the second object. 472 @type pipe_to: str 473 """ 474 475 # Loop over the modifiable objects. 476 for data_name in dir(object_from): 477 # Skip special objects (starting with _, or in the original class and base class namespaces). 478 if search('^_', data_name) or data_name in list(object_from.__class__.__dict__.keys()) or (hasattr(object_from.__class__, '__bases__') and len(object_from.__class__.__bases__) and data_name in list(object_from.__class__.__bases__[0].__dict__.keys())): 479 continue 480 481 # Skip some more special objects. 482 if data_name in ['structural_data']: 483 continue 484 485 # Get the original object. 486 data_from = None 487 if hasattr(object_from, data_name): 488 data_from = getattr(object_from, data_name) 489 490 # Get the target object. 491 if data_from and not hasattr(object_to, data_name): 492 raise RelaxError("The structural object " + repr(data_name) + " of the " + repr(pipe_from) + " data pipe is not located in the " + repr(pipe_to) + " data pipe.") 493 elif data_from: 494 data_to = getattr(object_to, data_name) 495 else: 496 continue 497 498 # The data must match! 499 if data_from != data_to: 500 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".")
501 502
503 - def _conv_factor_rex(self):
504 """Calculate and return the Rex conversion factor. 505 506 @return: The Rex conversion factor. 507 @rtype: float 508 """ 509 510 # The factor. 511 return 1.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2
512 513
514 - def _create_model(self, model=None, equation=None, params=None, spin_id=None):
515 """Function for creating a custom model-free model. 516 517 @param model: The name of the model. 518 @type model: str 519 @param equation: The equation type to use. The 3 allowed types are: 'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}. 520 @type equation: str 521 @param params: A list of the parameters to include in the model. The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'. 522 @type params: list of str 523 @param spin_id: The spin identification string. 524 @type spin_id: str 525 """ 526 527 # Test if the current data pipe exists. 528 pipes.test() 529 530 # Test if the pipe type is 'mf'. 531 function_type = pipes.get_type() 532 if function_type != 'mf': 533 raise RelaxFuncSetupError(specific_fns.get_string(function_type)) 534 535 # Test if sequence data is loaded. 536 if not exists_mol_res_spin_data(): 537 raise RelaxNoSequenceError 538 539 # Check the validity of the model-free equation type. 540 valid_types = ['mf_orig', 'mf_ext', 'mf_ext2'] 541 if not equation in valid_types: 542 raise RelaxError("The model-free equation type argument " + repr(equation) + " is invalid and should be one of " + repr(valid_types) + ".") 543 544 # Check the validity of the parameter array. 545 s2, te, s2f, tf, s2s, ts, rex, csa, r = 0, 0, 0, 0, 0, 0, 0, 0, 0 546 for i in xrange(len(params)): 547 # Invalid parameter flag. 548 invalid_param = 0 549 550 # S2. 551 if params[i] == 's2': 552 # Does the array contain more than one instance of S2. 553 if s2: 554 invalid_param = 1 555 s2 = 1 556 557 # Does the array contain S2s. 558 s2s_flag = 0 559 for j in xrange(len(params)): 560 if params[j] == 's2s': 561 s2s_flag = 1 562 if s2s_flag: 563 invalid_param = 1 564 565 # te. 566 elif params[i] == 'te': 567 # Does the array contain more than one instance of te and has the extended model-free formula been selected. 568 if equation == 'mf_ext' or te: 569 invalid_param = 1 570 te = 1 571 572 # Does the array contain the parameter S2. 573 s2_flag = 0 574 for j in xrange(len(params)): 575 if params[j] == 's2': 576 s2_flag = 1 577 if not s2_flag: 578 invalid_param = 1 579 580 # S2f. 581 elif params[i] == 's2f': 582 # Does the array contain more than one instance of S2f and has the original model-free formula been selected. 583 if equation == 'mf_orig' or s2f: 584 invalid_param = 1 585 s2f = 1 586 587 # S2s. 588 elif params[i] == 's2s': 589 # Does the array contain more than one instance of S2s and has the original model-free formula been selected. 590 if equation == 'mf_orig' or s2s: 591 invalid_param = 1 592 s2s = 1 593 594 # tf. 595 elif params[i] == 'tf': 596 # Does the array contain more than one instance of tf and has the original model-free formula been selected. 597 if equation == 'mf_orig' or tf: 598 invalid_param = 1 599 tf = 1 600 601 # Does the array contain the parameter S2f. 602 s2f_flag = 0 603 for j in xrange(len(params)): 604 if params[j] == 's2f': 605 s2f_flag = 1 606 if not s2f_flag: 607 invalid_param = 1 608 609 # ts. 610 elif params[i] == 'ts': 611 # Does the array contain more than one instance of ts and has the original model-free formula been selected. 612 if equation == 'mf_orig' or ts: 613 invalid_param = 1 614 ts = 1 615 616 # Does the array contain the parameter S2 or S2s. 617 flag = 0 618 for j in xrange(len(params)): 619 if params[j] == 's2' or params[j] == 's2f': 620 flag = 1 621 if not flag: 622 invalid_param = 1 623 624 # Rex. 625 elif params[i] == 'rex': 626 if rex: 627 invalid_param = 1 628 rex = 1 629 630 # Bond length. 631 elif params[i] == 'r': 632 if r: 633 invalid_param = 1 634 r = 1 635 636 # CSA. 637 elif params[i] == 'csa': 638 if csa: 639 invalid_param = 1 640 csa = 1 641 642 # Unknown parameter. 643 else: 644 raise RelaxError("The parameter " + params[i] + " is not supported.") 645 646 # The invalid parameter flag is set. 647 if invalid_param: 648 raise RelaxError("The parameter array " + repr(params) + " contains an invalid combination of parameters.") 649 650 # Set up the model. 651 self._model_setup(model, equation, params, spin_id)
652 653
654 - def _delete(self):
655 """Delete all the model-free data.""" 656 657 # Test if the current pipe exists. 658 pipes.test() 659 660 # Test if the pipe type is set to 'mf'. 661 function_type = pipes.get_type() 662 if function_type != 'mf': 663 raise RelaxFuncSetupError(specific_fns.setup.get_string(function_type)) 664 665 # Test if the sequence data is loaded. 666 if not exists_mol_res_spin_data(): 667 raise RelaxNoSequenceError 668 669 # Get all data structure names. 670 names = self.data_names() 671 672 # Loop over the spins. 673 for spin in spin_loop(): 674 # Loop through the data structure names. 675 for name in names: 676 # Skip the data structure if it does not exist. 677 if not hasattr(spin, name): 678 continue 679 680 # Delete the data. 681 delattr(spin, name)
682 683
684 - def _determine_model_type(self):
685 """Determine the global model type. 686 687 @return: The name of the model type, which will be one of 'all', 'diff', 'mf', or 'local_tm'. If all parameters are fixed (and no spins selected), None is returned. 688 @rtype: str or None 689 """ 690 691 # Test if sequence data is loaded. 692 if not exists_mol_res_spin_data(): 693 raise RelaxNoSequenceError 694 695 # If there is a local tm, fail if not all residues have a local tm parameter. 696 local_tm = False 697 for spin in spin_loop(): 698 # No params. 699 if not hasattr(spin, 'params') or not spin.params: 700 continue 701 702 # Local tm. 703 if not local_tm and 'local_tm' in spin.params: 704 local_tm = True 705 706 # Inconsistencies. 707 elif local_tm and not 'local_tm' in spin.params: 708 raise RelaxError("All residues must either have a local tm parameter or not.") 709 710 # Check if any model-free parameters are allowed to vary. 711 mf_all_fixed = True 712 mf_all_deselected = True 713 for spin in spin_loop(): 714 # Skip deselected spins. 715 if not spin.select: 716 continue 717 718 # At least one spin is selected. 719 mf_all_deselected = False 720 721 # Test the fixed flag. 722 if not hasattr(spin, 'fixed'): 723 mf_all_fixed = False 724 break 725 if not spin.fixed: 726 mf_all_fixed = False 727 break 728 729 # No spins selected?!? 730 if mf_all_deselected: 731 # All parameters fixed! 732 if not hasattr(cdp, 'diff_tensor') or cdp.diff_tensor.fixed: 733 return None 734 735 return 'diff' 736 737 # Local tm. 738 if local_tm: 739 return 'local_tm' 740 741 # Test if the diffusion tensor data is loaded. 742 if not diffusion_tensor.diff_data_exists(): 743 # Catch when the local tm value is set but not in the parameter list. 744 for spin in spin_loop(): 745 if hasattr(spin, 'local_tm') and spin.local_tm != None and not 'local_tm' in spin.params: 746 raise RelaxError("The local tm value is set but not located in the model parameter list.") 747 748 # Normal error. 749 raise RelaxNoTensorError('diffusion') 750 751 # 'diff' model type. 752 if mf_all_fixed: 753 # All parameters fixed! 754 if cdp.diff_tensor.fixed: 755 return None 756 757 return 'diff' 758 759 # 'mf' model type. 760 if cdp.diff_tensor.fixed: 761 return 'mf' 762 763 # 'all' model type. 764 else: 765 return 'all'
766 767
768 - def _model_map(self, model):
769 """Return the equation name and parameter list corresponding to the given model. 770 771 @param model: The model-free model. 772 @type model: str 773 @return: The equation type (either 'mf_orig' or 'mf_ext') and the model-free parameter list corresponding to the model. 774 @rtype: str, list 775 """ 776 777 # Block 1. 778 if model == 'm0': 779 equation = 'mf_orig' 780 params = [] 781 elif model == 'm1': 782 equation = 'mf_orig' 783 params = ['s2'] 784 elif model == 'm2': 785 equation = 'mf_orig' 786 params = ['s2', 'te'] 787 elif model == 'm3': 788 equation = 'mf_orig' 789 params = ['s2', 'rex'] 790 elif model == 'm4': 791 equation = 'mf_orig' 792 params = ['s2', 'te', 'rex'] 793 elif model == 'm5': 794 equation = 'mf_ext' 795 params = ['s2f', 's2', 'ts'] 796 elif model == 'm6': 797 equation = 'mf_ext' 798 params = ['s2f', 'tf', 's2', 'ts'] 799 elif model == 'm7': 800 equation = 'mf_ext' 801 params = ['s2f', 's2', 'ts', 'rex'] 802 elif model == 'm8': 803 equation = 'mf_ext' 804 params = ['s2f', 'tf', 's2', 'ts', 'rex'] 805 elif model == 'm9': 806 equation = 'mf_orig' 807 params = ['rex'] 808 809 # Block 2. 810 elif model == 'm10': 811 equation = 'mf_orig' 812 params = ['csa'] 813 elif model == 'm11': 814 equation = 'mf_orig' 815 params = ['csa', 's2'] 816 elif model == 'm12': 817 equation = 'mf_orig' 818 params = ['csa', 's2', 'te'] 819 elif model == 'm13': 820 equation = 'mf_orig' 821 params = ['csa', 's2', 'rex'] 822 elif model == 'm14': 823 equation = 'mf_orig' 824 params = ['csa', 's2', 'te', 'rex'] 825 elif model == 'm15': 826 equation = 'mf_ext' 827 params = ['csa', 's2f', 's2', 'ts'] 828 elif model == 'm16': 829 equation = 'mf_ext' 830 params = ['csa', 's2f', 'tf', 's2', 'ts'] 831 elif model == 'm17': 832 equation = 'mf_ext' 833 params = ['csa', 's2f', 's2', 'ts', 'rex'] 834 elif model == 'm18': 835 equation = 'mf_ext' 836 params = ['csa', 's2f', 'tf', 's2', 'ts', 'rex'] 837 elif model == 'm19': 838 equation = 'mf_orig' 839 params = ['csa', 'rex'] 840 841 # Block 3. 842 elif model == 'm20': 843 equation = 'mf_orig' 844 params = ['r'] 845 elif model == 'm21': 846 equation = 'mf_orig' 847 params = ['r', 's2'] 848 elif model == 'm22': 849 equation = 'mf_orig' 850 params = ['r', 's2', 'te'] 851 elif model == 'm23': 852 equation = 'mf_orig' 853 params = ['r', 's2', 'rex'] 854 elif model == 'm24': 855 equation = 'mf_orig' 856 params = ['r', 's2', 'te', 'rex'] 857 elif model == 'm25': 858 equation = 'mf_ext' 859 params = ['r', 's2f', 's2', 'ts'] 860 elif model == 'm26': 861 equation = 'mf_ext' 862 params = ['r', 's2f', 'tf', 's2', 'ts'] 863 elif model == 'm27': 864 equation = 'mf_ext' 865 params = ['r', 's2f', 's2', 'ts', 'rex'] 866 elif model == 'm28': 867 equation = 'mf_ext' 868 params = ['r', 's2f', 'tf', 's2', 'ts', 'rex'] 869 elif model == 'm29': 870 equation = 'mf_orig' 871 params = ['r', 'rex'] 872 873 # Block 4. 874 elif model == 'm30': 875 equation = 'mf_orig' 876 params = ['r', 'csa'] 877 elif model == 'm31': 878 equation = 'mf_orig' 879 params = ['r', 'csa', 's2'] 880 elif model == 'm32': 881 equation = 'mf_orig' 882 params = ['r', 'csa', 's2', 'te'] 883 elif model == 'm33': 884 equation = 'mf_orig' 885 params = ['r', 'csa', 's2', 'rex'] 886 elif model == 'm34': 887 equation = 'mf_orig' 888 params = ['r', 'csa', 's2', 'te', 'rex'] 889 elif model == 'm35': 890 equation = 'mf_ext' 891 params = ['r', 'csa', 's2f', 's2', 'ts'] 892 elif model == 'm36': 893 equation = 'mf_ext' 894 params = ['r', 'csa', 's2f', 'tf', 's2', 'ts'] 895 elif model == 'm37': 896 equation = 'mf_ext' 897 params = ['r', 'csa', 's2f', 's2', 'ts', 'rex'] 898 elif model == 'm38': 899 equation = 'mf_ext' 900 params = ['r', 'csa', 's2f', 'tf', 's2', 'ts', 'rex'] 901 elif model == 'm39': 902 equation = 'mf_orig' 903 params = ['r', 'csa', 'rex'] 904 905 906 # Preset models with local correlation time. 907 ############################################ 908 909 # Block 1. 910 elif model == 'tm0': 911 equation = 'mf_orig' 912 params = ['local_tm'] 913 elif model == 'tm1': 914 equation = 'mf_orig' 915 params = ['local_tm', 's2'] 916 elif model == 'tm2': 917 equation = 'mf_orig' 918 params = ['local_tm', 's2', 'te'] 919 elif model == 'tm3': 920 equation = 'mf_orig' 921 params = ['local_tm', 's2', 'rex'] 922 elif model == 'tm4': 923 equation = 'mf_orig' 924 params = ['local_tm', 's2', 'te', 'rex'] 925 elif model == 'tm5': 926 equation = 'mf_ext' 927 params = ['local_tm', 's2f', 's2', 'ts'] 928 elif model == 'tm6': 929 equation = 'mf_ext' 930 params = ['local_tm', 's2f', 'tf', 's2', 'ts'] 931 elif model == 'tm7': 932 equation = 'mf_ext' 933 params = ['local_tm', 's2f', 's2', 'ts', 'rex'] 934 elif model == 'tm8': 935 equation = 'mf_ext' 936 params = ['local_tm', 's2f', 'tf', 's2', 'ts', 'rex'] 937 elif model == 'tm9': 938 equation = 'mf_orig' 939 params = ['local_tm', 'rex'] 940 941 # Block 2. 942 elif model == 'tm10': 943 equation = 'mf_orig' 944 params = ['local_tm', 'csa'] 945 elif model == 'tm11': 946 equation = 'mf_orig' 947 params = ['local_tm', 'csa', 's2'] 948 elif model == 'tm12': 949 equation = 'mf_orig' 950 params = ['local_tm', 'csa', 's2', 'te'] 951 elif model == 'tm13': 952 equation = 'mf_orig' 953 params = ['local_tm', 'csa', 's2', 'rex'] 954 elif model == 'tm14': 955 equation = 'mf_orig' 956 params = ['local_tm', 'csa', 's2', 'te', 'rex'] 957 elif model == 'tm15': 958 equation = 'mf_ext' 959 params = ['local_tm', 'csa', 's2f', 's2', 'ts'] 960 elif model == 'tm16': 961 equation = 'mf_ext' 962 params = ['local_tm', 'csa', 's2f', 'tf', 's2', 'ts'] 963 elif model == 'tm17': 964 equation = 'mf_ext' 965 params = ['local_tm', 'csa', 's2f', 's2', 'ts', 'rex'] 966 elif model == 'tm18': 967 equation = 'mf_ext' 968 params = ['local_tm', 'csa', 's2f', 'tf', 's2', 'ts', 'rex'] 969 elif model == 'tm19': 970 equation = 'mf_orig' 971 params = ['local_tm', 'csa', 'rex'] 972 973 # Block 3. 974 elif model == 'tm20': 975 equation = 'mf_orig' 976 params = ['local_tm', 'r'] 977 elif model == 'tm21': 978 equation = 'mf_orig' 979 params = ['local_tm', 'r', 's2'] 980 elif model == 'tm22': 981 equation = 'mf_orig' 982 params = ['local_tm', 'r', 's2', 'te'] 983 elif model == 'tm23': 984 equation = 'mf_orig' 985 params = ['local_tm', 'r', 's2', 'rex'] 986 elif model == 'tm24': 987 equation = 'mf_orig' 988 params = ['local_tm', 'r', 's2', 'te', 'rex'] 989 elif model == 'tm25': 990 equation = 'mf_ext' 991 params = ['local_tm', 'r', 's2f', 's2', 'ts'] 992 elif model == 'tm26': 993 equation = 'mf_ext' 994 params = ['local_tm', 'r', 's2f', 'tf', 's2', 'ts'] 995 elif model == 'tm27': 996 equation = 'mf_ext' 997 params = ['local_tm', 'r', 's2f', 's2', 'ts', 'rex'] 998 elif model == 'tm28': 999 equation = 'mf_ext' 1000 params = ['local_tm', 'r', 's2f', 'tf', 's2', 'ts', 'rex'] 1001 elif model == 'tm29': 1002 equation = 'mf_orig' 1003 params = ['local_tm', 'r', 'rex'] 1004 1005 # Block 4. 1006 elif model == 'tm30': 1007 equation = 'mf_orig' 1008 params = ['local_tm', 'r', 'csa'] 1009 elif model == 'tm31': 1010 equation = 'mf_orig' 1011 params = ['local_tm', 'r', 'csa', 's2'] 1012 elif model == 'tm32': 1013 equation = 'mf_orig' 1014 params = ['local_tm', 'r', 'csa', 's2', 'te'] 1015 elif model == 'tm33': 1016 equation = 'mf_orig' 1017 params = ['local_tm', 'r', 'csa', 's2', 'rex'] 1018 elif model == 'tm34': 1019 equation = 'mf_orig' 1020 params = ['local_tm', 'r', 'csa', 's2', 'te', 'rex'] 1021 elif model == 'tm35': 1022 equation = 'mf_ext' 1023 params = ['local_tm', 'r', 'csa', 's2f', 's2', 'ts'] 1024 elif model == 'tm36': 1025 equation = 'mf_ext' 1026 params = ['local_tm', 'r', 'csa', 's2f', 'tf', 's2', 'ts'] 1027 elif model == 'tm37': 1028 equation = 'mf_ext' 1029 params = ['local_tm', 'r', 'csa', 's2f', 's2', 'ts', 'rex'] 1030 elif model == 'tm38': 1031 equation = 'mf_ext' 1032 params = ['local_tm', 'r', 'csa', 's2f', 'tf', 's2', 'ts', 'rex'] 1033 elif model == 'tm39': 1034 equation = 'mf_orig' 1035 params = ['local_tm', 'r', 'csa', 'rex'] 1036 1037 # Invalid model. 1038 else: 1039 raise RelaxError("The model '%s' is invalid." % model) 1040 1041 # Return the values. 1042 return equation, params
1043 1044
1045 - def _model_setup(self, model=None, equation=None, params=None, spin_id=None):
1046 """Function for updating various data structures depending on the model selected. 1047 1048 @param model: The name of the model. 1049 @type model: str 1050 @param equation: The equation type to use. The 3 allowed types are: 'mf_orig' for the original model-free equations with parameters {s2, te}; 'mf_ext' for the extended model-free equations with parameters {s2f, tf, s2, ts}; and 'mf_ext2' for the extended model-free equations with parameters {s2f, tf, s2s, ts}. 1051 @type equation: str 1052 @param params: A list of the parameters to include in the model. The allowed parameter names includes those for the equation type as well as chemical exchange 'rex', the bond length 'r', and the chemical shift anisotropy 'csa'. 1053 @type params: list of str 1054 @param spin_id: The spin identification string. 1055 @type spin_id: str 1056 """ 1057 1058 # Test that no diffusion tensor exists if local tm is a parameter in the model. 1059 if params: 1060 for param in params: 1061 if param == 'local_tm' and hasattr(pipes.get_pipe(), 'diff_tensor'): 1062 raise RelaxTensorError('diffusion') 1063 1064 # Loop over the sequence. 1065 for spin in spin_loop(spin_id): 1066 # Initialise the data structures (if needed). 1067 self.data_init(spin) 1068 1069 # Model-free model, equation, and parameter types. 1070 spin.model = model 1071 spin.equation = equation 1072 spin.params = params
1073 1074
1075 - def _remove_tm(self, spin_id=None):
1076 """Remove local tm from the set of model-free parameters for the given spins. 1077 1078 @param spin_id: The spin identification string. 1079 @type spin_id: str or None 1080 """ 1081 1082 # Test if the current data pipe exists. 1083 pipes.test() 1084 1085 # Test if the pipe type is 'mf'. 1086 function_type = pipes.get_type() 1087 if function_type != 'mf': 1088 raise RelaxFuncSetupError(specific_fns.get_string(function_type)) 1089 1090 # Test if sequence data is loaded. 1091 if not exists_mol_res_spin_data(): 1092 raise RelaxNoSequenceError 1093 1094 # Loop over the spins. 1095 for spin in spin_loop(spin_id): 1096 # Skip deselected spins. 1097 if not spin.select: 1098 continue 1099 1100 # Test if a local tm parameter exists. 1101 if not hasattr(spin, 'params') or not 'local_tm' in spin.params: 1102 continue 1103 1104 # Remove tm. 1105 spin.params.remove('local_tm') 1106 1107 # Model name. 1108 if match('^tm', spin.model): 1109 spin.model = spin.model[1:] 1110 1111 # Delete the local tm variable. 1112 del spin.local_tm 1113 1114 # Set all the minimisation stats to None. 1115 spin.chi2 = None 1116 spin.iter = None 1117 spin.f_count = None 1118 spin.g_count = None 1119 spin.h_count = None 1120 spin.warning = None 1121 1122 # Set the global minimisation stats to None. 1123 cdp.chi2 = None 1124 cdp.iter = None 1125 cdp.f_count = None 1126 cdp.g_count = None 1127 cdp.h_count = None 1128 cdp.warning = None
1129 1130
1131 - def _select_model(self, model=None, spin_id=None):
1132 """Function for the selection of a preset model-free model. 1133 1134 @param model: The name of the model. 1135 @type model: str 1136 @param spin_id: The spin identification string. 1137 @type spin_id: str 1138 """ 1139 1140 # Test if the current data pipe exists. 1141 pipes.test() 1142 1143 # Test if the pipe type is 'mf'. 1144 function_type = pipes.get_type() 1145 if function_type != 'mf': 1146 raise RelaxFuncSetupError(specific_fns.get_string(function_type)) 1147 1148 # Test if sequence data is loaded. 1149 if not exists_mol_res_spin_data(): 1150 raise RelaxNoSequenceError 1151 1152 # Obtain the model info. 1153 equation, params = self._model_map(model) 1154 1155 # Set up the model. 1156 self._model_setup(model, equation, params, spin_id)
1157 1158
1159 - def _units_rex(self):
1160 """Return the units for the Rex parameter. 1161 1162 @return: The field strength dependent Rex units. 1163 @rtype: str 1164 """ 1165 1166 # No frequency info. 1167 if not hasattr(cdp, 'frq_labels') or len(cdp.frq_labels) == 0: 1168 return '' 1169 1170 # The units. 1171 return cdp.frq_labels[0] + ' MHz'
1172 1173
1174 - def create_mc_data(self, data_id=None):
1175 """Create the Monte Carlo Ri data. 1176 1177 @keyword data_id: The spin identification string, as yielded by the base_data_loop() generator method. 1178 @type data_id: str 1179 @return: The Monte Carlo simulation data. 1180 @rtype: list of floats 1181 """ 1182 1183 # Initialise the MC data structure. 1184 mc_data = [] 1185 1186 # Get the spin container and global spin index. 1187 spin = return_spin(data_id) 1188 global_index = find_index(data_id) 1189 1190 # Skip deselected spins. 1191 if not spin.select: 1192 return 1193 1194 # Test if the model is set. 1195 if not hasattr(spin, 'model') or not spin.model: 1196 raise RelaxNoModelError 1197 1198 # Loop over the relaxation data. 1199 for ri_id in cdp.ri_ids: 1200 # Back calculate the value. 1201 value = self.back_calc_ri(spin_index=global_index, ri_id=ri_id, ri_type=cdp.ri_type[ri_id], frq=cdp.frq[ri_id]) 1202 1203 # Append the value. 1204 mc_data.append(value) 1205 1206 # Return the data. 1207 return mc_data
1208 1209
1210 - def data_init(self, data_cont, sim=False):
1211 """Initialise the spin specific data structures. 1212 1213 @param data_cont: The spin data container. 1214 @type data_cont: SpinContainer instance 1215 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure. 1216 @type sim: bool 1217 """ 1218 1219 # Get the data names. 1220 data_names = self.data_names() 1221 1222 # Loop over the data structure names. 1223 for name in data_names: 1224 # Blacklisted data structures. 1225 if name in ['ri_data', 'ri_data_bc', 'ri_data_err']: 1226 continue 1227 1228 # Data structures which are initially empty arrays. 1229 list_data = [ 'params' ] 1230 if name in list_data: 1231 init_data = [] 1232 1233 # Set everything else initially to None. 1234 init_data = None 1235 1236 # If the name is not in 'data_cont', add it. 1237 if not hasattr(data_cont, name): 1238 setattr(data_cont, name, init_data)
1239 1240
1241 - def data_names(self, set='all', error_names=False, sim_names=False):
1242 """Return a list of all spin container specific model-free object names. 1243 1244 Description 1245 =========== 1246 1247 The names are as follows: 1248 1249 - 'model', the model-free model name. 1250 - 'equation', the model-free equation type. 1251 - 'params', an array of the model-free parameter names associated with the model. 1252 - 's2', S2. 1253 - 's2f', S2f. 1254 - 's2s', S2s. 1255 - 'local_tm', local tm. 1256 - 'te', te. 1257 - 'tf', tf. 1258 - 'ts', ts. 1259 - 'rex', Rex. 1260 - 'r', bond length. 1261 - 'csa', CSA value. 1262 - 'nucleus', the heteronucleus type. 1263 - 'chi2', chi-squared value. 1264 - 'iter', iterations. 1265 - 'f_count', function count. 1266 - 'g_count', gradient count. 1267 - 'h_count', hessian count. 1268 - 'warning', minimisation warning. 1269 1270 1271 @keyword set: The set of object names to return. This can be set to 'all' for all 1272 names, to 'generic' for generic object names, 'params' for 1273 model-free parameter names, or to 'min' for minimisation specific 1274 object names. 1275 @type set: str 1276 @keyword error_names: A flag which if True will add the error object names as well. 1277 @type error_names: bool 1278 @keyword sim_names: A flag which if True will add the Monte Carlo simulation object 1279 names as well. 1280 @type sim_names: bool 1281 @return: The list of object names. 1282 @rtype: list of str 1283 """ 1284 1285 # Initialise. 1286 names = [] 1287 1288 # Generic. 1289 if set == 'all' or set == 'generic': 1290 names.append('select') 1291 names.append('fixed') 1292 names.append('proton_type') 1293 names.append('heteronuc_type') 1294 names.append('attached_proton') 1295 names.append('nucleus') 1296 names.append('model') 1297 names.append('equation') 1298 names.append('params') 1299 names.append('xh_vect') 1300 1301 # Parameters. 1302 if set == 'all' or set == 'params': 1303 names.append('s2') 1304 names.append('s2f') 1305 names.append('s2s') 1306 names.append('local_tm') 1307 names.append('te') 1308 names.append('tf') 1309 names.append('ts') 1310 names.append('rex') 1311 names.append('r') 1312 names.append('csa') 1313 1314 # Minimisation statistics. 1315 if set == 'all' or set == 'min': 1316 names.append('chi2') 1317 names.append('iter') 1318 names.append('f_count') 1319 names.append('g_count') 1320 names.append('h_count') 1321 names.append('warning') 1322 1323 # Relaxation data. 1324 if set == 'all': 1325 names = names + relax_data.get_data_names() 1326 1327 # Parameter errors. 1328 if error_names and (set == 'all' or set == 'params'): 1329 names.append('s2_err') 1330 names.append('s2f_err') 1331 names.append('s2s_err') 1332 names.append('local_tm_err') 1333 names.append('te_err') 1334 names.append('tf_err') 1335 names.append('ts_err') 1336 names.append('rex_err') 1337 names.append('r_err') 1338 names.append('csa_err') 1339 1340 # Parameter simulation values. 1341 if sim_names and (set == 'all' or set == 'params'): 1342 names.append('s2_sim') 1343 names.append('s2f_sim') 1344 names.append('s2s_sim') 1345 names.append('local_tm_sim') 1346 names.append('te_sim') 1347 names.append('tf_sim') 1348 names.append('ts_sim') 1349 names.append('rex_sim') 1350 names.append('r_sim') 1351 names.append('csa_sim') 1352 1353 # Relaxation data simulation values. 1354 if sim_names and set == 'all': 1355 names = names + relax_data.get_data_names(sim_names=True) 1356 1357 # Return the names. 1358 return names
1359 1360
1361 - def data_type(self, param=None):
1362 """Return the type of data, as a string, that the parameter should be. 1363 1364 @keyword param: The parameter name. 1365 @type param: list of str 1366 @return: The type of the parameter, as a string. I.e. 'int', 'float', 'str', 'bool', 'list of str', 'dict of bool', etc. 1367 @rtype: str 1368 """ 1369 1370 # A dictionary of all the types. 1371 types = { 1372 'select': bool, 1373 'fixed': bool, 1374 'proton_type': str, 1375 'heteronuc_type': str, 1376 'attached_proton': str, 1377 'nucleus': str, 1378 'model': str, 1379 'equation': str, 1380 'params': [str], 1381 'xh_vect': [float], 1382 's2': float, 1383 's2f': float, 1384 's2s': float, 1385 'local_tm': float, 1386 'te': float, 1387 'tf': float, 1388 'ts': float, 1389 'rex': float, 1390 'r': float, 1391 'csa': float, 1392 'chi2': float, 1393 'iter': int, 1394 'f_count': int, 1395 'g_count': int, 1396 'h_count': int, 1397 'warning': str 1398 } 1399 1400 # Return the type, if in the list. 1401 if types.has_key(param): 1402 return types[param]
1403 1404 1405 default_value_doc = ["Model-free default values", """ 1406 _______________________________________________________________________________________ 1407 | | | | 1408 | Data type | Object name | Value | 1409 |_______________________________________|____________________|________________________| 1410 | | | | 1411 | Local tm | 'local_tm' | 10 * 1e-9 | 1412 | | | | 1413 | Order parameters S2, S2f, and S2s | 's2', 's2f', 's2s' | 0.8 | 1414 | | | | 1415 | Correlation time te | 'te' | 100 * 1e-12 | 1416 | | | | 1417 | Correlation time tf | 'tf' | 10 * 1e-12 | 1418 | | | | 1419 | Correlation time ts | 'ts' | 1000 * 1e-12 | 1420 | | | | 1421 | Chemical exchange relaxation | 'rex' | 0.0 | 1422 | | | | 1423 | Bond length | 'r' | 1.02 * 1e-10 | 1424 | | | | 1425 | CSA | 'csa' | -172 * 1e-6 | 1426 | | | | 1427 | Heteronucleus type | 'heteronuc_type' | '15N' | 1428 | | | | 1429 | Proton type | 'proton_type' | '1H' | 1430 |_______________________________________|____________________|________________________| 1431 1432 """] 1433
1434 - def default_value(self, param):
1435 """The default model-free parameter values. 1436 1437 @param param: The model-free parameter. 1438 @type param: str 1439 @return: The default value. 1440 @rtype: float 1441 """ 1442 1443 # Diffusion tensor parameter. 1444 diff_val = diffusion_tensor.default_value(param) 1445 if diff_val != None: 1446 return diff_val 1447 1448 # Model-free parameter. 1449 return self.SPIN_PARAMS.get_default(param)
1450 1451
1452 - def deselect(self, model_info, sim_index=None):
1453 """Deselect models or simulations. 1454 1455 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1456 @type model_info: int 1457 @keyword sim_index: The optional Monte Carlo simulation index. If None, then models will be deselected, otherwise the given simulation will. 1458 @type sim_index: None or int 1459 """ 1460 1461 # Determine the model type. 1462 model_type = self._determine_model_type() 1463 1464 # Local models. 1465 if model_type == 'mf' or model_type == 'local_tm': 1466 # Get the spin. 1467 spin = return_spin_from_index(model_info) 1468 1469 # Spin deselection. 1470 if sim_index == None: 1471 spin.select = False 1472 1473 # Simulation deselection. 1474 else: 1475 spin.select_sim[sim_index] = False 1476 1477 # Global models. 1478 else: 1479 # Global model deselection. 1480 if sim_index == None: 1481 raise RelaxError("Cannot deselect the global model.") 1482 1483 # Simulation deselection. 1484 else: 1485 # Deselect. 1486 cdp.select_sim[sim_index] = False
1487 1488
1489 - def duplicate_data(self, pipe_from=None, pipe_to=None, model_info=None, global_stats=False, verbose=True):
1490 """Duplicate the data specific to a single model-free model. 1491 1492 @keyword pipe_from: The data pipe to copy the data from. 1493 @type pipe_from: str 1494 @keyword pipe_to: The data pipe to copy the data to. 1495 @type pipe_to: str 1496 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1497 @type model_info: int 1498 @keyword global_stats: The global statistics flag. 1499 @type global_stats: bool 1500 @keyword verbose: A flag which if True will cause info about each spin to be printed out as the sequence is generated. 1501 @type verbose: bool 1502 """ 1503 1504 # Arg tests. 1505 if model_info == None: 1506 raise RelaxError("The model_info argument cannot be None.") 1507 1508 # First create the pipe_to data pipe, if it doesn't exist, but don't switch to it. 1509 if not pipes.has_pipe(pipe_to): 1510 pipes.create(pipe_to, pipe_type='mf', switch=False) 1511 1512 # Get the data pipes. 1513 dp_from = pipes.get_pipe(pipe_from) 1514 dp_to = pipes.get_pipe(pipe_to) 1515 1516 # Duplicate all non-sequence specific data. 1517 for data_name in dir(dp_from): 1518 # Skip the container objects. 1519 if data_name in ['diff_tensor', 'mol', 'structure']: 1520 continue 1521 1522 # Skip special objects. 1523 if search('^_', data_name) or data_name in list(dp_from.__class__.__dict__.keys()): 1524 continue 1525 1526 # Get the original object. 1527 data_from = getattr(dp_from, data_name) 1528 1529 # The data already exists. 1530 if hasattr(dp_to, data_name): 1531 # Get the object in the target pipe. 1532 data_to = getattr(dp_to, data_name) 1533 1534 # The data must match! 1535 if data_from != data_to: 1536 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".") 1537 1538 # Skip the data. 1539 continue 1540 1541 # Duplicate the data. 1542 setattr(dp_to, data_name, deepcopy(data_from)) 1543 1544 # Diffusion tensor comparison. 1545 if hasattr(dp_from, 'diff_tensor'): 1546 # Duplicate the tensor if it doesn't exist. 1547 if not hasattr(dp_to, 'diff_tensor'): 1548 setattr(dp_to, 'diff_tensor', deepcopy(dp_from.diff_tensor)) 1549 1550 # Otherwise compare the objects inside the container. 1551 else: 1552 # Loop over the modifiable objects. 1553 for data_name in dp_from.diff_tensor.__mod_attr__: 1554 # Get the original object. 1555 data_from = None 1556 if hasattr(dp_from.diff_tensor, data_name): 1557 data_from = getattr(dp_from.diff_tensor, data_name) 1558 1559 # Get the target object. 1560 if data_from and not hasattr(dp_to.diff_tensor, data_name): 1561 raise RelaxError("The diffusion tensor object " + repr(data_name) + " of the " + repr(pipe_from) + " data pipe is not located in the " + repr(pipe_to) + " data pipe.") 1562 elif data_from: 1563 data_to = getattr(dp_to.diff_tensor, data_name) 1564 else: 1565 continue 1566 1567 # The data must match! 1568 if data_from != data_to: 1569 raise RelaxError("The object " + repr(data_name) + " is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".") 1570 1571 # Structure comparison. 1572 if hasattr(dp_from, 'structure'): 1573 # Duplicate the tensor if it doesn't exist. 1574 if not hasattr(dp_to, 'structure'): 1575 setattr(dp_to, 'structure', deepcopy(dp_from.structure)) 1576 1577 # Otherwise compare the objects inside the container. 1578 else: 1579 # Modifiable object checks. 1580 self._compare_objects(dp_from.structure, dp_to.structure, pipe_from, pipe_to) 1581 1582 # Tests for the model and molecule containers. 1583 if len(dp_from.structure.structural_data) != len(dp_from.structure.structural_data): 1584 raise RelaxError("The number of structural models is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".") 1585 1586 # Loop over the models. 1587 for i in range(len(dp_from.structure.structural_data)): 1588 # Alias. 1589 model_from = dp_from.structure.structural_data[i] 1590 model_to = dp_to.structure.structural_data[i] 1591 1592 # Model numbers. 1593 if model_from.num != model_to.num: 1594 raise RelaxError("The structure models are not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".") 1595 1596 # Molecule number. 1597 if len(model_from.mol) != len(model_to.mol): 1598 raise RelaxError("The number of molecules is not consistent between the pipes " + repr(pipe_from) + " and " + repr(pipe_to) + ".") 1599 1600 # Loop over the models. 1601 for mol_index in range(len(model_from.mol)): 1602 # Modifiable object checks. 1603 self._compare_objects(model_from.mol[mol_index], model_to.mol[mol_index], pipe_from, pipe_to) 1604 1605 # No sequence data, so skip the rest. 1606 if dp_from.mol.is_empty(): 1607 return 1608 1609 # Duplicate the sequence data if it doesn't exist. 1610 if dp_to.mol.is_empty(): 1611 sequence.copy(pipe_from=pipe_from, pipe_to=pipe_to, preserve_select=True, verbose=verbose) 1612 1613 # Determine the model type of the original data pipe. 1614 pipes.switch(pipe_from) 1615 model_type = self._determine_model_type() 1616 1617 # Sequence specific data. 1618 if model_type == 'mf' or (model_type == 'local_tm' and not global_stats): 1619 # Get the spin container indices. 1620 mol_index, res_index, spin_index = convert_from_global_index(global_index=model_info, pipe=pipe_from) 1621 1622 # Duplicate the spin specific data. 1623 dp_to.mol[mol_index].res[res_index].spin[spin_index] = deepcopy(dp_from.mol[mol_index].res[res_index].spin[spin_index]) 1624 1625 # Other data types. 1626 else: 1627 # Duplicate all the spin specific data. 1628 dp_to.mol = deepcopy(dp_from.mol)
1629 1630 1631 eliminate_doc = [["Local tm model elimination rule", """ 1632 The local tm, in some cases, may exceed the value expected for a global correlation time. Generally the tm value will be stuck at the upper limit defined for the parameter. These models are eliminated using the rule: 1633 1634 tm >= c 1635 1636 The default value of c is 50 ns, although this can be overridden by supplying the value (in seconds) as the first element of the args tuple. 1637 """], 1638 ["Internal correlation times {te, tf, ts} model elimination rules", """ 1639 These parameters may experience the same problem as the local tm in that the model fails and the parameter value is stuck at the upper limit. These parameters are constrained using the formula (te, tf, ts <= 2tm). These failed models are eliminated using the rule: 1640 1641 te, tf, ts >= c . tm 1642 1643 The default value of c is 1.5. Because of round-off errors and the constraint algorithm, setting c to 2 will result in no models being eliminated as the minimised parameters will always be less than 2tm. The value can be changed by supplying the value as the second element of the tuple. 1644 """], 1645 ["Arguments", """ 1646 The 'args' argument must be a tuple of length 2, the elements of which must be numbers. For example, to eliminate models which have a local tm value greater than 25 ns and models with internal correlation times greater than 1.5 times tm, set 'args' to (25 * 1e-9, 1.5). 1647 """]] 1648
1649 - def eliminate(self, name, value, model_info, args, sim=None):
1650 """Model-free model elimination, parameter by parameter. 1651 1652 @param name: The parameter name. 1653 @type name: str 1654 @param value: The parameter value. 1655 @type value: float 1656 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1657 @type model_info: int 1658 @param args: The c1 and c2 elimination constant overrides. 1659 @type args: None or tuple of float 1660 @keyword sim: The Monte Carlo simulation index. 1661 @type sim: int 1662 @return: True if the model is to be eliminated, False otherwise. 1663 @rtype: bool 1664 """ 1665 1666 # Default values. 1667 c1 = 50.0 * 1e-9 1668 c2 = 1.5 1669 1670 # Depack the arguments. 1671 if args != None: 1672 c1, c2 = args 1673 1674 # Determine the model type. 1675 model_type = self._determine_model_type() 1676 1677 # Can't handle this one yet! 1678 if model_type != 'mf' and model_type != 'local_tm': 1679 raise RelaxError("Elimination of the global model is not yet supported.") 1680 1681 # Get the spin and it's id string. 1682 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True) 1683 1684 # Get the tm value. 1685 if model_type == 'local_tm': 1686 tm = spin.local_tm 1687 else: 1688 tm = cdp.diff_tensor.tm 1689 1690 # No tm value set, so skip the tests (no elimination). 1691 if tm == None: 1692 return False 1693 1694 # Local tm. 1695 if name == 'local_tm' and value >= c1: 1696 if sim == None: 1697 print(("Data pipe '%s': The local tm parameter of %.5g is greater than %.5g, eliminating spin system '%s'." % (pipes.cdp_name(), value, c1, spin_id))) 1698 else: 1699 print(("Data pipe '%s': The local tm parameter of %.5g is greater than %.5g, eliminating simulation %i of spin system '%s'." % (pipes.cdp_name(), value, c1, sim, spin_id))) 1700 return True 1701 1702 # Internal correlation times. 1703 if match('t[efs]', name) and value >= c2 * tm: 1704 if sim == None: 1705 print(("Data pipe '%s': The %s value of %.5g is greater than %.5g, eliminating spin system '%s'." % (pipes.cdp_name(), name, value, c2*tm, spin_id))) 1706 else: 1707 print(("Data pipe '%s': The %s value of %.5g is greater than %.5g, eliminating simulation %i of spin system '%s'." % (pipes.cdp_name(), name, value, c2*tm, sim, spin_id))) 1708 return True 1709 1710 # Accept model. 1711 return False
1712 1713
1714 - def get_param_names(self, model_info=None):
1715 """Return a vector of parameter names. 1716 1717 @keyword model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1718 @type model_info: int 1719 @return: The vector of parameter names. 1720 @rtype: list of str 1721 """ 1722 1723 # Determine the model type. 1724 model_type = self._determine_model_type() 1725 1726 # Get the spin ids. 1727 if model_type == 'mf' or model_type == 'local_tm': 1728 # Get the spin and it's id string. 1729 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True) 1730 else: 1731 spin_id = None 1732 1733 # Assemble and return the parameter names. 1734 return self._assemble_param_names(model_type, spin_id=spin_id)
1735 1736
1737 - def get_param_values(self, model_info=None, sim_index=None):
1738 """Return a vector of parameter values. 1739 1740 @keyword model_info: The model index from model_info(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1741 @type model_info: int 1742 @keyword sim_index: The Monte Carlo simulation index. 1743 @type sim_index: int 1744 @return: The vector of parameter values. 1745 @rtype: list of str 1746 """ 1747 1748 # Test if the model-free models have been set up. 1749 for spin in spin_loop(): 1750 # Skip deselected spins. 1751 if not spin.select: 1752 continue 1753 1754 # Not setup. 1755 if not spin.model: 1756 raise RelaxNoModelError 1757 1758 # Determine the model type. 1759 model_type = self._determine_model_type() 1760 1761 # Set the spin container (to None if the model is global). 1762 if model_type == 'mf' or model_type == 'local_tm': 1763 spin = return_spin_from_index(model_info) 1764 else: 1765 spin = None 1766 1767 # Assemble the parameter values and return them. 1768 return self._assemble_param_vector(spin=spin, sim_index=sim_index, model_type=model_type)
1769 1770
1771 - def is_spin_param(self, name):
1772 """Determine whether the given parameter is spin specific. 1773 1774 Unless a diffusion parameter is encountered, this method will return true. 1775 1776 @param name: The name of the parameter. 1777 @type name: str 1778 @return: If the parameter is a diffusion parameter, False I returned. Otherwise True 1779 is returned. 1780 @rtype: bool 1781 """ 1782 1783 # Catch a diffusion parameter. 1784 if diffusion_tensor.return_data_name(name): 1785 return False 1786 1787 # All the rest: 1788 else: 1789 return True
1790 1791
1792 - def map_bounds(self, param, spin_id=None):
1793 """Create bounds for the OpenDX mapping function. 1794 1795 @param param: The name of the parameter to return the lower and upper bounds of. 1796 @type param: str 1797 @param spin_id: The spin identification string. 1798 @type spin_id: str 1799 @return: The upper and lower bounds of the parameter. 1800 @rtype: list of float 1801 """ 1802 1803 # Get the spin. 1804 spin = return_spin(spin_id) 1805 1806 # {s2, s2f, s2s}. 1807 if search('^s2', param): 1808 return [0.0, 1.0] 1809 1810 # {local tm, te, tf, ts}. 1811 elif search('^t', param) or param == 'local_tm': 1812 return [0.0, 1e-8] 1813 1814 # Rex. 1815 elif param == 'rex': 1816 return [0.0, 30.0 / (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2] 1817 1818 # Bond length. 1819 elif param == 'r': 1820 return [1.0 * 1e-10, 1.1 * 1e-10] 1821 1822 # CSA. 1823 elif param == 'csa': 1824 return [-100 * 1e-6, -300 * 1e-6]
1825 1826
1827 - def model_desc(self, model_info):
1828 """Return a description of the model. 1829 1830 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1831 @type model_info: int 1832 @return: The model description. 1833 @rtype: str 1834 """ 1835 1836 # Determine the model type. 1837 model_type = self._determine_model_type() 1838 1839 # Global models. 1840 if model_type == 'all': 1841 return "Global model - all diffusion tensor parameters and spin specific model-free parameters." 1842 elif model_type == 'diff': 1843 return "Diffusion tensor model." 1844 1845 # Spin specific model. 1846 else: 1847 # Get the spin container. 1848 spin, spin_id = return_spin_from_index(model_info, return_spin_id=True) 1849 1850 # Return the description. 1851 return "Model-free model of spin '%s'." % spin_id
1852 1853
1854 - def model_loop(self):
1855 """Generator method for looping over the models (global or local). 1856 1857 If the model type is 'all' or 'diff', then this yields the single value of zero. Otherwise 1858 the global spin index is yielded. 1859 1860 1861 @return: The model index. This is zero for the global models or equal to the global spin 1862 index (which covers the molecule, residue, and spin indices). 1863 @rtype: int 1864 """ 1865 1866 # Determine the model type. 1867 model_type = self._determine_model_type() 1868 1869 # Global model. 1870 if model_type == 'all' or model_type == 'diff': 1871 yield 0 1872 1873 # Spin specific models. 1874 else: 1875 # Loop over the spins. 1876 global_index = -1 1877 for spin in spin_loop(): 1878 # Increment the global spin index. 1879 global_index = global_index + 1 1880 1881 # Yield the spin index. 1882 yield global_index
1883 1884
1885 - def model_statistics(self, model_info=None, spin_id=None, global_stats=None):
1886 """Return the k, n, and chi2 model statistics. 1887 1888 k - number of parameters. 1889 n - number of data points. 1890 chi2 - the chi-squared value. 1891 1892 1893 @keyword model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 1894 @type model_info: int 1895 @keyword spin_id: The spin identification string. Either this or the instance keyword argument must be supplied. 1896 @type spin_id: None or str 1897 @keyword global_stats: A parameter which determines if global or local statistics are returned. If None, then the appropriateness of global or local statistics is automatically determined. 1898 @type global_stats: None or bool 1899 @return: The optimisation statistics, in tuple format, of the number of parameters (k), the number of data points (n), and the chi-squared value (chi2). 1900 @rtype: tuple of (int, int, float) 1901 """ 1902 1903 # Bad argument combination. 1904 if model_info == None and spin_id == None: 1905 raise RelaxError("Either the model_info or spin_id argument must be supplied.") 1906 elif model_info != None and spin_id != None: 1907 raise RelaxError("The model_info arg " + repr(model_info) + " and spin_id arg " + repr(spin_id) + " clash. Only one should be supplied.") 1908 1909 # Determine the model type. 1910 model_type = self._determine_model_type() 1911 1912 # Determine if local or global statistics will be returned. 1913 if global_stats == None: 1914 if model_type in ['mf', 'local_tm']: 1915 global_stats = False 1916 else: 1917 global_stats = True 1918 1919 # Statistics for a single residue. 1920 if not global_stats: 1921 # Get the SpinContainer. 1922 if spin_id: 1923 spin = return_spin(spin_id) 1924 else: 1925 spin = return_spin_from_index(model_info) 1926 1927 # Skip deselected residues. 1928 if not spin.select: 1929 return None, None, None 1930 1931 # Missing data sets. 1932 if not hasattr(spin, 'ri_data'): 1933 return None, None, None 1934 1935 # Count the number of parameters. 1936 param_vector = self._assemble_param_vector(spin=spin) 1937 k = len(param_vector) 1938 1939 # Count the number of data points. 1940 n = len(spin.ri_data) 1941 1942 # The chi2 value. 1943 chi2 = spin.chi2 1944 1945 # Global stats. 1946 elif global_stats: 1947 # Count the number of parameters. 1948 param_vector = self._assemble_param_vector() 1949 k = len(param_vector) 1950 1951 # Count the number of data points. 1952 n = 0 1953 chi2 = 0 1954 for spin in spin_loop(): 1955 # Skip deselected residues. 1956 if not spin.select: 1957 continue 1958 1959 # Skip residues with no relaxation data. 1960 if not hasattr(spin, 'ri_data') or not len(spin.ri_data): 1961 continue 1962 1963 n = n + len(spin.ri_data) 1964 1965 # Local tm models. 1966 if model_type == 'local_tm': 1967 chi2 = chi2 + spin.chi2 1968 1969 # The chi2 value. 1970 if model_type != 'local_tm': 1971 if not hasattr(cdp, 'chi2'): 1972 raise RelaxError("Global statistics are not available, most likely because the global model has not been optimised.") 1973 chi2 = cdp.chi2 1974 1975 # Return the data. 1976 return k, n, chi2
1977 1978
1979 - def model_type(self):
1980 """Return the type of the model, either being 'local' or 'global'. 1981 1982 @return: The model type, one of 'local' or 'global'. 1983 @rtype: str 1984 """ 1985 1986 # Determine the model type. 1987 model_type = self._determine_model_type() 1988 1989 # Global models. 1990 if model_type in ['all', 'diff']: 1991 return 'global' 1992 1993 # Local models. 1994 else: 1995 return 'local'
1996 1997
1998 - def num_instances(self):
1999 """Function for returning the number of instances. 2000 2001 @return: The number of instances used for optimisation. Either the number of spins if 2002 the local optimisations are setup ('mf' and 'local_tm'), or 1 for the global 2003 models. 2004 @rtype: int 2005 """ 2006 2007 # Test if sequence data exists. 2008 if not exists_mol_res_spin_data(): 2009 return 0 2010 2011 # Determine the model type. 2012 model_type = self._determine_model_type() 2013 2014 # Sequence specific data. 2015 if model_type == 'mf' or model_type == 'local_tm': 2016 return count_spins() 2017 2018 # Other data. 2019 elif model_type == 'diff' or model_type == 'all': 2020 return 1 2021 2022 # Should not be here. 2023 else: 2024 raise RelaxFault
2025 2026
2027 - def overfit_deselect(self):
2028 """Deselect spins which have insufficient data to support minimisation.""" 2029 2030 # Print out. 2031 print("\n\nOver-fit spin deselection.\n") 2032 2033 # Test if sequence data exists. 2034 if not exists_mol_res_spin_data(): 2035 raise RelaxNoSequenceError 2036 2037 # Is structural data required? 2038 need_vect = False 2039 if hasattr(cdp, 'diff_tensor') and (cdp.diff_tensor.type == 'spheroid' or cdp.diff_tensor.type == 'ellipsoid'): 2040 need_vect = True 2041 2042 # Loop over the sequence. 2043 for spin, spin_id in spin_loop(return_id=True): 2044 # Skip deselected spins. 2045 if not spin.select: 2046 continue 2047 2048 # The number of relaxation data points. 2049 data_points = 0 2050 if hasattr(cdp, 'ri_ids') and hasattr(spin, 'ri_data'): 2051 for id in cdp.ri_ids: 2052 if spin.ri_data.has_key(id) and spin.ri_data[id] != None: 2053 data_points += 1 2054 2055 # Relaxation data must exist! 2056 if not hasattr(spin, 'ri_data'): 2057 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data')) 2058 spin.select = False 2059 2060 # Require 3 or more relaxation data points. 2061 elif data_points < 3: 2062 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required')) 2063 spin.select = False 2064 2065 # Require at least as many data points as params to prevent over-fitting. 2066 elif hasattr(spin, 'params') and spin.params and len(spin.params) > data_points: 2067 warn(RelaxDeselectWarning(spin_id, 'over-fitting - more parameters than data points')) 2068 spin.select = False 2069 2070 # Test for structural data if required. 2071 elif need_vect and not hasattr(spin, 'xh_vect'): 2072 warn(RelaxDeselectWarning(spin_id, 'missing structural data')) 2073 spin.select = False 2074 elif need_vect and spin.xh_vect == None: 2075 warn(RelaxDeselectWarning(spin_id, 'missing structural data')) 2076 spin.select = False
2077 2078
2079 - def return_data_desc(self, name):
2080 """Return a description of the spin specific object. 2081 2082 @param name: The name of the spin specific object. 2083 @type name: str 2084 @return: The object description, or None. 2085 @rtype: str or None 2086 """ 2087 2088 # Spin parameter. 2089 if self.SPIN_PARAMS.contains(name): 2090 return self.SPIN_PARAMS.get_desc(name) 2091 2092 # Otherwise try the relaxation data specific objects. 2093 return relax_data.return_data_desc(name)
2094 2095 2096 return_data_name_doc = ["Model-free data type string matching patterns", """ 2097 _____________________________________________ 2098 | | | 2099 | Data type | Object name | 2100 |________________________|__________________| 2101 | | | 2102 | Local tm | 'local_tm' | 2103 | | | 2104 | Order parameter S2 | 's2' | 2105 | | | 2106 | Order parameter S2f | 's2f' | 2107 | | | 2108 | Order parameter S2s | 's2s' | 2109 | | | 2110 | Correlation time te | 'te' | 2111 | | | 2112 | Correlation time tf | 'tf' | 2113 | | | 2114 | Correlation time ts | 'ts' | 2115 | | | 2116 | Chemical exchange | 'rex' | 2117 | | | 2118 | Bond length | 'r' | 2119 | | | 2120 | CSA | 'csa' | 2121 | | | 2122 | Heteronucleus type | 'heteronuc_type' | 2123 | | | 2124 | Proton type | 'proton_type' | 2125 |________________________|__________________| 2126 2127 """] 2128
2129 - def return_data_name(self, param):
2130 """Return a unique identifying string for the model-free parameter. 2131 2132 @param param: The model-free parameter name. 2133 @type param: str 2134 @return: The unique parameter identifying string. 2135 @rtype: str 2136 """ 2137 2138 # Diffusion tensor parameters. 2139 diff_obj = diffusion_tensor.return_data_name(param) 2140 if diff_obj: 2141 return param 2142 2143 # Spin parameter. 2144 if self.SPIN_PARAMS.contains(param): 2145 return param
2146 2147 2148 set_doc = ["Model-free set details", """ 2149 Setting a parameter value may have no effect depending on which model-free model is chosen, for example if S2f values and S2s values are set but the run corresponds to model-free model 'm4' then, because these data values are not parameters of the model, they will have no effect. 2150 2151 Note that the Rex values are scaled quadratically with field strength and should be supplied as a field strength independent value. Use the following formula to get the correct value: 2152 2153 value = rex / (2.0 * pi * frequency) ** 2 2154 2155 where: 2156 rex is the chemical exchange value for the current frequency. 2157 pi is in the namespace of relax, ie just type 'pi'. 2158 frequency is the proton frequency corresponding to the data. 2159 """] 2160 2161
2162 - def set_error(self, model_info, index, error):
2163 """Set the parameter errors. 2164 2165 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2166 @type model_info: int 2167 @param index: The index of the parameter to set the errors for. 2168 @type index: int 2169 @param error: The error value. 2170 @type error: float 2171 """ 2172 2173 # Parameter increment counter. 2174 inc = 0 2175 2176 # Determine the model type. 2177 model_type = self._determine_model_type() 2178 2179 # Get the parameter object names. 2180 param_names = self.data_names(set='params') 2181 2182 2183 # Diffusion tensor parameter errors. 2184 #################################### 2185 2186 if model_type == 'diff' or model_type == 'all': 2187 # Spherical diffusion. 2188 if cdp.diff_tensor.type == 'sphere': 2189 # Return the parameter array. 2190 if index == 0: 2191 cdp.diff_tensor.tm_err = error 2192 2193 # Increment. 2194 inc = inc + 1 2195 2196 # Spheroidal diffusion. 2197 elif cdp.diff_tensor.type == 'spheroid': 2198 # Return the parameter array. 2199 if index == 0: 2200 cdp.diff_tensor.tm_err = error 2201 elif index == 1: 2202 cdp.diff_tensor.Da_err = error 2203 elif index == 2: 2204 cdp.diff_tensor.theta_err = error 2205 elif index == 3: 2206 cdp.diff_tensor.phi_err = error 2207 2208 # Increment. 2209 inc = inc + 4 2210 2211 # Ellipsoidal diffusion. 2212 elif cdp.diff_tensor.type == 'ellipsoid': 2213 # Return the parameter array. 2214 if index == 0: 2215 cdp.diff_tensor.tm_err = error 2216 elif index == 1: 2217 cdp.diff_tensor.Da_err = error 2218 elif index == 2: 2219 cdp.diff_tensor.Dr_err = error 2220 elif index == 3: 2221 cdp.diff_tensor.alpha_err = error 2222 elif index == 4: 2223 cdp.diff_tensor.beta_err = error 2224 elif index == 5: 2225 cdp.diff_tensor.gamma_err = error 2226 2227 # Increment. 2228 inc = inc + 6 2229 2230 2231 # Model-free parameter errors for the model type 'all'. 2232 ####################################################### 2233 2234 if model_type == 'all': 2235 # Loop over the spins. 2236 for spin in spin_loop(): 2237 # Skip deselected spins. 2238 if not spin.select: 2239 continue 2240 2241 # Loop over the residue specific parameters. 2242 for param in param_names: 2243 # Return the parameter array. 2244 if index == inc: 2245 setattr(spin, param + "_err", error) 2246 2247 # Increment. 2248 inc = inc + 1 2249 2250 2251 # Model-free parameters for the model types 'mf' and 'local_tm'. 2252 ################################################################ 2253 2254 if model_type == 'mf' or model_type == 'local_tm': 2255 # Get the spin container. 2256 spin = return_spin_from_index(model_info) 2257 2258 # Skip deselected residues. 2259 if not spin.select: 2260 return 2261 2262 # Loop over the residue specific parameters. 2263 for param in param_names: 2264 # Return the parameter array. 2265 if index == inc: 2266 setattr(spin, param + "_err", error) 2267 2268 # Increment. 2269 inc = inc + 1
2270 2271
2272 - def set_param_values(self, param=None, value=None, spin_id=None, force=True):
2273 """Set the model-free parameter values. 2274 2275 @keyword param: The parameter name list. 2276 @type param: list of str 2277 @keyword value: The parameter value list. 2278 @type value: list 2279 @keyword spin_id: The spin identification string, only used for spin specific parameters. 2280 @type spin_id: None or str 2281 @keyword force: A flag which if True will cause current values to be overwritten. If False, a RelaxError will raised if the parameter value is already set. 2282 @type force: bool 2283 """ 2284 2285 # Checks. 2286 arg_check.is_str_list(param, 'parameter name') 2287 2288 # Separate out the diffusion tensor parameters from the model-free parameters. 2289 diff_params = [] 2290 diff_vals = [] 2291 mf_params = [] 2292 mf_vals = [] 2293 for i in range(len(param)): 2294 # Diffusion tensor parameter. 2295 diff_obj = diffusion_tensor.return_data_name(param[i]) 2296 if diff_obj: 2297 diff_params.append(param[i]) 2298 diff_vals.append(value[i]) 2299 2300 # Model-free parameter. 2301 else: 2302 mf_params.append(param[i]) 2303 mf_vals.append(value[i]) 2304 2305 # Set the diffusion tensor parameters. 2306 if diff_params: 2307 diffusion_tensor.set(value=diff_vals, param=diff_params) 2308 2309 # Set the model-free parameters. 2310 for i in range(len(mf_params)): 2311 # The object name. 2312 obj_name = self.return_data_name(mf_params[i]) 2313 2314 # Check if it is a model-free parameter. 2315 if obj_name not in self.data_names(set='params') and obj_name not in self.data_names(set='generic'): 2316 raise RelaxError("The parameter '%s' is unknown. It should be one of %s or %s" % (mf_params[i], self.data_names(set='params'), self.data_names(set='generic'))) 2317 2318 # Set the parameter. 2319 for spin in spin_loop(spin_id): 2320 setattr(spin, obj_name, mf_vals[i])
2321 2322
2323 - def set_selected_sim(self, model_info, select_sim):
2324 """Set all simulation selection flags. 2325 2326 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2327 @type model_info: int 2328 @param select_sim: The selection flags. 2329 @type select_sim: bool 2330 """ 2331 2332 # Determine the model type. 2333 model_type = self._determine_model_type() 2334 2335 # Global model. 2336 if model_type == 'all' or model_type == 'diff': 2337 cdp.select_sim = select_sim 2338 2339 # Spin specific model. 2340 else: 2341 # Get the spin container. 2342 spin = return_spin_from_index(model_info) 2343 2344 # Skip if deselected. 2345 if not spin.select: 2346 return 2347 2348 # Set the simulation flags. 2349 spin.select_sim = deepcopy(select_sim)
2350 2351
2352 - def set_update(self, param, spin):
2353 """Function to update the other model-free parameters. 2354 2355 @param param: The name of the parameter which has been changed. 2356 @type param: str 2357 @param spin: The SpinContainer object. 2358 @type spin: SpinContainer 2359 """ 2360 2361 # S2f parameter. 2362 if param == 's2f': 2363 # Update S2 if S2s exists. 2364 if hasattr(spin, 's2s') and spin.s2s != None: 2365 spin.s2 = spin.s2f * spin.s2s 2366 2367 2368 # S2s parameter. 2369 if param == 's2s': 2370 # Update S2 if S2f exists. 2371 if hasattr(spin, 's2f') and spin.s2f != None: 2372 spin.s2 = spin.s2f * spin.s2s
2373 2374
2375 - def sim_init_values(self):
2376 """Initialise the Monte Carlo parameter values.""" 2377 2378 # Determine the model type. 2379 model_type = self._determine_model_type() 2380 2381 # Get the parameter object names. 2382 param_names = self.data_names(set='params') 2383 2384 # Get the minimisation statistic object names. 2385 min_names = self.data_names(set='min') 2386 2387 # List of diffusion tensor parameters. 2388 if model_type == 'diff' or model_type == 'all': 2389 # Spherical diffusion. 2390 if cdp.diff_tensor.type == 'sphere': 2391 diff_params = ['tm'] 2392 2393 # Spheroidal diffusion. 2394 elif cdp.diff_tensor.type == 'spheroid': 2395 diff_params = ['tm', 'Da', 'theta', 'phi'] 2396 2397 # Ellipsoidal diffusion. 2398 elif cdp.diff_tensor.type == 'ellipsoid': 2399 diff_params = ['tm', 'Da', 'Dr', 'alpha', 'beta', 'gamma'] 2400 2401 2402 # Test if Monte Carlo parameter values have already been set. 2403 ############################################################# 2404 2405 # Diffusion tensor parameters and non spin specific minimisation statistics. 2406 if model_type == 'diff' or model_type == 'all': 2407 # Loop over the parameters. 2408 for object_name in diff_params: 2409 # Name for the simulation object. 2410 sim_object_name = object_name + '_sim' 2411 2412 # Test if the simulation object already exists. 2413 if hasattr(cdp.diff_tensor, sim_object_name): 2414 raise RelaxError("Monte Carlo parameter values have already been set.") 2415 2416 # Loop over the minimisation stats objects. 2417 for object_name in min_names: 2418 # Name for the simulation object. 2419 sim_object_name = object_name + '_sim' 2420 2421 # Test if the simulation object already exists. 2422 if hasattr(cdp, sim_object_name): 2423 raise RelaxError("Monte Carlo parameter values have already been set.") 2424 2425 # Spin specific parameters. 2426 if model_type != 'diff': 2427 for spin in spin_loop(): 2428 # Skip deselected spins. 2429 if not spin.select: 2430 continue 2431 2432 # Loop over all the parameter names. 2433 for object_name in param_names: 2434 # Name for the simulation object. 2435 sim_object_name = object_name + '_sim' 2436 2437 # Test if the simulation object already exists. 2438 if hasattr(spin, sim_object_name): 2439 raise RelaxError("Monte Carlo parameter values have already been set.") 2440 2441 2442 # Set the Monte Carlo parameter values. 2443 ####################################### 2444 2445 # Loop over the global minimisation stats objects. 2446 for object_name in min_names: 2447 # Skip non-existent objects. 2448 if not hasattr(cdp, object_name): 2449 continue 2450 2451 # Name for the simulation object. 2452 sim_object_name = object_name + '_sim' 2453 2454 # Create the simulation object. 2455 setattr(cdp, sim_object_name, []) 2456 2457 # Get the simulation object. 2458 sim_object = getattr(cdp, sim_object_name) 2459 2460 # Loop over the simulations. 2461 for j in xrange(cdp.sim_number): 2462 # Get the object. 2463 object = getattr(cdp, object_name) 2464 2465 # Copy and append the data. 2466 sim_object.append(deepcopy(object)) 2467 2468 # Diffusion tensor parameters and non spin specific minimisation statistics. 2469 if model_type == 'diff' or model_type == 'all': 2470 # Loop over the parameters. 2471 for object_name in diff_params: 2472 # Name for the simulation object. 2473 sim_object_name = object_name + '_sim' 2474 2475 # Create the simulation object. 2476 setattr(cdp.diff_tensor, sim_object_name, []) 2477 2478 # Get the simulation object. 2479 sim_object = getattr(cdp.diff_tensor, sim_object_name) 2480 2481 # Loop over the simulations. 2482 for j in xrange(cdp.sim_number): 2483 # Copy and append the data. 2484 sim_object.append(deepcopy(getattr(cdp.diff_tensor, object_name))) 2485 2486 # Spin specific parameters. 2487 if model_type != 'diff': 2488 for spin in spin_loop(): 2489 # Skip deselected spins. 2490 if not spin.select: 2491 continue 2492 2493 # Loop over all the data names. 2494 for object_name in param_names: 2495 # Name for the simulation object. 2496 sim_object_name = object_name + '_sim' 2497 2498 # Create the simulation object. 2499 setattr(spin, sim_object_name, []) 2500 2501 # Get the simulation object. 2502 sim_object = getattr(spin, sim_object_name) 2503 2504 # Loop over the simulations. 2505 for j in xrange(cdp.sim_number): 2506 # Copy and append the data. 2507 sim_object.append(deepcopy(getattr(spin, object_name))) 2508 2509 # Loop over all the minimisation object names. 2510 for object_name in min_names: 2511 # Name for the simulation object. 2512 sim_object_name = object_name + '_sim' 2513 2514 # Create the simulation object. 2515 setattr(spin, sim_object_name, []) 2516 2517 # Get the simulation object. 2518 sim_object = getattr(spin, sim_object_name) 2519 2520 # Loop over the simulations. 2521 for j in xrange(cdp.sim_number): 2522 # Copy and append the data. 2523 sim_object.append(deepcopy(getattr(spin, object_name)))
2524 2525
2526 - def sim_return_chi2(self, model_info, index=None):
2527 """Return the simulation chi-squared values. 2528 2529 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2530 @type model_info: int 2531 @keyword index: The optional simulation index. 2532 @type index: int 2533 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned. 2534 @rtype: list of float or float 2535 """ 2536 2537 # Determine the model type. 2538 model_type = self._determine_model_type() 2539 2540 # Single instance. 2541 if model_type == 'all' or model_type == 'diff': 2542 return cdp.chi2_sim 2543 2544 # Multiple instances. 2545 else: 2546 # Get the spin container. 2547 spin = return_spin_from_index(model_info) 2548 2549 # Return the list. 2550 return spin.chi2_sim
2551 2552
2553 - def sim_return_param(self, model_info, index):
2554 """Return the array of simulation parameter values. 2555 2556 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2557 @type model_info: int 2558 @param index: The index of the parameter to return the array of values for. 2559 @type index: int 2560 @return: The array of simulation parameter values. 2561 @rtype: list of float 2562 """ 2563 2564 # Parameter increment counter. 2565 inc = 0 2566 2567 # Determine the model type. 2568 model_type = self._determine_model_type() 2569 2570 # Get the parameter object names. 2571 param_names = self.data_names(set='params') 2572 2573 2574 # Diffusion tensor parameters. 2575 ############################## 2576 2577 if model_type == 'diff' or model_type == 'all': 2578 # Spherical diffusion. 2579 if cdp.diff_tensor.type == 'sphere': 2580 # Return the parameter array. 2581 if index == 0: 2582 return cdp.diff_tensor.tm_sim 2583 2584 # Increment. 2585 inc = inc + 1 2586 2587 # Spheroidal diffusion. 2588 elif cdp.diff_tensor.type == 'spheroid': 2589 # Return the parameter array. 2590 if index == 0: 2591 return cdp.diff_tensor.tm_sim 2592 elif index == 1: 2593 return cdp.diff_tensor.Da_sim 2594 elif index == 2: 2595 return cdp.diff_tensor.theta_sim 2596 elif index == 3: 2597 return cdp.diff_tensor.phi_sim 2598 2599 # Increment. 2600 inc = inc + 4 2601 2602 # Ellipsoidal diffusion. 2603 elif cdp.diff_tensor.type == 'ellipsoid': 2604 # Return the parameter array. 2605 if index == 0: 2606 return cdp.diff_tensor.tm_sim 2607 elif index == 1: 2608 return cdp.diff_tensor.Da_sim 2609 elif index == 2: 2610 return cdp.diff_tensor.Dr_sim 2611 elif index == 3: 2612 return cdp.diff_tensor.alpha_sim 2613 elif index == 4: 2614 return cdp.diff_tensor.beta_sim 2615 elif index == 5: 2616 return cdp.diff_tensor.gamma_sim 2617 2618 # Increment. 2619 inc = inc + 6 2620 2621 2622 # Model-free parameters for the model type 'all'. 2623 ################################################# 2624 2625 if model_type == 'all': 2626 # Loop over the spins. 2627 for spin in spin_loop(): 2628 # Skip deselected spins. 2629 if not spin.select: 2630 continue 2631 2632 # Loop over the spin specific parameters. 2633 for param in param_names: 2634 # Return the parameter array. 2635 if index == inc: 2636 return getattr(spin, param + "_sim") 2637 2638 # Increment. 2639 inc = inc + 1 2640 2641 2642 # Model-free parameters for the model types 'mf' and 'local_tm'. 2643 ################################################################ 2644 2645 if model_type == 'mf' or model_type == 'local_tm': 2646 # Get the spin container. 2647 spin = return_spin_from_index(model_info) 2648 2649 # Skip deselected spins. 2650 if not spin.select: 2651 return 2652 2653 # Loop over the spin specific parameters. 2654 for param in param_names: 2655 # Return the parameter array. 2656 if index == inc: 2657 return getattr(spin, param + "_sim") 2658 2659 # Increment. 2660 inc = inc + 1
2661 2662
2663 - def sim_return_selected(self, model_info):
2664 """Return the array of selected simulation flags for the spin. 2665 2666 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2667 @type model_info: int 2668 @return: The array of selected simulation flags. 2669 @rtype: list of int 2670 """ 2671 2672 # Determine the model type. 2673 model_type = self._determine_model_type() 2674 2675 # Single instance. 2676 if model_type == 'all' or model_type == 'diff': 2677 return cdp.select_sim 2678 2679 # Multiple instances. 2680 else: 2681 # Get the spin container. 2682 spin = return_spin_from_index(model_info) 2683 2684 # Skip if deselected. 2685 if not spin.select: 2686 return 2687 2688 # Return the list. 2689 return spin.select_sim
2690 2691
2692 - def skip_function(self, model_info):
2693 """Skip certain data. 2694 2695 @param model_info: The model index from model_loop(). This is zero for the global models or equal to the global spin index (which covers the molecule, residue, and spin indices). 2696 @type model_info: int 2697 @return: True if the data should be skipped, False otherwise. 2698 @rtype: bool 2699 """ 2700 2701 # Determine the model type. 2702 model_type = self._determine_model_type() 2703 2704 # Sequence specific data. 2705 if (model_type == 'mf' or model_type == 'local_tm') and not return_spin_from_index(model_info).select: 2706 return True 2707 2708 # Don't skip. 2709 return False
2710