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