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

Source Code for Module specific_analyses.api_common

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