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