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

Source Code for Module specific_fns.api_common

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2013 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Common API methods for use in different specific analyses.""" 
 24   
 25  # Python module imports. 
 26  from copy import deepcopy 
 27   
 28  # relax module imports. 
 29  import arg_check 
 30  from data.mol_res_spin import SpinContainer 
 31  from generic_fns.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin, spin_loop 
 32  from relax_errors import RelaxError, RelaxLenError, RelaxNoSequenceError 
 33   
 34   
35 -class API_common:
36 """Base class containing API methods common to multiple analysis types.""" 37
38 - def _base_data_loop_spin(self):
39 """Generator method for looping over the base data of the specific analysis type (spin system specific). 40 41 This method simply loops over the spins, returning the spin identification string. 42 43 @return: The spin identification string 44 @rtype: str 45 """ 46 47 # Loop over the spins. 48 for spin, spin_id in spin_loop(return_id=True): 49 # Skip deselected spins. 50 if not spin.select: 51 continue 52 53 # Yield the spin id string. 54 yield spin_id
55 56
57 - def _create_mc_relax_data(self, data_id):
58 """Return the Monte Carlo relaxation data list for the corresponding spin. 59 60 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method. 61 @type data_id: str 62 """ 63 64 # Get the spin container. 65 spin = return_spin(data_id) 66 67 # Initialise the data structure. 68 data = [] 69 70 # Add the data. 71 for ri_id in cdp.ri_ids: 72 data.append(spin.ri_data[ri_id]) 73 74 # Return the data. 75 return data
76 77
78 - def _data_init_dummy(self, data_cont, sim=False):
79 """Dummy method for initialising data structures. 80 81 This method does nothing! 82 83 84 @param data_cont: The data container. 85 @type data_cont: instance 86 @keyword sim: The unused Monte Carlo simulation flag. 87 @type sim: bool 88 """
89 90
91 - def _eliminate_false(self, name, value, model_info, args, sim=None):
92 """Dummy method for model elimination. 93 94 This simply returns False to signal that no model elimination is to be performed. 95 96 97 @param name: The parameter name. 98 @type name: str 99 @param value: The parameter value. 100 @type value: float 101 @param model_info: The model index from model_info(). 102 @type model_info: int 103 @param args: The elimination constant overrides. 104 @type args: None or tuple of float 105 @keyword sim: The Monte Carlo simulation index. 106 @type sim: int 107 @return: False to prevent model elimination. 108 @rtype: bool 109 """ 110 111 # Don't eliminate. 112 return False
113 114
115 - def _has_errors_spin(self):
116 """Testing if errors exist for the current data pipe (spin system specific). 117 118 @return: The answer to the question of whether errors exist. 119 @rtype: bool 120 """ 121 122 # Diffusion tensor errors. 123 if hasattr(cdp, 'diff'): 124 for object_name in dir(cdp.diff): 125 # The object error name. 126 object_error = object_name + '_err' 127 128 # Error exists. 129 if hasattr(cdp.diff, object_error): 130 return True 131 132 # Loop over the sequence. 133 for spin in spin_loop(): 134 # Parameter errors. 135 for object_name in dir(spin): 136 # The object error name. 137 object_error = object_name + '_err' 138 139 # Error exists. 140 if hasattr(spin, object_error): 141 return True 142 143 # No errors found. 144 return False
145 146
147 - def _is_spin_param_true(self, name):
148 """Dummy method stating that the parameter is spin specific. 149 150 This method always returns true, hence all parameters will be considered residents of a SpinContainer object unless this method is overwritten. 151 152 @param name: The name of the parameter. 153 @type name: str 154 @return: True 155 @rtype: bool 156 """ 157 158 # Return the default of True. 159 return True
160 161
162 - def _model_loop_spin(self):
163 """Default generator method for looping over the models, where each spin has a separate model. 164 165 In this case only a single model per spin system is assumed. Hence the yielded data is the spin container object. 166 167 168 @return: The spin container. 169 @rtype: SpinContainer instance 170 """ 171 172 # Loop over the sequence. 173 for spin in spin_loop(): 174 # Skip deselected spins. 175 if not spin.select: 176 continue 177 178 # Yield the spin container. 179 yield spin
180 181
183 """Default generator method for looping over a single global (non-spin specific) model. 184 185 The loop will yield a single index, zero, once to indicate a single model. 186 187 188 @return: The global model index of zero. 189 @rtype: int 190 """ 191 192 # Yield the index zero. 193 yield 0
194 195
196 - def _num_instances_spin(self):
197 """Return the number of instances, equal to the number of selected spins. 198 199 @return: The number of instances (equal to the number of spins). 200 @rtype: int 201 """ 202 203 # Test if sequence data is loaded. 204 if not exists_mol_res_spin_data(): 205 raise RelaxNoSequenceError 206 207 # Return the number of spins. 208 return count_spins()
209 210
211 - def _overfit_deselect_dummy(self, data_check=True, verbose=True):
212 """Dummy method, normally for deselecting spins with insufficient data for minimisation."""
213 214
215 - def _return_no_conversion_factor(self, param):
216 """Method for returning 1.0. 217 218 @param param: The parameter name. 219 @type param: str 220 @return: A conversion factor of 1.0. 221 @rtype: float 222 """ 223 224 return 1.0
225 226
227 - def _return_data_relax_data(self, spin):
228 """Return the Ri data structure for the given spin. 229 230 @param spin: The SpinContainer object. 231 @type spin: SpinContainer instance 232 @return: The array of relaxation data values. 233 @rtype: list of float 234 """ 235 236 # Convert to a list. 237 data = [] 238 for ri_id in cdp.ri_ids: 239 # Handle missing data. 240 if ri_id not in spin.ri_data: 241 data.append(None) 242 243 # Append the value. 244 else: 245 data.append(spin.ri_data[ri_id]) 246 247 # Return the list. 248 return data
249 250
251 - def _return_error_relax_data(self, data_id):
252 """Return the Ri error structure for the corresponding spin. 253 254 @param data_id: The data identification information, as yielded by the base_data_loop() generator method. 255 @type data_id: str 256 @return: The array of relaxation data error values. 257 @rtype: list of float 258 """ 259 260 # Get the spin container. 261 spin = return_spin(data_id) 262 263 # Convert to a list. 264 error = [] 265 for ri_id in cdp.ri_ids: 266 # Handle missing data/errors. 267 if ri_id not in spin.ri_data_err: 268 error.append(None) 269 270 # Append the value. 271 else: 272 error.append(spin.ri_data_err[ri_id]) 273 274 # Return the list. 275 return error
276 277
278 - def _return_value_general(self, spin, param, sim=None, bc=False):
279 """Return the value and error corresponding to the parameter 'param'. 280 281 If sim is set to an integer, return the value of the simulation and None. The values are taken from the given SpinContainer object. 282 283 284 @param spin: The SpinContainer object. 285 @type spin: SpinContainer 286 @param param: The name of the parameter to return values for. 287 @type param: str 288 @param sim: The Monte Carlo simulation index. 289 @type sim: None or int 290 @keyword bc: The back-calculated data flag. If True, then the back-calculated data will be returned rather than the actual data. 291 @type bc: bool 292 @return: The value and error corresponding to 293 @rtype: tuple of length 2 of floats or None 294 """ 295 296 # Initialise. 297 index = None 298 299 # Get the object name. 300 object_name = self.return_data_name(param) 301 302 # The error, simulation and back calculated names. 303 if object_name: 304 object_error = object_name + '_err' 305 object_sim = object_name + '_sim' 306 object_bc = object_name + '_bc' 307 key = None 308 309 # The data type does not exist. 310 else: 311 # Is it a spectrum id? 312 if hasattr(cdp, 'spectrum_ids') and param in cdp.spectrum_ids: 313 object_name = 'intensities' 314 object_error = 'intensity_err' 315 object_sim = 'intensity_sim' 316 object_bc = 'intensity_bc' 317 key = param 318 319 # Unknown data type. 320 else: 321 raise RelaxError("The parameter " + repr(param) + " does not exist.") 322 323 # Initial values. 324 value = None 325 error = None 326 327 # Switch to back calculated data. 328 if bc: 329 object_name = object_bc 330 331 # Value or sim value? 332 if sim != None: 333 object_name = object_sim 334 335 # The spin value. 336 if hasattr(spin, object_name): 337 value = getattr(spin, object_name) 338 339 # The error. 340 if hasattr(spin, object_error): 341 error = getattr(spin, object_error) 342 343 # The global value. 344 elif hasattr(cdp, object_name): 345 value = getattr(cdp, object_name) 346 347 # The error. 348 if hasattr(cdp, object_error): 349 error = getattr(cdp, object_error) 350 351 # List object. 352 if index != None: 353 value = value[index] 354 if error: 355 error = error[index] 356 357 # Dictionary object. 358 if key: 359 # Handle missing data. 360 if key not in value: 361 value = None 362 else: 363 value = value[key] 364 365 if error: 366 # Handle missing errors. 367 if key not in error: 368 error = None 369 else: 370 error = error[key] 371 372 # Return the data. 373 if sim == None: 374 return value, error 375 else: 376 return value[sim], error
377 378
379 - def _set_error_spin(self, model_info, index, error):
380 """Set the parameter errors (spin system specific). 381 382 @param model_info: The spin container originating from model_loop(). 383 @type model_info: unknown 384 @param index: The index of the parameter to set the errors for. 385 @type index: int 386 @param error: The error value. 387 @type error: float 388 """ 389 390 # The spin container. 391 if not isinstance(model_info, SpinContainer): 392 raise RelaxError("The model information argument is not a spin container.") 393 spin = model_info 394 395 # Parameter increment counter. 396 inc = 0 397 398 # Loop over the residue specific parameters. 399 for param in self.data_names(set='params'): 400 # Return the parameter array. 401 if index == inc: 402 setattr(spin, param + "_err", error) 403 404 # Increment. 405 inc = inc + 1
406 407
408 - def _set_param_values_global(self, param=None, value=None, spin_id=None, force=True):
409 """Set the global parameter values in the top layer of the data pipe. 410 411 @keyword param: The parameter name list. 412 @type param: list of str 413 @keyword value: The parameter value list. 414 @type value: list 415 @keyword spin_id: The spin identification string (unused). 416 @type spin_id: None 417 @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. 418 @type force: bool 419 """ 420 421 # Checks. 422 arg_check.is_str_list(param, 'parameter name') 423 arg_check.is_list(value, 'parameter value') 424 425 # Loop over the parameters. 426 for i in range(len(param)): 427 # Get the object's name. 428 obj_name = self.return_data_name(param[i]) 429 430 # Is the parameter is valid? 431 if not obj_name: 432 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i]) 433 434 # Is the parameter already set. 435 if not force and hasattr(cdp, obj_name) and getattr(cdp, obj_name) != None: 436 raise RelaxError("The parameter '%s' already exists, set the force flag to True to overwrite." % param[i]) 437 438 # Set the parameter. 439 setattr(cdp, obj_name, value[i])
440 441
442 - def _set_param_values_spin(self, param=None, value=None, spin_id=None, force=True):
443 """Set the spin specific parameter values. 444 445 @keyword param: The parameter name list. 446 @type param: list of str 447 @keyword value: The parameter value list. 448 @type value: list 449 @keyword spin_id: The spin identification string, only used for spin specific parameters. 450 @type spin_id: None or str 451 @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. 452 @type force: bool 453 """ 454 455 # Checks. 456 arg_check.is_str_list(param, 'parameter name') 457 arg_check.is_list(value, 'parameter value') 458 459 # Loop over the parameters. 460 for i in range(len(param)): 461 # Is the parameter is valid? 462 if not self.PARAMS.contains(param[i]): 463 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i]) 464 465 # Spin loop. 466 for spin in spin_loop(spin_id): 467 # Skip deselected spins. 468 if not spin.select: 469 continue 470 471 # Set the parameter. 472 setattr(spin, param[i], value[i])
473 474
475 - def _set_selected_sim_global(self, model_info, select_sim):
476 """Set the simulation selection flag (for a single global model). 477 478 @param model_info: The model information originating from model_loop(). This should be zero for the single global model. 479 @type model_info: int 480 @param select_sim: The selection flag for the simulations. 481 @type select_sim: bool 482 """ 483 484 # Set the array. 485 cdp.select_sim = deepcopy(select_sim)
486 487
488 - def _set_selected_sim_spin(self, model_info, select_sim):
489 """Set the simulation selection flag (spin system specific). 490 491 @param model_info: The model information originating from model_loop(). 492 @type model_info: unknown 493 @param select_sim: The selection flag for the simulations. 494 @type select_sim: bool 495 """ 496 497 # The spin container. 498 if not isinstance(model_info, SpinContainer): 499 raise RelaxError("The model information argument is not a spin container.") 500 spin = model_info 501 502 # Set the array. 503 spin.select_sim = deepcopy(select_sim)
504 505
506 - def _set_update(self, param, spin):
507 """Dummy method to do nothing! 508 509 @param param: The name of the parameter which has been changed. 510 @type param: str 511 @param spin: The SpinContainer object. 512 @type spin: SpinContainer 513 """
514 515
516 - def _sim_init_values_spin(self):
517 """Initialise the Monte Carlo parameter values (spin system specific).""" 518 519 # Get the parameter object names. 520 param_names = self.data_names(set='params') 521 522 # Get the minimisation statistic object names. 523 min_names = self.data_names(set='min') 524 525 526 # Test if Monte Carlo parameter values have already been set. 527 ############################################################# 528 529 # Loop over the spins. 530 for spin in spin_loop(): 531 # Skip deselected spins. 532 if not spin.select: 533 continue 534 535 # Loop over all the parameter names. 536 for object_name in param_names: 537 # Name for the simulation object. 538 sim_object_name = object_name + '_sim' 539 540 541 # Set the Monte Carlo parameter values. 542 ####################################### 543 544 # Loop over the residues. 545 for spin in spin_loop(): 546 # Skip deselected residues. 547 if not spin.select: 548 continue 549 550 # Loop over all the data names. 551 for object_name in param_names: 552 # Name for the simulation object. 553 sim_object_name = object_name + '_sim' 554 555 # Create the simulation object. 556 setattr(spin, sim_object_name, []) 557 558 # Get the simulation object. 559 sim_object = getattr(spin, sim_object_name) 560 561 # Loop over the simulations. 562 for j in range(cdp.sim_number): 563 # Copy and append the data. 564 sim_object.append(deepcopy(getattr(spin, object_name))) 565 566 # Loop over all the minimisation object names. 567 for object_name in min_names: 568 # Name for the simulation object. 569 sim_object_name = object_name + '_sim' 570 571 # Create the simulation object. 572 setattr(spin, sim_object_name, []) 573 574 # Get the simulation object. 575 sim_object = getattr(spin, sim_object_name) 576 577 # Loop over the simulations. 578 for j in range(cdp.sim_number): 579 # Copy and append the data. 580 sim_object.append(deepcopy(getattr(spin, object_name)))
581 582
583 - def _sim_pack_relax_data(self, data_id, sim_data):
584 """Pack the Monte Carlo simulation relaxation data into the corresponding spin container. 585 586 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method. 587 @type data_id: str 588 @param sim_data: The Monte Carlo simulation data. 589 @type sim_data: list of float 590 """ 591 592 # Get the spin container. 593 spin = return_spin(data_id) 594 595 # Initialise the data structure. 596 spin.ri_data_sim = {} 597 598 # Loop over the relaxation data. 599 for i in range(len(cdp.ri_ids)): 600 # The ID. 601 ri_id = cdp.ri_ids[i] 602 603 # Initialise the MC data list. 604 spin.ri_data_sim[ri_id] = [] 605 606 # Loop over the simulations. 607 for j in range(cdp.sim_number): 608 spin.ri_data_sim[ri_id].append(sim_data[j][i])
609 610
611 - def _sim_return_chi2_spin(self, model_info, index=None):
612 """Return the simulation chi-squared values (spin system specific). 613 614 @param model_info: The model information originating from model_loop(). 615 @type model_info: unknown 616 @keyword index: The optional simulation index. 617 @type index: int 618 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned. 619 @rtype: list of float or float 620 """ 621 622 # The spin container. 623 if not isinstance(model_info, SpinContainer): 624 raise RelaxError("The model information argument is not a spin container.") 625 spin = model_info 626 627 # Index. 628 if index != None: 629 return spin.chi2_sim[index] 630 631 # List of vals. 632 else: 633 return spin.chi2_sim
634 635
636 - def _sim_return_param_spin(self, model_info, index):
637 """Return the array of simulation parameter values (spin system specific). 638 639 @param model_info: The model information originating from model_loop(). 640 @type model_info: unknown 641 @param index: The index of the parameter to return the array of values for. 642 @type index: int 643 @return: The array of simulation parameter values. 644 @rtype: list of float 645 """ 646 647 # The spin container. 648 if not isinstance(model_info, SpinContainer): 649 raise RelaxError("The model information argument is not a spin container.") 650 spin = model_info 651 652 # Parameter increment counter. 653 inc = 0 654 655 # Loop over the residue specific parameters. 656 for param in self.data_names(set='params'): 657 # Return the parameter array. 658 if index == inc: 659 return getattr(spin, param + "_sim") 660 661 # Increment. 662 inc = inc + 1
663 664
665 - def _sim_return_selected_global(self, model_info):
666 """Return the array of selected simulation flags for the global model. 667 668 @param model_info: The model information originating from model_loop(). This should be zero for the single global model. 669 @type model_info: int 670 @return: The array of selected simulation flags. 671 @rtype: list of int 672 """ 673 674 # Return the array. 675 return cdp.select_sim
676 677
678 - def _sim_return_selected_spin(self, model_info):
679 """Return the array of selected simulation flags (spin system specific). 680 681 @param model_info: The model information originating from model_loop(). 682 @type model_info: unknown 683 @return: The array of selected simulation flags. 684 @rtype: list of int 685 """ 686 687 # The spin container. 688 if not isinstance(model_info, SpinContainer): 689 raise RelaxError("The model information argument is not a spin container.") 690 spin = model_info 691 692 # Return the array. 693 return spin.select_sim
694 695
696 - def _test_grid_ops_general(self, lower=None, upper=None, inc=None, n=None):
697 """Test that the grid search options are reasonable. 698 699 @param lower: The lower bounds of the grid search which must be equal to the number of parameters in the model. 700 @type lower: array of numbers 701 @param upper: The upper bounds of the grid search which must be equal to the number of parameters in the model. 702 @type upper: array of numbers 703 @param inc: The increments for each dimension of the space for the grid search. The number of elements in the array must equal to the number of parameters in the model. 704 @type inc: array of int 705 @param n: The number of parameters in the model. 706 @type n: int 707 """ 708 709 # Lower bounds test. 710 if lower != None: 711 if len(lower) != n: 712 raise RelaxLenError('lower bounds', n) 713 714 # Upper bounds. 715 if upper != None: 716 if len(upper) != n: 717 raise RelaxLenError('upper bounds', n) 718 719 # Increment. 720 if isinstance(inc, list): 721 if len(inc) != n: 722 raise RelaxLenError('increment', n)
723