Package auto_analyses :: Module frame_order
[hide private]
[frames] | no frames]

Source Code for Module auto_analyses.frame_order

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2011-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 full frame order analysis.""" 
 24   
 25   
 26  # Python module imports. 
 27  from numpy import float64, zeros 
 28  from os import F_OK, access, getcwd, sep 
 29  import sys 
 30   
 31  # relax module imports. 
 32  from data_store import Relax_data_store; ds = Relax_data_store() 
 33  from pipe_control.pipes import get_pipe 
 34  from lib.text.sectioning import section, subsection, title 
 35  from lib.geometry.coord_transform import spherical_to_cartesian 
 36  from prompt.interpreter import Interpreter 
 37  from lib.errors import RelaxError 
 38  from lib.io import open_write_file 
 39  from status import Status; status = Status() 
 40   
 41   
42 -class Frame_order_analysis:
43 """The frame order auto-analysis protocol.""" 44
45 - def __init__(self, data_pipe_full=None, data_pipe_subset=None, pipe_bundle=None, results_dir=None, grid_inc=11, grid_inc_rigid=21, min_algor='simplex', num_int_pts_grid=50, num_int_pts_subset=[20, 100], func_tol_subset=[1e-2, 1e-2], num_int_pts_full=[100, 1000, 200000], func_tol_full=[1e-2, 1e-3, 1e-4], mc_sim_num=500, mc_int_pts=1000, mc_func_tol=1e-3, models=['rigid', 'free rotor', 'rotor', 'iso cone, free rotor', 'iso cone, torsionless', 'iso cone', 'pseudo-ellipse, torsionless', 'pseudo-ellipse']):
46 """Perform the full frame order analysis. 47 48 @param data_pipe_full: The name of the data pipe containing all of the RDC and PCS data. 49 @type data_pipe_full: str 50 @param data_pipe_subset: The name of the data pipe containing all of the RDC data but only a small subset of ~5 PCS points. 51 @type data_pipe_subset: str 52 @keyword pipe_bundle: The data pipe bundle to associate all spawned data pipes with. 53 @type pipe_bundle: str 54 @keyword results_dir: The directory where files are saved in. 55 @type results_dir: str 56 @keyword grid_inc: The number of grid increments to use in the grid search of certain models. 57 @type grid_inc: int 58 @keyword grid_inc_rigid: The number of grid increments to use in the grid search of the initial rigid model. 59 @type grid_inc_rigid: int 60 @keyword min_algor: The minimisation algorithm (in most cases this should not be changed). 61 @type min_algor: str 62 @keyword num_int_pts_grid: The number of Sobol' points for the PCS numerical integration in the grid searches. 63 @type num_int_pts_grid: int 64 @keyword num_int_pts_subset: The list of the number of Sobol' points for the PCS numerical integration to use iteratively in the optimisations after the grid search (for the PCS data subset). 65 @type num_int_pts_subset: list of int 66 @keyword func_tol_subset: The minimisation function tolerance cutoff to terminate optimisation (for the PCS data subset, see the minimise user function). 67 @type func_tol_subset: list of float 68 @keyword num_int_pts_full: The list of the number of Sobol' points for the PCS numerical integration to use iteratively in the optimisations after the grid search (for all PCS and RDC data). 69 @type num_int_pts_full: list of int 70 @keyword func_tol_full: The minimisation function tolerance cutoff to terminate optimisation (for all PCS and RDC data, see the minimise user function). 71 @type func_tol_full: list of float 72 @keyword mc_sim_num: The number of Monte Carlo simulations to be used for error analysis at the end of the analysis. 73 @type mc_sim_num: int 74 @keyword mc_int_num: The number of Sobol' points for the PCS numerical integration during Monte Carlo simulations. 75 @type mc_int_num: int 76 @keyword mc_func_tol: The minimisation function tolerance cutoff to terminate optimisation during Monte Carlo simulations. 77 @type mc_func_tol: float 78 @keyword models: The frame order models to use in the analysis. The 'rigid' model must be included as this is essential for the analysis. 79 @type models: list of str 80 """ 81 82 # Execution lock. 83 status.exec_lock.acquire(pipe_bundle, mode='auto-analysis') 84 85 # Initial printout. 86 title(file=sys.stdout, text="Frame order auto-analysis", prespace=7) 87 88 # Store the args. 89 self.data_pipe_full = data_pipe_full 90 self.data_pipe_subset = data_pipe_subset 91 self.pipe_bundle = pipe_bundle 92 self.grid_inc = grid_inc 93 self.grid_inc_rigid = grid_inc_rigid 94 self.min_algor = min_algor 95 self.num_int_pts_grid = num_int_pts_grid 96 self.num_int_pts_subset = num_int_pts_subset 97 self.func_tol_subset = func_tol_subset 98 self.num_int_pts_full = num_int_pts_full 99 self.func_tol_full = func_tol_full 100 self.mc_sim_num = mc_sim_num 101 self.mc_int_pts = mc_int_pts 102 self.mc_func_tol = mc_func_tol 103 self.models = models 104 105 # A dictionary and list of the data pipe names. 106 self.pipe_name_dict = {} 107 self.pipe_name_list = [] 108 109 # Project directory (i.e. directory containing the model-free model results and the newly generated files) 110 if results_dir: 111 self.results_dir = results_dir + sep 112 else: 113 self.results_dir = getcwd() + sep 114 115 # Data checks. 116 self.check_vars() 117 118 # Load the interpreter. 119 self.interpreter = Interpreter(show_script=False, raise_relax_error=True) 120 self.interpreter.populate_self() 121 self.interpreter.on(verbose=False) 122 123 # Execute the full protocol. 124 try: 125 # The nested model optimisation protocol. 126 self.nested_models() 127 128 # The final results does not already exist. 129 if not self.read_results(model='final', pipe_name='final'): 130 # Model selection. 131 self.interpreter.model_selection(method='AIC', modsel_pipe='final', pipes=self.pipe_name_list) 132 133 # The number of integration points. 134 self.interpreter.frame_order.num_int_pts(num=self.mc_int_pts) 135 136 # Monte Carlo simulations. 137 self.interpreter.monte_carlo.setup(number=self.mc_sim_num) 138 self.interpreter.monte_carlo.create_data() 139 self.interpreter.monte_carlo.initial_values() 140 self.interpreter.minimise(self.min_algor, func_tol=self.mc_func_tol, constraints=False) 141 self.interpreter.eliminate() 142 self.interpreter.monte_carlo.error_analysis() 143 144 # Finish. 145 self.interpreter.results.write(file='results', dir=self.results_dir+'final', force=True) 146 147 # Visualisation of the final results. 148 self.visualisation(model='final') 149 150 # Clean up. 151 finally: 152 # Finish and unlock execution. 153 status.exec_lock.release() 154 155 # Save the final program state. 156 self.interpreter.state.save('final_state', dir=self.results_dir, force=True)
157 158
159 - def check_vars(self):
160 """Check that the user has set the variables correctly.""" 161 162 # The pipe bundle. 163 if not isinstance(self.pipe_bundle, str): 164 raise RelaxError("The pipe bundle name '%s' is invalid." % self.pipe_bundle) 165 166 # Minimisation variables. 167 if not isinstance(self.grid_inc, int): 168 raise RelaxError("The grid_inc user variable '%s' is incorrectly set. It should be an integer." % self.grid_inc) 169 if not isinstance(self.grid_inc_rigid, int): 170 raise RelaxError("The grid_inc_rigid user variable '%s' is incorrectly set. It should be an integer." % self.grid_inc) 171 if not isinstance(self.min_algor, str): 172 raise RelaxError("The min_algor user variable '%s' is incorrectly set. It should be a string." % self.min_algor) 173 if not isinstance(self.num_int_pts_grid, int): 174 raise RelaxError("The num_int_pts_grid user variable '%s' is incorrectly set. It should be an integer." % self.mc_sim_num) 175 if not isinstance(self.mc_sim_num, int): 176 raise RelaxError("The mc_sim_num user variable '%s' is incorrectly set. It should be an integer." % self.mc_sim_num) 177 if not isinstance(self.mc_int_pts, int): 178 raise RelaxError("The mc_int_pts user variable '%s' is incorrectly set. It should be an integer." % self.mc_int_pts) 179 if not isinstance(self.mc_func_tol, float): 180 raise RelaxError("The mc_func_tol user variable '%s' is incorrectly set. It should be a floating point number." % self.mc_func_tol) 181 182 # Zooming minimisation (PCS subset). 183 if len(self.num_int_pts_subset) != len(self.func_tol_subset): 184 raise RelaxError("The num_int_pts_subset and func_tol_subset user variables of '%s' and '%s' respectively must be of the same length." % (self.num_int_pts_subset, self.func_tol_subset)) 185 for i in range(len(self.num_int_pts_subset)): 186 if not isinstance(self.num_int_pts_subset[i], int): 187 raise RelaxError("The num_int_pts_subset user variable '%s' must be a list of integers." % self.num_int_pts_subset) 188 if not isinstance(self.func_tol_subset[i], float): 189 raise RelaxError("The func_tol_subset user variable '%s' must be a list of floats." % self.func_tol_subset) 190 191 # Zooming minimisation (all RDC and PCS data). 192 if len(self.num_int_pts_full) != len(self.func_tol_full): 193 raise RelaxError("The num_int_pts_full and func_tol_full user variables of '%s' and '%s' respectively must be of the same length." % (self.num_int_pts_full, self.func_tol_full)) 194 for i in range(len(self.num_int_pts_full)): 195 if not isinstance(self.num_int_pts_full[i], int): 196 raise RelaxError("The num_int_pts_full user variable '%s' must be a list of integers." % self.num_int_pts_full) 197 if not isinstance(self.func_tol_full[i], float): 198 raise RelaxError("The func_tol_full user variable '%s' must be a list of floats." % self.func_tol_full)
199 200
201 - def custom_grid_incs(self, model):
202 """Set up a customised grid search increment number for each model. 203 204 @param model: The frame order model. 205 @type model: str 206 @return: The list of increment values. 207 @rtype: list of int and None 208 """ 209 210 # Initialise the structure. 211 incs = [] 212 if hasattr(cdp, 'pivot_fixed') and not cdp.pivot_fixed: 213 incs += [None, None, None] 214 if hasattr(cdp, 'ave_pos_translation') and cdp.ave_pos_translation: 215 incs += [None, None, None] 216 217 # The rotor model. 218 if model == 'rotor': 219 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc] 220 221 # The free rotor model. 222 if model == 'free rotor': 223 incs += [self.grid_inc, self.grid_inc, self.grid_inc, self.grid_inc] 224 225 # The torsionless isotropic cone model. 226 if model == 'iso cone, torsionless': 227 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc] 228 229 # The free rotor isotropic cone model. 230 if model == 'iso cone, free rotor': 231 incs += [None, None, None, None, self.grid_inc] 232 233 # The isotropic cone model. 234 if model == 'iso cone': 235 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc, None] 236 237 # The torsionless pseudo-elliptic cone model. 238 if model == 'pseudo-ellipse, torsionless': 239 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc, self.grid_inc, None] 240 241 # The free rotor pseudo-elliptic cone model. 242 if model == 'pseudo-ellipse, free rotor': 243 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc, self.grid_inc, None] 244 245 # The pseudo-elliptic cone model. 246 if model == 'pseudo-ellipse': 247 incs += [None, None, None, self.grid_inc, self.grid_inc, self.grid_inc, self.grid_inc, None, None] 248 249 # Return the increment list. 250 return incs
251 252
253 - def nested_params(self, model):
254 """Copy the parameters from the simpler nested models for faster optimisation. 255 256 @param model: The frame order model. 257 @type model: str 258 """ 259 260 # The average position from the rigid model. 261 if model not in []: 262 # Get the rigid data pipe. 263 rigid_pipe = get_pipe(self.pipe_name_dict['rigid']) 264 265 # Copy the average position parameters from the rigid model. 266 if hasattr(rigid_pipe, 'ave_pos_x'): 267 cdp.ave_pos_x = rigid_pipe.ave_pos_x 268 if hasattr(rigid_pipe, 'ave_pos_y'): 269 cdp.ave_pos_y = rigid_pipe.ave_pos_y 270 if hasattr(rigid_pipe, 'ave_pos_z'): 271 cdp.ave_pos_z = rigid_pipe.ave_pos_z 272 if model not in ['free rotor', 'iso cone, free rotor']: 273 cdp.ave_pos_alpha = rigid_pipe.ave_pos_alpha 274 cdp.ave_pos_beta = rigid_pipe.ave_pos_beta 275 cdp.ave_pos_gamma = rigid_pipe.ave_pos_gamma 276 277 # The cone axis from the rotor model. 278 if model in ['iso cone']: 279 # Get the rotor data pipe. 280 rotor_pipe = get_pipe(self.pipe_name_dict['rotor']) 281 282 # Copy the cone axis. 283 cdp.axis_theta = rotor_pipe.axis_theta 284 cdp.axis_phi = rotor_pipe.axis_phi 285 286 # The cone axis from the free rotor model. 287 if model in ['iso cone, free rotor']: 288 # Get the rotor data pipe. 289 free_rotor_pipe = get_pipe(self.pipe_name_dict['free rotor']) 290 291 # Copy the cone axis. 292 cdp.axis_theta = free_rotor_pipe.axis_theta 293 cdp.axis_phi = free_rotor_pipe.axis_phi 294 295 # The torsion from the rotor model. 296 if model in ['iso cone', 'pseudo-ellipse']: 297 # Get the rotor data pipe. 298 rotor_pipe = get_pipe(self.pipe_name_dict['rotor']) 299 300 # Copy the cone axis. 301 cdp.cone_sigma_max = rotor_pipe.cone_sigma_max 302 303 # The cone angles from from the torsionless isotropic cone model. 304 if model in ['pseudo-ellipse, torsionless', 'pseudo-ellipse, free rotor', 'pseudo-ellipse']: 305 # Get the rotor data pipe. 306 pipe = get_pipe(self.pipe_name_dict['iso cone, torsionless']) 307 308 # Copy the cone axis. 309 cdp.cone_theta_x = pipe.cone_theta 310 cdp.cone_theta_y = pipe.cone_theta
311 312
313 - def nested_models(self):
314 """Protocol for the nested optimisation of the frame order models.""" 315 316 # First optimise the rigid model using all data. 317 self.optimise_rigid() 318 319 # Iteratively optimise the frame order models. 320 for model in self.models: 321 # Skip the already optimised rigid model. 322 if model == 'rigid': 323 continue 324 325 # The model title. 326 title = model[0].upper() + model[1:] 327 328 # Printout. 329 section(file=sys.stdout, text="%s frame order model"%title, prespace=5) 330 331 # The data pipe name. 332 self.pipe_name_dict[model] = '%s - %s' % (title, self.pipe_bundle) 333 self.pipe_name_list.append(self.pipe_name_dict[model]) 334 335 # The results file already exists, so read its contents instead. 336 if self.read_results(model=model, pipe_name=self.pipe_name_dict[model]): 337 # Re-perform model elimination just in case. 338 self.interpreter.eliminate() 339 340 # The PDB representation of the model and visualisation script (in case this was not completed correctly). 341 self.visualisation(model=model) 342 343 # Skip to the next model. 344 continue 345 346 # Create the data pipe using the full data set, and switch to it. 347 self.interpreter.pipe.copy(self.data_pipe_subset, self.pipe_name_dict[model], bundle_to=self.pipe_bundle) 348 self.interpreter.pipe.switch(self.pipe_name_dict[model]) 349 350 # Select the Frame Order model. 351 self.interpreter.frame_order.select_model(model=model) 352 353 # Copy nested parameters. 354 self.nested_params(model) 355 356 # The optimisation settings. 357 self.interpreter.frame_order.num_int_pts(num=self.num_int_pts_grid) 358 self.interpreter.frame_order.quad_int(flag=False) 359 360 # Grid search. 361 incs = self.custom_grid_incs(model) 362 self.interpreter.grid_search(inc=incs, constraints=False) 363 364 # Minimise (for the PCS data subset and full RDC set). 365 for i in range(len(self.num_int_pts_subset)): 366 self.interpreter.frame_order.num_int_pts(num=self.num_int_pts_subset[i]) 367 self.interpreter.minimise(self.min_algor, func_tol=self.func_tol_subset[i], constraints=False) 368 369 # Copy the PCS data. 370 self.interpreter.pcs.copy(pipe_from=self.data_pipe_full, pipe_to=self.pipe_name_dict[model]) 371 372 # Minimise (for the full data set). 373 for i in range(len(self.num_int_pts_full)): 374 self.interpreter.frame_order.num_int_pts(num=self.num_int_pts_full[i]) 375 self.interpreter.minimise(self.min_algor, func_tol=self.func_tol_full[i], constraints=False) 376 377 # Results printout. 378 self.print_results() 379 380 # Model elimination. 381 self.interpreter.eliminate() 382 383 # Save the results. 384 self.interpreter.results.write(dir=self.results_dir+model, force=True) 385 386 # The PDB representation of the model and visualisation script. 387 self.visualisation(model=model)
388 389
390 - def optimise_rigid(self):
391 """Optimise the rigid frame order model. 392 393 The Sobol' integration is not used here, so the algorithm is different to the other frame order models. 394 """ 395 396 # The model. 397 model = 'rigid' 398 title = model[0].upper() + model[1:] 399 400 # Print out. 401 section(file=sys.stdout, text="%s frame order model"%title, prespace=5) 402 403 # The data pipe name. 404 self.pipe_name_dict[model] = '%s - %s' % (title, self.pipe_bundle) 405 self.pipe_name_list.append(self.pipe_name_dict[model]) 406 407 # The results file already exists, so read its contents instead. 408 if self.read_results(model=model, pipe_name=self.pipe_name_dict[model]): 409 # The PDB representation of the model (in case this was not completed correctly). 410 self.interpreter.frame_order.pdb_model(dir=self.results_dir+model, force=True) 411 412 # Nothing more to do. 413 return 414 415 # Create the data pipe using the full data set, and switch to it. 416 self.interpreter.pipe.copy(self.data_pipe_full, self.pipe_name_dict[model], bundle_to=self.pipe_bundle) 417 self.interpreter.pipe.switch(self.pipe_name_dict[model]) 418 419 # Select the Frame Order model. 420 self.interpreter.frame_order.select_model(model=model) 421 422 # Split grid search if translation is active. 423 if cdp.ave_pos_translation: 424 # Printout. 425 print("\n\nTranslation active - splitting the grid search and iterating.") 426 427 # Loop twice. 428 for i in range(2): 429 # First optimise the rotation. 430 self.interpreter.grid_search(inc=[None, None, None, self.grid_inc_rigid, self.grid_inc_rigid, self.grid_inc_rigid], constraints=False) 431 432 # Then the translation. 433 self.interpreter.grid_search(inc=[self.grid_inc_rigid, self.grid_inc_rigid, self.grid_inc_rigid, None, None, None], constraints=False) 434 435 # Standard grid search. 436 else: 437 self.interpreter.grid_search(inc=self.grid_inc_rigid, constraints=False) 438 439 # Minimise. 440 self.interpreter.minimise(self.min_algor, constraints=False) 441 442 # Results printout. 443 self.print_results() 444 445 # Save the results. 446 self.interpreter.results.write(dir=self.results_dir+model, force=True) 447 448 # The PDB representation of the model. 449 self.interpreter.frame_order.pdb_model(dir=self.results_dir+model, force=True)
450 451
452 - def print_results(self):
453 """Print out the optimisation results for the current data pipe.""" 454 455 # Header. 456 sys.stdout.write("\nFinal optimisation results:\n") 457 458 # Formatting string. 459 format_float = " %-20s %20.15f\n" 460 format_vect = " %-20s %20s\n" 461 462 # Average position. 463 if hasattr(cdp, 'ave_pos_x') or hasattr(cdp, 'ave_pos_alpha') or hasattr(cdp, 'ave_pos_beta') or hasattr(cdp, 'ave_pos_gamma'): 464 sys.stdout.write("\nAverage moving domain position:\n") 465 if hasattr(cdp, 'ave_pos_x'): 466 sys.stdout.write(format_float % ('x:', cdp.ave_pos_x)) 467 if hasattr(cdp, 'ave_pos_y'): 468 sys.stdout.write(format_float % ('y:', cdp.ave_pos_y)) 469 if hasattr(cdp, 'ave_pos_z'): 470 sys.stdout.write(format_float % ('z:', cdp.ave_pos_z)) 471 if hasattr(cdp, 'ave_pos_alpha'): 472 sys.stdout.write(format_float % ('alpha:', cdp.ave_pos_alpha)) 473 if hasattr(cdp, 'ave_pos_beta'): 474 sys.stdout.write(format_float % ('beta:', cdp.ave_pos_beta)) 475 if hasattr(cdp, 'ave_pos_gamma'): 476 sys.stdout.write(format_float % ('gamma:', cdp.ave_pos_gamma)) 477 478 # Frame order eigenframe. 479 if hasattr(cdp, 'eigen_alpha') or hasattr(cdp, 'eigen_beta') or hasattr(cdp, 'eigen_gamma') or hasattr(cdp, 'axis_theta') or hasattr(cdp, 'axis_phi'): 480 sys.stdout.write("\nFrame order eigenframe:\n") 481 if hasattr(cdp, 'eigen_alpha'): 482 sys.stdout.write(format_float % ('eigen alpha:', cdp.eigen_alpha)) 483 if hasattr(cdp, 'eigen_beta'): 484 sys.stdout.write(format_float % ('eigen beta:', cdp.eigen_beta)) 485 if hasattr(cdp, 'eigen_gamma'): 486 sys.stdout.write(format_float % ('eigen gamma:', cdp.eigen_gamma)) 487 488 # The cone axis. 489 if hasattr(cdp, 'axis_theta'): 490 # The angles. 491 sys.stdout.write(format_float % ('axis theta:', cdp.axis_theta)) 492 sys.stdout.write(format_float % ('axis phi:', cdp.axis_phi)) 493 494 # The axis. 495 axis = zeros(3, float64) 496 spherical_to_cartesian([1.0, cdp.axis_theta, cdp.axis_phi], axis) 497 sys.stdout.write(format_vect % ('axis:', axis)) 498 499 # Frame ordering. 500 if hasattr(cdp, 'cone_theta_x') or hasattr(cdp, 'cone_theta_y') or hasattr(cdp, 'cone_theta') or hasattr(cdp, 'cone_s1') or hasattr(cdp, 'cone_sigma_max'): 501 sys.stdout.write("\nFrame ordering:\n") 502 if hasattr(cdp, 'cone_theta_x'): 503 sys.stdout.write(format_float % ('cone theta_x:', cdp.cone_theta_x)) 504 if hasattr(cdp, 'cone_theta_y'): 505 sys.stdout.write(format_float % ('cone theta_y:', cdp.cone_theta_y)) 506 if hasattr(cdp, 'cone_theta'): 507 sys.stdout.write(format_float % ('cone theta:', cdp.cone_theta)) 508 if hasattr(cdp, 'cone_s1'): 509 sys.stdout.write(format_float % ('cone s1:', cdp.cone_s1)) 510 if hasattr(cdp, 'cone_sigma_max'): 511 sys.stdout.write(format_float % ('sigma_max:', cdp.cone_sigma_max)) 512 513 # Minimisation statistics. 514 if hasattr(cdp, 'chi2'): 515 sys.stdout.write("\nMinimisation statistics:\n") 516 if hasattr(cdp, 'chi2'): 517 sys.stdout.write(format_float % ('chi2:', cdp.chi2)) 518 519 # Final spacing. 520 sys.stdout.write("\n")
521 522
523 - def read_results(self, model=None, pipe_name=None):
524 """Attempt to read old results files. 525 526 @keyword model: The frame order model. 527 @type model: str 528 @keyword pipe_name: The name of the data pipe to use for this model. 529 @type pipe_name: str 530 @return: True if the file exists and has been read, False otherwise. 531 @rtype: bool 532 """ 533 534 # The file name. 535 path = self.results_dir + model + sep + 'results.bz2' 536 537 # The file does not exist. 538 if not access(path, F_OK): 539 return False 540 541 # Create an empty data pipe. 542 self.interpreter.pipe.create(pipe_name=pipe_name, pipe_type='frame order') 543 544 # Read the results file. 545 self.interpreter.results.read(path) 546 547 # Results printout. 548 self.print_results() 549 550 # Success. 551 return True
552 553
554 - def visualisation(self, model=None):
555 """Create visual representations of the frame order results for the given model. 556 557 This includes a PDB representation of the motions (the 'cone.pdb' file located in each model directory) together with a relax script for displaying the average domain positions together with the cone/motion representation in PyMOL (the 'pymol_display.py' file, also created in the model directory). 558 559 @keyword model: The frame order model to visualise. This should match the model of the current data pipe, unless the special value of 'final' is used to indicate the visualisation of the final results. 560 @type model: str 561 """ 562 563 # Sanity check. 564 if model != 'final' and model != cdp.model: 565 raise RelaxError("The model '%s' does not match the model '%s' of the current data pipe." % (model, cdp.model)) 566 567 # The PDB representation of the model. 568 self.interpreter.frame_order.pdb_model(dir=self.results_dir+model, force=True) 569 570 # Create the visualisation script. 571 subsection(file=sys.stdout, text="Creating a PyMOL visualisation script.") 572 script = open_write_file(file_name='pymol_display.py', dir=self.results_dir+model, force=True) 573 574 # Add a comment for the user. 575 script.write("# relax script for displaying the frame order results of this '%s' model in PyMOL.\n\n" % model) 576 577 # The script contents. 578 script.write("# PyMOL visualisation.\n") 579 script.write("pymol.view()\n") 580 script.write("pymol.command('show spheres')\n") 581 script.write("pymol.frame_order(file='frame_order.pdb', dist_file='frame_order_distribution.pdb')\n") 582 583 # Close the file. 584 script.close()
585