Package specific_analyses :: Package relax_disp :: Module data
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.relax_disp.data

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2004-2015 Edward d'Auvergne                                   # 
   4  # Copyright (C) 2009 Sebastien Morin                                          # 
   5  # Copyright (C) 2013-2014 Troels E. Linnet                                    # 
   6  #                                                                             # 
   7  # This file is part of the program relax (http://www.nmr-relax.com).          # 
   8  #                                                                             # 
   9  # This program is free software: you can redistribute it and/or modify        # 
  10  # it under the terms of the GNU General Public License as published by        # 
  11  # the Free Software Foundation, either version 3 of the License, or           # 
  12  # (at your option) any later version.                                         # 
  13  #                                                                             # 
  14  # This program is distributed in the hope that it will be useful,             # 
  15  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
  16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
  17  # GNU General Public License for more details.                                # 
  18  #                                                                             # 
  19  # You should have received a copy of the GNU General Public License           # 
  20  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
  21  #                                                                             # 
  22  ############################################################################### 
  23   
  24  # Module docstring. 
  25  """Module for handling relaxation dispersion data within the relax data store. 
  26   
  27  Ordering of data 
  28  ================ 
  29   
  30  The dispersion data model is based on the following concepts, in order of importance: 
  31   
  32      - 'exp', the experiment type, 
  33      - 'spin', the spins of the cluster, 
  34      - 'frq', the spectrometer frequency (if multiple field data is present), 
  35      - 'offset', the spin-lock offsets, 
  36      - 'point', the dispersion point (nu_CPMG value or spin-lock nu1 field strength), 
  37      - 'time', the relaxation time point (if exponential curve data has been collected). 
  38   
  39   
  40  Indices 
  41  ======= 
  42   
  43  The data structures used in this module consist of many different index types which follow the data ordering above.  These are abbreviated as: 
  44   
  45      - Ei or ei:  The index for each experiment type. 
  46      - Si or si:  The index for each spin of the spin cluster. 
  47      - Mi or mi:  The index for each magnetic field strength. 
  48      - Oi or oi:  The index for each spin-lock offset.  In the case of CPMG-type data, this index is always zero. 
  49      - Di or di:  The index for each dispersion point (either the spin-lock field strength or the nu_CPMG frequency). 
  50      - Ti or ti:  The index for each dispersion point (either the spin-lock field strength or the nu_CPMG frequency). 
  51  """ 
  52   
  53  # Python module imports. 
  54  from math import cos, pi, sin, sqrt 
  55  from numpy import array, concatenate, float64, int32, max, ones, unique, zeros 
  56  from os import F_OK, access 
  57  from os.path import expanduser 
  58  from random import gauss 
  59  from re import search 
  60  import sys 
  61  from warnings import warn 
  62   
  63  # relax module imports. 
  64  from lib.dispersion.variables import EXP_TYPE_CPMG_DQ, EXP_TYPE_CPMG_MQ, EXP_TYPE_CPMG_PROTON_MQ, EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_ZQ, EXP_TYPE_DESC_CPMG_DQ, EXP_TYPE_DESC_CPMG_MQ, EXP_TYPE_DESC_CPMG_PROTON_MQ, EXP_TYPE_DESC_CPMG_PROTON_SQ, EXP_TYPE_DESC_CPMG_SQ, EXP_TYPE_DESC_CPMG_ZQ, EXP_TYPE_DESC_R1RHO, EXP_TYPE_LIST, EXP_TYPE_LIST_CPMG, EXP_TYPE_LIST_R1RHO, EXP_TYPE_R1RHO, MODEL_B14, MODEL_B14_FULL, MODEL_DPL94, MODEL_LIST_FIT_R1, MODEL_LIST_MMQ, MODEL_LIST_NUMERIC_CPMG, MODEL_LIST_R1RHO_FULL, MODEL_LIST_R1RHO_ON_RES, MODEL_LIST_R1RHO_OFF_RES, MODEL_MP05, MODEL_NOREX, MODEL_NS_R1RHO_2SITE, MODEL_PARAMS, MODEL_R2EFF, MODEL_TAP03, MODEL_TP02, PARAMS_R20 
  65  from lib.errors import RelaxError, RelaxNoSpectraError, RelaxNoSpinError, RelaxSpinTypeError 
  66  from lib.float import isNaN 
  67  from lib.io import extract_data, get_file_path, open_write_file, strip, write_data 
  68  from lib.nmr import frequency_to_ppm, frequency_to_ppm_from_rad, frequency_to_rad_per_s, rotating_frame_params 
  69  from lib.periodic_table import periodic_table 
  70  from lib.plotting.api import write_xy_data, write_xy_header 
  71  from lib.plotting.grace import script_grace2images 
  72  from lib.sequence import read_spin_data, write_spin_data 
  73  from lib.text.sectioning import section 
  74  from lib.warnings import RelaxWarning, RelaxNoSpinWarning 
  75  from pipe_control import pipes 
  76  from pipe_control.mol_res_spin import check_mol_res_spin_data, exists_mol_res_spin_data, generate_spin_id_unique, generate_spin_string, return_spin, spin_loop 
  77  from pipe_control.pipes import check_pipe 
  78  from pipe_control.result_files import add_result_file 
  79  from pipe_control.selection import desel_spin 
  80  from pipe_control.sequence import return_attached_protons 
  81  from pipe_control.spectrum import add_spectrum_id, error_analysis 
  82  from pipe_control.spectrometer import check_frequency, get_frequency 
  83  from pipe_control import value 
  84  import specific_analyses 
  85  from specific_analyses.relax_disp.checks import check_exp_type, check_interpolate_offset_cpmg_model, check_missing_r1, check_mixed_curve_types 
  86  from stat import S_IRWXU, S_IRGRP, S_IROTH 
  87  from os import chmod, sep 
  88   
  89   
  90  # Module variables. 
  91  R20_KEY_FORMAT = "%s - %.8f MHz" 
  92   
  93  # Plotting variables. 
  94  Y_AXIS_R2_EFF = "r2_eff" 
  95  Y_AXIS_R2_R1RHO = "r2_r1rho" 
  96   
  97  X_AXIS_DISP = "disp" 
  98  X_AXIS_W_EFF = "w_eff" 
  99  X_AXIS_THETA = "theta" 
 100   
 101  INTERPOLATE_DISP = "disp" 
 102  INTERPOLATE_OFFSET = "offset" 
 103   
 104  # Default hardcoded colours (one colour for each magnetic field strength). 
 105  COLOUR_ORDER = [4, 15, 2, 13, 11, 1, 3, 5, 6, 7, 8, 9, 10, 12, 14] * 1000 
 106   
 107   
108 -def average_intensity(spin=None, exp_type=None, frq=None, offset=None, point=None, time=None, sim_index=None, error=False):
109 """Return the average peak intensity for the spectrometer frequency, dispersion point, and relaxation time. 110 111 This is for handling replicate peak intensity data. 112 113 114 @keyword spin: The spin container to average the peak intensities for. 115 @type spin: SpinContainer instance 116 @keyword exp_type: The experiment type. 117 @type exp_type: str 118 @keyword frq: The spectrometer frequency. 119 @type frq: float 120 @keyword offset: The spin-lock or hard pulse offset. 121 @type offset: float 122 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 123 @type point: float 124 @keyword time: The relaxation time period. 125 @type time: float 126 @keyword sim_index: The simulation index. This should be None for the measured intensity values. 127 @type sim_index: None or int 128 @keyword error: A flag which if True will average and return the peak intensity errors. 129 @type error: bool 130 @return: The average peak intensity value. 131 @rtype: float 132 """ 133 134 # The keys. 135 int_keys = find_intensity_keys(exp_type=exp_type, frq=frq, offset=offset, point=point, time=time) 136 137 # Initialise. 138 intensity = 0.0 139 140 # Loop over the replicates. 141 for i in range(len(int_keys)): 142 # Simulation intensity data. 143 if sim_index != None: 144 # Error checking. 145 if not int_keys[i] in spin.peak_intensity_sim: 146 raise RelaxError("The peak intensity simulation data is missing the key '%s'." % int_keys[i]) 147 148 # Sum. 149 intensity += spin.peak_intensity_sim[int_keys[i]][sim_index] 150 151 # Error intensity data. 152 elif error: 153 # Error checking. 154 if not hasattr(spin, 'peak_intensity_err') or not int_keys[i] in spin.peak_intensity_err: 155 raise RelaxError("The peak intensity errors are missing the key '%s'." % int_keys[i]) 156 157 # Sum. 158 intensity += spin.peak_intensity_err[int_keys[i]]**2 159 160 # Normal intensity data. 161 else: 162 # Error checking. 163 if not int_keys[i] in spin.peak_intensity: 164 raise RelaxError("The peak intensity data is missing the key '%s'." % int_keys[i]) 165 166 # Sum. 167 intensity += spin.peak_intensity[int_keys[i]] 168 169 # Average. 170 if error: 171 intensity = sqrt(intensity / len(int_keys)) 172 else: 173 intensity /= len(int_keys) 174 175 # Return the value. 176 return intensity
177 178
179 -def calc_rotating_frame_params(spin=None, spin_id=None, fields=None, verbosity=0):
180 """Calculates and rotating frame parameters, calculated from: 181 - The spectrometer frequency. 182 - The spin-lock or hard pulse offset. 183 - The dispersion point data (the spin-lock field strength in Hz). 184 185 The return will be for each spin, 186 - Rotating frame tilt angle ( theta = arctan(w_1 / Omega) ) [rad] 187 - The average resonance offset in the rotating frame ( Domega = w_{pop_ave} - w_rf ) [rad/s] 188 - Effective field in rotating frame ( w_eff = sqrt( Omega^2 + w_1^2 ) ) [rad/s] 189 190 Calculations are mentioned in the U{manual<http://www.nmr-relax.com/manual/Dispersion_model_summary.html>} 191 192 @keyword spin: The spin system specific data container 193 @type spin: SpinContainer instance 194 @keyword spin_id: The spin ID string. 195 @type spin_id: None or str 196 @keyword fields: The spin-lock field strengths to use instead of the user loaded values - to enable interpolation. The dimensions are {Ei, Mi}. 197 @type fields: rank-2 list of floats 198 @keyword verbosity: A flag specifying to print calculations. 199 @type verbosity: int 200 @return: List with dict() of theta, Domega, w_eff and list of dict() keys. 201 @rtype: List of dict() 202 """ 203 204 # If the spin is not selected, return None 205 if not spin.select: 206 return None, None, None, None 207 208 # If the spin does not have isotope, return None 209 if not hasattr(spin, 'isotope'): 210 return None, None, None, None 211 212 # Get the field count 213 field_count = count_frq() 214 215 # Check the experiment type 216 if not has_r1rho_exp_type(): 217 raise RelaxError("The experiment type is not of R1rho type.") 218 219 # Get the spin_lock_field points 220 if fields == None: 221 spin_lock_nu1 = return_spin_lock_nu1(ref_flag=False) 222 else: 223 spin_lock_nu1 = fields 224 225 # The offset and R1 data. 226 offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=[spin], spin_ids=[spin_id], field_count=field_count, fields=spin_lock_nu1) 227 228 # Loop over the index of spins, then exp_type, frq, offset 229 if verbosity: 230 print("Printing the following") 231 print("exp_type spin_id frq offset{ppm} offsets[ei][si][mi][oi]{rad/s} ei mi oi si di cur_spin.chemical_shift{ppm} chemical_shifts[ei][si][mi]{rad/s} spin_lock_nu1{Hz} tilt_angles[ei][si][mi][oi]{rad} av_res_offset[ei][si][mi][oi]{rad/s}") 232 233 si = 0 234 theta_spin_dic = dict() 235 Domega_spin_dic = dict() 236 w_eff_spin_dic = dict() 237 dic_key_list = [] 238 239 for exp_type, frq, offset, ei, mi, oi in loop_exp_frq_offset(return_indices=True): 240 # Loop over the dispersion points. 241 spin_lock_fields = spin_lock_nu1[ei][mi][oi] 242 for di in range(len(spin_lock_fields)): 243 if verbosity: 244 print("%-8s %-10s %11.1f %8.4f %12.5f %i %i %i %i %i %7.3f %12.5f %12.5f %12.5f %12.5f"%(exp_type, spin_id, frq, offset, offsets[ei][si][mi][oi], ei, mi, oi, si, di, spin.chemical_shift, chemical_shifts[ei][si][mi], spin_lock_fields[di], tilt_angles[ei][si][mi][oi][di], Delta_omega[ei][si][mi][oi][di])) 245 dic_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=spin_lock_fields[di]) 246 dic_key_list.append(dic_key) 247 theta_spin_dic["%s"%(dic_key)] = tilt_angles[ei][si][mi][oi][di] 248 Domega_spin_dic["%s"%(dic_key)] = Delta_omega[ei][si][mi][oi][di] 249 w_eff_spin_dic["%s"%(dic_key)] = w_eff[ei][si][mi][oi][di] 250 251 # Return the dic and list of keys 252 return [theta_spin_dic, Domega_spin_dic, w_eff_spin_dic, dic_key_list]
253 254
255 -def check_intensity_errors(spin_id=None):
256 """Check if intensity errors have already been calculated by the user. 257 258 @keyword spin_id: The spin identification string. 259 @type spin_id: str 260 """ 261 262 # Check if intensity errors have already been calculated by the user. 263 precalc = True 264 for cur_spin, mol_name, resi, resn, cur_spin_id in spin_loop(selection=spin_id, full_info=True, return_id=True, skip_desel=True): 265 # No structure. 266 if not hasattr(cur_spin, 'peak_intensity_err'): 267 precalc = False 268 break 269 270 # Determine if a spectrum ID is missing from the list. 271 for id in cdp.spectrum_ids: 272 if id not in cur_spin.peak_intensity_err: 273 precalc = False 274 break 275 276 # If no error analysis of peak heights exists. 277 if not precalc: 278 # Printout. 279 section(file=sys.stdout, text="Error analysis", prespace=2) 280 281 # Loop over the spectrometer frequencies. 282 for frq in loop_frq(): 283 # Generate a list of spectrum IDs matching the frequency. 284 ids = [] 285 for id in cdp.spectrum_ids: 286 # Check that the spectrometer frequency matches. 287 match_frq = True 288 if frq != None and cdp.spectrometer_frq[id] != frq: 289 match_frq = False 290 291 # Add the ID. 292 if match_frq: 293 ids.append(id) 294 295 # Run the error analysis on the subset. 296 error_analysis(subset=ids)
297 298
299 -def count_exp():
300 """Count the number of experiments present. 301 302 @return: The experiment count 303 @rtype: int 304 """ 305 306 # The normal count variable. 307 return len(cdp.exp_type_list)
308 309
310 -def count_frq():
311 """Count the number of spectrometer frequencies present. 312 313 @return: The spectrometer frequency count 314 @rtype: int 315 """ 316 317 # Handle missing frequency data. 318 if not hasattr(cdp, 'spectrometer_frq'): 319 return 1 320 321 # The normal count variable. 322 return cdp.spectrometer_frq_count
323 324
325 -def count_relax_times(exp_type=None, frq=None, offset=None, point=None, ei=None):
326 """Count the number of relaxation times present. 327 328 @keyword exp_type: The experiment type. 329 @type exp_type: str 330 @keyword frq: The spectrometer frequency in Hz. 331 @type frq: float 332 @keyword offset: The spin-lock or hard pulse offset value in ppm. 333 @type offset: None or float 334 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 335 @type point: float 336 @keyword ei: The experiment type index. 337 @type ei: str 338 @return: The relaxation time count for the given experiment. 339 @rtype: int 340 """ 341 342 # Loop over the times. 343 count = 0 344 for time in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point): 345 # Find a matching experiment ID. 346 found = False 347 for id in cdp.exp_type: 348 # Skip non-matching experiments. 349 if cdp.exp_type[id] != cdp.exp_type_list[ei]: 350 continue 351 352 # Found. 353 found = True 354 break 355 356 # No data. 357 if not found: 358 continue 359 360 # A new time. 361 count += 1 362 363 # Return the count. 364 return count
365 366
367 -def count_spins(spins=None):
368 """Count the number of selected spins in the spin cluster.""" 369 370 # Count the selected spins. 371 spin_num = 0 372 for spin in spins: 373 if spin.select: 374 spin_num += 1 375 376 # Return the count. 377 return spin_num
378 379
380 -def cpmg_setup(spectrum_id=None, cpmg_frq=None, ncyc_even=True):
381 """Set the CPMG frequency associated with a given spectrum. 382 383 @keyword spectrum_id: The spectrum identification string. 384 @type spectrum_id: str 385 @keyword cpmg_frq: The frequency, in Hz, of the CPMG pulse train. 386 @type cpmg_frq: float 387 @keyword ncyc_even: A flag which if True means that the number of CPMG blocks must be even. This is pulse sequence dependant. 388 @type ncyc_even: bool 389 """ 390 391 # Test if the spectrum id exists. 392 if spectrum_id not in cdp.spectrum_ids: 393 raise RelaxNoSpectraError(spectrum_id) 394 395 # Initialise the global data structures if needed. 396 if not hasattr(cdp, 'cpmg_frqs'): 397 cdp.cpmg_frqs = {} 398 if not hasattr(cdp, 'cpmg_frqs_list'): 399 cdp.cpmg_frqs_list = [] 400 if not hasattr(cdp, 'ncyc_even'): 401 cdp.ncyc_even = {} 402 403 # Add the frequency at the correct position, converting to a float if needed. 404 if cpmg_frq == None: 405 cdp.cpmg_frqs[spectrum_id] = cpmg_frq 406 else: 407 cdp.cpmg_frqs[spectrum_id] = float(cpmg_frq) 408 409 # The unique curves for the R2eff fitting (CPMG). 410 if cdp.cpmg_frqs[spectrum_id] not in cdp.cpmg_frqs_list: 411 cdp.cpmg_frqs_list.append(cdp.cpmg_frqs[spectrum_id]) 412 413 # Sort the list (handling None for Python 3). 414 flag = False 415 if None in cdp.cpmg_frqs_list: 416 cdp.cpmg_frqs_list.pop(cdp.cpmg_frqs_list.index(None)) 417 flag = True 418 cdp.cpmg_frqs_list.sort() 419 if flag: 420 cdp.cpmg_frqs_list.insert(0, None) 421 422 # Update the exponential curve count (skipping the reference if present). 423 cdp.dispersion_points = len(cdp.cpmg_frqs_list) 424 if None in cdp.cpmg_frqs_list: 425 cdp.dispersion_points -= 1 426 427 # Add the ncyc flag. 428 cdp.ncyc_even[spectrum_id] = ncyc_even 429 430 # Printout. 431 print("The spectrum ID '%s' CPMG frequency is set to %s Hz." % (spectrum_id, cdp.cpmg_frqs[spectrum_id])) 432 print("The spectrum ID '%s' even number of CPMG blocks flag is set to %s." % (spectrum_id, cdp.ncyc_even[spectrum_id]))
433 434
435 -def decompose_r20_key(key=None):
436 """Decompose the unique R20 key into the experiment type and spectrometer frequency. 437 438 @keyword key: The unique R20 key. 439 @type key: str 440 @return: The experiment and the spectrometer frequency in Hz. 441 @rtype: str, float 442 """ 443 444 # Loop over the experiments and frequencies until the matching key is found. 445 for exp_type, frq in loop_exp_frq(): 446 if key == generate_r20_key(exp_type=exp_type, frq=frq): 447 return exp_type, frq
448 449
450 -def find_intensity_keys(exp_type=None, frq=None, offset=None, point=None, time=None, raise_error=True):
451 """Return the key corresponding to the spectrometer frequency, dispersion point, and relaxation time. 452 453 @keyword exp_type: The experiment type. 454 @type exp_type: str 455 @keyword frq: The spectrometer frequency. 456 @type frq: float 457 @keyword offset: The optional offset value for off-resonance R1rho-type data. 458 @type offset: None or float 459 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 460 @type point: float 461 @keyword time: The relaxation time period. 462 @type time: float 463 @keyword raise_error: A flag which if True will cause a RelaxError to be raised if no keys could be found. 464 @type raise_error: bool 465 @return: The keys corresponding to the spectrometer frequency, dispersion point, and relaxation time. 466 @rtype: list of str 467 """ 468 469 # Check. 470 if exp_type == None: 471 raise RelaxError("The experiment type has not been supplied.") 472 473 # Catch NaNs. 474 if isNaN(point): 475 point = None 476 477 # The dispersion data. 478 if exp_type in EXP_TYPE_LIST_CPMG: 479 disp_data = cdp.cpmg_frqs 480 else: 481 disp_data = cdp.spin_lock_nu1 482 483 # Loop over all spectrum IDs, returning the matching ID. 484 ids = [] 485 for id in cdp.exp_type: 486 # Skip non-matching experiments. 487 if cdp.exp_type[id] != exp_type: 488 continue 489 490 # Skip non-matching spectrometer frequencies. 491 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 492 continue 493 494 # Skip non-matching offsets. 495 if offset != None and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 496 continue 497 498 # Skip non-matching dispersion points. 499 if disp_data[id] != point: 500 continue 501 502 # The reference point, so checking the time is pointless (and can fail as specifying the time should not be necessary). 503 if point == None or isNaN(point): 504 ids.append(id) 505 506 # Matching time. 507 elif time == None: 508 ids.append(id) 509 elif cdp.relax_times[id] == time: 510 ids.append(id) 511 512 # Check for missing IDs. 513 if raise_error and len(ids) == 0: 514 if point == None or isNaN(point): 515 raise RelaxError("No reference intensity data could be found corresponding to the spectrometer frequency of %s MHz and relaxation time of %s s." % (frq*1e-6, time)) 516 else: 517 raise RelaxError("No intensity data could be found corresponding to the spectrometer frequency of %s MHz, dispersion point of %s and relaxation time of %s s." % (frq*1e-6, point, time)) 518 519 # Return the IDs. 520 return ids
521 522
523 -def generate_r20_key(exp_type=None, frq=None):
524 """Generate the unique R20 key from the experiment type and spectrometer frequency. 525 526 @keyword exp_type: The experiment type. 527 @type exp_type: str 528 @keyword frq: The spectrometer frequency in Hz. 529 @type frq: float 530 @return: The unique R20 key. 531 @rtype: str 532 """ 533 534 # Generate and return the unique key. 535 return R20_KEY_FORMAT % (exp_type, frq/1e6)
536 537
538 -def get_curve_type(id=None):
539 """Return the unique curve type. 540 541 @keyword id: The spectrum ID. If not supplied, then all data will be assumed. 542 @type id: str 543 @return: The curve type - either 'fixed time' or 'exponential'. 544 @rtype: str 545 """ 546 547 # All data. 548 if id == None: 549 # Data checks. 550 check_mixed_curve_types() 551 552 # Determine the curve type. 553 curve_type = 'fixed time' 554 if has_exponential_exp_type(): 555 curve_type = 'exponential' 556 557 # A specific ID. 558 else: 559 # Determine the curve type. 560 curve_type = 'exponential' 561 exp_type = cdp.exp_type[id] 562 frq = cdp.spectrometer_frq[id] 563 if count_relax_times(exp_type = exp_type, frq = frq, ei = cdp.exp_type_list.index(cdp.exp_type[id])) == 1: 564 curve_type = 'fixed time' 565 566 # Return the type. 567 return curve_type
568 569
570 -def get_exp_type(id=None):
571 """Return the experiment type for the given ID. 572 573 @keyword id: The spectrum ID. 574 @type id: str 575 @return: The experiment type corresponding to the ID. 576 @rtype: str 577 """ 578 579 # Data check. 580 check_exp_type(id=id) 581 582 # Return the type. 583 return cdp.exp_type[id]
584 585
586 -def has_cpmg_exp_type():
587 """Determine if the current data pipe contains CPMG experiment types. 588 589 @return: True if CPMG experiment types exist, False otherwise. 590 @rtype: bool 591 """ 592 593 # No experiment types set. 594 if not hasattr(cdp, 'exp_type'): 595 return False 596 597 # Loop over all experiment types. 598 for exp_type in cdp.exp_type_list: 599 if exp_type in EXP_TYPE_LIST_CPMG: 600 return True 601 602 # No CPMG experiment types. 603 return False
604 605
606 -def has_disp_data(spins=None, spin_ids=None, exp_type=None, frq=None, offset=None, point=None):
607 """Determine if dispersion data exists for the given data combination. 608 609 @keyword spins: The list of spin containers in the cluster. 610 @type spins: list of SpinContainer instances 611 @keyword spin_ids: The list of spin IDs for the cluster. 612 @type spin_ids: list of str 613 @keyword exp_type: The experiment type. 614 @type exp_type: str 615 @keyword frq: The spectrometer frequency. 616 @type frq: float 617 @keyword offset: For R1rho-type data, the spin-lock offset value in ppm. 618 @type offset: None or float 619 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 620 @type point: float 621 @return: True if dispersion data exists, False otherwise. 622 @rtype: bool 623 """ 624 625 # Skip reference spectra. 626 if point == None: 627 return False 628 629 # The key. 630 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 631 632 # Loop over the spins. 633 for si in range(len(spins)): 634 # Alias the correct spin. 635 current_spin = spins[si] 636 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 637 current_spin = return_attached_protons(spin_ids[si])[0] 638 639 # The data is present. 640 if key in current_spin.r2eff: 641 return True 642 643 # No data. 644 return False
645 646
647 -def has_exponential_exp_type():
648 """Determine if the current data pipe contains exponential curves. 649 650 @return: True if spectral data for exponential curves exist, False otherwise. 651 @rtype: bool 652 """ 653 654 # No experiment types set. 655 if not hasattr(cdp, 'exp_type'): 656 return False 657 658 # Loop over all spectra IDs. 659 for id in cdp.exp_type: 660 if get_curve_type(id) == 'exponential': 661 return True 662 663 # No exponential data. 664 return False
665 666
667 -def has_fixed_time_exp_type():
668 """Determine if the current data pipe contains fixed time data. 669 670 @return: True if spectral data for fixed time data exists, False otherwise. 671 @rtype: bool 672 """ 673 674 # No experiment types set. 675 if not hasattr(cdp, 'exp_type'): 676 return False 677 678 # Loop over all experiment types. 679 for id in cdp.exp_type: 680 if get_curve_type(id) == 'fixed time': 681 return True 682 683 # No exponential data. 684 return False
685 686
687 -def has_proton_mmq_cpmg():
688 """Determine if the current data pipe contains either proton SQ or MQ (MMQ) CPMG data. 689 690 This is only for the MMQ models. 691 692 693 @return: True if either proton SQ or MQ CPMG data exists, False otherwise. 694 @rtype: bool 695 """ 696 697 # 1H MMQ data exists. 698 if has_proton_sq_cpmg(): 699 return True 700 if has_proton_mq_cpmg(): 701 return True 702 703 # No 1H MMQ CPMG data. 704 return False
705 706
707 -def has_proton_mq_cpmg():
708 """Determine if the current data pipe contains proton MQ CPMG data. 709 710 This is only for the MMQ models. 711 712 713 @return: True if proton MQ CPMG data exists, False otherwise. 714 @rtype: bool 715 """ 716 717 # Proton MQ CPMG data is present. 718 if EXP_TYPE_CPMG_PROTON_MQ in cdp.exp_type_list: 719 return True 720 721 # No 1H MQ CPMG data. 722 return False
723 724
725 -def has_proton_sq_cpmg():
726 """Determine if the current data pipe contains proton SQ CPMG data. 727 728 This is only for the MMQ models. 729 730 731 @return: True if proton SQ CPMG data exists, False otherwise. 732 @rtype: bool 733 """ 734 735 # Proton SQ CPMG data is present. 736 if EXP_TYPE_CPMG_PROTON_SQ in cdp.exp_type_list: 737 return True 738 739 # No 1H SQ CPMG data. 740 return False
741 742
743 -def has_r1rho_exp_type():
744 """Determine if the current data pipe contains R1rho experiment types. 745 746 @return: True if R1rho experiment types exist, False otherwise. 747 @rtype: bool 748 """ 749 750 # No experiment types set. 751 if not hasattr(cdp, 'exp_type'): 752 return False 753 754 # Loop over all experiment types. 755 for exp_type in cdp.exp_type_list: 756 if exp_type in EXP_TYPE_LIST_R1RHO: 757 return True 758 759 # No CPMG experiment types. 760 return False
761 762
763 -def insignificance(level=0.0):
764 """Deselect all spins with insignificant dispersion profiles. 765 766 @keyword level: The R2eff/R1rho value in rad/s by which to judge insignificance. If the maximum difference between two points on all dispersion curves for a spin is less than this value, that spin will be deselected. 767 @type level: float 768 """ 769 770 # Nothing to do. 771 if level == 0.0: 772 return 773 774 # Number of spectrometer fields. 775 fields = [None] 776 field_count = 1 777 if hasattr(cdp, 'spectrometer_frq_count'): 778 fields = cdp.spectrometer_frq_list 779 field_count = cdp.spectrometer_frq_count 780 781 # Loop over all spins. 782 for spin, spin_id in spin_loop(return_id=True, skip_desel=True): 783 # Nothing to do (the R2eff model has no dispersion curves). 784 if spin.model == 'R2eff': 785 continue 786 787 # Get all the data. 788 try: 789 values, errors, missing, frqs, frqs_H, exp_types, relax_times = return_r2eff_arrays(spins=[spin], spin_ids=[spin_id], fields=fields, field_count=field_count) 790 791 # No R2eff data, so skip the rest. 792 except RelaxError: 793 continue 794 795 # The flag. 796 desel = True 797 798 # Loop over the experiments, magnetic fields, and offsets. 799 max_diff = 0.0 800 for exp_type, frq, offset, ei, mi, oi in loop_exp_frq_offset(return_indices=True): 801 # No data. 802 if not len(values[ei][0][mi][oi]): 803 continue 804 805 # The difference. 806 diff = values[ei][0][mi][oi].max() - values[ei][0][mi][oi].min() 807 808 # Significance detected. 809 if diff > level: 810 desel = False 811 812 # Store the maximum for the deselection printout. 813 if diff > max_diff: 814 max_diff = diff 815 816 # Deselect the spin. 817 if desel: 818 # Printout. 819 print("Deselecting spin '%s', the maximum dispersion curve difference for all curves is %s rad/s." % (spin_id, max_diff)) 820 821 # Deselection. 822 desel_spin(spin_id)
823 824
825 -def interpolate_disp(spin=None, spin_id=None, si=None, num_points=None, extend_hz=None, relax_times=None):
826 """Interpolate function for 2D Grace plotting function for the dispersion curves. 827 828 @keyword spin: The specific spin data container. 829 @type spin: SpinContainer instance. 830 @keyword spin_id: The spin ID string. 831 @type spin_id: str 832 @keyword si: The index of the given spin in the cluster. 833 @type si: int 834 @keyword num_points: The number of points to generate the interpolated fitted curves with. 835 @type num_points: int 836 @keyword extend_hz: How far to extend the interpolated fitted curves to (in Hz). 837 @type extend_hz: float 838 @keyword relax_times: The experiment specific fixed time period for relaxation (in seconds). The dimensions are {Ei, Mi, Oi, Di, Ti}. 839 @type relax_times: rank-4 list of floats 840 @return: The interpolated_flag, list of back calculated R2eff/R1rho values in rad/s {Ei, Si, Mi, Oi, Di}, list of interpolated frequencies for cpmg_frqs in Hz {Ei, Si, Mi, Oi, Di}, interpolated spin-lock offsets in rad/s {Ei, Si, Mi, Oi}, list of interpolated spin-lock field strength frequencies for spin_lock_nu1_new in Hz {Ei, Si, Mi, Oi, Di}, chemical shifts in rad/s {Ei, Si, Mi}, interpolated rotating frame tilt angles theta {Ei, Si, Mi, Oi, Di}, interpolated average resonance offset in the rotating frame Omega in rad/s {Ei, Si, Mi, Oi, Di} and the interpolated effective field in rotating frame w_eff in rad/s {Ei, Si, Mi, Oi, Di}. 841 @rtype: boolean, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-3 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-2 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays 842 """ 843 # Set the flag. 844 interpolated_flag = True 845 846 # Initialise some structures. 847 cpmg_frqs_new = None 848 spin_lock_nu1_new = None 849 relax_times_new = None 850 851 # Interpolate the CPMG frequencies (numeric models). 852 if spin.model in MODEL_LIST_NUMERIC_CPMG or spin.model in [MODEL_B14, MODEL_B14_FULL]: 853 cpmg_frqs = return_cpmg_frqs(ref_flag=False) 854 if cpmg_frqs != None and len(cpmg_frqs[0][0]): 855 cpmg_frqs_new = [] 856 relax_times_new = [] 857 for ei in range(len(cpmg_frqs)): 858 # Add a new dimension. 859 cpmg_frqs_new.append([]) 860 relax_times_new.append([]) 861 862 # Then loop over the spectrometer frequencies. 863 for mi in range(len(cpmg_frqs[ei])): 864 # Add a new dimension. 865 cpmg_frqs_new[ei].append([]) 866 relax_times_new[ei].append([]) 867 868 # Finally the offsets. 869 for oi in range(len(cpmg_frqs[ei][mi])): 870 # Add a new dimension. 871 cpmg_frqs_new[ei][mi].append([]) 872 relax_times_new[ei][mi].append([]) 873 874 # No data. 875 if not len(cpmg_frqs[ei][mi][oi]): 876 continue 877 878 # There is no way to interpolate the time points correct. 879 # The best suggestion is to concatenate all values at original offset, and then make a unique list. 880 relax_time_temp = array([]) 881 for di_o, times in enumerate(relax_times[ei][mi][oi]): 882 relax_time_temp = concatenate( (relax_time_temp, times) ) 883 884 # Make a unique list. 885 relax_time_temp = unique(relax_time_temp) 886 887 # The minimum frequency unit. 888 min_frq = 1.0 / max(relax_time_temp) 889 max_frq = max(cpmg_frqs[ei][mi][oi]) + round(extend_hz / min_frq) * min_frq 890 num_points = int(round(max_frq / min_frq)) 891 892 # Interpolate (adding the extended amount to the end). 893 for di in range(num_points): 894 point = (di + 1) * min_frq 895 cpmg_frqs_new[ei][mi][oi].append(point) 896 relax_times_new[ei][mi][oi].append(relax_time_temp) 897 898 # Convert to a numpy array. 899 cpmg_frqs_new[ei][mi][oi] = array(cpmg_frqs_new[ei][mi][oi], float64) 900 901 # Interpolate the CPMG frequencies (analytic models). 902 else: 903 cpmg_frqs = return_cpmg_frqs(ref_flag=False) 904 if cpmg_frqs != None and len(cpmg_frqs[0][0]): 905 cpmg_frqs_new = [] 906 relax_times_new = [] 907 for ei in range(len(cpmg_frqs)): 908 # Add a new dimension. 909 cpmg_frqs_new.append([]) 910 relax_times_new.append([]) 911 912 # Then loop over the spectrometer frequencies. 913 for mi in range(len(cpmg_frqs[ei])): 914 # Add a new dimension. 915 cpmg_frqs_new[ei].append([]) 916 relax_times_new[ei].append([]) 917 918 # Finally the offsets. 919 for oi in range(len(cpmg_frqs[ei][mi])): 920 # Add a new dimension. 921 cpmg_frqs_new[ei][mi].append([]) 922 relax_times_new[ei][mi].append([]) 923 924 # No data. 925 if not len(cpmg_frqs[ei][mi][oi]): 926 continue 927 928 # There is no way to interpolate the time points correct. 929 # The best suggestion is to concatenate all values at original offset, and then make a unique list. 930 relax_time_temp = array([]) 931 for di_o, times in enumerate(relax_times[ei][mi][oi]): 932 relax_time_temp = concatenate( (relax_time_temp, times) ) 933 934 # Make a unique list. 935 relax_time_temp = unique(relax_time_temp) 936 937 # Interpolate (adding the extended amount to the end). 938 for di in range(num_points): 939 point = (di + 1) * (max(cpmg_frqs[ei][mi][oi])+extend_hz) / num_points 940 cpmg_frqs_new[ei][mi][oi].append(point) 941 relax_times_new[ei][mi][oi].append(relax_time_temp) 942 943 # Convert to a numpy array. 944 cpmg_frqs_new[ei][mi][oi] = array(cpmg_frqs_new[ei][mi][oi], float64) 945 946 # Interpolate the spin-lock field strengths. 947 spin_lock_nu1 = return_spin_lock_nu1(ref_flag=False) 948 949 if spin_lock_nu1 != None and len(spin_lock_nu1[0][0][0]): 950 spin_lock_nu1_new = [] 951 relax_times_new = [] 952 for ei in range(len(spin_lock_nu1)): 953 # Add a new dimension. 954 spin_lock_nu1_new.append([]) 955 relax_times_new.append([]) 956 957 # Then loop over the spectrometer frequencies. 958 for mi in range(len(spin_lock_nu1[ei])): 959 # Add a new dimension. 960 spin_lock_nu1_new[ei].append([]) 961 relax_times_new[ei].append([]) 962 963 # Finally the offsets. 964 for oi in range(len(spin_lock_nu1[ei][mi])): 965 # Add a new dimension. 966 spin_lock_nu1_new[ei][mi].append([]) 967 relax_times_new[ei][mi].append([]) 968 969 # No data. 970 if not len(spin_lock_nu1[ei][mi][oi]): 971 continue 972 973 # There is no way to interpolate the time points correct. 974 # The best suggestion is to concatenate all values at original offset, and then make a unique list. 975 relax_time_temp = array([]) 976 for di_o, times in enumerate(relax_times[ei][mi][oi]): 977 relax_time_temp = concatenate( (relax_time_temp, times) ) 978 979 # Make a unique list. 980 relax_time_temp = unique(relax_time_temp) 981 982 # Interpolate (adding the extended amount to the end). 983 for di in range(num_points): 984 point = (di + 1) * (max(spin_lock_nu1[ei][mi][oi])+extend_hz) / num_points 985 spin_lock_nu1_new[ei][mi][oi].append(point) 986 relax_times_new[ei][mi][oi].append(relax_time_temp) 987 988 # Convert to a numpy array. 989 spin_lock_nu1_new[ei][mi][oi] = array(spin_lock_nu1_new[ei][mi][oi], float64) 990 991 # Number of spectrometer fields. 992 fields = [None] 993 field_count = 1 994 if hasattr(cdp, 'spectrometer_frq_count'): 995 fields = cdp.spectrometer_frq_list 996 field_count = cdp.spectrometer_frq_count 997 998 # The offset data. 999 if spin.model in MODEL_LIST_R1RHO_FULL and has_r1rho_exp_type(): 1000 offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=[spin], spin_ids=[spin_id], field_count=field_count, fields=spin_lock_nu1_new) 1001 else: 1002 offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=[spin], spin_ids=[spin_id], field_count=field_count, fields=cpmg_frqs_new) 1003 1004 if spin.model == MODEL_R2EFF: 1005 back_calc = None 1006 else: 1007 # Back calculate R2eff data for the second sets of plots. 1008 back_calc = specific_analyses.relax_disp.optimisation.back_calc_r2eff(spins=[spin], spin_ids=[spin_id], cpmg_frqs=cpmg_frqs_new, spin_lock_nu1=spin_lock_nu1_new, relax_times_new=relax_times_new) 1009 1010 return interpolated_flag, back_calc, cpmg_frqs_new, offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff
1011 1012
1013 -def interpolate_offset(spin=None, spin_id=None, si=None, num_points=None, extend_ppm=None, relax_times=None):
1014 """Interpolate function for 2D Grace plotting function for the dispersion curves, interpolating through spin-lock offset in rad/s. 1015 1016 @keyword spin: The specific spin data container. 1017 @type spin: SpinContainer instance. 1018 @keyword spin_id: The spin ID string. 1019 @type spin_id: str 1020 @keyword si: The index of the given spin in the cluster. 1021 @type si: int 1022 @keyword num_points: The number of points to generate the interpolated fitted curves with. 1023 @type num_points: int 1024 @keyword extend_ppm: How far to extend the interpolated fitted curves to in offset ppm. 1025 @type extend_ppm: float 1026 @keyword relax_times: The experiment specific fixed time period for relaxation (in seconds). The dimensions are {Ei, Mi, Oi, Di, Ti}. 1027 @type relax_times: rank-4 list of floats 1028 @return: The interpolated_flag, list of back calculated R2eff/R1rho values in rad/s {Ei, Si, Mi, Oi, Di}, list of interpolated frequencies for cpmg_frqs in Hz {Ei, Si, Mi, Oi, Di}, interpolated spin-lock offsets in rad/s {Ei, Si, Mi, Oi}, list of interpolated spin-lock field strength frequencies for spin_lock_nu1_new in Hz {Ei, Si, Mi, Oi, Di}, chemical shifts in rad/s {Ei, Si, Mi}, interpolated rotating frame tilt angles theta {Ei, Si, Mi, Oi, Di}, interpolated average resonance offset in the rotating frame Omega in rad/s {Ei, Si, Mi, Oi, Di} and the interpolated effective field in rotating frame w_eff in rad/s {Ei, Si, Mi, Oi, Di}. 1029 @rtype: boolean, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-3 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-2 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays 1030 """ 1031 1032 # Set the flag. 1033 interpolated_flag = True 1034 1035 # Initialise some structures. 1036 spin_lock_offset_new = [] 1037 relax_times_new = None 1038 1039 # Get the spin-lock field strengths. 1040 spin_lock_nu1 = return_spin_lock_nu1(ref_flag=False) 1041 1042 # Get the current minimum and maximum spin_lock_offset 1043 if not hasattr(cdp, 'spin_lock_offset'): 1044 min_offset = 0 1045 max_offset = 0 1046 1047 else: 1048 min_offset = min(cdp.spin_lock_offset_list) 1049 max_offset = max(cdp.spin_lock_offset_list) 1050 1051 if spin_lock_nu1 != None and len(spin_lock_nu1[0][0][0]): 1052 for ei in range(len(spin_lock_nu1)): 1053 # Add a new dimension for ei. 1054 spin_lock_offset_new.append([]) 1055 1056 # Add a new dimension for si. 1057 spin_lock_offset_new[ei].append([]) 1058 1059 # Then loop over the spectrometer frequencies. 1060 for mi in range(len(spin_lock_nu1[ei])): 1061 # Add a new dimension for mi. 1062 spin_lock_offset_new[ei][0].append([]) 1063 1064 # Interpolate (adding the extended amount to the end). 1065 for oi in range(num_points+1): 1066 offset_point = oi * (max_offset+extend_ppm) / num_points 1067 spin_lock_offset_new[ei][0][mi].append(offset_point) 1068 1069 # Convert to a numpy array. 1070 spin_lock_offset_new[ei][0][mi] = array(spin_lock_offset_new[ei][0][mi], float64) 1071 1072 # Number of spectrometer fields. 1073 fields = [None] 1074 field_count = 1 1075 if hasattr(cdp, 'spectrometer_frq_count'): 1076 fields = cdp.spectrometer_frq_list 1077 field_count = cdp.spectrometer_frq_count 1078 1079 # The offset data. 1080 offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff = return_offset_data(spins=[spin], spin_ids=[spin_id], field_count=field_count, spin_lock_offset=spin_lock_offset_new, fields=spin_lock_nu1) 1081 1082 # Interpolated relaxation time. 1083 if tilt_angles != None and len(tilt_angles[0][0][0]): 1084 relax_times_new = [] 1085 for ei in range(len(tilt_angles)): 1086 # Add a new dimension. 1087 relax_times_new.append([]) 1088 1089 # Then loop over the spectrometer frequencies. 1090 for mi in range(len(tilt_angles[ei][0])): 1091 # Add a new dimension. 1092 relax_times_new[ei].append([]) 1093 1094 # There is no way to interpolate the time points correct. 1095 # The best suggestion is to concatenate all values at original offset and dispersion point, and then make a unique list. 1096 relax_time_temp = array([]) 1097 for oi_o, relax_times_oi in enumerate(relax_times[ei][mi]): 1098 for di_o, times in enumerate(relax_times_oi): 1099 relax_time_temp = concatenate( (relax_time_temp, times) ) 1100 1101 # Make a unique list. 1102 relax_time_temp = unique(relax_time_temp) 1103 1104 # Finally the offsets. 1105 for oi in range(len(tilt_angles[ei][0][mi])): 1106 # Add a new dimension. 1107 relax_times_new[ei][mi].append([]) 1108 1109 # Interpolate (adding the extended amount to the end). 1110 for di in range(len(tilt_angles[ei][0][mi][oi])): 1111 relax_times_new[ei][mi][oi].append(relax_time_temp) 1112 1113 if spin.model == MODEL_R2EFF: 1114 back_calc = None 1115 else: 1116 # Back calculate R2eff data for the second sets of plots. 1117 back_calc = specific_analyses.relax_disp.optimisation.back_calc_r2eff(spins=[spin], spin_ids=[spin_id], spin_lock_offset=spin_lock_offset_new, spin_lock_nu1=spin_lock_fields_inter, relax_times_new=relax_times_new) 1118 1119 # cpmg_frqs are not interpolated. 1120 cpmg_frqs_new = None 1121 1122 return interpolated_flag, back_calc, cpmg_frqs_new, offsets, spin_lock_fields_inter, chemical_shifts, tilt_angles, Delta_omega, w_eff
1123 1124
1125 -def is_cpmg_exp_type(id=None):
1126 """Determine if the given spectrum ID corresponds to a CPMG experiment type. 1127 1128 @keyword id: The spectrum ID string. 1129 @type id: str 1130 @return: True if the spectrum ID corresponds to a CPMG experiment type, False otherwise. 1131 @rtype: bool 1132 """ 1133 1134 # No experiment type set. 1135 if not hasattr(cdp, 'exp_type') or id not in cdp.exp_type: 1136 return False 1137 1138 # CPMG experiment type. 1139 if cdp.exp_type[id] in EXP_TYPE_LIST_CPMG: 1140 return True 1141 1142 # Not a CPMG experiment type. 1143 return False
1144 1145
1146 -def is_r1_optimised(model=None):
1147 """Should R1 values be optimised? 1148 1149 @keyword model: The model to test for. 1150 @type model: str 1151 @return: True if the R1 values should be optimised, False if loaded values should be used instead. 1152 @rtype: bool 1153 """ 1154 1155 # Return False for all models which do not support R1 optimisation. 1156 if model not in MODEL_LIST_FIT_R1: 1157 return False 1158 if model == MODEL_NOREX and (cdp != None and hasattr(cdp, 'exp_type_list') and EXP_TYPE_R1RHO not in cdp.exp_type_list): 1159 return False 1160 1161 # Firstly use the R1 fit flag as an override. 1162 if hasattr(cdp, 'r1_fit'): 1163 return cdp.r1_fit 1164 1165 # Catch on-resonance models. 1166 if model in MODEL_LIST_R1RHO_ON_RES: 1167 return False 1168 1169 # Otherwise, is the R1 data loaded? 1170 return check_missing_r1(model=model)
1171 1172
1173 -def is_r1rho_exp_type(id=None):
1174 """Determine if the given spectrum ID corresponds to a R1rho experiment type. 1175 1176 @keyword id: The spectrum ID string. 1177 @type id: str 1178 @return: True if the spectrum ID corresponds to a R1rho experiment type, False otherwise. 1179 @rtype: bool 1180 """ 1181 1182 # No experiment type set. 1183 if not hasattr(cdp, 'exp_type') or id not in cdp.exp_type: 1184 return False 1185 1186 # R1rho experiment type. 1187 if cdp.exp_type[id] in EXP_TYPE_LIST_R1RHO: 1188 return True 1189 1190 # Not a R1rho experiment type. 1191 return False
1192 1193
1194 -def loop_cluster(skip_desel=True):
1195 """Loop over the spin groupings for one model applied to multiple spins. 1196 1197 @keyword skip_desel: A flag which if True will cause deselected spins or spin clusters to be skipped. 1198 @type skip_desel: bool 1199 @return: The list of spin IDs per block will be yielded. 1200 @rtype: list of str 1201 """ 1202 1203 # No clustering, so loop over the sequence. 1204 if not hasattr(cdp, 'clustering'): 1205 for spin, spin_id in spin_loop(return_id=True, skip_desel=skip_desel): 1206 # Skip protons for MMQ data. 1207 if hasattr(spin, 'model') and spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 1208 continue 1209 1210 # Return the spin ID as a list. 1211 yield [spin_id] 1212 1213 # Loop over the clustering. 1214 else: 1215 # The clusters. 1216 for key in cdp.clustering: 1217 # Skip the free spins. 1218 if key == 'free spins': 1219 continue 1220 1221 # Create the spin ID lists. 1222 spin_id_list = [] 1223 for spin_id in cdp.clustering[key]: 1224 # Skip deselected spins. 1225 spin = return_spin(spin_id) 1226 if skip_desel and not spin.select: 1227 continue 1228 1229 # Skip protons for MMQ data. 1230 if hasattr(spin, 'model') and spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 1231 continue 1232 1233 # Add the spin ID. 1234 spin_id_list.append(spin_id) 1235 1236 # Yield the cluster. 1237 yield spin_id_list 1238 1239 # The free spins. 1240 for spin_id in cdp.clustering['free spins']: 1241 # Skip deselected spins. 1242 spin = return_spin(spin_id) 1243 if skip_desel and not spin.select: 1244 continue 1245 1246 # Skip protons for MMQ data. 1247 if hasattr(spin, 'model') and spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 1248 continue 1249 1250 # Yield each spin individually. 1251 yield [spin_id]
1252 1253
1254 -def loop_exp(return_indices=False):
1255 """Generator method for looping over all experiment types. 1256 1257 @keyword return_indices: A flag which if True will cause the experiment type index to be returned as well. 1258 @type return_indices: bool 1259 @return: The experiment type, and the index if asked. 1260 @rtype: str, (int) 1261 """ 1262 1263 # Initialise the index. 1264 ei = -1 1265 1266 # Loop over the experiment types. 1267 for exp_type in cdp.exp_type_list: 1268 # Increment the index. 1269 ei += 1 1270 1271 # Yield each unique experiment type. 1272 if return_indices: 1273 yield exp_type, ei 1274 else: 1275 yield exp_type
1276 1277
1278 -def loop_exp_frq(return_indices=False):
1279 """Generator method for looping over the exp and frq data. 1280 1281 These are the experiment types and spectrometer frequencies. 1282 1283 1284 @keyword return_indices: A flag which if True will cause the experiment type and spectrometer frequency indices to be returned as well. 1285 @type return_indices: bool 1286 @return: The experiment type and spectrometer frequency in Hz, and the indices if asked. 1287 @rtype: str, float, (int, int) 1288 """ 1289 1290 # First loop over the experiment types. 1291 for exp_type, ei in loop_exp(return_indices=True): 1292 # Then loop over the spectrometer frequencies. 1293 for frq, mi in loop_frq(return_indices=True): 1294 # Yield the data. 1295 if return_indices: 1296 yield exp_type, frq, ei, mi 1297 else: 1298 yield exp_type, frq
1299 1300
1301 -def loop_exp_frq_offset(return_indices=False):
1302 """Generator method for looping over the exp, frq, and offset data. 1303 1304 These are the experiment types, spectrometer frequencies and spin-lock offset data. 1305 1306 1307 @keyword return_indices: A flag which if True will cause the experiment type, spectrometer frequency and spin-lock offset indices to be returned as well. 1308 @type return_indices: bool 1309 @return: The experiment type, spectrometer frequency in Hz and spin-lock offset data, and the indices if asked. 1310 @rtype: str, float, float, (int, int, int) 1311 """ 1312 1313 # First loop over the experiment types. 1314 for exp_type, ei in loop_exp(return_indices=True): 1315 # Then loop over the spectrometer frequencies. 1316 for frq, mi in loop_frq(return_indices=True): 1317 # And finally the offset data. 1318 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 1319 # Yield the data. 1320 if return_indices: 1321 yield exp_type, frq, offset, ei, mi, oi 1322 else: 1323 yield exp_type, frq, offset
1324 1325
1326 -def loop_exp_frq_offset_point(return_indices=False):
1327 """Generator method for looping over the exp, frq, offset, and point data. 1328 1329 These are the experiment types, spectrometer frequencies, spin-lock offset data, and dispersion points. 1330 1331 1332 @keyword return_indices: A flag which if True will cause the experiment type, spectrometer frequency, spin-lock offset and dispersion point indices to be returned as well. 1333 @type return_indices: bool 1334 @return: The experiment type, spectrometer frequency in Hz, spin-lock offset data and dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the indices if asked. 1335 @rtype: str, float, float, float, (int, int, int, int) 1336 """ 1337 1338 # First loop over the experiment types. 1339 for exp_type, ei in loop_exp(return_indices=True): 1340 # Then loop over the spectrometer frequencies. 1341 for frq, mi in loop_frq(return_indices=True): 1342 # Then loop over the offset data. 1343 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 1344 # And finally the dispersion points. 1345 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 1346 # Yield the data. 1347 if return_indices: 1348 yield exp_type, frq, offset, point, ei, mi, oi, di 1349 else: 1350 yield exp_type, frq, offset, point
1351 1352
1353 -def loop_exp_frq_offset_point_time(return_indices=False):
1354 """Generator method for looping over the exp, frq, offset, and point data. 1355 1356 These are the experiment types, spectrometer frequencies, spin-lock offset data, and dispersion points. 1357 1358 1359 @keyword return_indices: A flag which if True will cause the experiment type, spectrometer frequency, spin-lock offset and dispersion point indices to be returned as well. 1360 @type return_indices: bool 1361 @return: The experiment type, spectrometer frequency in Hz, spin-lock offset data and dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the indices if asked. 1362 @rtype: str, float, float, float, (int, int, int, int) 1363 """ 1364 1365 # First loop over the experiment types. 1366 for exp_type, ei in loop_exp(return_indices=True): 1367 # Then loop over the spectrometer frequencies. 1368 for frq, mi in loop_frq(return_indices=True): 1369 # Then loop over the offset data. 1370 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 1371 # Then the dispersion points. 1372 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 1373 # Finally the relaxation times. 1374 for time, ti in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point, return_indices=True): 1375 # Yield the data. 1376 if return_indices: 1377 yield exp_type, frq, offset, point, time, ei, mi, oi, di, ti 1378 else: 1379 yield exp_type, frq, offset, point, time
1380 1381
1382 -def loop_exp_frq_point(return_indices=False):
1383 """Generator method for looping over the exp, frq, and point data. 1384 1385 These are the experiment types, spectrometer frequencies and dispersion points. 1386 1387 1388 @keyword return_indices: A flag which if True will cause the experiment type, spectrometer frequency and dispersion point indices to be returned as well. 1389 @type return_indices: bool 1390 @return: The experiment type, spectrometer frequency in Hz and dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the indices if asked. 1391 @rtype: str, float, float, (int, int, int) 1392 """ 1393 1394 # First loop over the experiment types. 1395 for exp_type, ei in loop_exp(return_indices=True): 1396 # Then loop over the spectrometer frequencies. 1397 for frq, mi in loop_frq(return_indices=True): 1398 # And finally the dispersion points. 1399 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=0.0, return_indices=True): 1400 # Yield the data. 1401 if return_indices: 1402 yield exp_type, frq, point, ei, mi, di 1403 else: 1404 yield exp_type, frq, point
1405 1406
1407 -def loop_exp_frq_point_time(return_indices=False):
1408 """Generator method for looping over the exp, frq, point, and time data. 1409 1410 These are the experiment types, spectrometer frequencies, dispersion points, and relaxation times. 1411 1412 1413 @keyword return_indices: A flag which if True will cause the experiment type, spectrometer frequency, dispersion point, and relaxation time indices to be returned as well. 1414 @type return_indices: bool 1415 @return: The experiment type, spectrometer frequency in Hz, dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), the relaxation time, and the indices if asked. 1416 @rtype: str, float, float, float, (int, int, int, int) 1417 """ 1418 1419 # First loop over the experiment types. 1420 for exp_type, ei in loop_exp(return_indices=True): 1421 # Then the spectrometer frequencies. 1422 for frq, mi in loop_frq(return_indices=True): 1423 # Then the dispersion points. 1424 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=0.0, return_indices=True): 1425 # Finally the relaxation times. 1426 for time, ti in loop_time(exp_type=exp_type, frq=frq, point=point, return_indices=True): 1427 # Yield all data. 1428 if return_indices: 1429 yield exp_type, frq, point, time, ei, mi, di, ti 1430 else: 1431 yield exp_type, frq, point, time
1432 1433
1434 -def loop_frq(return_indices=False):
1435 """Generator method for looping over all spectrometer frequencies. 1436 1437 @keyword return_indices: A flag which if True will cause the spectrometer frequency index to be returned as well. 1438 @type return_indices: bool 1439 @return: The spectrometer frequency in Hz, and the index if asked. 1440 @rtype: float, (int) 1441 """ 1442 1443 # Handle missing frequency data. 1444 frqs = [None] 1445 if hasattr(cdp, 'spectrometer_frq_list'): 1446 frqs = cdp.spectrometer_frq_list 1447 1448 # Initialise the index. 1449 mi = -1 1450 1451 # Loop over the spectrometer frequencies. 1452 for field in frqs: 1453 # Increment the index. 1454 mi += 1 1455 1456 # Yield each unique spectrometer field strength. 1457 if return_indices: 1458 yield field, mi 1459 else: 1460 yield field
1461 1462
1463 -def loop_frq_offset(exp_type=None, return_indices=False):
1464 """Generator method for looping over the spectrometer frequencies and dispersion points. 1465 1466 @keyword exp_type: The experiment type. 1467 @type exp_type: str 1468 @keyword return_indices: A flag which if True will cause the spectrometer frequency and dispersion point indices to be returned as well. 1469 @type return_indices: bool 1470 @return: The spectrometer frequency in Hz and dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 1471 @rtype: float, float, (int, int) 1472 """ 1473 1474 # Checks. 1475 if exp_type == None: 1476 raise RelaxError("The experiment type must be supplied.") 1477 1478 # First loop over the spectrometer frequencies. 1479 for frq, mi in loop_frq(return_indices=True): 1480 # Then the offset points. 1481 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 1482 # Yield the data. 1483 if return_indices: 1484 yield frq, offset, mi, oi 1485 else: 1486 yield frq, offset
1487 1488
1489 -def loop_frq_point(exp_type=None, return_indices=False):
1490 """Generator method for looping over the spectrometer frequencies and dispersion points. 1491 1492 @keyword exp_type: The experiment type. 1493 @type exp_type: str 1494 @keyword return_indices: A flag which if True will cause the spectrometer frequency and dispersion point indices to be returned as well. 1495 @type return_indices: bool 1496 @return: The spectrometer frequency in Hz and dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 1497 @rtype: float, float, (int, int) 1498 """ 1499 1500 # First loop over the spectrometer frequencies. 1501 for frq, mi in loop_frq(return_indices=True): 1502 # Then the dispersion points. 1503 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=0.0, return_indices=True): 1504 # Yield the data. 1505 if return_indices: 1506 yield frq, point, mi, di 1507 else: 1508 yield frq, point
1509 1510
1511 -def loop_frq_offset_point_key(exp_type=None):
1512 """Generator method for looping over the spectrometer frequencies, spin-lock offsets and dispersion points (returning the key). 1513 1514 @keyword exp_type: The experiment type. 1515 @type exp_type: str 1516 @return: The key corresponding to the spectrometer frequency, offset and dispersion point. 1517 @rtype: str 1518 """ 1519 1520 # First loop over the spectrometer frequencies, offsets and dispersion points. 1521 for frq, offset, point in loop_frq_offset_point(return_indices=True): 1522 # Generate and yield the key. 1523 yield return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point)
1524 1525
1526 -def loop_frq_point_time(exp_type=None, return_indices=False):
1527 """Generator method for looping over the spectrometer frequencies, dispersion points, and relaxation times. 1528 1529 @keyword exp_type: The experiment type. 1530 @type exp_type: str 1531 @keyword return_indices: A flag which if True will cause the spectrometer frequency, dispersion point, and relaxation time indices to be returned as well. 1532 @type return_indices: bool 1533 @return: The spectrometer frequency in Hz, dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the relaxation time. 1534 @rtype: float, float, float 1535 """ 1536 1537 # First loop over the spectrometer frequencies. 1538 for frq, mi in loop_frq(return_indices=True): 1539 # Then the dispersion points. 1540 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=0.0, return_indices=True): 1541 # Finally the relaxation times. 1542 for time, ti in loop_time(exp_type=exp_type, frq=frq, point=point, return_indices=True): 1543 # Yield all data. 1544 if return_indices: 1545 yield frq, point, time, mi, di, ti 1546 else: 1547 yield frq, point, time
1548 1549
1550 -def loop_offset(exp_type=None, frq=None, return_indices=False):
1551 """Generator method for looping over the spin-lock offset values. 1552 1553 @keyword exp_type: The experiment type. 1554 @type exp_type: str 1555 @keyword frq: The spectrometer frequency. 1556 @type frq: float 1557 @keyword return_indices: A flag which if True will cause the offset index to be returned as well. 1558 @type return_indices: bool 1559 @return: The spin-lock offset value and the index if asked. 1560 @rtype: float, (int) 1561 """ 1562 1563 # Checks. 1564 if exp_type == None: 1565 raise RelaxError("The experiment type must be supplied.") 1566 if frq == None: 1567 raise RelaxError("The spectrometer frequency must be supplied.") 1568 1569 # Initialise the index. 1570 oi = -1 1571 1572 # CPMG-type data. 1573 if exp_type in EXP_TYPE_LIST_CPMG: 1574 # Yield a single set of dummy values until hard pulse offset handling is implemented. 1575 yield 0.0, 0 1576 1577 # R1rho-type data. 1578 if exp_type in EXP_TYPE_LIST_R1RHO: 1579 # No offsets set. 1580 if not hasattr(cdp, 'spin_lock_offset_list'): 1581 yield 0.0, 0 1582 1583 # Loop over the offset data. 1584 else: 1585 for offset in cdp.spin_lock_offset_list: 1586 # Find a matching experiment ID. 1587 found = False 1588 for id in cdp.exp_type: 1589 # Skip non-matching experiments. 1590 if cdp.exp_type[id] != exp_type: 1591 continue 1592 1593 # Skip non-matching spectrometer frequencies. 1594 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 1595 continue 1596 1597 # Skip non-matching offsets. 1598 if cdp.spin_lock_offset[id] != offset: 1599 continue 1600 1601 # Found. 1602 found = True 1603 break 1604 1605 # No data. 1606 if not found: 1607 continue 1608 1609 # Increment the index. 1610 oi += 1 1611 1612 # Yield each unique field strength or frequency. 1613 if return_indices: 1614 yield offset, oi 1615 else: 1616 yield offset
1617 1618
1619 -def loop_offset_point(exp_type=None, frq=None, skip_ref=True, return_indices=False):
1620 """Generator method for looping over the offsets and dispersion points. 1621 1622 @keyword exp_type: The experiment type. 1623 @type exp_type: str 1624 @keyword frq: The spectrometer frequency. 1625 @type frq: float 1626 @keyword skip_ref: A flag which if True will cause the reference point to be skipped. 1627 @type skip_ref: bool 1628 @keyword return_indices: A flag which if True will cause the offset and dispersion point indices to be returned as well. 1629 @type return_indices: bool 1630 @return: The offsets in ppm and the dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the index if asked. 1631 @rtype: float, float, (int, int) 1632 """ 1633 1634 # First loop over the offsets. 1635 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 1636 # Then the dispersion points. 1637 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 1638 # Yield all data. 1639 if return_indices: 1640 yield offset, point, oi, di 1641 else: 1642 yield offset, point
1643 1644
1645 -def loop_point(exp_type=None, frq=None, offset=None, time=None, skip_ref=True, return_indices=False):
1646 """Generator method for looping over the dispersion points. 1647 1648 @keyword exp_type: The experiment type. 1649 @type exp_type: str 1650 @keyword frq: The spectrometer frequency. 1651 @type frq: float 1652 @keyword offset: The spin-lock or hard pulse offset value in ppm. 1653 @type offset: None or float 1654 @keyword time: The relaxation time period. 1655 @type time: float 1656 @keyword skip_ref: A flag which if True will cause the reference point to be skipped. 1657 @type skip_ref: bool 1658 @keyword return_indices: A flag which if True will cause the experiment type index to be returned as well. 1659 @type return_indices: bool 1660 @return: Dispersion point data for the given indices (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz), and the index if asked. 1661 @rtype: float, (int) 1662 """ 1663 1664 # Checks. 1665 if exp_type == None: 1666 raise RelaxError("The experiment type must be supplied.") 1667 if frq == None: 1668 raise RelaxError("The spectrometer frequency must be supplied.") 1669 if offset == None: 1670 raise RelaxError("The offset must be supplied.") 1671 1672 # Assemble the dispersion data. 1673 ref_flag = not skip_ref 1674 if exp_type in EXP_TYPE_LIST_CPMG: 1675 fields = return_cpmg_frqs_single(exp_type=exp_type, frq=frq, offset=offset, time=time, ref_flag=ref_flag) 1676 elif exp_type in EXP_TYPE_LIST_R1RHO: 1677 fields = return_spin_lock_nu1_single(exp_type=exp_type, frq=frq, offset=offset, ref_flag=ref_flag) 1678 else: 1679 raise RelaxError("The experiment type '%s' is unknown." % exp_type) 1680 1681 # Initialise the index. 1682 di = -1 1683 1684 # Loop over the field data. 1685 for field in fields: 1686 # Skip the reference (the None value will be converted to the numpy nan value). 1687 if skip_ref and isNaN(field): 1688 continue 1689 1690 # Increment the index. 1691 di += 1 1692 1693 # Yield each unique field strength or frequency. 1694 if return_indices: 1695 yield field, di 1696 else: 1697 yield field
1698 1699
1700 -def loop_spectrum_ids(exp_type=None, frq=None, offset=None, point=None, time=None):
1701 """Generator method for selectively looping over the spectrum IDs. 1702 1703 @keyword exp_type: The experiment type. 1704 @type exp_type: str 1705 @keyword frq: The spectrometer frequency. 1706 @type frq: float 1707 @keyword offset: For R1rho-type data, the spin-lock offset value in ppm. 1708 @type offset: None or float 1709 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 1710 @type point: float 1711 @keyword time: The relaxation time period. 1712 @type time: float 1713 @return: The spectrum ID. 1714 @rtype: str 1715 """ 1716 1717 # Loop over all spectrum IDs. 1718 for id in cdp.spectrum_ids: 1719 # Experiment type filter. 1720 if exp_type != None: 1721 # No experiment type set. 1722 if not hasattr(cdp, 'exp_type') or id not in cdp.exp_type: 1723 continue 1724 1725 # No match. 1726 if cdp.exp_type[id] != exp_type: 1727 continue 1728 1729 # The frequency filter. 1730 if frq != None: 1731 # No frequency data set. 1732 if not hasattr(cdp, 'spectrometer_frq') or id not in cdp.spectrometer_frq: 1733 continue 1734 1735 # No match. 1736 if cdp.spectrometer_frq[id] != frq: 1737 continue 1738 1739 # The dispersion point filter. 1740 if point != None: 1741 # No experiment type set. 1742 if not hasattr(cdp, 'exp_type') or id not in cdp.exp_type: 1743 continue 1744 1745 # The experiment type. 1746 exp_type = cdp.exp_type[id] 1747 1748 # The CPMG dispersion data. 1749 if exp_type in EXP_TYPE_LIST_CPMG: 1750 # No dispersion point data set. 1751 if not hasattr(cdp, 'cpmg_frqs') or id not in cdp.cpmg_frqs: 1752 continue 1753 1754 # Alias the structure 1755 disp_data = cdp.cpmg_frqs 1756 1757 # The R1rho dispersion data. 1758 else: 1759 # No dispersion point data set. 1760 if not hasattr(cdp, 'spin_lock_nu1') or id not in cdp.spin_lock_nu1: 1761 continue 1762 1763 # Alias the structure 1764 disp_data = cdp.spin_lock_nu1 1765 1766 # No match. 1767 if disp_data[id] != point: 1768 continue 1769 1770 # The time filter. 1771 if time != None: 1772 # No time data set. 1773 if not hasattr(cdp, 'relax_times') or id not in cdp.relax_times: 1774 continue 1775 1776 # No match. 1777 if cdp.relax_times[id] != time: 1778 continue 1779 1780 # Yield the Id. 1781 yield id
1782 1783
1784 -def loop_time(exp_type=None, frq=None, offset=None, point=None, return_indices=False):
1785 """Generator method for looping over the relaxation times. 1786 1787 @keyword exp_type: The experiment type. 1788 @type exp_type: str 1789 @keyword frq: The spectrometer frequency in Hz. 1790 @type frq: float 1791 @keyword offset: The spin-lock or hard pulse offset value in ppm. 1792 @type offset: None or float 1793 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 1794 @type point: float 1795 @keyword return_indices: A flag which if True will cause the relaxation time index to be returned as well. 1796 @type return_indices: bool 1797 @return: The relaxation time. 1798 @rtype: float 1799 """ 1800 1801 # Initialise the index. 1802 ti = -1 1803 1804 # Loop over the time points. 1805 if hasattr(cdp, 'relax_time_list'): 1806 for time in cdp.relax_time_list: 1807 # Find a matching experiment ID. 1808 found = False 1809 for id in cdp.exp_type: 1810 # Skip non-matching experiments. 1811 if exp_type != None and cdp.exp_type[id] != exp_type: 1812 continue 1813 1814 # Skip non-matching spectrometer frequencies. 1815 if frq != None and hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 1816 continue 1817 1818 # Skip non-matching offsets. 1819 if offset != None and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 1820 continue 1821 1822 # The dispersion point filter. 1823 if point != None: 1824 # No experiment type set. 1825 if not hasattr(cdp, 'exp_type') or id not in cdp.exp_type: 1826 continue 1827 1828 # The experiment type. 1829 exp_type = cdp.exp_type[id] 1830 1831 # The CPMG dispersion data. 1832 if exp_type in EXP_TYPE_LIST_CPMG: 1833 # No dispersion point data set. 1834 if hasattr(cdp, 'cpmg_frqs') and cdp.cpmg_frqs[id] != point: 1835 continue 1836 1837 # The R1rho data 1838 if exp_type in EXP_TYPE_R1RHO: 1839 if hasattr(cdp, 'spin_lock_nu1') and cdp.spin_lock_nu1[id] != point: 1840 continue 1841 1842 if time != cdp.relax_times[id]: 1843 continue 1844 1845 # Found. 1846 found = True 1847 break 1848 1849 # No data. 1850 if not found: 1851 continue 1852 1853 # Increment the index. 1854 ti += 1 1855 1856 # Yield each unique relaxation time. 1857 if return_indices: 1858 yield time, ti 1859 else: 1860 yield time 1861 1862 # No times set. 1863 else: 1864 if return_indices: 1865 yield None, None 1866 else: 1867 yield None
1868 1869
1870 -def num_exp_types():
1871 """Count the number of experiment types present. 1872 1873 @return: The number of experiment types. 1874 @rtype: int 1875 """ 1876 1877 # The count. 1878 count = len(cdp.exp_type_list) 1879 1880 # Return the count. 1881 return count
1882 1883
1884 -def pack_back_calc_r2eff(spin=None, spin_id=None, si=None, back_calc=None, proton_mmq_flag=False):
1885 """Store the back calculated R2eff data for the given spin. 1886 1887 @keyword spin: The spin data container to store the data in. 1888 @type spin: SpinContainer instance 1889 @keyword spin_id: The spin ID string. 1890 @type spin_id: str 1891 @keyword si: The index of the given spin in the cluster. 1892 @type si: int 1893 @keyword back_calc: The back calculated data. The first index corresponds to the experiment type, the second is the spin of the cluster, the third is the magnetic field strength, and the fourth is the dispersion point. 1894 @type back_calc: list of lists of lists of lists of float 1895 @keyword proton_mmq_flag: The flag specifying if proton SQ or MQ CPMG data exists for the spin. 1896 @type proton_mmq_flag: bool 1897 """ 1898 1899 # Get the attached proton. 1900 proton = None 1901 if proton_mmq_flag: 1902 proton = return_attached_protons(spin_id)[0] 1903 1904 # Loop over the R2eff data. 1905 for exp_type, frq, offset, point, ei, mi, oi, di in loop_exp_frq_offset_point(return_indices=True): 1906 # The R2eff key. 1907 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 1908 1909 # Alias the correct spin. 1910 current_spin = spin 1911 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 1912 current_spin = proton 1913 1914 # Missing data. 1915 if not hasattr(current_spin, 'r2eff') or key not in current_spin.r2eff: 1916 continue 1917 1918 # Initialise. 1919 if not hasattr(current_spin, 'r2eff_bc'): 1920 current_spin.r2eff_bc = {} 1921 1922 # Store the back-calculated data. 1923 current_spin.r2eff_bc[key] = back_calc[ei][si][mi][oi][di]
1924 1925
1926 -def plot_disp_curves(dir=None, y_axis=Y_AXIS_R2_EFF, x_axis=X_AXIS_DISP, num_points=1000, extend_hz=500.0, extend_ppm=500.0, interpolate=INTERPOLATE_DISP, force=False):
1927 """Custom 2D Grace plotting function for the dispersion curves. 1928 1929 One file will be created per spin system. 1930 1931 A python "grace to PNG/EPS/SVG..." conversion script is created at the end 1932 1933 @keyword dir: The optional directory to place the file into. 1934 @type dir: str 1935 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 1936 @type y_axis: str 1937 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 1938 @type x_axis: str 1939 @keyword num_points: The number of points to generate the interpolated fitted curves with. 1940 @type num_points: int 1941 @keyword extend_hz: How far to extend the interpolated fitted curves to, when interpolating over CPMG frequency or spin-lock field strength (in Hz). 1942 @type extend_hz: float 1943 @keyword extend_ppm: How far to extend the interpolated fitted curves to, when interpolating over spin-lock offset (in ppm). 1944 @type extend_ppm: float 1945 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 1946 @type interpolate: float 1947 @param force: Boolean argument which if True causes the files to be overwritten if it already exists. 1948 @type force: bool 1949 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 1950 1951 # Checks. 1952 check_pipe() 1953 check_mol_res_spin_data() 1954 1955 # Check if interpolating against offset for CPMG models. 1956 # This is currently not implemented, and will raise an error. 1957 check_interpolate_offset_cpmg_model(interpolate=interpolate) 1958 1959 # 1H MMQ flag. 1960 proton_mmq_flag = has_proton_mmq_cpmg() 1961 1962 # Determine file name: 1963 file_name_ini = return_grace_file_name_ini(y_axis=y_axis, x_axis=x_axis, interpolate=interpolate) 1964 1965 # Plot dispersion curves. 1966 plot_disp_curves_to_file(file_name_ini=file_name_ini, dir=dir, y_axis=y_axis, x_axis=x_axis, interpolate=interpolate, num_points=num_points, extend_hz=extend_hz, extend_ppm=extend_ppm, force=force, proton_mmq_flag=proton_mmq_flag) 1967 1968 # Write a python "grace to PNG/EPS/SVG..." conversion script. 1969 # Open the file for writing. 1970 file_name = "grace2images.py" 1971 file_path = get_file_path(file_name, dir) 1972 1973 # Prevent to write the file multiple times. 1974 if access(file_path, F_OK) and not force: 1975 pass 1976 1977 else: 1978 file = open_write_file(file_name, dir, force) 1979 1980 # Write the file. 1981 script_grace2images(file=file) 1982 1983 # Close the batch script, then make it executable (expanding any ~ characters). 1984 file.close() 1985 if dir: 1986 dir = expanduser(dir) 1987 chmod(dir + sep + file_name, S_IRWXU|S_IRGRP|S_IROTH) 1988 else: 1989 file_name = expanduser(file_name) 1990 chmod(file_name, S_IRWXU|S_IRGRP|S_IROTH)
1991 1992
1993 -def plot_disp_curves_to_file(file_name_ini=None, dir=None, y_axis=None, x_axis=None, interpolate=None, num_points=None, extend_hz=None, extend_ppm=None, force=None, proton_mmq_flag=None):
1994 """Custom 2D Grace plotting function for the dispersion curves, interpolating theta through spin-lock offset rather than spin-lock field strength. 1995 1996 One file will be created per spin system. 1997 1998 @keyword file_name_ini: The first part of the file_name. 1999 @type file_name_ini: str 2000 @keyword dir: The optional directory to place the file into. 2001 @type dir: str 2002 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 2003 @type y_axis: str 2004 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 2005 @type x_axis: str 2006 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 2007 @type interpolate: float 2008 @keyword num_points: The number of points to generate the interpolated fitted curves with. 2009 @type num_points: int 2010 @keyword extend_hz: How far to extend the interpolated fitted curves to, when interpolating over CPMG frequency or spin-lock field strength (in Hz). 2011 @type extend_hz: float 2012 @keyword extend_ppm: How far to extend the interpolated fitted curves to, when interpolating over spin-lock offset (in ppm). 2013 @type extend_ppm: float 2014 @param force: Boolean argument which if True causes the files to be overwritten if it already exists. 2015 @type force: bool 2016 @keyword proton_mmq_flag: The flag specifying if proton SQ or MQ CPMG data exists for the spin. 2017 @type proton_mmq_flag: bool 2018 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 2019 2020 # Loop over each spin. Initialise spin counter. 2021 si = 0 2022 for spin, mol_name, res_num, res_name, spin_id in spin_loop(full_info=True, return_id=True, skip_desel=True): 2023 # Skip protons for MMQ data. 2024 if spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 2025 continue 2026 2027 # Initialise some data structures. 2028 data = [] 2029 set_labels = [] 2030 x_err_flag = False 2031 y_err_flag = False 2032 axis_labels = [] 2033 set_colours = [] 2034 x_axis_type_zero = [] 2035 symbols = [] 2036 symbol_sizes = [] 2037 linetype = [] 2038 linestyle = [] 2039 2040 # Number of spectrometer fields. 2041 fields = [None] 2042 field_count = 1 2043 if hasattr(cdp, 'spectrometer_frq_count'): 2044 fields = cdp.spectrometer_frq_list 2045 field_count = cdp.spectrometer_frq_count 2046 2047 # Get the relax_times. 2048 values, errors, missing, frqs, frqs_H, exp_types, relax_times = return_r2eff_arrays(spins=[spin], spin_ids=[spin_id], fields=fields, field_count=field_count) 2049 2050 # Set up the interpolated curve data structures. 2051 interpolated_flag = False 2052 2053 # The unique file name. 2054 file_name = "%s%s.agr" % (file_name_ini, spin_id.replace('#', '_').replace(':', '_').replace('@', '_')) 2055 2056 if interpolate == INTERPOLATE_DISP: 2057 # Interpolate through disp points. 2058 interpolated_flag, back_calc, cpmg_frqs_new, offsets_inter, spin_lock_nu1_new, chemical_shifts, tilt_angles_inter, Delta_omega_inter, w_eff_inter = interpolate_disp(spin=spin, spin_id=spin_id, si=si, num_points=num_points, extend_hz=extend_hz, relax_times=relax_times) 2059 2060 elif interpolate == INTERPOLATE_OFFSET: 2061 # Interpolate through disp points. 2062 interpolated_flag, back_calc, cpmg_frqs_new, offsets_inter, spin_lock_nu1_new, chemical_shifts, tilt_angles_inter, Delta_omega_inter, w_eff_inter = interpolate_offset(spin=spin, spin_id=spin_id, si=si, num_points=num_points, extend_ppm=extend_ppm, relax_times=relax_times) 2063 2064 # Do not interpolate, if model is R2eff. 2065 if spin.model == MODEL_R2EFF: 2066 interpolated_flag = False 2067 2068 # Open the file for writing. 2069 file_path = get_file_path(file_name, dir) 2070 file = open_write_file(file_name, dir, force) 2071 2072 # Get the attached proton. 2073 proton = None 2074 if proton_mmq_flag: 2075 proton = return_attached_protons(spin_id)[0] 2076 2077 # Loop over each experiment type. 2078 graph_index = 0 2079 for exp_type, ei in loop_exp(return_indices=True): 2080 # Update the structures. 2081 data.append([]) 2082 set_labels.append([]) 2083 set_colours.append([]) 2084 x_axis_type_zero.append([]) 2085 symbols.append([]) 2086 symbol_sizes.append([]) 2087 linetype.append([]) 2088 linestyle.append([]) 2089 2090 # Alias the correct spin. 2091 current_spin = spin 2092 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 2093 current_spin = proton 2094 2095 # Loop over the spectrometer frequencies and offsets. 2096 if interpolate == INTERPOLATE_DISP: 2097 err, data, set_labels, set_colours, x_axis_type_zero, symbols, symbol_sizes, linetype, linestyle, axis_labels = return_grace_data_vs_disp(y_axis=y_axis, x_axis=x_axis, interpolate=interpolate, exp_type=exp_type, ei=ei, current_spin=current_spin, spin_id=spin_id, si=si, back_calc=back_calc, cpmg_frqs_new=cpmg_frqs_new, spin_lock_nu1_new=spin_lock_nu1_new, chemical_shifts=chemical_shifts, offsets_inter=offsets_inter, tilt_angles_inter=tilt_angles_inter, Delta_omega_inter=Delta_omega_inter, w_eff_inter=w_eff_inter, interpolated_flag=interpolated_flag, graph_index=graph_index, data=data, set_labels=set_labels, set_colours=set_colours, x_axis_type_zero=x_axis_type_zero, symbols=symbols, symbol_sizes=symbol_sizes, linetype=linetype, linestyle=linestyle, axis_labels=axis_labels) 2098 2099 elif interpolate == INTERPOLATE_OFFSET: 2100 err, data, set_labels, set_colours, x_axis_type_zero, symbols, symbol_sizes, linetype, linestyle, axis_labels = return_grace_data_vs_offset(y_axis=y_axis, x_axis=x_axis, interpolate=interpolate, exp_type=exp_type, ei=ei, current_spin=current_spin, spin_id=spin_id, si=si, back_calc=back_calc, cpmg_frqs_new=cpmg_frqs_new, spin_lock_nu1_new=spin_lock_nu1_new, chemical_shifts=chemical_shifts, offsets_inter=offsets_inter, tilt_angles_inter=tilt_angles_inter, Delta_omega_inter=Delta_omega_inter, w_eff_inter=w_eff_inter, interpolated_flag=interpolated_flag, graph_index=graph_index, data=data, set_labels=set_labels, set_colours=set_colours, x_axis_type_zero=x_axis_type_zero, symbols=symbols, symbol_sizes=symbol_sizes, linetype=linetype, linestyle=linestyle, axis_labels=axis_labels) 2101 2102 # Increment the graph index. 2103 graph_index += 1 2104 2105 # Remove all NaN values. 2106 for i in range(len(data)): 2107 for j in range(len(data[i])): 2108 for k in range(len(data[i][j])): 2109 for l in range(len(data[i][j][k])): 2110 if isNaN(data[i][j][k][l]): 2111 data[i][j][k][l] = 0.0 2112 2113 # Write the header. 2114 spin_string = generate_spin_string(spin=spin, mol_name=mol_name, res_num=res_num, res_name=res_name) 2115 title = "Relaxation dispersion plot for: %s"%(spin_string) 2116 if interpolate == INTERPOLATE_DISP: 2117 subtitle = "Interpolated through Spin-lock field strength \\xw\\B\\s1\\N" 2118 elif interpolate == INTERPOLATE_OFFSET: 2119 subtitle = "Interpolated through Spin-lock offset \\xw\\B\\srf\\N" 2120 2121 graph_num = len(data) 2122 sets = [] 2123 legend = [] 2124 for gi in range(len(data)): 2125 sets.append(len(data[gi])) 2126 legend.append(False) 2127 legend[0] = True 2128 write_xy_header(format='grace', file=file, title=title, subtitle=subtitle, graph_num=graph_num, sets=sets, set_names=set_labels, set_colours=set_colours, x_axis_type_zero=x_axis_type_zero, symbols=symbols, symbol_sizes=symbol_sizes, linetype=linetype, linestyle=linestyle, axis_labels=axis_labels, legend=legend, legend_box_fill_pattern=[0]*graph_num, legend_char_size=[0.8]*graph_num) 2129 2130 # Write the data. 2131 graph_type = 'xy' 2132 if err: 2133 graph_type = 'xydy' 2134 write_xy_data(format='grace', data=data, file=file, graph_type=graph_type) 2135 2136 # Close the file. 2137 file.close() 2138 2139 # Add the file to the results file list. 2140 add_result_file(type='grace', label='Grace', file=file_path)
2141 2142
2143 -def plot_exp_curves(file=None, dir=None, force=None, norm=None):
2144 """Custom 2D Grace plotting function for the exponential curves. 2145 2146 @keyword file: The name of the Grace file to create. 2147 @type file: str 2148 @keyword dir: The optional directory to place the file into. 2149 @type dir: str 2150 @param force: Boolean argument which if True causes the file to be overwritten if it already exists. 2151 @type force: bool 2152 @keyword norm: The normalisation flag which if set to True will cause all graphs to be normalised to a starting value of 1. 2153 @type norm: bool 2154 """ 2155 2156 # Test if the current pipe exists. 2157 check_pipe() 2158 2159 # Test if the sequence data is loaded. 2160 if not exists_mol_res_spin_data(): 2161 raise RelaxNoSequenceError 2162 2163 # Open the file for writing. 2164 file_path = get_file_path(file, dir) 2165 file = open_write_file(file, dir, force) 2166 2167 # Initialise some data structures. 2168 data = [] 2169 set_labels = [] 2170 x_err_flag = False 2171 y_err_flag = False 2172 2173 # 1H MMQ flag. 2174 proton_mmq_flag = has_proton_mmq_cpmg() 2175 2176 # Loop over the spectrometer frequencies. 2177 graph_index = 0 2178 err = False 2179 for exp_type, frq, offset, ei, mi, oi in loop_exp_frq_offset(return_indices=True): 2180 # Loop over the dispersion points. 2181 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 2182 # Create a new graph. 2183 data.append([]) 2184 2185 # Loop over each spin. 2186 for spin, id in spin_loop(return_id=True, skip_desel=True): 2187 # Skip protons for MMQ data. 2188 if spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 2189 continue 2190 2191 # No data present. 2192 if not hasattr(spin, 'peak_intensity'): 2193 continue 2194 2195 # Get the attached proton. 2196 proton = None 2197 if proton_mmq_flag: 2198 proton = return_attached_protons(spin_id)[0] 2199 2200 # Alias the correct spin. 2201 current_spin = spin 2202 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 2203 current_spin = proton 2204 2205 # Append a new set structure and set the name to the spin ID. 2206 data[graph_index].append([]) 2207 if graph_index == 0: 2208 set_labels.append("Spin %s" % id) 2209 2210 # Loop over the relaxation time periods. 2211 for time in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point): 2212 # The key. 2213 keys = find_intensity_keys(exp_type=exp_type, frq=frq, offset=offset, point=point, time=time) 2214 2215 # Loop over each key. 2216 for key in keys: 2217 # No key present. 2218 if key not in current_spin.peak_intensity: 2219 continue 2220 2221 # Add the data. 2222 if hasattr(current_spin, 'peak_intensity_err'): 2223 data[graph_index][-1].append([time, current_spin.peak_intensity[key], spin.peak_intensity_err[key]]) 2224 err = True 2225 else: 2226 data[graph_index][-1].append([time, current_spin.peak_intensity[key]]) 2227 2228 # Increment the frq index. 2229 graph_index += 1 2230 2231 # The axis labels. 2232 axis_labels = ['Relaxation time period (s)', 'Peak intensities'] 2233 2234 # Write the header. 2235 graph_num = len(data) 2236 sets = [] 2237 for gi in range(graph_num): 2238 sets.append(len(data[gi])) 2239 write_xy_header(format='grace', file=file, graph_num=graph_num, sets=sets, set_names=[set_labels]*graph_num, axis_labels=[axis_labels]*graph_num, norm=[norm]*graph_num) 2240 2241 # Write the data. 2242 graph_type = 'xy' 2243 if err: 2244 graph_type = 'xydy' 2245 write_xy_data(format='grace', data=data, file=file, graph_type=graph_type, norm=[norm]*graph_num) 2246 2247 # Close the file. 2248 file.close() 2249 2250 # Add the file to the results file list. 2251 add_result_file(type='grace', label='Grace', file=file_path)
2252 2253
2254 -def r20_from_min_r2eff(force=True, verbosity=1):
2255 """Set the R20 values to the minimum R2eff values. 2256 2257 For a 2 field cpmg experiment with model CR72, that would drop number of uniform grid search point from gridNr^5 to gridNr^3. 2258 For standard 21 grid Nr, it would make the grid search 441 times faster. 2259 2260 @keyword force: A flag forcing the overwriting of current values. 2261 @type force: bool 2262 @keyword verbosity: A flag specifying to print the setting of values. 2263 @type verbosity: int 2264 """ 2265 2266 # Number of spectrometer fields. 2267 fields = [None] 2268 field_count = 1 2269 if hasattr(cdp, 'spectrometer_frq_count'): 2270 fields = cdp.spectrometer_frq_list 2271 field_count = cdp.spectrometer_frq_count 2272 2273 # Loop over all spins. 2274 for spin, spin_id in spin_loop(return_id=True, skip_desel=True): 2275 # Nothing to do (the R2eff model has no dispersion curves). 2276 if spin.model == MODEL_R2EFF: 2277 print("The spin model is %s. The %s model has no dispersion curves, so will not set the grid values."%(spin.model, spin.model)) 2278 continue 2279 2280 # Get all the data. 2281 try: 2282 values, errors, missing, frqs, frqs_H, exp_types, relax_times = return_r2eff_arrays(spins=[spin], spin_ids=[spin_id], fields=fields, field_count=field_count) 2283 2284 # No R2eff data, so skip the rest. 2285 except RelaxError: 2286 continue 2287 2288 # Loop over the experiments, magnetic fields, and offsets. 2289 for exp_type, frq, offset, ei, mi, oi in loop_exp_frq_offset(return_indices=True): 2290 # No data. 2291 if not len(values[ei][0][mi][oi]): 2292 continue 2293 2294 # The minimum 2295 min_val = values[ei][0][mi][oi].min() 2296 2297 # Loop over the parameters for the current model 2298 for param in MODEL_PARAMS[spin.model]: 2299 # Check if the param is r2 2300 if param in PARAMS_R20: 2301 # Set the value 2302 value.set(val=min_val, param=param, index=mi, spin_id=spin_id, force=force) 2303 if verbosity: 2304 print("For %s, frq=%3.1f, offset=%3.1f, for grid search setting initial %s=%3.2f for spin: %s"%(exp_type, frq/1E6, offset, param, min_val, spin_id))
2305 2306
2307 -def r2eff_read(id=None, file=None, dir=None, disp_frq=None, offset=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None, sep=None):
2308 """Read R2eff/R1rho values directly from a file whereby each row corresponds to a different spin. 2309 2310 @keyword id: The experiment ID string to associate the data with. 2311 @type id: str 2312 @keyword file: The name of the file to open. 2313 @type file: str 2314 @keyword dir: The directory containing the file (defaults to the current directory if None). 2315 @type dir: str or None 2316 @keyword disp_frq: For CPMG-type data, the frequency of the CPMG pulse train. For R1rho-type data, the spin-lock field strength (nu1). The units must be Hertz. 2317 @type disp_frq: float 2318 @keyword offset: For R1rho-type data, the spin-lock offset value in ppm. 2319 @type offset: None or float 2320 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none. 2321 @type spin_id_col: int or None 2322 @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. 2323 @type mol_name_col: int or None 2324 @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. 2325 @type res_name_col: int or None 2326 @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. 2327 @type res_num_col: int or None 2328 @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. 2329 @type spin_name_col: int or None 2330 @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. 2331 @type spin_num_col: int or None 2332 @keyword data_col: The column containing the R2eff/R1rho data in Hz. 2333 @type data_col: int or None 2334 @keyword error_col: The column containing the R2eff/R1rho errors. 2335 @type error_col: int or None 2336 @keyword sep: The column separator which, if None, defaults to whitespace. 2337 @type sep: str or None 2338 """ 2339 2340 # Data checks. 2341 check_pipe() 2342 check_mol_res_spin_data() 2343 check_frequency(id=id) 2344 check_exp_type(id=id) 2345 2346 # Store the spectrum ID. 2347 add_spectrum_id(id) 2348 2349 # Get the metadata. 2350 frq = get_frequency(id=id) 2351 exp_type = get_exp_type(id=id) 2352 2353 # Loop over the data. 2354 data_flag = False 2355 mol_names = [] 2356 res_nums = [] 2357 res_names = [] 2358 spin_nums = [] 2359 spin_names = [] 2360 values = [] 2361 errors = [] 2362 for data in read_spin_data(file=file, dir=dir, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, data_col=data_col, error_col=error_col, sep=sep): 2363 # Unpack. 2364 if data_col and error_col: 2365 mol_name, res_num, res_name, spin_num, spin_name, value, error = data 2366 elif data_col: 2367 mol_name, res_num, res_name, spin_num, spin_name, value = data 2368 error = None 2369 else: 2370 mol_name, res_num, res_name, spin_num, spin_name, error = data 2371 value = None 2372 2373 # Test the error value (cannot be 0.0). 2374 if error == 0.0: 2375 raise RelaxError("An invalid error value of zero has been encountered.") 2376 2377 # Get the corresponding spin container. 2378 spin_id = generate_spin_id_unique(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) 2379 spin = return_spin(spin_id) 2380 if spin == None: 2381 warn(RelaxNoSpinWarning(spin_id)) 2382 continue 2383 2384 # The dispersion point key. 2385 point_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=disp_frq) 2386 2387 # Store the R2eff data. 2388 if data_col: 2389 # Initialise if necessary. 2390 if not hasattr(spin, 'r2eff'): 2391 spin.r2eff = {} 2392 2393 # Store. 2394 spin.r2eff[point_key] = value 2395 2396 # Store the R2eff error. 2397 if error_col: 2398 # Initialise if necessary. 2399 if not hasattr(spin, 'r2eff_err'): 2400 spin.r2eff_err = {} 2401 2402 # Store. 2403 spin.r2eff_err[point_key] = error 2404 2405 # Data added. 2406 data_flag = True 2407 2408 # Append the data for printout. 2409 mol_names.append(mol_name) 2410 res_nums.append(res_num) 2411 res_names.append(res_name) 2412 spin_nums.append(spin_num) 2413 spin_names.append(spin_name) 2414 values.append(value) 2415 errors.append(error) 2416 2417 # Print out. 2418 write_spin_data(file=sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name='R2eff', error=errors, error_name='R2eff_error') 2419 2420 # Update the global structures. 2421 if data_flag: 2422 # Set the dispersion point frequency. 2423 if exp_type in EXP_TYPE_LIST_CPMG: 2424 cpmg_setup(spectrum_id=id, cpmg_frq=disp_frq) 2425 else: 2426 spin_lock_field(spectrum_id=id, field=disp_frq)
2427 2428
2429 -def r2eff_read_spin(id=None, spin_id=None, file=None, dir=None, disp_point_col=None, offset_col=None, data_col=None, error_col=None, sep=None):
2430 """Read R2eff/R1rho values from file whereby each row is a different dispersion point. 2431 2432 @keyword id: The experiment ID string to associate the data with. This will be modified to include the dispersion point data as "%s_%s" % (id, disp_point). 2433 @type id: str 2434 @keyword spin_id: The spin ID string. 2435 @type spin_id: str 2436 @keyword file: The name of the file to open. 2437 @type file: str 2438 @keyword dir: The directory containing the file (defaults to the current directory if None). 2439 @type dir: str or None 2440 @keyword disp_point_col: The column containing the dispersion point information. For CPMG-type data, this is the frequency of the CPMG pulse train. For R1rho-type data, this is the spin-lock field strength (nu1). The units must be Hertz. 2441 @type disp_point_col: int 2442 @keyword offset_col: This is for R1rho data - the dispersion point column can be substituted for the offset values in Hertz. 2443 @type offset_col: None or int 2444 @keyword data_col: The column containing the R2eff/R1rho data in Hz. 2445 @type data_col: int 2446 @keyword error_col: The column containing the R2eff/R1rho errors. 2447 @type error_col: int 2448 @keyword sep: The column separator which, if None, defaults to whitespace. 2449 @type sep: str or None 2450 """ 2451 2452 # Data checks. 2453 check_pipe() 2454 check_mol_res_spin_data() 2455 2456 # Get the spin. 2457 spin = return_spin(spin_id) 2458 if spin == None: 2459 raise RelaxNoSpinError(spin_id) 2460 2461 # Extract the data from the file, removing comments and blank lines. 2462 file_data = extract_data(file, dir, sep=sep) 2463 file_data = strip(file_data) 2464 2465 # Loop over the data. 2466 data = [] 2467 new_ids = [] 2468 for line in file_data: 2469 # Invalid columns. 2470 if disp_point_col != None and disp_point_col > len(line): 2471 warn(RelaxWarning("The data %s is invalid, no dispersion point column can be found." % line)) 2472 continue 2473 if offset_col != None and offset_col > len(line): 2474 warn(RelaxWarning("The data %s is invalid, no offset column can be found." % line)) 2475 continue 2476 if data_col > len(line): 2477 warn(RelaxWarning("The R2eff/R1rho data %s is invalid, no data column can be found." % line)) 2478 continue 2479 if error_col > len(line): 2480 warn(RelaxWarning("The R2eff/R1rho data %s is invalid, no error column can be found." % line)) 2481 continue 2482 2483 # Unpack. 2484 if disp_point_col != None: 2485 ref_data = line[disp_point_col-1] 2486 elif offset_col != None: 2487 ref_data = line[offset_col-1] 2488 value = line[data_col-1] 2489 error = line[error_col-1] 2490 2491 # Convert and check the dispersion point or offset. 2492 try: 2493 ref_data = float(ref_data) 2494 except ValueError: 2495 if disp_point_col != None: 2496 warn(RelaxWarning("The dispersion point data of the line %s is invalid." % line)) 2497 elif offset_col != None: 2498 warn(RelaxWarning("The offset data of the line %s is invalid." % line)) 2499 continue 2500 2501 # Convert and check the value. 2502 if value == 'None': 2503 value = None 2504 if value != None: 2505 try: 2506 value = float(value) 2507 except ValueError: 2508 warn(RelaxWarning("The R2eff/R1rho value of the line %s is invalid." % line)) 2509 continue 2510 2511 # Convert and check the error. 2512 if error == 'None': 2513 error = None 2514 if error != None: 2515 try: 2516 error = float(error) 2517 except ValueError: 2518 warn(RelaxWarning("The R2eff/R1rho error of the line %s is invalid." % line)) 2519 continue 2520 2521 # Test the error value (cannot be 0.0). 2522 if error == 0.0: 2523 raise RelaxError("An invalid error value of zero has been encountered.") 2524 2525 # Find the matching spectrum ID. 2526 new_id = None 2527 for spectrum_id in cdp.spectrum_ids: 2528 # Skip IDs which don't start with the base ID. 2529 if not search("^%s"%id, spectrum_id): 2530 continue 2531 2532 # Find a close enough dispersion point (to one decimal place to allow for user truncation). 2533 if disp_point_col != None: 2534 if hasattr(cdp, 'cpmg_frqs') and spectrum_id in cdp.cpmg_frqs: 2535 if abs(ref_data - cdp.cpmg_frqs[spectrum_id]) < 0.1: 2536 new_id = spectrum_id 2537 break 2538 if hasattr(cdp, 'spin_lock_nu1') and spectrum_id in cdp.spin_lock_nu1: 2539 if abs(ref_data - cdp.spin_lock_nu1[spectrum_id]) < 0.1: 2540 new_id = spectrum_id 2541 break 2542 2543 # Find a close enough offset (to one decimal place to allow for user truncation). 2544 elif offset_col != None: 2545 if hasattr(cdp, 'spin_lock_offset') and spectrum_id in cdp.spin_lock_offset: 2546 # The sign to multiply offsets by. 2547 sign = 1.0 2548 if spin.isotope == '15N': 2549 sign = -1.0 2550 2551 # Convert the data. 2552 data_new = sign * frequency_to_ppm(frq=ref_data, B0=cdp.spectrometer_frq[spectrum_id], isotope=spin.isotope) 2553 2554 # Store the ID. 2555 if abs(data_new - cdp.spin_lock_offset[spectrum_id]) < 0.1: 2556 new_id = spectrum_id 2557 break 2558 2559 # No match. 2560 if new_id == None: 2561 if disp_point_col != None: 2562 raise RelaxError("The experiment ID corresponding to the base ID '%s' and the dispersion point '%s' could not be found." % (id, ref_data)) 2563 if offset_col != None: 2564 raise RelaxError("The experiment ID corresponding to the base ID '%s' and the offset '%s' could not be found." % (id, data_new)) 2565 2566 # Add the ID to the list. 2567 new_ids.append(new_id) 2568 2569 # Data checks. 2570 check_frequency(id=new_id) 2571 check_exp_type(id=new_id) 2572 2573 # Store the spectrum ID. 2574 add_spectrum_id(new_id) 2575 2576 # Get the metadata. 2577 frq = get_frequency(id=new_id) 2578 exp_type = get_exp_type(id=new_id) 2579 2580 # The dispersion point key. 2581 if disp_point_col != None: 2582 disp_point = ref_data 2583 offset = 0.0 2584 elif offset_col != None: 2585 disp_point = cdp.spin_lock_nu1[new_id] 2586 offset = data_new 2587 point_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=disp_point) 2588 2589 # Store the R2eff data. 2590 if data_col: 2591 # Initialise if necessary. 2592 if not hasattr(spin, 'r2eff'): 2593 spin.r2eff = {} 2594 2595 # Store. 2596 spin.r2eff[point_key] = value 2597 2598 # Store the R2eff error. 2599 if error_col: 2600 # Initialise if necessary. 2601 if not hasattr(spin, 'r2eff_err'): 2602 spin.r2eff_err = {} 2603 2604 # Store. 2605 spin.r2eff_err[point_key] = error 2606 2607 # Append the data for printout. 2608 if disp_point_col != None: 2609 data.append(["%-40s" % point_key, "%20.15f" % disp_point, "%20.15f" % value, "%20.15f" % error]) 2610 else: 2611 data.append(["%-40s" % point_key, "%20.15f" % offset, "%20.15f" % value, "%20.15f" % error]) 2612 2613 # Data added. 2614 data_flag = True 2615 2616 # No data, so fail hard! 2617 if not len(data): 2618 raise RelaxError("No R2eff/R1rho data could be extracted.") 2619 2620 # Print out. 2621 print("The following R2eff/R1rho data has been loaded into the relax data store:\n") 2622 if disp_point_col != None: 2623 write_data(out=sys.stdout, headings=["R2eff_key", "Disp_point", "R2eff", "R2eff_error"], data=data) 2624 else: 2625 write_data(out=sys.stdout, headings=["R2eff_key", "Offset (ppm)", "R2eff", "R2eff_error"], data=data)
2626 2627
2628 -def randomise_R1(spin=None, ri_id=None, N=None):
2629 """Randomise the R1 data for the given spin for use in the Monte Carlo simulations. 2630 2631 @keyword spin: The spin container to randomise the data for. 2632 @type spin: SpinContainer instance 2633 @keyword ri_id: The relaxation data ID string. 2634 @type ri_id: str 2635 @keyword N: The number of randomisations to perform. 2636 @type N: int 2637 """ 2638 2639 # The data already exists. 2640 if hasattr(spin, 'ri_data_sim') and ri_id in spin.ri_data_sim: 2641 return 2642 2643 # Initialise the structure. 2644 if not hasattr(spin, 'ri_data_sim'): 2645 spin.ri_data_sim = {} 2646 spin.ri_data_sim[ri_id] = [] 2647 2648 # Randomise. 2649 for i in range(N): 2650 spin.ri_data_sim[ri_id].append(gauss(spin.ri_data[ri_id], spin.ri_data_err[ri_id]))
2651 2652
2653 -def relax_time(time=0.0, spectrum_id=None):
2654 """Set the relaxation time period associated with a given spectrum. 2655 2656 @keyword time: The time, in seconds, of the relaxation period. 2657 @type time: float 2658 @keyword spectrum_id: The spectrum identification string. 2659 @type spectrum_id: str 2660 """ 2661 2662 # Test if the spectrum id exists. 2663 if spectrum_id not in cdp.spectrum_ids: 2664 raise RelaxNoSpectraError(spectrum_id) 2665 2666 # Initialise the global relaxation time data structures if needed. 2667 if not hasattr(cdp, 'relax_times'): 2668 cdp.relax_times = {} 2669 if not hasattr(cdp, 'relax_time_list'): 2670 cdp.relax_time_list = [] 2671 2672 # Add the time, converting to a float if needed. 2673 cdp.relax_times[spectrum_id] = float(time) 2674 2675 # The unique time points. 2676 if cdp.relax_times[spectrum_id] not in cdp.relax_time_list: 2677 cdp.relax_time_list.append(cdp.relax_times[spectrum_id]) 2678 cdp.relax_time_list.sort() 2679 2680 # Update the exponential time point count. 2681 cdp.num_time_pts = len(cdp.relax_time_list) 2682 2683 # Printout. 2684 print("Setting the '%s' spectrum relaxation time period to %s s." % (spectrum_id, cdp.relax_times[spectrum_id]))
2685 2686
2687 -def return_cpmg_frqs(ref_flag=True):
2688 """Return the list of nu_CPMG frequencies. 2689 2690 @keyword ref_flag: A flag which if False will cause the reference spectrum frequency of None to be removed from the list. 2691 @type ref_flag: bool 2692 @return: The list of nu_CPMG frequencies in Hz. It has the dimensions {Ei, Mi, Oi}. 2693 @rtype: rank-2 list of numpy rank-1 float64 arrays 2694 """ 2695 2696 # No data. 2697 if not hasattr(cdp, 'cpmg_frqs_list'): 2698 return None 2699 2700 # Initialise. 2701 cpmg_frqs = [] 2702 2703 # First loop over the experiment types. 2704 for exp_type, ei in loop_exp(return_indices=True): 2705 # Add a new dimension. 2706 cpmg_frqs.append([]) 2707 2708 # Then loop over the spectrometer frequencies. 2709 for frq, mi in loop_frq(return_indices=True): 2710 # Add a new dimension. 2711 cpmg_frqs[ei].append([]) 2712 2713 # Loop over the offsets. 2714 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 2715 # Add a new dimension. 2716 cpmg_frqs[ei][mi].append([]) 2717 2718 # Loop over the fields. 2719 for point in cdp.cpmg_frqs_list: 2720 # Skip reference points. 2721 if (not ref_flag) and point == None: 2722 continue 2723 2724 # Find a matching experiment ID. 2725 found = False 2726 for id in cdp.exp_type: 2727 # Skip non-matching experiments. 2728 if cdp.exp_type[id] != exp_type: 2729 continue 2730 2731 # Skip non-matching spectrometer frequencies. 2732 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 2733 continue 2734 2735 # Skip non-matching points. 2736 if cdp.cpmg_frqs[id] != point: 2737 continue 2738 2739 # Found. 2740 found = True 2741 break 2742 2743 # No data. 2744 if not found: 2745 continue 2746 2747 # Add the data. 2748 cpmg_frqs[ei][mi][oi].append(point) 2749 2750 # Convert to a numpy array. 2751 cpmg_frqs[ei][mi][oi] = array(cpmg_frqs[ei][mi][oi], float64) 2752 2753 # Return the data. 2754 return cpmg_frqs
2755 2756
2757 -def return_cpmg_frqs_single(exp_type=None, frq=None, offset=None, time=None, ref_flag=True):
2758 """Return the list of nu_CPMG frequencies. 2759 2760 @keyword exp_type: The experiment type. 2761 @type exp_type: str 2762 @keyword frq: The spectrometer frequency in Hz. 2763 @type frq: float 2764 @keyword offset: The hard pulse offset, if desired. 2765 @type offset: None or float 2766 @keyword time: The relaxation time period. 2767 @type time: float 2768 @keyword ref_flag: A flag which if False will cause the reference spectrum frequency of None to be removed from the list. 2769 @type ref_flag: bool 2770 @return: The list of nu_CPMG frequencies in Hz. 2771 @rtype: numpy rank-1 float64 array 2772 """ 2773 2774 # No data. 2775 if not hasattr(cdp, 'cpmg_frqs_list'): 2776 return None 2777 2778 # Initialise. 2779 cpmg_frqs = [] 2780 2781 # Loop over the points. 2782 for point in cdp.cpmg_frqs_list: 2783 # Skip reference points. 2784 if (not ref_flag) and point == None: 2785 continue 2786 2787 # Find a matching experiment ID. 2788 found = False 2789 for id in cdp.exp_type: 2790 # Skip non-matching experiments. 2791 if cdp.exp_type[id] != exp_type: 2792 continue 2793 2794 # Skip non-matching spectrometer frequencies. 2795 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 2796 continue 2797 2798 # Skip non-matching offsets. 2799 if offset != None and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 2800 continue 2801 2802 # Skip non-matching time points. 2803 if time != None and hasattr(cdp, 'relax_times') and cdp.relax_times[id] != time: 2804 continue 2805 2806 # Skip non-matching points. 2807 if cdp.cpmg_frqs[id] != point: 2808 continue 2809 2810 # Found. 2811 found = True 2812 break 2813 2814 # No data. 2815 if not found: 2816 continue 2817 2818 # Add the data. 2819 cpmg_frqs.append(point) 2820 2821 # Return the data as a numpy array. 2822 return array(cpmg_frqs, float64)
2823 2824
2825 -def return_grace_data_vs_disp(y_axis=None, x_axis=None, interpolate=None, exp_type=None, ei=None, current_spin=None, spin_id=None, si=None, back_calc=None, cpmg_frqs_new=None, spin_lock_nu1_new=None, chemical_shifts=None, offsets_inter=None, tilt_angles_inter=None, Delta_omega_inter=None, w_eff_inter=None, interpolated_flag=None, graph_index=None, data=None, set_labels=None, set_colours=None, x_axis_type_zero=None, symbols=None, symbol_sizes=None, linetype=None, linestyle=None, axis_labels=None):
2826 """Return data in lists for 2D Grace plotting function, to prepate plotting R1rho R2 as function of effective field in rotating frame w_eff. 2827 2828 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 2829 @type y_axis: str 2830 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 2831 @type x_axis: str 2832 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 2833 @type interpolate: float 2834 @keyword exp_type: The experiment type. 2835 @type exp_type: str 2836 @keyword ei: The experiment type index. 2837 @type ei: int 2838 @keyword current_spin: The specific spin data container. 2839 @type current_spin: SpinContainer instance. 2840 @keyword spin_id: The spin ID string. 2841 @type spin_id: str 2842 @keyword si: The index of the given spin in the cluster. 2843 @type si: int 2844 @keyword back_calc: The back calculated data. The first index corresponds to the experiment type, the second is the spin of the cluster, the third is the magnetic field strength, and the fourth is the dispersion point. 2845 @type back_calc: list of lists of lists of lists of float 2846 @keyword cpmg_frqs_new: The interpolated CPMG frequencies in Hertz. The dimensions are {Ei, Mi, Oi}. 2847 @type cpmg_frqs_new: rank-3 list of floats 2848 @keyword spin_lock_nu1_new: The interpolated spin-lock field strengths in Hertz. The dimensions are {Ei, Mi, Oi}. 2849 @type spin_lock_nu1_new: rank-3 list of floats 2850 @keyword chemical_shifts: The chemical shifts in rad/s {Ei, Si, Mi} 2851 @type chemical_shifts: rank-3 list of floats 2852 @keyword offsets_inter: Interpolated spin-lock offsets in rad/s {Ei, Si, Mi, Oi} 2853 @type offsets_inter: rank-3 list of numpy rank-1 float arrays 2854 @keyword tilt_angles_inter: The interpolated rotating frame tilt angles {Ei, Si, Mi, Oi, Di} 2855 @type tilt_angles_inter: rank-5 list of floats 2856 @keyword Delta_omega_inter: The interpolated average resonance offset in the rotating frame in rad/s {Ei, Si, Mi, Oi, Di} 2857 @type Delta_omega_inter: rank-5 list of floats 2858 @keyword w_eff_inter: The interpolated effective field in rotating frame in rad/s {Ei, Si, Mi, Oi, Di}. 2859 @type w_eff_inter: rank-5 list of floats 2860 @keyword interpolated_flag: Flag telling if the graph should be interpolated. 2861 @type interpolated_flag: bool 2862 @keyword graph_index: Graph index for xmgrace. 2863 @type graph_index: int 2864 @keyword data: The 4D structure of numerical data to graph (see docstring). 2865 @type data: list of lists of lists of float 2866 @keyword set_labels: Data labels to be used per experiment. 2867 @type set_labels: list of list of strings 2868 @keyword set_colours: The colours for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 2869 @type set_colours: None or list of list of int 2870 @keyword x_axis_type_zero: The flags specifying if the X-axis should be placed at zero. 2871 @type x_axis_type_zero: list of lists of bool 2872 @keyword symbols: The symbol style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 2873 @type symbols: list of list of int 2874 @keyword symbol_sizes: The symbol size for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 2875 @type symbol_sizes: list of list of int 2876 @keyword linetype: The line type for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 2877 @type linetype: list of list of int 2878 @keyword linestyle: The line style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 2879 @type linestyle: list of list of int 2880 @keyword axis_labels: The labels for the axes (in the [X, Y] list format). The first dimension is the graph. 2881 @type axis_labels: list of list of str 2882 @return: The xy graph or xydy error graph, the 4D structure of numerical data to grace graph, the names associated with each graph data set Gx.Sy, the colours for each graph data set Gx.Sy, flags specifying if the X-axis should be placed at zero, the symbol style for each graph data set Gx.Sy, the symbol size for each graph data set Gx.Sy, the line type for each graph data set Gx.Sy, the line style for each graph data set Gx.Sy, the labels for the axes (in the [X, Y] list format). 2883 @rtype: boolean, list of lists of lists of float, list of list of str, list of list of int, list of lists of bool, list of list of int, list of list of int, list of list of int, list of list of int, list of list of str 2884 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 2885 2886 set_index = 0 2887 err = False 2888 colour_index = 0 2889 2890 # Return r1. 2891 field_count = cdp.spectrometer_frq_count 2892 r1 = return_r1_data(spins=[current_spin], spin_ids=[spin_id], field_count=field_count) 2893 r1_err = return_r1_err_data(spins=[current_spin], spin_ids=[spin_id], field_count=field_count) 2894 2895 # Add the recorded data points. 2896 data_type = "data" 2897 for frq, offset, mi, oi in loop_frq_offset(exp_type=exp_type, return_indices=True): 2898 # Add a new set for the data at each frequency and offset. 2899 data[graph_index].append([]) 2900 2901 # Return data label plotting info. 2902 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, offset=offset, interpolated_flag=interpolated_flag) 2903 2904 # Save settings. 2905 set_labels[ei].append(label) 2906 symbols[graph_index].append(symbols_int) 2907 symbol_sizes[graph_index].append(symbol_sizes_float) 2908 linetype[graph_index].append(linetype_int) 2909 linestyle[graph_index].append(linestyle_int) 2910 2911 # The other settings. 2912 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 2913 x_axis_type_zero[graph_index].append(True) 2914 2915 # Loop over the dispersion points. 2916 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 2917 # The data key. 2918 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 2919 2920 # No data present. 2921 if key not in current_spin.r2eff: 2922 continue 2923 2924 # Convert offset to rad/s from ppm. 2925 if hasattr(current_spin, 'isotope'): 2926 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 2927 else: 2928 offset_rad = 0.0 2929 2930 # Convert spin-lock field strength from Hz to rad/s. 2931 omega1 = point * 2.0 * pi 2932 2933 # Return the rotating frame parameters. 2934 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 2935 2936 # Return the x and y point. 2937 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, point=point, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 2938 2939 # Add the data. 2940 data[graph_index][set_index].append([x_point, y_point]) 2941 2942 # Handle the errors. 2943 if err: 2944 data[graph_index][set_index][-1].append(y_err_point) 2945 2946 # Increment the graph set index. 2947 set_index += 1 2948 colour_index += 1 2949 2950 # Add the back calculated data. 2951 colour_index = 0 2952 data_type = "back_calculated" 2953 for frq, offset, mi, oi in loop_frq_offset(exp_type=exp_type, return_indices=True): 2954 # Add a new set for the data at each frequency and offset. 2955 data[graph_index].append([]) 2956 2957 # Return data label plotting info. 2958 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, offset=offset, interpolated_flag=interpolated_flag) 2959 2960 # Save settings. 2961 set_labels[ei].append(label) 2962 symbols[graph_index].append(symbols_int) 2963 symbol_sizes[graph_index].append(symbol_sizes_float) 2964 linetype[graph_index].append(linetype_int) 2965 linestyle[graph_index].append(linestyle_int) 2966 2967 # The other settings. 2968 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 2969 x_axis_type_zero[graph_index].append(True) 2970 2971 # Loop over the dispersion points. 2972 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 2973 # The data key. 2974 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 2975 2976 # No data present. 2977 if not hasattr(current_spin, 'r2eff_bc') or key not in current_spin.r2eff_bc: 2978 continue 2979 2980 # Convert offset to rad/s from ppm. 2981 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 2982 2983 # Convert spin-lock field strength from Hz to rad/s. 2984 omega1 = point * 2.0 * pi 2985 2986 # Return the rotating frame parameters. 2987 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 2988 2989 # Return the x and y point. 2990 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, point=point, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 2991 2992 # Add the data. 2993 data[graph_index][set_index].append([x_point, y_point]) 2994 2995 # Handle the errors. 2996 if err: 2997 data[graph_index][set_index][-1].append(None) 2998 2999 # Increment the graph set index. 3000 set_index += 1 3001 colour_index += 1 3002 3003 # Add the interpolated back calculated data. 3004 data_type = "interpolated" 3005 if interpolated_flag: 3006 colour_index = 0 3007 for frq, offset, mi, oi in loop_frq_offset(exp_type=exp_type, return_indices=True): 3008 # Add a new set for the data at each frequency and offset. 3009 data[graph_index].append([]) 3010 3011 # Return data label plotting info. 3012 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(spin=current_spin, data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, offset=offset, interpolated_flag=interpolated_flag) 3013 3014 # Save settings. 3015 set_labels[ei].append(label) 3016 symbols[graph_index].append(symbols_int) 3017 symbol_sizes[graph_index].append(symbol_sizes_float) 3018 linetype[graph_index].append(linetype_int) 3019 linestyle[graph_index].append(linestyle_int) 3020 3021 # The other settings. 3022 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3023 x_axis_type_zero[graph_index].append(True) 3024 3025 # Loop over the dispersion points. 3026 for di, r2eff in enumerate(back_calc[ei][si][mi][oi]): 3027 # Skip invalid points (values of 1e100). 3028 if r2eff > 1e50: 3029 continue 3030 3031 # The X point. 3032 if exp_type in EXP_TYPE_LIST_CPMG: 3033 point = cpmg_frqs_new[ei][mi][oi][di] 3034 else: 3035 point = spin_lock_nu1_new[ei][mi][oi][di] 3036 3037 theta = tilt_angles_inter[ei][si][mi][oi][di] 3038 w_eff = w_eff_inter[ei][si][mi][oi][di] 3039 3040 # Return the x and y point. 3041 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, back_calc=r2eff, point=point, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3042 3043 # Add the data. 3044 data[graph_index][set_index].append([x_point, y_point]) 3045 3046 # Handle the errors. 3047 if err: 3048 data[graph_index][set_index][-1].append(None) 3049 3050 # Increment the graph set index. 3051 set_index += 1 3052 colour_index += 1 3053 3054 # Add the residuals for statistical comparison. 3055 colour_index = 0 3056 data_type = "residual" 3057 for frq, offset, mi, oi in loop_frq_offset(exp_type=exp_type, return_indices=True): 3058 # Add a new set for the data at each frequency and offset. 3059 data[graph_index].append([]) 3060 3061 # Return data label plotting info. 3062 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(spin=current_spin, data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, offset=offset, interpolated_flag=interpolated_flag) 3063 3064 # Save settings. 3065 set_labels[ei].append(label) 3066 symbols[graph_index].append(symbols_int) 3067 symbol_sizes[graph_index].append(symbol_sizes_float) 3068 linetype[graph_index].append(linetype_int) 3069 linestyle[graph_index].append(linestyle_int) 3070 3071 # The other settings. 3072 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3073 x_axis_type_zero[graph_index].append(True) 3074 3075 # Loop over the dispersion points. 3076 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 3077 # The data key. 3078 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 3079 3080 # No data present. 3081 if key not in current_spin.r2eff or not hasattr(current_spin, 'r2eff_bc') or key not in current_spin.r2eff_bc: 3082 continue 3083 3084 # Convert offset to rad/s from ppm. 3085 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 3086 3087 # Convert spin-lock field strength from Hz to rad/s. 3088 omega1 = point * 2.0 * pi 3089 3090 # Return the rotating frame parameters. 3091 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 3092 3093 # Return the x and y point. 3094 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, y_axis=y_axis, x_axis=x_axis, interpolate=interpolate, data_key=key, spin=current_spin, point=point, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3095 3096 # Add the data. 3097 data[graph_index][set_index].append([x_point, y_point]) 3098 3099 # Handle the errors. 3100 if err: 3101 data[graph_index][set_index][-1].append(y_err_point) 3102 3103 # Increment the graph set index. 3104 set_index += 1 3105 colour_index += 1 3106 3107 # The axis labels. 3108 x_axis_label, y_axis_label = return_grace_x_y_axis_labels(y_axis=y_axis, x_axis=x_axis, exp_type=exp_type, interpolate=interpolate) 3109 axis_labels.append([x_axis_label, y_axis_label]) 3110 3111 return err, data, set_labels, set_colours, x_axis_type_zero, symbols, symbol_sizes, linetype, linestyle, axis_labels
3112 3113
3114 -def return_grace_data_vs_offset(y_axis=None, x_axis=None, interpolate=None, exp_type=None, ei=None, current_spin=None, spin_id=None, si=None, back_calc=None, cpmg_frqs_new=None, spin_lock_nu1_new=None, chemical_shifts=None, offsets_inter=None, tilt_angles_inter=None, Delta_omega_inter=None, w_eff_inter=None, interpolated_flag=None, graph_index=None, data=None, set_labels=None, set_colours=None, x_axis_type_zero=None, symbols=None, symbol_sizes=None, linetype=None, linestyle=None, axis_labels=None):
3115 """Return data in lists for 2D Grace plotting function, to prepate plotting R1rho R2 as function of effective field in rotating frame w_eff. 3116 3117 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3118 @type y_axis: str 3119 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 3120 @type x_axis: str 3121 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 3122 @type interpolate: float 3123 @keyword exp_type: The experiment type. 3124 @type exp_type: str 3125 @keyword ei: The experiment type index. 3126 @type ei: int 3127 @keyword current_spin: The specific spin data container. 3128 @type current_spin: SpinContainer instance. 3129 @keyword spin_id: The spin ID string. 3130 @type spin_id: str 3131 @keyword si: The index of the given spin in the cluster. 3132 @type si: int 3133 @keyword back_calc: The back calculated data. The first index corresponds to the experiment type, the second is the spin of the cluster, the third is the magnetic field strength, and the fourth is the dispersion point. 3134 @type back_calc: list of lists of lists of lists of float 3135 @keyword cpmg_frqs_new: The interpolated CPMG frequencies in Hertz. The dimensions are {Ei, Mi, Oi}. 3136 @type cpmg_frqs_new: rank-3 list of floats 3137 @keyword spin_lock_nu1_new: The interpolated spin-lock field strengths in Hertz. The dimensions are {Ei, Mi, Oi}. 3138 @type spin_lock_nu1_new: rank-3 list of floats 3139 @keyword chemical_shifts: The chemical shifts in rad/s {Ei, Si, Mi} 3140 @type chemical_shifts: rank-3 list of floats 3141 @keyword offsets_inter: Interpolated spin-lock offsets in rad/s {Ei, Si, Mi, Oi} 3142 @type offsets_inter: rank-3 list of numpy rank-1 float arrays 3143 @keyword tilt_angles_inter: The interpolated rotating frame tilt angles {Ei, Si, Mi, Oi, Di} 3144 @type tilt_angles_inter: rank-5 list of floats 3145 @keyword Delta_omega_inter: The interpolated average resonance offset in the rotating frame in rad/s {Ei, Si, Mi, Oi, Di} 3146 @type Delta_omega_inter: rank-5 list of floats 3147 @keyword w_eff_inter: The interpolated effective field in rotating frame in rad/s {Ei, Si, Mi, Oi, Di}. 3148 @type w_eff_inter: rank-5 list of floats 3149 @keyword interpolated_flag: Flag telling if the graph should be interpolated. 3150 @type interpolated_flag: bool 3151 @keyword graph_index: Graph index for xmgrace. 3152 @type graph_index: int 3153 @keyword data: The 4D structure of numerical data to graph (see docstring). 3154 @type data: list of lists of lists of float 3155 @keyword set_labels: Data labels to be used per experiment. 3156 @type set_labels: list of list of strings 3157 @keyword set_colours: The colours for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 3158 @type set_colours: None or list of list of int 3159 @keyword x_axis_type_zero: The flags specifying if the X-axis should be placed at zero. 3160 @type x_axis_type_zero: list of lists of bool 3161 @keyword symbols: The symbol style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 3162 @type symbols: list of list of int 3163 @keyword symbol_sizes: The symbol size for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 3164 @type symbol_sizes: list of list of int 3165 @keyword linetype: The line type for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 3166 @type linetype: list of list of int 3167 @keyword linestyle: The line style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 3168 @type linestyle: list of list of int 3169 @keyword axis_labels: The labels for the axes (in the [X, Y] list format). The first dimension is the graph. 3170 @type axis_labels: list of list of str 3171 @return: The xy graph or xydy error graph, the 4D structure of numerical data to grace graph, the names associated with each graph data set Gx.Sy, the colours for each graph data set Gx.Sy, flags specifying if the X-axis should be placed at zero, the symbol style for each graph data set Gx.Sy, the symbol size for each graph data set Gx.Sy, the line type for each graph data set Gx.Sy, the line style for each graph data set Gx.Sy, the labels for the axes (in the [X, Y] list format). 3172 @rtype: boolean, list of lists of lists of float, list of list of str, list of list of int, list of lists of bool, list of list of int, list of list of int, list of list of int, list of list of int, list of list of str 3173 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 3174 3175 set_index = 0 3176 err = False 3177 colour_index = 0 3178 3179 # Return r1. 3180 field_count = cdp.spectrometer_frq_count 3181 r1 = return_r1_data(spins=[current_spin], spin_ids=[spin_id], field_count=field_count) 3182 r1_err = return_r1_err_data(spins=[current_spin], spin_ids=[spin_id], field_count=field_count) 3183 3184 # Add the recorded data points. 3185 data_type = "data" 3186 for frq, mi in loop_frq(return_indices=True): 3187 # Loop over the all the dispersion points. 3188 for di, point in enumerate(spin_lock_nu1_new[ei][mi][0]): 3189 # Add a new set for the data at each frequency and offset. 3190 data[graph_index].append([]) 3191 3192 # Return data label plotting info. 3193 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, point=point, interpolated_flag=interpolated_flag) 3194 3195 # Save settings. 3196 set_labels[ei].append(label) 3197 symbols[graph_index].append(symbols_int) 3198 symbol_sizes[graph_index].append(symbol_sizes_float) 3199 linetype[graph_index].append(linetype_int) 3200 linestyle[graph_index].append(linestyle_int) 3201 3202 # The other settings. 3203 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3204 x_axis_type_zero[graph_index].append(True) 3205 3206 # Loop over the spin_lock offsets. 3207 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 3208 # The data key. 3209 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 3210 3211 # No data present. 3212 if key not in current_spin.r2eff: 3213 continue 3214 3215 # Convert offset to rad/s from ppm. 3216 if hasattr(current_spin, 'isotope'): 3217 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 3218 else: 3219 offset_rad = 0.0 3220 3221 # Convert spin-lock field strength from Hz to rad/s. 3222 omega1 = point * 2.0 * pi 3223 3224 # Return the rotating frame parameters. 3225 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 3226 3227 # Return the x and y point. 3228 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, offset=offset, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3229 3230 # Add the data. 3231 data[graph_index][set_index].append([x_point, y_point]) 3232 3233 # Handle the errors. 3234 if err: 3235 data[graph_index][set_index][-1].append(y_err_point) 3236 3237 # Increment the graph set index. 3238 set_index += 1 3239 colour_index += 1 3240 3241 # Add the back calculated data. 3242 colour_index = 0 3243 data_type = "back_calculated" 3244 for frq, mi in loop_frq(return_indices=True): 3245 # Loop over the all the dispersion points. 3246 for di, point in enumerate(spin_lock_nu1_new[ei][mi][0]): 3247 # Add a new set for the data at each frequency and offset. 3248 data[graph_index].append([]) 3249 3250 # Return data label plotting info. 3251 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, point=point, interpolated_flag=interpolated_flag) 3252 3253 # Save settings. 3254 set_labels[ei].append(label) 3255 symbols[graph_index].append(symbols_int) 3256 symbol_sizes[graph_index].append(symbol_sizes_float) 3257 linetype[graph_index].append(linetype_int) 3258 linestyle[graph_index].append(linestyle_int) 3259 3260 # The other settings. 3261 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3262 x_axis_type_zero[graph_index].append(True) 3263 3264 # Loop over the spin_lock offsets. 3265 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 3266 # The data key. 3267 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 3268 3269 # No data present. 3270 if not hasattr(current_spin, 'r2eff_bc') or key not in current_spin.r2eff_bc: 3271 continue 3272 3273 # Convert offset to rad/s from ppm. 3274 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 3275 3276 # Convert spin-lock field strength from Hz to rad/s. 3277 omega1 = point * 2.0 * pi 3278 3279 # Return the rotating frame parameters. 3280 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 3281 3282 # Return the x and y point. 3283 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, offset=offset, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3284 3285 # Add the data. 3286 data[graph_index][set_index].append([x_point, y_point]) 3287 3288 # Handle the errors. 3289 if err: 3290 data[graph_index][set_index][-1].append(None) 3291 3292 # Increment the graph set index. 3293 set_index += 1 3294 colour_index += 1 3295 3296 # Add the interpolated back calculated data. 3297 data_type = "interpolated" 3298 if interpolated_flag: 3299 colour_index = 0 3300 for frq, mi in loop_frq(return_indices=True): 3301 # Loop over the all the dispersion points. 3302 for di, point in enumerate(spin_lock_nu1_new[ei][mi][0]): 3303 # Add a new set for the data at each frequency and dispersion points. 3304 data[graph_index].append([]) 3305 3306 # Return data label plotting info. 3307 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(spin=current_spin, data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, point=point, interpolated_flag=interpolated_flag) 3308 3309 # Save settings. 3310 set_labels[ei].append(label) 3311 symbols[graph_index].append(symbols_int) 3312 symbol_sizes[graph_index].append(symbol_sizes_float) 3313 linetype[graph_index].append(linetype_int) 3314 linestyle[graph_index].append(linestyle_int) 3315 3316 # The other settings. 3317 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3318 x_axis_type_zero[graph_index].append(True) 3319 3320 # Loop over the offsets. 3321 for oi, r2eff_arr in enumerate(back_calc[ei][si][mi]): 3322 # Assign r2eff 3323 r2eff = r2eff_arr[di] 3324 3325 # Skip invalid points (values of 1e100). 3326 if r2eff > 1e50: 3327 continue 3328 3329 # The X point. 3330 if exp_type in EXP_TYPE_LIST_CPMG: 3331 offset = None 3332 theta = None 3333 w_eff = None 3334 3335 else: 3336 theta = tilt_angles_inter[ei][si][mi][oi][di] 3337 w_eff = w_eff_inter[ei][si][mi][oi][di] 3338 offset = frequency_to_ppm_from_rad(frq=offsets_inter[ei][si][mi][oi], B0=frq, isotope=current_spin.isotope) 3339 3340 # Return the x and y point. 3341 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, x_axis=x_axis, y_axis=y_axis, interpolate=interpolate, data_key=key, spin=current_spin, back_calc=r2eff, offset=offset, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3342 3343 # Add the data. 3344 data[graph_index][set_index].append([x_point, y_point]) 3345 3346 # Handle the errors. 3347 if err: 3348 data[graph_index][set_index][-1].append(None) 3349 3350 # Increment the graph set index. 3351 set_index += 1 3352 colour_index += 1 3353 3354 # Add the residuals for statistical comparison. 3355 colour_index = 0 3356 data_type = "residual" 3357 for frq, mi in loop_frq(return_indices=True): 3358 # Loop over the all the dispersion points. 3359 for di, point in enumerate(spin_lock_nu1_new[ei][mi][0]): 3360 # Add a new set for the data at each frequency and offset. 3361 data[graph_index].append([]) 3362 3363 # Return data label plotting info. 3364 label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int = return_x_y_data_labels_settings(spin=current_spin, data_type=data_type, y_axis=y_axis, exp_type=exp_type, frq=frq, point=point, interpolated_flag=interpolated_flag) 3365 3366 # Save settings. 3367 set_labels[ei].append(label) 3368 symbols[graph_index].append(symbols_int) 3369 symbol_sizes[graph_index].append(symbol_sizes_float) 3370 linetype[graph_index].append(linetype_int) 3371 linestyle[graph_index].append(linestyle_int) 3372 3373 # The other settings. 3374 set_colours[graph_index].append(COLOUR_ORDER[colour_index]) 3375 x_axis_type_zero[graph_index].append(True) 3376 3377 # Loop over the spin_lock offsets. 3378 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 3379 # The data key. 3380 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 3381 3382 # No data present. 3383 if key not in current_spin.r2eff or not hasattr(current_spin, 'r2eff_bc') or key not in current_spin.r2eff_bc: 3384 continue 3385 3386 # Convert offset to rad/s from ppm. 3387 offset_rad = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=current_spin.isotope) 3388 3389 # Convert spin-lock field strength from Hz to rad/s. 3390 omega1 = point * 2.0 * pi 3391 3392 # Return the rotating frame parameters. 3393 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=chemical_shifts[ei][si][mi], spin_lock_offset=offset_rad, omega1=omega1) 3394 3395 # Return the x and y point. 3396 x_point, y_point, err, y_err_point = return_grace_x_y_point(data_type=data_type, y_axis=y_axis, x_axis=x_axis, interpolate=interpolate, data_key=key, spin=current_spin, offset=offset, r1=r1[si][mi], r1_err=r1_err[si][mi], w_eff=w_eff, theta=theta, err=err) 3397 3398 # Add the data. 3399 data[graph_index][set_index].append([x_point, y_point]) 3400 3401 # Handle the errors. 3402 if err: 3403 data[graph_index][set_index][-1].append(y_err_point) 3404 3405 # Increment the graph set index. 3406 set_index += 1 3407 colour_index += 1 3408 3409 # The axis labels. 3410 x_axis_label, y_axis_label = return_grace_x_y_axis_labels(y_axis=y_axis, x_axis=x_axis, exp_type=exp_type, interpolate=interpolate) 3411 axis_labels.append([x_axis_label, y_axis_label]) 3412 3413 return err, data, set_labels, set_colours, x_axis_type_zero, symbols, symbol_sizes, linetype, linestyle, axis_labels
3414 3415
3416 -def return_grace_file_name_ini(y_axis=None, x_axis=None, interpolate=None):
3417 """Return the initial part of the file name for the xmgrace plot files. 3418 3419 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3420 @type y_axis: str 3421 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 3422 @type x_axis: str 3423 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 3424 @type interpolate: float 3425 @return: The X-axis label for grace plotting, yhe Y-axis label for grace plotting 3426 @rtype: str, str 3427 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 3428 3429 if y_axis == Y_AXIS_R2_EFF and x_axis == X_AXIS_DISP and interpolate == INTERPOLATE_DISP: 3430 file_name_ini = "disp" 3431 3432 # Special file name for R2_R1RHO data. 3433 elif has_r1rho_exp_type() and y_axis == Y_AXIS_R2_EFF and x_axis != X_AXIS_DISP: 3434 file_name_ini = "%s_vs_%s_inter_%s"%("r1rho", x_axis, interpolate) 3435 3436 elif has_cpmg_exp_type() and y_axis == Y_AXIS_R2_R1RHO: 3437 file_name_ini = "%s_vs_%s_inter_%s"%("r2", x_axis, interpolate) 3438 3439 else: 3440 file_name_ini = "%s_vs_%s_inter_%s"%(y_axis, x_axis, interpolate) 3441 3442 # Return axis labels 3443 return file_name_ini
3444 3445
3446 -def return_grace_x_y_axis_labels(y_axis=None, x_axis=None, exp_type=None, interpolate=None):
3447 """Return the X and Y labels and plot settings, according to selected axis to plot for. 3448 3449 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3450 @type y_axis: str 3451 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 3452 @type x_axis: str 3453 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 3454 @type interpolate: float 3455 @return: The X-axis label for grace plotting, yhe Y-axis label for grace plotting 3456 @rtype: str, str 3457 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 3458 3459 # If x_axis is with dispersion points. 3460 if x_axis == X_AXIS_DISP: 3461 if interpolate == INTERPOLATE_DISP: 3462 if exp_type in EXP_TYPE_LIST_CPMG: 3463 # Set x_label. 3464 x_label = "\\qCPMG pulse train frequency \\xn\\B\\sCPMG\\N\\Q (Hz)" 3465 3466 elif exp_type in EXP_TYPE_LIST_R1RHO: 3467 # Set x_label. 3468 x_label = "\\qSpin-lock field strength \\xn\\B\\s1\\N\\Q (Hz)" 3469 3470 elif interpolate == INTERPOLATE_OFFSET: 3471 x_label = "\\qSpin-lock offset \\Q (ppm)" 3472 3473 # If x_axis is effective field w_eff. 3474 elif x_axis == X_AXIS_W_EFF: 3475 # Set x_label. 3476 x_label = "\\qEffective field in rotating frame \\xw\\B\\seff\\N\\Q (rad.s\\S-1\\N)" 3477 3478 # If x_axis is angle theta. 3479 elif x_axis == X_AXIS_THETA: 3480 # Set x_label. 3481 x_label = "\\qRotating frame tilt angle \\xq\\B\\Q (rad)" 3482 3483 # If plotting either CPMG R2eff or R1rho. 3484 if y_axis == Y_AXIS_R2_EFF: 3485 if exp_type in EXP_TYPE_LIST_CPMG: 3486 # Set y_label. 3487 y_label = "%s - \\qR\\s2,eff\\N\\Q (rad.s\\S-1\\N)"%exp_type 3488 3489 elif exp_type in EXP_TYPE_LIST_R1RHO: 3490 # Set y_label. 3491 y_label = "%s - \\qR\\s1\\xr\\B\\N\\Q (rad.s\\S-1\\N)"%exp_type 3492 3493 # If plotting special R1rho R2 values. 3494 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3495 elif y_axis == Y_AXIS_R2_R1RHO: 3496 if exp_type in EXP_TYPE_LIST_CPMG: 3497 # Set y_label. 3498 y_label = "%s - \\qR\\s2\\N\\Q (rad.s\\S-1\\N)"%exp_type 3499 3500 elif exp_type in EXP_TYPE_LIST_R1RHO: 3501 # Set y_label. 3502 y_label = "%s - \\qR\\s2\\N\\Q (rad.s\\S-1\\N)"%exp_type 3503 3504 # Return axis labels 3505 return x_label, y_label
3506 3507
3508 -def return_x_y_data_labels_settings(spin=None, data_type=None, y_axis=None, exp_type=None, frq=None, offset=None, point=None, interpolated_flag=None):
3509 """Return the X and Y labels and plot settings, according to selected axis to plot for. 3510 3511 @keyword spin: The specific spin data container. 3512 @type spin: SpinContainer instance 3513 @keyword data_type: String flag to tell which data type to return for. Option can be either "data", "back_calculated", "interpolated" or "residual". 3514 @type data_type: str 3515 @keyword exp_type: The experiment type. 3516 @type exp_type: str 3517 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3518 @type y_axis: str 3519 @keyword frq: The spectrometer frequency in Hz. 3520 @type frq: float 3521 @keyword offset: The spin-lock offset. 3522 @type offset: None or float 3523 @keyword point: The Spin-lock field strength (Hz). 3524 @type point: float 3525 @keyword interpolated_flag: Flag telling if the graph should be interpolated. 3526 @type interpolated_flag: bool 3527 @return: The data label, the data symbol, the data symbol size, the data line type, the data line style. 3528 @rtype: str, int, float, int, int 3529 """ 3530 3531 # If plotting either CPMG R2eff or R1rho. 3532 if y_axis == Y_AXIS_R2_EFF: 3533 if exp_type in EXP_TYPE_LIST_CPMG: 3534 # Set y_label. 3535 r_string = "R\\s2eff\\N" 3536 3537 elif exp_type in EXP_TYPE_LIST_R1RHO: 3538 # Set y_label. 3539 r_string = "R\\s1\\xr\\B\\N" 3540 3541 # If plotting special R1rho R2 values. 3542 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3543 elif y_axis == Y_AXIS_R2_R1RHO: 3544 if exp_type in EXP_TYPE_LIST_CPMG: 3545 # Set y_label. 3546 r_string = "R\\s2\\N" 3547 3548 elif exp_type in EXP_TYPE_LIST_R1RHO: 3549 # Set y_label. 3550 r_string = "R\\s2\\N" 3551 3552 # Determine unit string. 3553 if offset != None and frq != None: 3554 u_string = " (%.1f MHz, %.3f ppm)" % (frq / 1e6, offset) 3555 elif point != None and frq != None: 3556 u_string = " (%.1f MHz, %.3f Hz)" % (frq / 1e6, point) 3557 elif frq != None: 3558 u_string = " (%.1f MHz)" % (frq / 1e6) 3559 elif offset != None: 3560 u_string = " (%.3f ppm)" % (offset) 3561 elif point != None: 3562 u_string = " (%.3f Hz)" % (point) 3563 3564 if data_type == "data": 3565 # Add a new label. 3566 label = r_string 3567 label += u_string 3568 3569 # Set graph settings for data type. 3570 symbols_int = 1 3571 symbol_sizes_float = 0.45 3572 linetype_int = 0 3573 linestyle_int = 0 3574 3575 elif data_type == "back_calculated": 3576 # Add a new label. 3577 label = "Back calculated %s"%(r_string) 3578 label += u_string 3579 3580 # Set graph settings for data type. 3581 symbols_int = 4 3582 symbol_sizes_float = 0.45 3583 linetype_int = 1 3584 linestyle_int = 0 3585 3586 if interpolated_flag: 3587 linestyle_int = 2 3588 else: 3589 linestyle_int = 1 3590 3591 elif data_type == "interpolated": 3592 # Add a new label. 3593 label = "%s interpolated curve"%(r_string) 3594 label += u_string 3595 3596 # Set graph settings for data type. 3597 if spin.model in MODEL_LIST_NUMERIC_CPMG: 3598 symbols_int =8 3599 else: 3600 symbols_int = 0 3601 3602 symbol_sizes_float = 0.20 3603 linetype_int = 1 3604 linestyle_int = 1 3605 3606 elif data_type == "residual": 3607 # Add a new label. 3608 label = "Residuals" 3609 label += u_string 3610 3611 # Set graph settings for data type. 3612 symbols_int = 9 3613 symbol_sizes_float = 0.45 3614 linetype_int = 1 3615 linestyle_int = 3 3616 3617 return label, symbols_int, symbol_sizes_float, linetype_int, linestyle_int
3618 3619
3620 -def return_grace_x_y_point(data_type=None, y_axis=None, x_axis=None, interpolate=None, data_key=None, spin=None, back_calc=None, offset=None, point=None, r1=None, r1_err=None, w_eff=None, theta=None, err=False):
3621 """Return the X and Y data point, according to selected axis to plot for. 3622 3623 @keyword data_type: String flag to tell which data type to return for. Option can be either "data", "back_calculated", "interpolated" or "residual". 3624 @type data_type: str 3625 @keyword y_axis: String flag to tell which data on Y axis to plot for. Option can be either "%s" which plot 'r2eff' for CPMG experiments or 'r1rho' for R1rho experiments or option can be "%s", which for R1rho experiments plot R2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta). 3626 @type y_axis: str 3627 @keyword x_axis: String flag to tell which data on X axis to plot for. Option can be either "%s" which plot 'CPMG frequency (Hz)' for CPMG experiments or 'Spin-lock field strength (Hz)' for R1rho experiments or option can be either "%s" or "%s" for R1rho experiments, which plot 'Effective field in rotating frame (rad/s)' or 'Rotating frame tilt angle theta (rad)'. 3628 @type x_axis: str 3629 @keyword interpolate: How to interpolate the fitted curves. Either by option "%s" which interpolate CPMG frequency or spin-lock field strength, or by option "%s" which interpole over spin-lock offset. 3630 @type interpolate: float 3631 @keyword data_key: The unique data key. 3632 @type data_key: str 3633 @keyword spin: The specific spin data container. 3634 @type spin: SpinContainer instance. 3635 @keyword back_calc: The back calculated of CPMG R2eff value, or R1rho value. 3636 @type back_calc: float 3637 @keyword offset: The spin-lock offset. 3638 @type offset: None or float 3639 @keyword point: The CPMG pulse train frequency (Hz) or Spin-lock field strength (Hz). 3640 @type point: float 3641 @keyword r1: The R1 relaxation data point. 3642 @type r1: float 3643 @keyword r1_err: error for R1 relaxation data point. 3644 @type r1_err: float 3645 @keyword w_eff: The effective field in rotating frame (rad/s). 3646 @type w_eff: float 3647 @keyword theta: The rotating frame tilt angle theta (rad). 3648 @type theta: float 3649 @keyword err: The flag for xy graph or xydy error graph. 3650 @type err: boolean 3651 @return: The X-point, the Y-point, the flag for xy graph or xydy error graph, the Y-error value. 3652 @rtype: float, float, boolean, float 3653 """%(Y_AXIS_R2_EFF, Y_AXIS_R2_R1RHO, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, INTERPOLATE_DISP, INTERPOLATE_OFFSET) 3654 3655 # Start setting y_err_point to none. 3656 y_err_point = None 3657 3658 if x_axis == X_AXIS_DISP: 3659 if interpolate == INTERPOLATE_DISP: 3660 # Set x_point. 3661 x_point = point 3662 3663 elif interpolate == INTERPOLATE_OFFSET: 3664 # Set x_point. 3665 x_point = offset 3666 3667 elif x_axis == X_AXIS_W_EFF: 3668 # Set x_point. 3669 x_point = w_eff 3670 3671 elif x_axis == X_AXIS_THETA: 3672 # Set x_point. 3673 x_point = theta 3674 3675 # Determine which data to return. 3676 if data_type == "data": 3677 # Determine y data type. 3678 if y_axis == Y_AXIS_R2_EFF: 3679 # Set y_point. 3680 y_point = spin.r2eff[data_key] 3681 3682 # Add the error. 3683 if hasattr(spin, 'r2eff_err') and data_key in spin.r2eff_err: 3684 err = True 3685 y_err_point = spin.r2eff_err[data_key] 3686 3687 elif y_axis == Y_AXIS_R2_R1RHO: 3688 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta) 3689 y_point = ( spin.r2eff[data_key] - r1*cos(theta)**2 ) / sin(theta)**2 3690 3691 # Add the error. 3692 if hasattr(spin, 'r2eff_err') and data_key in spin.r2eff_err: 3693 err = True 3694 y_err_point = ( spin.r2eff_err[data_key] - r1_err*cos(theta)**2 ) / sin(theta)**2 3695 3696 elif data_type == "back_calculated": 3697 # Determine y data type. 3698 if y_axis == Y_AXIS_R2_EFF: 3699 # Set y_point. 3700 y_point = spin.r2eff_bc[data_key] 3701 3702 elif y_axis == Y_AXIS_R2_R1RHO: 3703 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta) 3704 y_point = ( spin.r2eff_bc[data_key] - r1*cos(theta)**2 ) / sin(theta)**2 3705 3706 elif data_type == "interpolated": 3707 # Determine y data type. 3708 if y_axis == Y_AXIS_R2_EFF: 3709 # Set y_point. 3710 y_point = back_calc 3711 3712 elif y_axis == Y_AXIS_R2_R1RHO: 3713 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta) 3714 y_point = ( back_calc - r1*cos(theta)**2 ) / sin(theta)**2 3715 3716 elif data_type == "residual": 3717 # Determine y data type. 3718 if y_axis == Y_AXIS_R2_EFF: 3719 # Set y_point. 3720 y_point_data = spin.r2eff[data_key] 3721 y_point_bc = spin.r2eff_bc[data_key] 3722 3723 # Calculate residual. 3724 y_point = y_point_data - y_point_bc 3725 y_err_point = spin.r2eff_err[data_key] 3726 3727 elif y_axis == Y_AXIS_R2_R1RHO: 3728 # R_2 = R1rho / sin^2(theta) - R_1 / tan^2(theta) = (R1rho - R_1 * cos^2(theta) ) / sin^2(theta) 3729 y_point_data = ( spin.r2eff[data_key] - r1*cos(theta)**2 ) / sin(theta)**2 3730 y_point_bc = ( spin.r2eff_bc[data_key] - r1*cos(theta)**2 ) / sin(theta)**2 3731 3732 # Calculate residual. 3733 y_point = y_point_data - y_point_bc 3734 y_err_point = ( spin.r2eff_err[data_key] - r1_err*cos(theta)**2 ) / sin(theta)**2 3735 3736 return x_point, y_point, err, y_err_point
3737 3738
3739 -def return_index_from_disp_point(value, exp_type=None):
3740 """Convert the dispersion point data into the corresponding index. 3741 3742 @param value: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 3743 @type value: float 3744 @keyword exp_type: The experiment type. 3745 @type exp_type: str 3746 @return: The corresponding index. 3747 @rtype: int 3748 """ 3749 3750 # Check. 3751 if exp_type == None: 3752 raise RelaxError("The experiment type has not been supplied.") 3753 3754 # Initialise. 3755 index = 0 3756 ref_correction = False 3757 3758 # CPMG-type experiments. 3759 if exp_type in EXP_TYPE_LIST_CPMG: 3760 index = cdp.cpmg_frqs_list.index(value) 3761 if None in cdp.cpmg_frqs_list: 3762 ref_correction = True 3763 3764 # R1rho-type experiments. 3765 elif exp_type in EXP_TYPE_LIST_R1RHO: 3766 index = cdp.spin_lock_nu1_list.index(value) 3767 if None in cdp.spin_lock_nu1_list: 3768 ref_correction = True 3769 3770 # Remove the reference point (always at index 0). 3771 for id in loop_spectrum_ids(exp_type=exp_type): 3772 if ref_correction and get_curve_type(id) == 'fixed time': 3773 index -= 1 3774 break 3775 3776 # Return the index. 3777 return index
3778 3779
3780 -def return_index_from_exp_type(exp_type=None):
3781 """Convert the experiment type into the corresponding index. 3782 3783 @keyword exp_type: The experiment type. 3784 @type exp_type: str 3785 @return: The corresponding index. 3786 @rtype: int 3787 """ 3788 3789 # Check. 3790 if exp_type == None: 3791 raise RelaxError("The experiment type has not been supplied.") 3792 3793 # Return the index. 3794 if exp_type in cdp.exp_type_list: 3795 return cdp.exp_type_list.index(exp_type) 3796 3797 # The number of experiments. 3798 num = len(cdp.exp_type_list)
3799 3800
3801 -def return_index_from_frq(value):
3802 """Convert the dispersion point data into the corresponding index. 3803 3804 @param value: The spectrometer frequency in Hz. 3805 @type value: float 3806 @return: The corresponding index. 3807 @rtype: int 3808 """ 3809 3810 # No frequency present. 3811 if value == None: 3812 return 0 3813 3814 # Return the index. 3815 return cdp.spectrometer_frq_list.index(value)
3816 3817
3818 -def return_index_from_disp_point_key(key, exp_type=None):
3819 """Convert the dispersion point key into the corresponding index. 3820 3821 @keyword exp_type: The experiment type. 3822 @type exp_type: str 3823 @param key: The dispersion point or R2eff/R1rho key. 3824 @type key: str 3825 @return: The corresponding index. 3826 @rtype: int 3827 """ 3828 3829 # Check. 3830 if exp_type == None: 3831 raise RelaxError("The experiment type has not been supplied.") 3832 3833 # CPMG-type experiments. 3834 if exp_type in EXP_TYPE_LIST_CPMG: 3835 return return_index_from_disp_point(cdp.cpmg_frqs[key], exp_type=exp_type) 3836 3837 # R1rho-type experiments. 3838 elif exp_type in EXP_TYPE_LIST_R1RHO: 3839 return return_index_from_disp_point(cdp.spin_lock_nu1[key], exp_type=exp_type)
3840 3841
3842 -def return_key_from_di(mi=None, di=None):
3843 """Convert the dispersion point index into the corresponding key. 3844 3845 @keyword mi: The spectrometer frequency index. 3846 @type mi: int 3847 @keyword di: The dispersion point or R2eff/R1rho index. 3848 @type di: int 3849 @return: The corresponding key. 3850 @rtype: str 3851 """ 3852 3853 # Insert the reference point (always at index 0). 3854 if has_fixed_time_exp_type(): 3855 di += 1 3856 3857 # The frequency. 3858 frq = return_value_from_frq_index(mi) 3859 3860 # CPMG data. 3861 if exp_type in EXP_TYPE_LIST_CPMG: 3862 point = cdp.cpmg_frqs_list[di] 3863 points = cdp.cpmg_frqs 3864 3865 # R1rho data. 3866 else: 3867 point = cdp.spin_lock_nu1_list[di] 3868 points = cdp.spin_lock_nu1 3869 3870 # Find the keys matching the dispersion point. 3871 key_list = [] 3872 for key in points: 3873 if points[key] == point: 3874 key_list.append(key) 3875 3876 # Return the key. 3877 return key
3878 3879
3880 -def return_offset_data(spins=None, spin_ids=None, field_count=None, spin_lock_offset=None, fields=None):
3881 """Return numpy arrays of the chemical shifts, offsets and tilt angles. 3882 3883 Indices 3884 ======= 3885 3886 The data structures consist of many different index types. These are: 3887 3888 - Ei: The index for each experiment type. 3889 - Si: The index for each spin of the spin cluster. 3890 - Mi: The index for each magnetic field strength. 3891 - Oi: The index for each spin-lock offset. In the case of CPMG-type data, this index is always zero. 3892 - Di: The index for each dispersion point (either the spin-lock field strength or the nu_CPMG frequency). 3893 3894 3895 @keyword spins: The list of spin containers in the cluster. 3896 @type spins: list of SpinContainer instances 3897 @keyword spin_ids: The list of spin IDs for the cluster. 3898 @type spin_ids: list of str 3899 @keyword field_count: The number of spectrometer field strengths. This may not be equal to the length of the fields list as the user may not have set the field strength. 3900 @type field_count: int 3901 @keyword spin_lock_offset: The spin-lock offsets to use instead of the user loaded values - to enable interpolation. 3902 @type spin_lock_offset: list of lists of numpy rank-1 float arrays 3903 @keyword fields: The spin-lock field strengths to use instead of the user loaded values - to enable interpolation. The dimensions are {Ei, Mi}. 3904 @type fields: rank-2 list of floats 3905 @return: interpolated spin-lock offsets in rad/s {Ei, Si, Mi, Oi}, interpolated spin-lock field strength frequencies in Hz {Ei, Si, Mi, Oi, Di}, the chemical shifts in rad/s {Ei, Si, Mi}, the interpolated rotating frame tilt angles {Ei, Si, Mi, Oi, Di}, interpolated average resonance offset in the rotating frame in rad/s {Ei, Si, Mi, Oi, Di} and the interpolated effective field in rotating frame in rad/s {Ei, Si, Mi, Oi, Di}. 3906 @rtype: rank-3 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-2 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays, rank-4 list of numpy rank-1 float arrays 3907 """ 3908 3909 # The counts. 3910 exp_num = num_exp_types() 3911 spin_num = 0 3912 for spin in spins: 3913 if spin.select: 3914 spin_num += 1 3915 3916 # Initialise the data structures for the target function. 3917 fields_orig = fields 3918 shifts = [] 3919 offsets = [] 3920 spin_lock_fields_inter = [] 3921 tilt_angles = [] 3922 Domega = [] 3923 w_e = [] 3924 3925 for exp_type, ei in loop_exp(return_indices=True): 3926 shifts.append([]) 3927 offsets.append([]) 3928 spin_lock_fields_inter.append([]) 3929 tilt_angles.append([]) 3930 Domega.append([]) 3931 w_e.append([]) 3932 for si in range(spin_num): 3933 shifts[ei].append([]) 3934 offsets[ei].append([]) 3935 tilt_angles[ei].append([]) 3936 Domega[ei].append([]) 3937 w_e[ei].append([]) 3938 for frq, mi in loop_frq(return_indices=True): 3939 shifts[ei][si].append(None) 3940 offsets[ei][si].append([]) 3941 spin_lock_fields_inter[ei].append([]) 3942 tilt_angles[ei][si].append([]) 3943 Domega[ei][si].append([]) 3944 w_e[ei][si].append([]) 3945 # Enable possible interpolation of spin-lock offset. 3946 if spin_lock_offset != None: 3947 for oi, offset in enumerate(spin_lock_offset[ei][si][mi]): 3948 offsets[ei][si][mi].append(None) 3949 spin_lock_fields_inter[ei][mi].append([]) 3950 tilt_angles[ei][si][mi].append([]) 3951 Domega[ei][si][mi].append([]) 3952 w_e[ei][si][mi].append([]) 3953 else: 3954 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 3955 offsets[ei][si][mi].append(None) 3956 spin_lock_fields_inter[ei][mi].append([]) 3957 tilt_angles[ei][si][mi].append([]) 3958 Domega[ei][si][mi].append([]) 3959 w_e[ei][si][mi].append([]) 3960 3961 # Assemble the data. 3962 data_flag = False 3963 si = 0 3964 for spin_index in range(len(spins)): 3965 # Skip deselected spins. 3966 if not spins[spin_index].select: 3967 continue 3968 3969 # Alias the spin. 3970 spin = spins[spin_index] 3971 spin_id = spin_ids[spin_index] 3972 3973 # No data. 3974 shift = 0.0 3975 if hasattr(spin, 'chemical_shift'): 3976 shift = spin.chemical_shift 3977 elif has_r1rho_exp_type(): 3978 warn(RelaxWarning("The chemical shift for the spin '%s' cannot be found. Be careful, it is being set to 0.0 ppm so offset calculations will probably be wrong!" % spin_id)) 3979 3980 # Loop over the experiments and spectrometer frequencies. 3981 data_flag = True 3982 for exp_type, frq, ei, mi in loop_exp_frq(return_indices=True): 3983 # The R1rho and off-resonance R1rho flag. 3984 r1rho_flag = False 3985 if exp_type in EXP_TYPE_LIST_R1RHO: 3986 r1rho_flag = True 3987 r1rho_off_flag = False 3988 if exp_type in [MODEL_DPL94, MODEL_TP02, MODEL_TAP03, MODEL_MP05, MODEL_NS_R1RHO_2SITE]: 3989 r1rho_off_flag = True 3990 3991 # Make sure offset data exists for off-resonance R1rho-type experiments. 3992 if r1rho_off_flag and not hasattr(cdp, 'spin_lock_offset'): 3993 raise RelaxError("The spin-lock offsets have not been set.") 3994 3995 # Convert the shift from ppm to rad/s and store it. 3996 if hasattr(spin, 'isotope'): 3997 shifts[ei][si][mi] = frequency_to_rad_per_s(frq=shift, B0=frq, isotope=spin.isotope) 3998 else: 3999 shifts[ei][si][mi] = shift 4000 4001 # Enable possible interpolation of spin-lock offset. 4002 if spin_lock_offset != None: 4003 for oi, offset in enumerate(spin_lock_offset[ei][si][mi]): 4004 # Assign spin-lock fields to all loaded fields. 4005 fields = [x for x in cdp.spin_lock_nu1_list if x!=None] 4006 4007 # Save the fields to list. 4008 spin_lock_fields_inter[ei][mi][oi] = fields 4009 4010 # Find a matching experiment ID. 4011 found = False 4012 for id in cdp.exp_type: 4013 # Skip non-matching experiments. 4014 if cdp.exp_type[id] != exp_type: 4015 continue 4016 4017 # Skip non-matching spectrometer frequencies. 4018 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 4019 continue 4020 4021 # Found. 4022 found = True 4023 break 4024 4025 # No data. 4026 if not found: 4027 continue 4028 4029 # Store the offset in rad/s from ppm. Only once and using the first key. 4030 if offsets[ei][si][mi][oi] == None: 4031 if r1rho_flag and hasattr(cdp, 'spin_lock_offset') and hasattr(spin, 'isotope'): 4032 offsets[ei][si][mi][oi] = frequency_to_rad_per_s(frq=offset, B0=frq, isotope=spin.isotope) 4033 else: 4034 offsets[ei][si][mi][oi] = 0.0 4035 4036 # Loop over the dispersion points. 4037 for di in range(len(fields)): 4038 # Alias the point. 4039 point = fields[di] 4040 4041 # Skip reference spectra. 4042 if point == None: 4043 continue 4044 4045 # Convert spin-lock field strength from Hz to rad/s. 4046 omega1 = point * 2.0 * pi 4047 4048 # Return the rotating frame parameters. 4049 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=shifts[ei][si][mi], spin_lock_offset=offsets[ei][si][mi][oi], omega1=omega1) 4050 4051 # Assign the data to lists. 4052 Domega[ei][si][mi][oi].append(Delta_omega) 4053 tilt_angles[ei][si][mi][oi].append(theta) 4054 w_e[ei][si][mi][oi].append(w_eff) 4055 4056 4057 else: 4058 # Loop over offset. 4059 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 4060 # The spin-lock data. 4061 if fields_orig != None: 4062 fields = fields_orig[ei][mi][oi] 4063 else: 4064 if not r1rho_flag: 4065 fields = return_cpmg_frqs_single(exp_type=exp_type, frq=frq, offset=offset, ref_flag=False) 4066 else: 4067 fields = return_spin_lock_nu1_single(exp_type=exp_type, frq=frq, offset=offset, ref_flag=False) 4068 4069 # Save the fields to list. 4070 spin_lock_fields_inter[ei][mi][oi] = fields 4071 4072 # Find a matching experiment ID. 4073 found = False 4074 for id in cdp.exp_type: 4075 # Skip non-matching experiments. 4076 if cdp.exp_type[id] != exp_type: 4077 continue 4078 4079 # Skip non-matching spectrometer frequencies. 4080 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 4081 continue 4082 4083 # Skip non-matching offsets. 4084 if r1rho_flag and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 4085 continue 4086 4087 # Found. 4088 found = True 4089 break 4090 4091 # No data. 4092 if not found: 4093 continue 4094 4095 # Store the offset in rad/s. Only once and using the first key. 4096 if offsets[ei][si][mi][oi] == None: 4097 if r1rho_flag and hasattr(cdp, 'spin_lock_offset') and hasattr(spin, 'isotope'): 4098 offsets[ei][si][mi][oi] = frequency_to_rad_per_s(frq=cdp.spin_lock_offset[id], B0=frq, isotope=spin.isotope) 4099 else: 4100 offsets[ei][si][mi][oi] = 0.0 4101 4102 # Loop over the dispersion points. 4103 for di in range(len(fields)): 4104 # Alias the point. 4105 point = fields[di] 4106 4107 # Skip reference spectra. 4108 if point == None: 4109 continue 4110 4111 # Convert spin-lock field strength from Hz to rad/s. 4112 omega1 = point * 2.0 * pi 4113 4114 # Return the rotating frame parameters. 4115 Delta_omega, theta, w_eff = rotating_frame_params(chemical_shift=shifts[ei][si][mi], spin_lock_offset=offsets[ei][si][mi][oi], omega1=omega1) 4116 4117 # Assign the data to lists. 4118 Domega[ei][si][mi][oi].append(Delta_omega) 4119 tilt_angles[ei][si][mi][oi].append(theta) 4120 w_e[ei][si][mi][oi].append(w_eff) 4121 4122 # Increment the spin index. 4123 si += 1 4124 4125 # No shift data for the spin cluster. 4126 if not data_flag: 4127 return None, None, None 4128 4129 # Convert to numpy arrays. 4130 #for ei in range(exp_num): 4131 # for si in range(spin_num): 4132 # for mi in range(field_count): 4133 # theta[ei][si][mi] = array(theta[ei][si][mi], float64) 4134 4135 # Return the structures. 4136 return offsets, spin_lock_fields_inter, shifts, tilt_angles, Domega, w_e
4137 4138
4139 -def return_param_key_from_data(exp_type=None, frq=0.0, offset=0.0, point=0.0):
4140 """Generate the unique key from the spectrometer frequency and dispersion point. 4141 4142 @keyword exp_type: The experiment type. 4143 @type exp_type: str 4144 @keyword frq: The spectrometer frequency in Hz. 4145 @type frq: float 4146 @keyword offset: The optional offset value for off-resonance R1rho-type data. 4147 @type offset: None or float 4148 @keyword point: The dispersion point data (either the spin-lock field strength in Hz or the nu_CPMG frequency in Hz). 4149 @type point: float 4150 @return: The unique key. 4151 @rtype: str 4152 """ 4153 4154 # Convert the experiment type. 4155 if exp_type == None: 4156 raise RelaxError("The experiment type must be supplied.") 4157 exp_type = exp_type.replace(' ', '_').lower() 4158 4159 # Convert None values. 4160 if frq == None: 4161 frq = 0.0 4162 if offset == None: 4163 offset = 0.0 4164 if point == None: 4165 point = 0.0 4166 4167 # Generate the unique key. 4168 key = "%s_%.8f_%.3f_%.3f" % (exp_type, frq/1e6, offset, point) 4169 4170 # Return the unique key. 4171 return key
4172 4173
4174 -def return_r1_data(spins=None, spin_ids=None, field_count=None, sim_index=None):
4175 """Return the R1 data structures for off-resonance R1rho experiments. 4176 4177 @keyword spins: The list of spin containers in the cluster. 4178 @type spins: list of SpinContainer instances 4179 @keyword spin_ids: The list of spin IDs for the cluster. 4180 @type spin_ids: list of str 4181 @keyword field_count: The number of spectrometer field strengths. This may not be equal to the length of the fields list as the user may not have set the field strength. 4182 @type field_count: int 4183 @keyword sim_index: The index of the simulation to return the R1 data of. This should be None if the normal data is required. 4184 @type sim_index: None or int 4185 @return: The R1 relaxation data. 4186 @rtype: numpy rank-2 float array 4187 """ 4188 4189 # The spin count. 4190 spin_num = count_spins(spins) 4191 4192 # Initialise the data structure. 4193 r1 = -ones((spin_num, field_count), float64) 4194 4195 # Set testing flags. 4196 flags = [False]*field_count 4197 4198 # The R1 fitting flag. 4199 r1_fit = is_r1_optimised(model=spins[0].model) 4200 4201 # Check for the presence of data. 4202 if not r1_fit and not hasattr(cdp, 'ri_ids'): 4203 warn_text = "No R1 relaxation data has been loaded. Setting it to 0.0. This is essential for the proper handling of offsets in off-resonance R1rho experiments." 4204 error_text = "No R1 relaxation data has been loaded. This is essential for the proper handling of offsets in off-resonance R1rho experiments." 4205 if has_r1rho_exp_type(): 4206 # For all R1rho models using R1, raise an error, if R1 has not been loaded. 4207 if r1_fit: 4208 raise RelaxError(error_text) 4209 4210 # For all models not listed in R1rho models, raise a warning, and set 0.0 as value. 4211 else: 4212 warn(RelaxWarning(warn_text)) 4213 r1 = 0.0 * r1 4214 4215 # For all non-R1rho experiments, return 0.0. 4216 else: 4217 r1 = 0.0 * r1 4218 4219 # Return the data. 4220 return r1 4221 4222 # For all R1rho models fitting R1. 4223 elif r1_fit: 4224 # Spin loop. 4225 for si in range(spin_num): 4226 # Assign spin: 4227 spin = spins[si] 4228 4229 # Loop over exp type and frq. 4230 for exp_type, frq, ei, mi in loop_exp_frq(return_indices=True): 4231 # Assign key 4232 r20_key = generate_r20_key(exp_type=exp_type, frq=frq) 4233 4234 # If no data is available. 4235 if len(spin.r1) == 0: 4236 r1[si, mi] = None 4237 4238 else: 4239 r1[si, mi] = spin.r1[r20_key] 4240 4241 # Flip the flag. 4242 flags[mi] = True 4243 4244 else: 4245 # Loop over the Rx IDs. 4246 for ri_id in cdp.ri_ids: 4247 # Only use R1 data. 4248 if cdp.ri_type[ri_id] != 'R1': 4249 continue 4250 4251 # The frequency. 4252 frq = cdp.spectrometer_frq[ri_id] 4253 mi = return_index_from_frq(frq) 4254 4255 # Flip the flag. 4256 flags[mi] = True 4257 4258 # Spin loop. 4259 for si in range(spin_num): 4260 # FIXME: This is a kludge - the data randomisation needs to be incorporated into the dispersion base_data_loop() method and the standard Monte Carlo simulation pathway used. 4261 # Randomise the R1 data, when required. 4262 if sim_index != None and (not hasattr(spins[si], 'ri_data_sim') or ri_id not in spins[si].ri_data_sim): 4263 randomise_R1(spin=spins[si], ri_id=ri_id, N=cdp.sim_number) 4264 4265 # Store the data. 4266 if sim_index != None: 4267 r1[si, mi] = spins[si].ri_data_sim[ri_id][sim_index] 4268 else: 4269 r1[si, mi] = spins[si].ri_data[ri_id] 4270 4271 # Check the data to prevent user mistakes. 4272 for mi in range(field_count): 4273 # The frequency. 4274 frq = return_value_from_frq_index(mi=mi) 4275 4276 # Check for R1 data for this frequency. 4277 if not flags[mi]: 4278 raise RelaxError("R1 data for the %.1f MHz field strength cannot be found." % (frq/1e6)) 4279 4280 # Check the spin data. 4281 for si in range(spin_num): 4282 if r1[si, mi] == -1.0: 4283 raise RelaxError("R1 data for the '%s' spin at %.1f MHz field strength cannot be found." % (spin_ids[si], frq/1e6)) 4284 4285 # Return the data. 4286 return r1
4287 4288
4289 -def return_r1_err_data(spins=None, spin_ids=None, field_count=None, sim_index=None):
4290 """Return the R1 error data structures for off-resonance R1rho experiments. 4291 4292 @keyword spins: The list of spin containers in the cluster. 4293 @type spins: list of SpinContainer instances 4294 @keyword spin_ids: The list of spin IDs for the cluster. 4295 @type spin_ids: list of str 4296 @keyword field_count: The number of spectrometer field strengths. This may not be equal to the length of the fields list as the user may not have set the field strength. 4297 @type field_count: int 4298 @keyword sim_index: The index of the simulation to return the R1 data of. This should be None if the normal data is required. 4299 @type sim_index: None or int 4300 @return: The R1 relaxation error data. 4301 @rtype: numpy rank-2 float array 4302 """ 4303 4304 # The spin count. 4305 spin_num = count_spins(spins) 4306 4307 # Initialise the data structure. 4308 r1_err = -ones((spin_num, field_count), float64) 4309 4310 # Set testing flags. 4311 flags = [False]*field_count 4312 4313 # The R1 fitting flag. 4314 r1_fit = is_r1_optimised(model=spins[0].model) 4315 4316 # Check for the presence of data. 4317 if not r1_fit and not hasattr(cdp, 'ri_ids'): 4318 warn_text = "No R1 relaxation data has been loaded. Setting it to 0.0. This is essential for the proper handling of offsets in off-resonance R1rho experiments." 4319 error_text = "No R1 relaxation data has been loaded. This is essential for the proper handling of offsets in off-resonance R1rho experiments." 4320 if has_r1rho_exp_type(): 4321 # For all R1rho models using R1, raise an error, if R1 has not been loaded. 4322 if r1_fit: 4323 raise RelaxError(error_text) 4324 4325 # For all models not listed in R1rho models, raise a warning, and set 0.0 as value. 4326 else: 4327 warn(RelaxWarning(warn_text)) 4328 r1_err = 0.0 * r1_err 4329 4330 # For all non-R1rho experiments, return 0.0. 4331 else: 4332 r1_err = 0.0 * r1_err 4333 4334 # Return the data. 4335 return r1_err 4336 4337 # For all R1rho models fitting R1. 4338 elif r1_fit: 4339 # Spin loop. 4340 for si in range(spin_num): 4341 # Assign spin: 4342 spin = spins[si] 4343 4344 # Loop over exp type and frq. 4345 for exp_type, frq, ei, mi in loop_exp_frq(return_indices=True): 4346 # Assign key 4347 r20_key = generate_r20_key(exp_type=exp_type, frq=frq) 4348 4349 # If no Monte-Carlo simulations has been performed, there will be no error. 4350 if not hasattr(spin, 'r1_err'): 4351 r1_err[si, mi] = None 4352 4353 else: 4354 r1_err[si, mi] = spin.r1_err[r20_key] 4355 4356 # Flip the flag. 4357 flags[mi] = True 4358 4359 else: 4360 # Loop over the Rx IDs. 4361 for ri_id in cdp.ri_ids: 4362 # Only use R1 data. 4363 if cdp.ri_type[ri_id] != 'R1': 4364 continue 4365 4366 # The frequency. 4367 frq = cdp.spectrometer_frq[ri_id] 4368 mi = return_index_from_frq(frq) 4369 4370 # Flip the flag. 4371 flags[mi] = True 4372 4373 # Spin loop. 4374 for si in range(spin_num): 4375 # FIXME: This is a kludge - the data randomisation needs to be incorporated into the dispersion base_data_loop() method and the standard Monte Carlo simulation pathway used. 4376 # Randomise the R1 data, when required. 4377 if sim_index != None and (not hasattr(spins[si], 'ri_data_sim') or ri_id not in spins[si].ri_data_sim): 4378 randomise_R1(spin=spins[si], ri_id=ri_id, N=cdp.sim_number) 4379 4380 # Store the data. 4381 if sim_index != None: 4382 r1_err[si, mi] = spins[si].ri_data_err_sim[ri_id][sim_index] 4383 else: 4384 r1_err[si, mi] = spins[si].ri_data_err[ri_id] 4385 4386 # Check the data to prevent user mistakes. 4387 for mi in range(field_count): 4388 # The frequency. 4389 frq = return_value_from_frq_index(mi=mi) 4390 4391 # Check for R1 data for this frequency. 4392 if not flags[mi]: 4393 raise RelaxError("R1 data for the %.1f MHz field strength cannot be found." % (frq/1e6)) 4394 4395 # Check the spin data. 4396 for si in range(spin_num): 4397 if r1_err[si, mi] == -1.0: 4398 raise RelaxError("R1 data for the '%s' spin at %.1f MHz field strength cannot be found." % (spin_ids[si], frq/1e6)) 4399 4400 # Return the data. 4401 return r1_err
4402 4403
4404 -def return_r2eff_arrays(spins=None, spin_ids=None, fields=None, field_count=None, sim_index=None):
4405 """Return numpy arrays of the R2eff/R1rho values and errors. 4406 4407 @keyword spins: The list of spin containers in the cluster. 4408 @type spins: list of SpinContainer instances 4409 @keyword spin_ids: The list of spin IDs for the cluster. 4410 @type spin_ids: list of str 4411 @keyword fields: The list of spectrometer field strengths. 4412 @type fields: list of float 4413 @keyword field_count: The number of spectrometer field strengths. This may not be equal to the length of the fields list as the user may not have set the field strength. 4414 @type field_count: int 4415 @keyword sim_index: The index of the simulation to return the data of. This should be None if the normal data is required. 4416 @type sim_index: None or int 4417 @return: The numpy array structures of the R2eff/R1rho values, errors, missing data, and corresponding Larmor frequencies. For each structure, the first dimension corresponds to the experiment types, the second the spins of a spin block, the third to the spectrometer field strength, and the fourth is the dispersion points. For the Larmor frequency structure, the fourth dimension is omitted. For R1rho-type data, an offset dimension is inserted between the spectrometer field strength and the dispersion points. 4418 @rtype: lists of numpy float arrays, lists of numpy float arrays, lists of numpy float arrays, numpy rank-2 int array 4419 """ 4420 4421 # The counts. 4422 exp_num = num_exp_types() 4423 spin_num = count_spins(spins) 4424 4425 # 1H MMQ flag. 4426 proton_mmq_flag = has_proton_mmq_cpmg() 4427 4428 # Initialise the data structures for the target function. 4429 exp_types = [] 4430 values = [] 4431 errors = [] 4432 missing = [] 4433 frqs = [] 4434 frqs_H = [] 4435 relax_times = [] 4436 for exp_type, ei in loop_exp(return_indices=True): 4437 values.append([]) 4438 errors.append([]) 4439 missing.append([]) 4440 frqs.append([]) 4441 frqs_H.append([]) 4442 relax_times.append([]) 4443 for si in range(spin_num): 4444 values[ei].append([]) 4445 errors[ei].append([]) 4446 missing[ei].append([]) 4447 frqs[ei].append([]) 4448 frqs_H[ei].append([]) 4449 for frq, mi in loop_frq(return_indices=True): 4450 values[ei][si].append([]) 4451 errors[ei][si].append([]) 4452 missing[ei][si].append([]) 4453 frqs[ei][si].append(0.0) 4454 frqs_H[ei][si].append(0.0) 4455 relax_times[ei].append([]) 4456 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 4457 values[ei][si][mi].append([]) 4458 errors[ei][si][mi].append([]) 4459 missing[ei][si][mi].append([]) 4460 relax_times[ei][mi].append([]) 4461 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 4462 relax_times[ei][mi][oi].append([]) 4463 4464 # Pack the R2eff/R1rho data. 4465 data_flag = False 4466 si = 0 4467 for spin_index in range(len(spins)): 4468 # Skip deselected spins. 4469 if not spins[spin_index].select: 4470 continue 4471 4472 # Alias the spin. 4473 spin = spins[spin_index] 4474 spin_id = spin_ids[spin_index] 4475 4476 # Get the attached proton. 4477 proton = None 4478 if proton_mmq_flag: 4479 # Get all protons. 4480 proton_spins = return_attached_protons(spin_id) 4481 4482 # Only one allowed. 4483 if len(proton_spins) > 1: 4484 raise RelaxError("Only one attached proton is supported for the MMQ-type models.") 4485 4486 # Missing proton. 4487 if not len(proton_spins): 4488 raise RelaxError("No proton attached to the spin '%s' could be found. This is required for the MMQ-type models." % spin_id) 4489 4490 # Alias the single proton. 4491 proton = proton_spins[0] 4492 4493 # No data. 4494 if not hasattr(spin, 'r2eff') and not hasattr(proton, 'r2eff'): 4495 continue 4496 data_flag = True 4497 4498 # No isotope information. 4499 if not hasattr(spin, 'isotope'): 4500 raise RelaxSpinTypeError(spin_id=spin_ids[si]) 4501 4502 # Loop over the R2eff data. 4503 for exp_type, frq, offset, point, ei, mi, oi, di in loop_exp_frq_offset_point(return_indices=True): 4504 # Alias the correct spin. 4505 current_spin = spin 4506 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 4507 current_spin = proton 4508 4509 # Add the experiment type. 4510 if exp_type not in exp_types: 4511 exp_types.append(exp_type) 4512 4513 # The key. 4514 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 4515 if mi == 0: 4516 fact = 60.83831274541046 4517 else: 4518 fact = 81.11775032721394 4519 4520 # The Larmor frequency for this spin (and that of an attached proton for the MMQ models) and field strength (in MHz*2pi to speed up the ppm to rad/s conversion). 4521 if frq != None: 4522 frqs[ei][si][mi] = 2.0 * pi * frq / periodic_table.gyromagnetic_ratio('1H') * periodic_table.gyromagnetic_ratio(spin.isotope) * 1e-6 4523 frqs_H[ei][si][mi] = 2.0 * pi * frq * 1e-6 4524 4525 # The relaxation times. 4526 for time, ti in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point, return_indices=True): 4527 relax_times[ei][mi][oi][di].append(time) 4528 4529 # Missing data. 4530 if key not in current_spin.r2eff: 4531 values[ei][si][mi][oi].append(0.0) 4532 errors[ei][si][mi][oi].append(1.0) 4533 missing[ei][si][mi][oi].append(1) 4534 continue 4535 else: 4536 missing[ei][si][mi][oi].append(0) 4537 4538 # The values. 4539 if sim_index == None: 4540 values[ei][si][mi][oi].append(current_spin.r2eff[key]) 4541 else: 4542 values[ei][si][mi][oi].append(current_spin.r2eff_sim[sim_index][key]) 4543 4544 # The errors. 4545 errors[ei][si][mi][oi].append(current_spin.r2eff_err[key]) 4546 4547 # Increment the spin index. 4548 si += 1 4549 4550 # No R2eff/R1rho data for the spin cluster. 4551 if not data_flag: 4552 raise RelaxError("No R2eff/R1rho data could be found for the spin cluster %s." % spin_ids) 4553 4554 # Convert to numpy arrays. 4555 for exp_type, ei in loop_exp(return_indices=True): 4556 for si in range(spin_num): 4557 for frq, mi in loop_frq(return_indices=True): 4558 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 4559 values[ei][si][mi][oi] = array(values[ei][si][mi][oi], float64) 4560 errors[ei][si][mi][oi] = array(errors[ei][si][mi][oi], float64) 4561 missing[ei][si][mi][oi] = array(missing[ei][si][mi][oi], int32) 4562 for point, di in loop_point(exp_type=exp_type, frq=frq, offset=offset, return_indices=True): 4563 relax_times[ei][mi][oi][di] = array(relax_times[ei][mi][oi][di], float64) 4564 4565 # Return the structures. 4566 return values, errors, missing, frqs, frqs_H, exp_types, relax_times
4567 4568
4569 -def return_relax_times():
4570 """Return the list of relaxation times. 4571 4572 @return: The list of relaxation times in s. 4573 @rtype: numpy rank-2 float64 array 4574 """ 4575 4576 # No data. 4577 if not hasattr(cdp, 'relax_times'): 4578 return None 4579 4580 # Initialise. 4581 relax_times = zeros((count_exp(), count_frq()), float64) 4582 4583 # Loop over the experiment types. 4584 for exp_type, frq, point, time, ei, mi, di, ti in loop_exp_frq_point_time(return_indices=True): 4585 # Fetch all of the matching intensity keys. 4586 keys = find_intensity_keys(exp_type=exp_type, frq=frq, point=point, time=time, raise_error=False) 4587 4588 # No data. 4589 if not len(keys): 4590 continue 4591 4592 # Add the data. 4593 relax_times[ei][mi] = cdp.relax_times[keys[0]] 4594 4595 # Return the data. 4596 return relax_times
4597 4598
4599 -def return_spin_lock_nu1(ref_flag=True):
4600 """Return the list of spin-lock field strengths. 4601 4602 @keyword ref_flag: A flag which if False will cause the reference spectrum frequency of None to be removed from the list. 4603 @type ref_flag: bool 4604 @return: The list of spin-lock field strengths in Hz. It has the dimensions {Ei, Mi, Oi}. 4605 @rtype: rank-2 list of numpy rank-1 float64 arrays 4606 """ 4607 4608 # No data. 4609 if not hasattr(cdp, 'spin_lock_nu1_list'): 4610 return None 4611 4612 # Initialise. 4613 nu1 = [] 4614 4615 # First loop over the experiment types. 4616 for exp_type, ei in loop_exp(return_indices=True): 4617 # Add a new dimension. 4618 nu1.append([]) 4619 4620 # Then loop over the spectrometer frequencies. 4621 for frq, mi in loop_frq(return_indices=True): 4622 # Add a new dimension. 4623 nu1[ei].append([]) 4624 4625 # Loop over the offsets. 4626 for offset, oi in loop_offset(exp_type=exp_type, frq=frq, return_indices=True): 4627 # Add a new dimension. 4628 nu1[ei][mi].append([]) 4629 4630 # Loop over the fields. 4631 for point in cdp.spin_lock_nu1_list: 4632 # Skip reference points. 4633 if (not ref_flag) and point == None: 4634 continue 4635 4636 # Find a matching experiment ID. 4637 found = False 4638 for id in cdp.exp_type: 4639 # Skip non-matching experiments. 4640 if cdp.exp_type[id] != exp_type: 4641 continue 4642 4643 # Skip non-matching spectrometer frequencies. 4644 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 4645 continue 4646 4647 # Skip non-matching offsets. 4648 if offset != None and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 4649 continue 4650 4651 # Skip non-matching points. 4652 if cdp.spin_lock_nu1[id] != point: 4653 continue 4654 4655 # Found. 4656 found = True 4657 break 4658 4659 # No data. 4660 if not found: 4661 continue 4662 4663 # Add the data. 4664 nu1[ei][mi][oi].append(point) 4665 4666 # Convert to a numpy array. 4667 nu1[ei][mi][oi] = array(nu1[ei][mi][oi], float64) 4668 4669 # Return the data. 4670 return nu1
4671 4672
4673 -def return_spin_lock_nu1_single(exp_type=None, frq=None, offset=None, ref_flag=True):
4674 """Return the list of spin-lock field strengths. 4675 4676 @keyword exp_type: The experiment type. 4677 @type exp_type: str 4678 @keyword frq: The spectrometer frequency in Hz. 4679 @type frq: float 4680 @keyword offset: The spin-lock offset. 4681 @type offset: None or float 4682 @keyword ref_flag: A flag which if False will cause the reference spectrum frequency of None to be removed from the list. 4683 @type ref_flag: bool 4684 @return: The list of spin-lock field strengths in Hz. 4685 @rtype: numpy rank-1 float64 array 4686 """ 4687 4688 # No data. 4689 if not hasattr(cdp, 'spin_lock_nu1_list'): 4690 return None 4691 4692 # Initialise. 4693 nu1 = [] 4694 4695 # Loop over the points. 4696 for point in cdp.spin_lock_nu1_list: 4697 # Skip reference points. 4698 if (not ref_flag) and point == None: 4699 continue 4700 4701 # Find a matching experiment ID. 4702 found = False 4703 for id in cdp.exp_type: 4704 # Skip non-matching experiments. 4705 if cdp.exp_type[id] != exp_type: 4706 continue 4707 4708 # Skip non-matching spectrometer frequencies. 4709 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 4710 continue 4711 4712 # Skip non-matching offsets. 4713 if offset != None and hasattr(cdp, 'spin_lock_offset') and cdp.spin_lock_offset[id] != offset: 4714 continue 4715 4716 # Skip non-matching points. 4717 if cdp.spin_lock_nu1[id] != point: 4718 continue 4719 4720 # Found. 4721 found = True 4722 break 4723 4724 # No data. 4725 if not found: 4726 continue 4727 4728 # Add the data. 4729 nu1.append(point) 4730 4731 # Return the data as a numpy array. 4732 return array(nu1, float64)
4733 4734
4735 -def return_value_from_frq_index(mi=None):
4736 """Return the spectrometer frequency corresponding to the frequency index. 4737 4738 @keyword mi: The spectrometer frequency index. 4739 @type mi: int 4740 @return: The spectrometer frequency in Hertz or None if no information is present. 4741 @rtype: float 4742 """ 4743 4744 # No data. 4745 if not hasattr(cdp, 'spectrometer_frq_list'): 4746 return None 4747 4748 # Return the field. 4749 return cdp.spectrometer_frq_list[mi]
4750 4751
4752 -def return_value_from_offset_index(ei=None, mi=None, oi=None):
4753 """Return the offset corresponding to the offset index. 4754 4755 @keyword ei: The experiment type index. 4756 @type ei: int 4757 @keyword mi: The spectrometer frequency index. 4758 @type mi: int 4759 @keyword oi: The offset index. 4760 @type oi: int 4761 @return: The offset in Hertz or None if no information is present. 4762 @rtype: float 4763 """ 4764 4765 # Checks. 4766 if ei == None: 4767 raise RelaxError("The experiment type index must be supplied.") 4768 if mi == None: 4769 raise RelaxError("The spectrometer frequency index must be supplied.") 4770 4771 # Initialise the index. 4772 new_oi = -1 4773 4774 # The experiment type and frequency. 4775 exp_type = cdp.exp_type_list[ei] 4776 frq = return_value_from_frq_index(mi) 4777 4778 # CPMG-type data. 4779 if exp_type in EXP_TYPE_LIST_CPMG: 4780 # Return zero until hard pulse offset handling is implemented. 4781 return 0.0 4782 4783 # R1rho-type data. 4784 if exp_type in EXP_TYPE_LIST_R1RHO: 4785 # No offsets. 4786 if not hasattr(cdp, 'spin_lock_offset'): 4787 return None 4788 4789 # Loop over the offset data. 4790 for offset in cdp.spin_lock_offset_list: 4791 # Increment the index. 4792 new_oi += 1 4793 4794 # Find a matching experiment ID. 4795 found = False 4796 for id in cdp.exp_type: 4797 # Skip non-matching experiments. 4798 if cdp.exp_type[id] != exp_type: 4799 continue 4800 4801 # Skip non-matching spectrometer frequencies. 4802 if hasattr(cdp, 'spectrometer_frq') and cdp.spectrometer_frq[id] != frq: 4803 continue 4804 4805 # Skip non-matching offsets. 4806 if new_oi != oi: 4807 continue 4808 4809 # Found. 4810 found = True 4811 break 4812 4813 # No data. 4814 if not found: 4815 continue 4816 4817 # Return the offset. 4818 return offset
4819 4820
4821 -def set_exp_type(spectrum_id=None, exp_type=None):
4822 """Select the relaxation dispersion experiment type performed. 4823 4824 @keyword spectrum_id: The spectrum ID string. 4825 @type spectrum_id: str 4826 @keyword exp: The relaxation dispersion experiment type. 4827 @type exp: str 4828 """ 4829 4830 # Data checks. 4831 check_pipe() 4832 4833 # Add the spectrum ID to the data store if needed. 4834 add_spectrum_id(spectrum_id) 4835 4836 # Check the experiment type. 4837 if exp_type not in EXP_TYPE_LIST: 4838 raise RelaxError("The relaxation dispersion experiment '%s' is invalid, it must be one of %s." % (exp_type, EXP_TYPE_LIST)) 4839 4840 # Initialise the experiment type data structures if needed. 4841 if not hasattr(cdp, 'exp_type'): 4842 cdp.exp_type = {} 4843 if not hasattr(cdp, 'exp_type_list'): 4844 cdp.exp_type_list = [] 4845 4846 # Store the value. 4847 cdp.exp_type[spectrum_id] = exp_type 4848 4849 # Unique experiments. 4850 if cdp.exp_type[spectrum_id] not in cdp.exp_type_list: 4851 cdp.exp_type_list.append(cdp.exp_type[spectrum_id]) 4852 4853 # Printout. 4854 text = "The spectrum ID '%s' is now set to " % spectrum_id 4855 if exp_type == EXP_TYPE_CPMG_SQ: 4856 text += EXP_TYPE_DESC_CPMG_SQ + "." 4857 elif exp_type == EXP_TYPE_CPMG_MQ: 4858 text += EXP_TYPE_DESC_CPMG_MQ + "." 4859 elif exp_type == EXP_TYPE_CPMG_DQ: 4860 text += EXP_TYPE_DESC_CPMG_DQ + "." 4861 elif exp_type == EXP_TYPE_CPMG_ZQ: 4862 text += EXP_TYPE_DESC_CPMG_ZQ + "." 4863 elif exp_type == EXP_TYPE_CPMG_PROTON_SQ: 4864 text += EXP_TYPE_DESC_CPMG_PROTON_SQ + "." 4865 elif exp_type == EXP_TYPE_CPMG_PROTON_MQ: 4866 text += EXP_TYPE_DESC_CPMG_PROTON_MQ + "." 4867 elif exp_type == EXP_TYPE_R1RHO: 4868 text += EXP_TYPE_DESC_R1RHO + "." 4869 print(text)
4870 4871
4872 -def spin_has_frq_data(spin=None, frq=None):
4873 """Determine if the spin has intensity data for the given spectrometer frequency. 4874 4875 @keyword spin: The specific spin data container. 4876 @type spin: SpinContainer instance 4877 @keyword frq: The spectrometer frequency. 4878 @type frq: float 4879 @return: True if data for that spectrometer frequency is present, False otherwise. 4880 @rtype: bool 4881 """ 4882 4883 # Loop over the intensity data. 4884 for key in spin.peak_intensity: 4885 if key in cdp.spectrometer_frq and cdp.spectrometer_frq[key] == frq: 4886 return True 4887 4888 # No data. 4889 return False
4890 4891
4892 -def spin_ids_to_containers(spin_ids):
4893 """Take the list of spin IDs and return the corresponding spin containers. 4894 4895 This is useful for handling the data from the model_loop() method. 4896 4897 4898 @param spin_ids: The list of spin ID strings. 4899 @type spin_ids: list of str 4900 @return: The list of spin containers. 4901 @rtype: list of SpinContainer instances 4902 """ 4903 4904 # Loop over the IDs and fetch the container. 4905 spins = [] 4906 for id in spin_ids: 4907 spins.append(return_spin(id)) 4908 4909 # Return the containers. 4910 return spins
4911 4912
4913 -def spin_lock_field(spectrum_id=None, field=None):
4914 """Set the spin-lock field strength (nu1) for the given spectrum. 4915 4916 @keyword spectrum_id: The spectrum ID string. 4917 @type spectrum_id: str 4918 @keyword field: The spin-lock field strength (nu1) in Hz. 4919 @type field: int or float 4920 """ 4921 4922 # Test if the spectrum ID exists. 4923 if spectrum_id not in cdp.spectrum_ids: 4924 raise RelaxNoSpectraError(spectrum_id) 4925 4926 # Initialise the global nu1 data structures if needed. 4927 if not hasattr(cdp, 'spin_lock_nu1'): 4928 cdp.spin_lock_nu1 = {} 4929 if not hasattr(cdp, 'spin_lock_nu1_list'): 4930 cdp.spin_lock_nu1_list = [] 4931 4932 # Add the frequency, converting to a float if needed. 4933 if field == None: 4934 cdp.spin_lock_nu1[spectrum_id] = field 4935 else: 4936 cdp.spin_lock_nu1[spectrum_id] = float(field) 4937 4938 # The unique curves for the R2eff fitting (R1rho). 4939 if cdp.spin_lock_nu1[spectrum_id] not in cdp.spin_lock_nu1_list: 4940 cdp.spin_lock_nu1_list.append(cdp.spin_lock_nu1[spectrum_id]) 4941 4942 # Sort the list (handling None for Python 3). 4943 flag = False 4944 if None in cdp.spin_lock_nu1_list: 4945 cdp.spin_lock_nu1_list.pop(cdp.spin_lock_nu1_list.index(None)) 4946 flag = True 4947 cdp.spin_lock_nu1_list.sort() 4948 if flag: 4949 cdp.spin_lock_nu1_list.insert(0, None) 4950 4951 # Update the exponential curve count (skipping the reference if present). 4952 cdp.dispersion_points = len(cdp.spin_lock_nu1_list) 4953 if None in cdp.spin_lock_nu1_list: 4954 cdp.dispersion_points -= 1 4955 4956 # Printout. 4957 if field == None: 4958 print("The spectrum ID '%s' is set to the reference." % spectrum_id) 4959 else: 4960 print("The spectrum ID '%s' spin-lock field strength is set to %s kHz." % (spectrum_id, cdp.spin_lock_nu1[spectrum_id]/1000.0))
4961 4962
4963 -def spin_lock_offset(spectrum_id=None, offset=None):
4964 """Set the spin-lock offset (omega_rf) for the given spectrum. 4965 4966 @keyword spectrum_id: The spectrum ID string. 4967 @type spectrum_id: str 4968 @keyword offset: The spin-lock offset (omega_rf) in ppm. 4969 @type offset: int or float 4970 """ 4971 4972 # Test if the spectrum ID exists. 4973 if spectrum_id not in cdp.spectrum_ids: 4974 raise RelaxNoSpectraError(spectrum_id) 4975 4976 # Initialise the global offset data structures if needed. 4977 if not hasattr(cdp, 'spin_lock_offset'): 4978 cdp.spin_lock_offset = {} 4979 if not hasattr(cdp, 'spin_lock_offset_list'): 4980 cdp.spin_lock_offset_list = [] 4981 4982 # Add the offset, converting to a float if needed. 4983 if offset == None: 4984 raise RelaxError("The offset value must be provided.") 4985 cdp.spin_lock_offset[spectrum_id] = float(offset) 4986 4987 # The unique curves for the R2eff fitting (R1rho). 4988 if cdp.spin_lock_offset[spectrum_id] not in cdp.spin_lock_offset_list: 4989 cdp.spin_lock_offset_list.append(cdp.spin_lock_offset[spectrum_id]) 4990 4991 # Sort the list. 4992 cdp.spin_lock_offset_list.sort() 4993 4994 # Printout. 4995 print("Setting the '%s' spectrum spin-lock offset to %s ppm." % (spectrum_id, cdp.spin_lock_offset[spectrum_id]))
4996 4997
4998 -def write_disp_curves(dir=None, force=None):
4999 """Write out the dispersion curves to text files. 5000 5001 One file will be created per spin system. 5002 5003 5004 @keyword dir: The optional directory to place the file into. 5005 @type dir: str 5006 @param force: If True, the files will be overwritten if they already exists. 5007 @type force: bool 5008 """ 5009 5010 # Checks. 5011 check_pipe() 5012 check_mol_res_spin_data() 5013 5014 # The formatting strings. 5015 format_head = "# %-18s %-20s %-20s %-20s %-20s %-20s\n" 5016 format = "%-20s %20s %20s %20s %20s %20s\n" 5017 5018 # 1H MMQ flag. 5019 proton_mmq_flag = has_proton_mmq_cpmg() 5020 5021 # Loop over each spin. 5022 for spin, spin_id in spin_loop(return_id=True, skip_desel=True): 5023 # Skip protons for MMQ data. 5024 if spin.model in MODEL_LIST_MMQ and spin.isotope == '1H': 5025 continue 5026 5027 # Define writing variables. 5028 writing_vars = [['disp', ("Experiment_name", "Field_strength_(MHz)", "Disp_point_(Hz)", "R2eff_(measured)", "R2eff_(back_calc)", "R2eff_errors")]] 5029 5030 # If the model is of R1rho type, then also write as R2eff as function of theta. 5031 if spin.model in MODEL_LIST_R1RHO_FULL and has_r1rho_exp_type() and hasattr(spin, 'isotope'): 5032 # Add additonal looping over writing parameters. 5033 writing_vars.append(['disp_theta', ("Experiment_name", "Field_strength_(MHz)", "Tilt_angle_(rad)", "R2eff_(measured)", "R2eff_(back_calc)", "R2eff_errors")]) 5034 5035 # Loop over writing vars 5036 for wvar in writing_vars: 5037 # Get the attached proton. 5038 proton = None 5039 if proton_mmq_flag: 5040 proton = return_attached_protons(spin_id)[0] 5041 5042 # The unique file name. 5043 file_name = "%s%s.out" % (wvar[0], spin_id.replace('#', '_').replace(':', '_').replace('@', '_')) 5044 5045 # Open the file for writing. 5046 file_path = get_file_path(file_name, dir) 5047 file = open_write_file(file_name, dir, force) 5048 5049 # Write a header. 5050 file.write(format_head % wvar[1]) 5051 5052 # Loop over the dispersion points. 5053 for exp_type, frq, offset, point, ei, mi, oi, di in loop_exp_frq_offset_point(return_indices=True): 5054 # Alias the correct spin. 5055 current_spin = spin 5056 if exp_type in [EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_PROTON_MQ]: 5057 current_spin = proton 5058 5059 # The data key. 5060 key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 5061 5062 # Format the R2eff data. 5063 r2eff = "-" 5064 if hasattr(current_spin, 'r2eff') and key in current_spin.r2eff: 5065 r2eff = "%.15f" % current_spin.r2eff[key] 5066 5067 # Format the R2eff back calc data. 5068 r2eff_bc = "-" 5069 if hasattr(current_spin, 'r2eff_bc') and key in current_spin.r2eff_bc: 5070 r2eff_bc = "%.15f" % current_spin.r2eff_bc[key] 5071 5072 # Format the R2eff errors. 5073 r2eff_err = "-" 5074 if hasattr(current_spin, 'r2eff_err') and key in current_spin.r2eff_err: 5075 r2eff_err = "%.15f" % current_spin.r2eff_err[key] 5076 5077 # Define value to be written. 5078 if wvar[0] == 'disp_theta': 5079 theta_spin_dic, Domega_spin_dic, w_eff_spin_dic, dic_key_list = calc_rotating_frame_params(spin=spin) 5080 value = theta_spin_dic[key] 5081 elif wvar[0] == 'disp_w_eff': 5082 theta_spin_dic, Domega_spin_dic, w_eff_spin_dic, dic_key_list = calc_rotating_frame_params(spin=spin) 5083 value = w_eff_spin_dic[key] 5084 # Else use the standard dispersion point data. 5085 else: 5086 value = point 5087 5088 # Write out the data. 5089 frq_text = "%.9f" % (frq/1e6) 5090 value_text = "%.6f" % value 5091 file.write(format % (repr(exp_type), frq_text, value_text, r2eff, r2eff_bc, r2eff_err)) 5092 5093 # Close the file. 5094 file.close() 5095 5096 # Add the file to the results file list. 5097 add_result_file(type='text', label='Text', file=file_path)
5098