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

Source Code for Module specific_analyses.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  from data_store.mol_res_spin import SpinContainer 
 30  import lib.arg_check 
 31  from lib.errors import RelaxError, RelaxLenError, RelaxNoSequenceError 
 32  from pipe_control.mol_res_spin import count_spins, exists_mol_res_spin_data, return_spin, spin_loop 
 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 _data_init_spin(self, data_cont, sim=False):
92 """Initialise data structures (spin system specific). 93 94 @param data_cont: The spin container. 95 @type data_cont: SpinContainer instance 96 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure. 97 @type sim: bool 98 """ 99 100 # Loop over the parameters. 101 for name in self.PARAMS.loop(set='params', scope='spin', error_names=False, sim_names=sim): 102 # Not a parameter of the model. 103 if name not in data_cont.params: 104 continue 105 106 # The value already exists. 107 if hasattr(data_cont, name): 108 continue 109 110 # The default value. 111 param_type = self.PARAMS.get_type(name) 112 if param_type == dict: 113 value = {} 114 elif param_type == list: 115 value = [] 116 else: 117 value = None 118 119 # Set the value. 120 setattr(data_cont, name, value)
121 122
123 - def _eliminate_false(self, name, value, model_info, args, sim=None):
124 """Dummy method for model elimination. 125 126 This simply returns False to signal that no model elimination is to be performed. 127 128 129 @param name: The parameter name. 130 @type name: str 131 @param value: The parameter value. 132 @type value: float 133 @param model_info: The model index from model_info(). 134 @type model_info: int 135 @param args: The elimination constant overrides. 136 @type args: None or tuple of float 137 @keyword sim: The Monte Carlo simulation index. 138 @type sim: int 139 @return: False to prevent model elimination. 140 @rtype: bool 141 """ 142 143 # Don't eliminate. 144 return False
145 146
147 - def _has_errors_spin(self):
148 """Testing if errors exist for the current data pipe (spin system specific). 149 150 @return: The answer to the question of whether errors exist. 151 @rtype: bool 152 """ 153 154 # Diffusion tensor errors. 155 if hasattr(cdp, 'diff'): 156 for object_name in dir(cdp.diff): 157 # The object error name. 158 object_error = object_name + '_err' 159 160 # Error exists. 161 if hasattr(cdp.diff, object_error): 162 return True 163 164 # Loop over the sequence. 165 for spin in spin_loop(): 166 # Parameter errors. 167 for object_name in dir(spin): 168 # The object error name. 169 object_error = object_name + '_err' 170 171 # Error exists. 172 if hasattr(spin, object_error): 173 return True 174 175 # No errors found. 176 return False
177 178
179 - def _is_spin_param_true(self, name):
180 """Dummy method stating that the parameter is spin specific. 181 182 This method always returns true, hence all parameters will be considered residents of a SpinContainer object unless this method is overwritten. 183 184 @param name: The name of the parameter. 185 @type name: str 186 @return: True 187 @rtype: bool 188 """ 189 190 # Return the default of True. 191 return True
192 193
194 - def _model_loop_spin(self):
195 """Default generator method for looping over the models, where each spin has a separate model. 196 197 In this case only a single model per spin system is assumed. Hence the yielded data is the spin container object. 198 199 200 @return: The spin container. 201 @rtype: SpinContainer instance 202 """ 203 204 # Loop over the sequence. 205 for spin in spin_loop(): 206 # Skip deselected spins. 207 if not spin.select: 208 continue 209 210 # Yield the spin container. 211 yield spin
212 213
215 """Default generator method for looping over a single global (non-spin specific) model. 216 217 The loop will yield a single index, zero, once to indicate a single model. 218 219 220 @return: The global model index of zero. 221 @rtype: int 222 """ 223 224 # Yield the index zero. 225 yield 0
226 227
228 - def _model_type_global(self):
229 """Return the type of the model as being 'global'. 230 231 @return: The model type of 'global'. 232 @rtype: str 233 """ 234 235 # Global models. 236 return 'global'
237 238
239 - def _model_type_local(self):
240 """Return the type of the model as being 'local'. 241 242 @return: The model type of 'local'. 243 @rtype: str 244 """ 245 246 # Local models. 247 return 'local'
248 249
250 - def _num_instances_spin(self):
251 """Return the number of instances, equal to the number of selected spins. 252 253 @return: The number of instances (equal to the number of spins). 254 @rtype: int 255 """ 256 257 # Test if sequence data is loaded. 258 if not exists_mol_res_spin_data(): 259 raise RelaxNoSequenceError 260 261 # Return the number of spins. 262 return count_spins()
263 264
265 - def _overfit_deselect_dummy(self, data_check=True, verbose=True):
266 """Dummy method, normally for deselecting spins with insufficient data for minimisation."""
267 268
269 - def _return_no_conversion_factor(self, param):
270 """Method for returning 1.0. 271 272 @param param: The parameter name. 273 @type param: str 274 @return: A conversion factor of 1.0. 275 @rtype: float 276 """ 277 278 return 1.0
279 280
281 - def _return_data_relax_data(self, spin):
282 """Return the Ri data structure for the given spin. 283 284 @param spin: The SpinContainer object. 285 @type spin: SpinContainer instance 286 @return: The array of relaxation data values. 287 @rtype: list of float 288 """ 289 290 # Convert to a list. 291 data = [] 292 for ri_id in cdp.ri_ids: 293 # Handle missing data. 294 if ri_id not in spin.ri_data: 295 data.append(None) 296 297 # Append the value. 298 else: 299 data.append(spin.ri_data[ri_id]) 300 301 # Return the list. 302 return data
303 304
305 - def _return_error_relax_data(self, data_id):
306 """Return the Ri error structure for the corresponding spin. 307 308 @param data_id: The data identification information, as yielded by the base_data_loop() generator method. 309 @type data_id: str 310 @return: The array of relaxation data error values. 311 @rtype: list of float 312 """ 313 314 # Get the spin container. 315 spin = return_spin(data_id) 316 317 # Convert to a list. 318 error = [] 319 for ri_id in cdp.ri_ids: 320 # Handle missing data/errors. 321 if ri_id not in spin.ri_data_err: 322 error.append(None) 323 324 # Append the value. 325 else: 326 error.append(spin.ri_data_err[ri_id]) 327 328 # Return the list. 329 return error
330 331
332 - def _return_value_general(self, spin, param, sim=None, bc=False):
333 """Return the value and error corresponding to the parameter 'param'. 334 335 If sim is set to an integer, return the value of the simulation and None. The values are taken from the given SpinContainer object. 336 337 338 @param spin: The SpinContainer object. 339 @type spin: SpinContainer 340 @param param: The name of the parameter to return values for. 341 @type param: str 342 @param sim: The Monte Carlo simulation index. 343 @type sim: None or int 344 @keyword bc: The back-calculated data flag. If True, then the back-calculated data will be returned rather than the actual data. 345 @type bc: bool 346 @return: The value and error corresponding to 347 @rtype: tuple of length 2 of floats or None 348 """ 349 350 # Initialise. 351 index = None 352 353 # Get the object name. 354 object_name = self.return_data_name(param) 355 356 # The error, simulation and back calculated names. 357 if object_name: 358 object_error = object_name + '_err' 359 object_sim = object_name + '_sim' 360 object_bc = object_name + '_bc' 361 key = None 362 363 # The data type does not exist. 364 else: 365 # Is it a spectrum id? 366 if hasattr(cdp, 'spectrum_ids') and param in cdp.spectrum_ids: 367 object_name = 'intensities' 368 object_error = 'intensity_err' 369 object_sim = 'intensity_sim' 370 object_bc = 'intensity_bc' 371 key = param 372 373 # Unknown data type. 374 else: 375 raise RelaxError("The parameter " + repr(param) + " does not exist.") 376 377 # Initial values. 378 value = None 379 error = None 380 381 # Switch to back calculated data. 382 if bc: 383 object_name = object_bc 384 385 # Value or sim value? 386 if sim != None: 387 object_name = object_sim 388 389 # The spin value. 390 if hasattr(spin, object_name): 391 value = getattr(spin, object_name) 392 393 # The spin error. 394 if hasattr(spin, object_error): 395 error = getattr(spin, object_error) 396 397 # The global value. 398 elif hasattr(cdp, object_name): 399 value = getattr(cdp, object_name) 400 401 # The error. 402 if hasattr(cdp, object_error): 403 error = getattr(cdp, object_error) 404 405 # List object. 406 if index != None: 407 value = value[index] 408 if error: 409 error = error[index] 410 411 # Dictionary object. 412 if key: 413 # Handle missing data. 414 if key not in value: 415 value = None 416 else: 417 value = value[key] 418 419 if error: 420 # Handle missing errors. 421 if key not in error: 422 error = None 423 else: 424 error = error[key] 425 426 # Return the data. 427 if sim == None: 428 return value, error 429 elif value == None: 430 return value, error 431 else: 432 return value[sim], error
433 434
435 - def _set_error_spin(self, model_info, index, error):
436 """Set the parameter errors (spin system specific). 437 438 @param model_info: The spin container originating from model_loop(). 439 @type model_info: unknown 440 @param index: The index of the parameter to set the errors for. 441 @type index: int 442 @param error: The error value. 443 @type error: float 444 """ 445 446 # The spin container. 447 if not isinstance(model_info, SpinContainer): 448 raise RelaxError("The model information argument is not a spin container.") 449 spin = model_info 450 451 # Parameter increment counter. 452 inc = 0 453 454 # Loop over the residue specific parameters. 455 for param in self.data_names(set='params'): 456 # Return the parameter array. 457 if index == inc: 458 setattr(spin, param + "_err", error) 459 460 # Increment. 461 inc = inc + 1
462 463
464 - def _set_param_values_global(self, param=None, value=None, spin_id=None, error=False, force=True):
465 """Set the global parameter values in the top layer of the data pipe. 466 467 @keyword param: The parameter name list. 468 @type param: list of str 469 @keyword value: The parameter value list. 470 @type value: list 471 @keyword spin_id: The spin identification string (unused). 472 @type spin_id: None 473 @keyword error: A flag which if True will allow the parameter errors to be set instead of the values. 474 @type error: bool 475 @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. 476 @type force: bool 477 """ 478 479 # Checks. 480 lib.arg_check.is_str_list(param, 'parameter name') 481 lib.arg_check.is_list(value, 'parameter value') 482 483 # Loop over the parameters. 484 for i in range(len(param)): 485 # Get the object's name. 486 obj_name = self.return_data_name(param[i]) 487 488 # Is the parameter is valid? 489 if not obj_name: 490 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i]) 491 492 # Error object. 493 if error: 494 obj_name += '_err' 495 496 # Is the parameter already set. 497 if not force and hasattr(cdp, obj_name) and getattr(cdp, obj_name) != None: 498 raise RelaxError("The parameter '%s' already exists, set the force flag to True to overwrite." % param[i]) 499 500 # Set the parameter. 501 setattr(cdp, obj_name, value[i])
502 503
504 - def _set_param_values_spin(self, param=None, value=None, spin_id=None, error=False, force=True):
505 """Set the spin specific parameter values. 506 507 @keyword param: The parameter name list. 508 @type param: list of str 509 @keyword value: The parameter value list. 510 @type value: list 511 @keyword spin_id: The spin identification string, only used for spin specific parameters. 512 @type spin_id: None or str 513 @keyword error: A flag which if True will allow the parameter errors to be set instead of the values. 514 @type error: bool 515 @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. 516 @type force: bool 517 """ 518 519 # Checks. 520 lib.arg_check.is_str_list(param, 'parameter name') 521 lib.arg_check.is_list(value, 'parameter value') 522 523 # Loop over the parameters. 524 for i in range(len(param)): 525 # Is the parameter is valid? 526 if not self.PARAMS.contains(param[i]): 527 raise RelaxError("The parameter '%s' is not valid for this data pipe type." % param[i]) 528 529 # Spin loop. 530 for spin in spin_loop(spin_id): 531 # Skip deselected spins. 532 if not spin.select: 533 continue 534 535 # The object name. 536 obj_name = param[i] 537 if error: 538 obj_name += '_err' 539 540 # Set the parameter. 541 setattr(spin, obj_name, value[i])
542 543
544 - def _set_selected_sim_global(self, model_info, select_sim):
545 """Set the simulation selection flag (for a single global model). 546 547 @param model_info: The model information originating from model_loop(). This should be zero for the single global model. 548 @type model_info: int 549 @param select_sim: The selection flag for the simulations. 550 @type select_sim: bool 551 """ 552 553 # Set the array. 554 cdp.select_sim = deepcopy(select_sim)
555 556
557 - def _set_selected_sim_spin(self, model_info, select_sim):
558 """Set the simulation selection flag (spin system specific). 559 560 @param model_info: The model information originating from model_loop(). 561 @type model_info: unknown 562 @param select_sim: The selection flag for the simulations. 563 @type select_sim: bool 564 """ 565 566 # The spin container. 567 if not isinstance(model_info, SpinContainer): 568 raise RelaxError("The model information argument is not a spin container.") 569 spin = model_info 570 571 # Set the array. 572 spin.select_sim = deepcopy(select_sim)
573 574
575 - def _set_update(self, param, spin):
576 """Dummy method to do nothing! 577 578 @param param: The name of the parameter which has been changed. 579 @type param: str 580 @param spin: The SpinContainer object. 581 @type spin: SpinContainer 582 """
583 584
585 - def _sim_init_values_spin(self):
586 """Initialise the Monte Carlo parameter values (spin system specific).""" 587 588 # Get the parameter object names. 589 param_names = self.data_names(set='params') 590 591 # Get the minimisation statistic object names. 592 min_names = self.data_names(set='min') 593 594 595 # Test if Monte Carlo parameter values have already been set. 596 ############################################################# 597 598 # Loop over the spins. 599 for spin in spin_loop(): 600 # Skip deselected spins. 601 if not spin.select: 602 continue 603 604 # Loop over all the parameter names. 605 for object_name in param_names: 606 # Name for the simulation object. 607 sim_object_name = object_name + '_sim' 608 609 610 # Set the Monte Carlo parameter values. 611 ####################################### 612 613 # Loop over the residues. 614 for spin in spin_loop(): 615 # Skip deselected residues. 616 if not spin.select: 617 continue 618 619 # Loop over all the data names. 620 for object_name in param_names: 621 # Not a parameter of the model. 622 if object_name not in spin.params: 623 continue 624 625 # Name for the simulation object. 626 sim_object_name = object_name + '_sim' 627 628 # Create the simulation object. 629 setattr(spin, sim_object_name, []) 630 631 # Get the simulation object. 632 sim_object = getattr(spin, sim_object_name) 633 634 # Loop over the simulations. 635 for j in range(cdp.sim_number): 636 # Copy and append the data. 637 sim_object.append(deepcopy(getattr(spin, object_name))) 638 639 # Loop over all the minimisation object names. 640 for object_name in min_names: 641 # Name for the simulation object. 642 sim_object_name = object_name + '_sim' 643 644 # Create the simulation object. 645 setattr(spin, sim_object_name, []) 646 647 # Get the simulation object. 648 sim_object = getattr(spin, sim_object_name) 649 650 # Loop over the simulations. 651 for j in range(cdp.sim_number): 652 # Copy and append the data. 653 sim_object.append(deepcopy(getattr(spin, object_name)))
654 655
656 - def _sim_pack_relax_data(self, data_id, sim_data):
657 """Pack the Monte Carlo simulation relaxation data into the corresponding spin container. 658 659 @param data_id: The spin identification string, as yielded by the base_data_loop() generator method. 660 @type data_id: str 661 @param sim_data: The Monte Carlo simulation data. 662 @type sim_data: list of float 663 """ 664 665 # Get the spin container. 666 spin = return_spin(data_id) 667 668 # Initialise the data structure. 669 spin.ri_data_sim = {} 670 671 # Loop over the relaxation data. 672 for i in range(len(cdp.ri_ids)): 673 # The ID. 674 ri_id = cdp.ri_ids[i] 675 676 # Initialise the MC data list. 677 spin.ri_data_sim[ri_id] = [] 678 679 # Loop over the simulations. 680 for j in range(cdp.sim_number): 681 spin.ri_data_sim[ri_id].append(sim_data[j][i])
682 683
684 - def _sim_return_chi2_spin(self, model_info, index=None):
685 """Return the simulation chi-squared values (spin system specific). 686 687 @param model_info: The model information originating from model_loop(). 688 @type model_info: unknown 689 @keyword index: The optional simulation index. 690 @type index: int 691 @return: The list of simulation chi-squared values. If the index is supplied, only a single value will be returned. 692 @rtype: list of float or float 693 """ 694 695 # The spin container. 696 if not isinstance(model_info, SpinContainer): 697 raise RelaxError("The model information argument is not a spin container.") 698 spin = model_info 699 700 # Index. 701 if index != None: 702 return spin.chi2_sim[index] 703 704 # List of vals. 705 else: 706 return spin.chi2_sim
707 708
709 - def _sim_return_param_spin(self, model_info, index):
710 """Return the array of simulation parameter values (spin system specific). 711 712 @param model_info: The model information originating from model_loop(). 713 @type model_info: unknown 714 @param index: The index of the parameter to return the array of values for. 715 @type index: int 716 @return: The array of simulation parameter values. 717 @rtype: list of float 718 """ 719 720 # The spin container. 721 if not isinstance(model_info, SpinContainer): 722 raise RelaxError("The model information argument is not a spin container.") 723 spin = model_info 724 725 # Parameter increment counter. 726 inc = 0 727 728 # Loop over the residue specific parameters. 729 for param in self.data_names(set='params'): 730 # Not a parameter of the model. 731 if param not in spin.params: 732 continue 733 734 # Return the parameter array. 735 if index == inc: 736 return getattr(spin, param + "_sim") 737 738 # Increment. 739 inc = inc + 1
740 741
742 - def _sim_return_selected_global(self, model_info):
743 """Return the array of selected simulation flags for the global model. 744 745 @param model_info: The model information originating from model_loop(). This should be zero for the single global model. 746 @type model_info: int 747 @return: The array of selected simulation flags. 748 @rtype: list of int 749 """ 750 751 # Return the array. 752 return cdp.select_sim
753 754
755 - def _sim_return_selected_spin(self, model_info):
756 """Return the array of selected simulation flags (spin system specific). 757 758 @param model_info: The model information originating from model_loop(). 759 @type model_info: unknown 760 @return: The array of selected simulation flags. 761 @rtype: list of int 762 """ 763 764 # The spin container. 765 if not isinstance(model_info, SpinContainer): 766 raise RelaxError("The model information argument is not a spin container.") 767 spin = model_info 768 769 # Return the array. 770 return spin.select_sim
771 772
773 - def _test_grid_ops_general(self, lower=None, upper=None, inc=None, n=None):
774 """Test that the grid search options are reasonable. 775 776 @param lower: The lower bounds of the grid search which must be equal to the number of parameters in the model. 777 @type lower: array of numbers 778 @param upper: The upper bounds of the grid search which must be equal to the number of parameters in the model. 779 @type upper: array of numbers 780 @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. 781 @type inc: array of int 782 @param n: The number of parameters in the model. 783 @type n: int 784 """ 785 786 # Lower bounds test. 787 if lower != None: 788 if len(lower) != n: 789 raise RelaxLenError('lower bounds', n) 790 791 # Upper bounds. 792 if upper != None: 793 if len(upper) != n: 794 raise RelaxLenError('upper bounds', n) 795 796 # Increment. 797 if isinstance(inc, list): 798 if len(inc) != n: 799 raise RelaxLenError('increment', n)
800