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