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