Package specific_analyses :: Package frame_order :: Module api
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.frame_order.api

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-2014 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  """The frame order API object.""" 
 24   
 25  # Python module imports. 
 26  from copy import deepcopy 
 27  from math import pi 
 28  from minfx.generic import generic_minimise 
 29  from minfx.grid import grid_point_array 
 30  from numpy import float64, zeros 
 31  from re import search 
 32   
 33  # relax module imports. 
 34  from lib.errors import RelaxError, RelaxNoModelError 
 35  from pipe_control import pipes 
 36  from pipe_control.interatomic import interatomic_loop, return_interatom 
 37  from pipe_control.mol_res_spin import return_spin, spin_loop 
 38  from pipe_control.rdc import check_rdcs 
 39  from specific_analyses.api_base import API_base 
 40  from specific_analyses.api_common import API_common 
 41  from specific_analyses.frame_order.data import domain_moving 
 42  from specific_analyses.frame_order.optimisation import grid_row, store_bc_data, target_fn_setup, unpack_opt_results 
 43  from specific_analyses.frame_order.parameter_object import Frame_order_params 
 44  from specific_analyses.frame_order.parameters import assemble_param_vector, assemble_scaling_matrix, linear_constraints, param_num, update_model 
 45   
 46   
47 -class Frame_order(API_base, API_common):
48 """Class containing the specific methods of the Frame Order theories.""" 49 50 # Class variable for storing the class instance (for the singleton design pattern). 51 instance = None 52
53 - def __init__(self):
54 """Initialise the class by placing API_common methods into the API.""" 55 56 # Place methods into the API. 57 self.deselect = self._deselect_global 58 self.is_spin_param = self._is_spin_param_false 59 self.model_loop = self._model_loop_single_global 60 self.model_type = self._model_type_global 61 self.overfit_deselect = self._overfit_deselect_dummy 62 self.return_conversion_factor = self._return_no_conversion_factor 63 self.set_param_values = self._set_param_values_global 64 65 # Place a copy of the parameter list object in the instance namespace. 66 self._PARAMS = Frame_order_params()
67 68
69 - def base_data_loop(self):
70 """Generator method for looping over the base data - RDCs and PCSs. 71 72 This loop yields the following: 73 74 - The RDC identification data for the interatomic data container and alignment. 75 - The PCS identification data for the spin data container and alignment. 76 77 @return: The base data type ('rdc' or 'pcs'), the spin or interatomic data container information (either one or two spin IDs), and the alignment ID string. 78 @rtype: list of str 79 """ 80 81 # Loop over the interatomic data containers for the moving domain (for the RDC data). 82 for interatom in interatomic_loop(selection1=domain_moving()): 83 # RDC checks. 84 if not check_rdcs(interatom): 85 continue 86 87 # Loop over the alignment IDs. 88 for align_id in cdp.rdc_ids: 89 # Yield the info set. 90 yield ['rdc', interatom.spin_id1, interatom.spin_id2, align_id] 91 92 # Loop over the spin containers for the moving domain (for the PCS data). 93 for spin, spin_id in spin_loop(selection=domain_moving(), return_id=True): 94 # Skip deselected spins. 95 if not spin.select: 96 continue 97 98 # No PCS, so skip. 99 if not hasattr(spin, 'pcs'): 100 continue 101 102 # Loop over the alignment IDs. 103 for align_id in cdp.pcs_ids: 104 # Yield the info set. 105 yield ['pcs', spin_id, align_id]
106 107
108 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
109 """Calculate the chi-squared value for the current parameter values. 110 111 @keyword spin_id: The spin identification string (unused). 112 @type spin_id: None 113 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity. 114 @type verbosity: int 115 @keyword sim_index: The optional MC simulation index (unused). 116 @type sim_index: None or int 117 """ 118 119 # Set up the target function for direct calculation. 120 model, param_vector, scaling_matrix = target_fn_setup(sim_index=sim_index, verbosity=verbosity) 121 122 # Make a single function call. This will cause back calculation and the data will be stored in the class instance. 123 chi2 = model.func(param_vector) 124 125 # Set the chi2. 126 cdp.chi2 = chi2 127 128 # Store the back-calculated data. 129 store_bc_data(model) 130 131 # Printout. 132 print("Chi2: %s" % chi2)
133 134
135 - def constraint_algorithm(self):
136 """Return the 'Log barrier' optimisation constraint algorithm. 137 138 @return: The 'Log barrier' constraint algorithm. 139 @rtype: str 140 """ 141 142 # The log barrier algorithm, as required by minfx. 143 return 'Log barrier'
144 145
146 - def create_mc_data(self, data_id=None):
147 """Create the Monte Carlo data by back calculating the RDCs or PCSs. 148 149 @keyword data_id: The data set as yielded by the base_data_loop() generator method. 150 @type data_id: list of str 151 @return: The Monte Carlo simulation data. 152 @rtype: list of floats 153 """ 154 155 # Initialise the MC data structure. 156 mc_data = [] 157 158 # The RDC data. 159 if data_id[0] == 'rdc': 160 # Unpack the set. 161 data_type, spin_id1, spin_id2, align_id = data_id 162 163 # Get the interatomic data container. 164 interatom = return_interatom(spin_id1, spin_id2) 165 166 # Does back-calculated data exist? 167 if not hasattr(interatom, 'rdc_bc'): 168 self.calculate() 169 170 # The data. 171 if not hasattr(interatom, 'rdc_bc') or align_id not in interatom.rdc_bc: 172 data = None 173 else: 174 data = interatom.rdc_bc[align_id] 175 176 # Append the data. 177 mc_data.append(data) 178 179 # The PCS data. 180 elif data_id[0] == 'pcs': 181 # Unpack the set. 182 data_type, spin_id, align_id = data_id 183 184 # Get the spin container. 185 spin = return_spin(spin_id) 186 187 # Does back-calculated data exist? 188 if not hasattr(spin, 'pcs_bc'): 189 self.calculate() 190 191 # The data. 192 if not hasattr(spin, 'pcs_bc') or align_id not in spin.pcs_bc: 193 data = None 194 else: 195 data = spin.pcs_bc[align_id] 196 197 # Append the data. 198 mc_data.append(data) 199 200 # Return the data. 201 return mc_data
202 203
204 - def duplicate_data(self, pipe_from=None, pipe_to=None, model_info=None, global_stats=False, verbose=True):
205 """Duplicate the data specific to a single frame order data pipe. 206 207 @keyword pipe_from: The data pipe to copy the data from. 208 @type pipe_from: str 209 @keyword pipe_to: The data pipe to copy the data to. 210 @type pipe_to: str 211 @param model_info: The model index from model_loop(). 212 @type model_info: int 213 @keyword global_stats: The global statistics flag. 214 @type global_stats: bool 215 @keyword verbose: Unused. 216 @type verbose: bool 217 """ 218 219 # Check that the data pipe does not exist. 220 if pipes.has_pipe(pipe_to): 221 raise RelaxError("The data pipe '%s' already exists." % pipe_to) 222 223 # Create the pipe_to data pipe by copying. 224 pipes.copy(pipe_from=pipe_from, pipe_to=pipe_to)
225 226
227 - def eliminate(self, name, value, model_info, args, sim=None):
228 """Model elimination method. 229 230 @param name: The parameter name. 231 @type name: str 232 @param value: The parameter value. 233 @type value: float 234 @param model_info: The model index from model_info(). 235 @type model_info: int 236 @param args: The elimination constant overrides. 237 @type args: None or tuple of float 238 @keyword sim: The Monte Carlo simulation index. 239 @type sim: int 240 @return: True if the model is to be eliminated, False otherwise. 241 @rtype: bool 242 """ 243 244 # Text to print out if a model failure occurs. 245 text = "The %s parameter of %.5g is %s than %.5g, eliminating " 246 if sim == None: 247 text += "the model." 248 else: 249 text += "simulation %i." % sim 250 251 # Isotropic order parameter out of range. 252 if name == 'cone_s1' and hasattr(cdp, 'cone_s1'): 253 if cdp.cone_s1 > 1.0: 254 print(text % ("cone S1 order", cdp.cone_s1, "greater", 1.0)) 255 return True 256 if cdp.cone_s1 < -0.125: 257 print(text % ("cone S1 order", cdp.cone_s1, "less", -0.125)) 258 return True 259 260 # Isotropic cone angle out of range. 261 if name == 'cone_theta' and hasattr(cdp, 'cone_theta'): 262 if cdp.cone_theta >= pi: 263 print(text % ("cone opening angle theta", cdp.cone_theta, "greater", pi)) 264 return True 265 if cdp.cone_theta < 0.0: 266 print(text % ("cone opening angle theta", cdp.cone_theta, "less", 0)) 267 return True 268 269 # Pseudo-ellipse cone angles out of range (0.001 instead of 0.0 because of truncation in the numerical integration). 270 if name == 'cone_theta_x' and hasattr(cdp, 'cone_theta_x'): 271 if cdp.cone_theta_x >= pi: 272 print(text % ("cone opening angle theta x", cdp.cone_theta_x, "greater", pi)) 273 return True 274 if cdp.cone_theta_x < 0.001: 275 print(text % ("cone opening angle theta x", cdp.cone_theta_x, "less", 0.001)) 276 return True 277 if name == 'cone_theta_y' and hasattr(cdp, 'cone_theta_y'): 278 if cdp.cone_theta_y >= pi: 279 print(text % ("cone opening angle theta y", cdp.cone_theta_y, "greater", pi)) 280 return True 281 if cdp.cone_theta_y < 0.001: 282 print(text % ("cone opening angle theta y", cdp.cone_theta_y, "less", 0.001)) 283 return True 284 285 # Torsion angle out of range. 286 if name == 'cone_sigma_max' and hasattr(cdp, 'cone_sigma_max'): 287 if cdp.cone_sigma_max >= pi: 288 print(text % ("torsion angle sigma_max", cdp.cone_sigma_max, "greater", pi)) 289 return True 290 if cdp.cone_sigma_max < 0.0: 291 print(text % ("torsion angle sigma_max", cdp.cone_sigma_max, "less", 0.0)) 292 return True 293 294 # No failure. 295 return False
296 297
298 - def get_param_names(self, model_info=None):
299 """Return a vector of parameter names. 300 301 @keyword model_info: The model index from model_info(). 302 @type model_info: int 303 @return: The vector of parameter names. 304 @rtype: list of str 305 """ 306 307 # First update the model, if needed. 308 update_model() 309 310 # Return the parameter list object. 311 return cdp.params
312 313
314 - def get_param_values(self, model_info=None, sim_index=None):
315 """Return a vector of parameter values. 316 317 @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). 318 @type model_info: int 319 @keyword sim_index: The Monte Carlo simulation index. 320 @type sim_index: int 321 @return: The vector of parameter values. 322 @rtype: list of str 323 """ 324 325 # Assemble the values and return it. 326 return assemble_param_vector(sim_index=sim_index)
327 328
329 - def grid_search(self, lower=None, upper=None, inc=None, constraints=False, verbosity=0, sim_index=None):
330 """Perform a grid search. 331 332 @keyword lower: The lower bounds of the grid search which must be equal to the number of parameters in the model. 333 @type lower: list of float 334 @keyword upper: The upper bounds of the grid search which must be equal to the number of parameters in the model. 335 @type upper: list of float 336 @keyword 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. 337 @type inc: int or list of int 338 @keyword constraints: If True, constraints are applied during the grid search (eliminating parts of the grid). If False, no constraints are used. 339 @type constraints: bool 340 @keyword verbosity: A flag specifying the amount of information to print. The higher the value, the greater the verbosity. 341 @type verbosity: int 342 @keyword sim_index: The Monte Carlo simulation index. 343 @type sim_index: None or int 344 """ 345 346 # Test if the Frame Order model has been set up. 347 if not hasattr(cdp, 'model'): 348 raise RelaxNoModelError('Frame Order') 349 350 # Parameter scaling. 351 scaling_matrix = assemble_scaling_matrix(scaling=True) 352 353 # The number of parameters. 354 n = param_num() 355 356 # If inc is an int, convert it into an array of that value. 357 if isinstance(inc, int): 358 incs = [inc]*n 359 else: 360 incs = inc 361 362 # Sanity check. 363 if len(incs) != n: 364 raise RelaxError("The size of the increment list %s does not match the number of parameters in %s." % (incs, cdp.params)) 365 366 # Initialise the grid increments structures. 367 lower_list = lower 368 upper_list = upper 369 grid = [] 370 """This structure is a list of lists. The first dimension corresponds to the model 371 parameter. The second dimension are the grid node positions.""" 372 373 # Generate the grid. 374 for i in range(n): 375 # Fixed parameter. 376 if incs[i] == None: 377 grid.append(None) 378 continue 379 380 # Reset. 381 dist_type = None 382 end_point = True 383 384 # The pivot point. 385 if cdp.params[i] in ['pivot_x', 'pivot_y', 'pivot_z']: 386 val = getattr(cdp, cdp.params[i]) 387 lower = val - 10.0 388 upper = val + 10.0 389 390 # Average domain position translation (in a +/- 5 Angstrom box). 391 if cdp.params[i] in ['ave_pos_x', 'ave_pos_y', 'ave_pos_z']: 392 lower = -5 393 upper = 5 394 395 # Linear angle grid from 0 to one inc before 2pi. 396 if cdp.params[i] in ['ave_pos_alpha', 'ave_pos_gamma', 'eigen_alpha', 'eigen_gamma', 'axis_phi']: 397 lower = 0.0 398 upper = 2*pi * (1.0 - 1.0/incs[i]) 399 400 # Linear angle grid from -pi to one inc before pi. 401 if cdp.params[i] in ['axis_alpha']: 402 lower = -pi 403 upper = pi * (1.0 - 1.0/incs[i]) 404 405 # Arccos grid from 0 to pi. 406 if cdp.params[i] in ['ave_pos_beta', 'eigen_beta', 'axis_theta']: 407 # Change the default increment numbers. 408 if not isinstance(inc, list): 409 incs[i] = int(incs[i] / 2) + 1 410 411 # The distribution type and end point. 412 dist_type = 'acos' 413 end_point = False 414 415 # Set the default bounds. 416 lower = 0.0 417 upper = pi 418 419 # The isotropic cone order parameter. 420 if cdp.params[i] == 'cone_s1': 421 lower = -0.125 422 upper = 1.0 423 424 # Linear angle grid from 0 to pi excluding the outer points. 425 if cdp.params[i] in ['cone_theta', 'cone_theta_x', 'cone_theta_y', 'cone_sigma_max']: 426 lower = pi * (1.0/incs[i]) 427 upper = pi * (1.0 - 1.0/incs[i]) 428 429 # Over-ride the bounds. 430 if lower_list: 431 lower = lower_list[i] 432 if upper_list: 433 upper = upper_list[i] 434 435 # Append the grid row. 436 row = grid_row(incs[i], lower, upper, dist_type=dist_type, end_point=end_point) 437 grid.append(row) 438 439 # Remove an inc if the end point has been removed. 440 if not end_point: 441 incs[i] -= 1 442 443 # Total number of points. 444 total_pts = 1 445 for i in range(n): 446 # Fixed parameter. 447 if grid[i] == None: 448 continue 449 450 total_pts = total_pts * len(grid[i]) 451 452 # Check the number. 453 max_pts = 50e6 454 if total_pts > max_pts: 455 raise RelaxError("The total number of grid points '%s' exceeds the maximum of '%s'." % (total_pts, int(max_pts))) 456 457 # Build the points array. 458 pts = zeros((total_pts, n), float64) 459 indices = zeros(n, int) 460 for i in range(total_pts): 461 # Loop over the dimensions. 462 for j in range(n): 463 # Fixed parameter. 464 if grid[j] == None: 465 # Get the current parameter value. 466 pts[i, j] = getattr(cdp, cdp.params[j]) / scaling_matrix[j, j] 467 468 # Add the point coordinate. 469 else: 470 pts[i, j] = grid[j][indices[j]] / scaling_matrix[j, j] 471 472 # Increment the step positions. 473 for j in range(n): 474 if incs[j] != None and indices[j] < incs[j]-1: 475 indices[j] += 1 476 break # Exit so that the other step numbers are not incremented. 477 else: 478 indices[j] = 0 479 480 # Minimisation. 481 self.minimise(min_algor='grid', min_options=pts, constraints=constraints, verbosity=verbosity, sim_index=sim_index)
482 483
484 - def map_bounds(self, param, spin_id=None):
485 """Create bounds for the OpenDX mapping function. 486 487 @param param: The name of the parameter to return the lower and upper bounds of. 488 @type param: str 489 @param spin_id: The spin identification string (unused). 490 @type spin_id: None 491 @return: The upper and lower bounds of the parameter. 492 @rtype: list of float 493 """ 494 495 # Average domain position. 496 if param in ['ave_pos_x', 'ave_pos_y', 'ave_pos_z']: 497 return [-100.0, 100] 498 if param in ['ave_pos_alpha', 'ave_pos_beta', 'ave_pos_gamma']: 499 return [0.0, 2*pi] 500 501 # Axis spherical coordinate theta. 502 if param == 'axis_theta': 503 return [0.0, pi] 504 505 # Axis spherical coordinate phi. 506 if param == 'axis_phi': 507 return [0.0, 2*pi] 508 509 # Axis alpha angle. 510 if param == 'axis_alpha': 511 return [0.0, 2*pi] 512 513 # Cone angle. 514 if param == 'cone_theta': 515 return [0.0, pi]
516 517
518 - def minimise(self, min_algor=None, min_options=None, func_tol=None, grad_tol=None, max_iterations=None, constraints=False, scaling=True, verbosity=0, sim_index=None, lower=None, upper=None, inc=None):
519 """Minimisation function. 520 521 @param min_algor: The minimisation algorithm to use. 522 @type min_algor: str 523 @param min_options: An array of options to be used by the minimisation algorithm. 524 @type min_options: array of str 525 @param func_tol: The function tolerance which, when reached, terminates optimisation. Setting this to None turns of the check. 526 @type func_tol: None or float 527 @param grad_tol: The gradient tolerance which, when reached, terminates optimisation. Setting this to None turns of the check. 528 @type grad_tol: None or float 529 @param max_iterations: The maximum number of iterations for the algorithm. 530 @type max_iterations: int 531 @param constraints: If True, constraints are used during optimisation. 532 @type constraints: bool 533 @param scaling: If True, diagonal scaling is enabled during optimisation to allow the problem to be better conditioned. 534 @type scaling: bool 535 @param verbosity: A flag specifying the amount of information to print. The higher the value, the greater the verbosity. 536 @type verbosity: int 537 @param sim_index: The index of the simulation to optimise. This should be None if normal optimisation is desired. 538 @type sim_index: None or int 539 @keyword lower: The lower bounds of the grid search which must be equal to the number of parameters in the model. This optional argument is only used when doing a grid search. 540 @type lower: array of numbers 541 @keyword upper: The upper bounds of the grid search which must be equal to the number of parameters in the model. This optional argument is only used when doing a grid search. 542 @type upper: array of numbers 543 @keyword 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. This argument is only used when doing a grid search. 544 @type inc: array of int 545 """ 546 547 # Set up the target function for direct calculation. 548 model, param_vector, scaling_matrix = target_fn_setup(sim_index=sim_index, verbosity=verbosity, scaling=scaling) 549 550 # Linear constraints. 551 A, b = None, None 552 if constraints: 553 A, b = linear_constraints(scaling_matrix=scaling_matrix) 554 555 # Grid search. 556 if search('^[Gg]rid', min_algor): 557 results = grid_point_array(func=model.func, args=(), points=min_options, verbosity=verbosity) 558 559 # Minimisation. 560 else: 561 results = generic_minimise(func=model.func, args=(), x0=param_vector, min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, maxiter=max_iterations, A=A, b=b, full_output=True, print_flag=verbosity) 562 563 # Unpack the results. 564 unpack_opt_results(results, scaling, scaling_matrix, sim_index) 565 566 # Store the back-calculated data. 567 store_bc_data(model)
568 569
570 - def model_desc(self, model_info):
571 """Return a description of the model. 572 573 @param model_info: The model index from model_loop(). 574 @type model_info: int 575 @return: The model description. 576 @rtype: str 577 """ 578 579 return ""
580 581
582 - def model_statistics(self, model_info=None, spin_id=None, global_stats=None):
583 """Return the k, n, and chi2 model statistics. 584 585 k - number of parameters. 586 n - number of data points. 587 chi2 - the chi-squared value. 588 589 590 @keyword model_info: Unused. 591 @type model_info: None 592 @keyword spin_id: Unused. 593 @type spin_id: None 594 @keyword global_stats: Unused. 595 @type global_stats: None 596 @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). 597 @rtype: tuple of (int, int, float) 598 """ 599 600 # Count the number of parameters. 601 k = len(cdp.params) 602 603 # The number of data points (RDCs + PCSs). 604 n = 0 605 for data in self.base_data_loop(): 606 n += 1 607 608 # Check for the chi2 value. 609 if not hasattr(cdp, 'chi2'): 610 raise RelaxError("Statistics are not available, most likely because the model has not been optimised.") 611 612 # Return the data. 613 return k, n, cdp.chi2
614 615
616 - def return_error(self, data_id):
617 """Return the RDC or PCS error structure. 618 619 @param data_id: The data set as yielded by the base_data_loop() generator method. 620 @type data_id: list of str 621 @return: The array of RDC or PCS error values. 622 @rtype: list of float 623 """ 624 625 # Initialise the MC data structure. 626 mc_errors = [] 627 628 # The RDC data. 629 if data_id[0] == 'rdc': 630 # Unpack the set. 631 data_type, spin_id1, spin_id2, align_id = data_id 632 633 # Get the interatomic data container. 634 interatom = return_interatom(spin_id1, spin_id2) 635 636 # Do errors exist? 637 if not hasattr(interatom, 'rdc_err'): 638 raise RelaxError("The RDC errors are missing for interatomic data container between spins '%s' and '%s'." % (spin_id1, spin_id2)) 639 640 # Handle missing data. 641 if align_id not in interatom.rdc_err: 642 mc_errors.append(None) 643 644 # Append the data. 645 else: 646 mc_errors.append(interatom.rdc_err[align_id]) 647 648 # The PCS data. 649 elif data_id[0] == 'pcs': 650 # Unpack the set. 651 data_type, spin_id, align_id = data_id 652 653 # Get the spin container. 654 spin = return_spin(spin_id) 655 656 # Do errors exist? 657 if not hasattr(spin, 'pcs_err'): 658 raise RelaxError("The PCS errors are missing for spin '%s'." % spin_id) 659 660 # Handle missing data. 661 if align_id not in spin.pcs_err: 662 mc_errors.append(None) 663 664 # Append the data. 665 else: 666 mc_errors.append(spin.pcs_err[align_id]) 667 668 # Return the errors. 669 return mc_errors
670 671
672 - def set_error(self, model_info, index, error):
673 """Set the parameter errors. 674 675 @param model_info: The model information originating from model_loop() (unused). 676 @type model_info: None 677 @param index: The index of the parameter to set the errors for. 678 @type index: int 679 @param error: The error value. 680 @type error: float 681 """ 682 683 # Parameter increment counter. 684 inc = 0 685 686 # Loop over the residue specific parameters. 687 for param in self.data_names(set='params'): 688 # Not a parameter of the model. 689 if param not in cdp.params: 690 continue 691 692 # Return the parameter array. 693 if index == inc: 694 setattr(cdp, param + "_err", error) 695 696 # Increment. 697 inc = inc + 1 698 699 # Add some additional parameters. 700 if cdp.model == 'iso cone, free rotor' and inc == index: 701 setattr(cdp, 'cone_theta_err', error)
702 703 704
705 - def set_selected_sim(self, model_info, select_sim):
706 """Set the simulation selection flag for the spin. 707 708 @param model_info: The model information originating from model_loop() (unused). 709 @type model_info: None 710 @param select_sim: The selection flag for the simulations. 711 @type select_sim: bool 712 """ 713 714 # Set the array. 715 cdp.select_sim = deepcopy(select_sim)
716 717
718 - def sim_init_values(self):
719 """Initialise the Monte Carlo parameter values.""" 720 721 # Get the parameter object names. 722 param_names = self.data_names(set='params') 723 724 # The model parameters. 725 model_params = deepcopy(cdp.params) 726 727 # Add some additional parameters. 728 if cdp.model == 'iso cone, free rotor': 729 param_names.append('cone_theta') 730 model_params.append('cone_theta') 731 732 # Get the minimisation statistic object names. 733 min_names = self.data_names(set='min') 734 735 736 # Test if Monte Carlo parameter values have already been set. 737 ############################################################# 738 739 # Loop over all the parameter names. 740 for object_name in param_names: 741 # Not a parameter of the model. 742 if object_name not in model_params: 743 continue 744 745 # Name for the simulation object. 746 sim_object_name = object_name + '_sim' 747 748 # Test if the simulation object already exists. 749 if hasattr(cdp, sim_object_name): 750 raise RelaxError("Monte Carlo parameter values have already been set.") 751 752 753 # Set the Monte Carlo parameter values. 754 ####################################### 755 756 # Loop over all the data names. 757 for object_name in param_names: 758 # Not a parameter of the model. 759 if object_name not in model_params: 760 continue 761 762 # Name for the simulation object. 763 sim_object_name = object_name + '_sim' 764 765 # Create the simulation object. 766 setattr(cdp, sim_object_name, []) 767 768 # Get the simulation object. 769 sim_object = getattr(cdp, sim_object_name) 770 771 # Loop over the simulations. 772 for j in range(cdp.sim_number): 773 # Copy and append the data. 774 sim_object.append(deepcopy(getattr(cdp, object_name))) 775 776 # Loop over all the minimisation object names. 777 for object_name in min_names: 778 # Name for the simulation object. 779 sim_object_name = object_name + '_sim' 780 781 # Create the simulation object. 782 setattr(cdp, sim_object_name, []) 783 784 # Get the simulation object. 785 sim_object = getattr(cdp, sim_object_name) 786 787 # Loop over the simulations. 788 for j in range(cdp.sim_number): 789 # Copy and append the data. 790 sim_object.append(deepcopy(getattr(cdp, object_name)))
791 792
793 - def sim_pack_data(self, data_id, sim_data):
794 """Pack the Monte Carlo simulation data. 795 796 @param data_id: The data set as yielded by the base_data_loop() generator method. 797 @type data_id: list of str 798 @param sim_data: The Monte Carlo simulation data. 799 @type sim_data: list of float 800 """ 801 802 # The RDC data. 803 if data_id[0] == 'rdc': 804 # Unpack the set. 805 data_type, spin_id1, spin_id2, align_id = data_id 806 807 # Get the interatomic data container. 808 interatom = return_interatom(spin_id1, spin_id2) 809 810 # Initialise. 811 if not hasattr(interatom, 'rdc_sim'): 812 interatom.rdc_sim = {} 813 814 # Store the data structure. 815 interatom.rdc_sim[align_id] = [] 816 for i in range(cdp.sim_number): 817 interatom.rdc_sim[align_id].append(sim_data[i][0]) 818 819 # The PCS data. 820 elif data_id[0] == 'pcs': 821 # Unpack the set. 822 data_type, spin_id, align_id = data_id 823 824 # Get the spin container. 825 spin = return_spin(spin_id) 826 827 # Initialise. 828 if not hasattr(spin, 'pcs_sim'): 829 spin.pcs_sim = {} 830 831 # Store the data structure. 832 spin.pcs_sim[data_id[2]] = [] 833 for i in range(cdp.sim_number): 834 spin.pcs_sim[data_id[2]].append(sim_data[i][0])
835 836
837 - def sim_return_param(self, model_info, index):
838 """Return the array of simulation parameter values. 839 840 @param model_info: The model information originating from model_loop(). 841 @type model_info: unknown 842 @param index: The index of the parameter to return the array of values for. 843 @type index: int 844 """ 845 846 # Parameter increment counter. 847 inc = 0 848 849 # Get the parameter object names. 850 param_names = self.data_names(set='params') 851 852 # Loop over the parameters. 853 for param in param_names: 854 # Not a parameter of the model. 855 if param not in cdp.params: 856 continue 857 858 # Return the parameter array. 859 if index == inc: 860 return getattr(cdp, param + "_sim") 861 862 # Increment. 863 inc = inc + 1 864 865 # Add some additional parameters. 866 if cdp.model == 'iso cone, free rotor' and inc == index: 867 return getattr(cdp, 'cone_theta_sim')
868 869
870 - def sim_return_selected(self, model_info):
871 """Return the array of selected simulation flags for the spin. 872 873 @param model_info: The model information originating from model_loop() (unused). 874 @type model_info: None 875 @return: The array of selected simulation flags. 876 @rtype: list of int 877 """ 878 879 # Return the array. 880 return cdp.select_sim
881