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