Package pipe_control :: Module align_tensor
[hide private]
[frames] | no frames]

Source Code for Module pipe_control.align_tensor

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2003-2013 Edward d'Auvergne                                   # 
   4  #                                                                             # 
   5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
   6  #                                                                             # 
   7  # This program is free software: you can redistribute it and/or modify        # 
   8  # it under the terms of the GNU General Public License as published by        # 
   9  # the Free Software Foundation, either version 3 of the License, or           # 
  10  # (at your option) any later version.                                         # 
  11  #                                                                             # 
  12  # This program is distributed in the hope that it will be useful,             # 
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
  15  # GNU General Public License for more details.                                # 
  16  #                                                                             # 
  17  # You should have received a copy of the GNU General Public License           # 
  18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
  19  #                                                                             # 
  20  ############################################################################### 
  21   
  22  # Module docstring. 
  23  """Module containing functions for the handling of alignment tensors.""" 
  24   
  25  # Python module imports. 
  26  from copy import deepcopy 
  27  from math import pi, sqrt 
  28  from numpy import arccos, dot, float64, linalg, zeros 
  29  from numpy.linalg import norm 
  30  from re import search 
  31  import sys 
  32  from warnings import warn 
  33   
  34  # relax module imports. 
  35  from data_store.align_tensor import AlignTensorList 
  36  from lib.alignment.alignment_tensor import calc_chi_tensor, kappa 
  37  from lib.errors import RelaxError, RelaxNoTensorError, RelaxStrError, RelaxTensorError, RelaxUnknownParamCombError, RelaxUnknownParamError 
  38  from lib.io import write_data 
  39  from lib.warnings import RelaxWarning 
  40  import pipe_control 
  41  from pipe_control import pipes 
  42  from pipe_control.angles import wrap_angles 
  43   
  44   
45 -def align_data_exists(tensor, pipe=None):
46 """Function for determining if alignment data exists in the current data pipe. 47 48 @param tensor: The alignment tensor identification string. 49 @type tensor: str 50 @param pipe: The data pipe to search for data in. 51 @type pipe: str 52 @return: The answer to the question. 53 @rtype: bool 54 """ 55 56 # The data pipe to check. 57 if pipe == None: 58 pipe = pipes.cdp_name() 59 60 # Get the data pipe. 61 pipe = pipes.get_pipe(pipe) 62 63 # Test if an alignment tensor corresponding to the arg 'tensor' exists. 64 if hasattr(pipe, 'align_tensors'): 65 for data in pipe.align_tensors: 66 if data.name == tensor: 67 return True 68 else: 69 return False
70 71
72 -def all_tensors_fixed():
73 """Determine if all alignment tensors are fixed. 74 75 @return: True if all tensors are fixed, False otherwise. 76 @rtype: bool 77 """ 78 79 # Loop over the tensors. 80 for i in range(len(cdp.align_tensors)): 81 # Not fixed, so return False. 82 if not cdp.align_tensors[i].fixed: 83 return False 84 85 # All tensors are fixed. 86 return True
87 88
89 -def copy(tensor_from=None, pipe_from=None, tensor_to=None, pipe_to=None):
90 """Function for copying alignment tensor data from one data pipe to another. 91 92 @param tensor_from: The identification string of the alignment tensor to copy the data from. 93 @type tensor_from: str 94 @param pipe_from: The data pipe to copy the alignment tensor data from. This defaults to the current data pipe. 95 @type pipe_from: str 96 @param tensor_to: The identification string of the alignment tensor to copy the data to. If set to None, then the ID string will be set to the value of tensor_from. 97 @type tensor_to: str or None 98 @param pipe_to: The data pipe to copy the alignment tensor data to. This defaults to the current data pipe. 99 @type pipe_to: str 100 """ 101 102 # Defaults. 103 if tensor_from == tensor_to and pipe_from == None and pipe_to == None: 104 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None when the tensor names are the same.") 105 elif pipe_from == None: 106 pipe_from = pipes.cdp_name() 107 elif pipe_to == None: 108 pipe_to = pipes.cdp_name() 109 110 # The target tensor ID string. 111 if tensor_to == None: 112 tensor_to = tensor_from 113 114 # Test if the pipe_from and pipe_to data pipes exist. 115 pipes.test(pipe_from) 116 pipes.test(pipe_to) 117 118 # Get the data pipes. 119 dp_from = pipes.get_pipe(pipe_from) 120 dp_to = pipes.get_pipe(pipe_to) 121 122 # Test if pipe_from contains alignment tensor data. 123 if not align_data_exists(tensor_from, pipe_from): 124 raise RelaxNoTensorError('alignment') 125 126 # Test if pipe_to contains alignment tensor data. 127 if align_data_exists(tensor_to, pipe_to): 128 raise RelaxTensorError('alignment') 129 130 # Create the align_tensors dictionary if it doesn't yet exist. 131 if not hasattr(dp_to, 'align_tensors'): 132 dp_to.align_tensors = AlignTensorList() 133 134 # Add the tensor if it doesn't already exist. 135 if tensor_to not in dp_to.align_tensors.names(): 136 dp_to.align_tensors.add_item(tensor_to) 137 138 # Find the tensor index. 139 index_from = get_tensor_index(tensor=tensor_from, pipe=pipe_from) 140 index_to = get_tensor_index(tensor=tensor_to, pipe=pipe_to) 141 142 # Copy the data. 143 if index_to == None: 144 dp_to.align_tensors.append(deepcopy(dp_from.align_tensors[index_from])) 145 index_to = len(dp_to.align_tensors) - 1 146 else: 147 dp_to.align_tensors[index_to] = deepcopy(dp_from.align_tensors[index_from]) 148 149 # Update the tensor's name. 150 dp_to.align_tensors[index_to].set('name', tensor_to) 151 152 # Add the align ID to the target data pipe if needed. 153 align_id = dp_from.align_tensors[index_from].align_id 154 if not hasattr(dp_to, 'align_ids'): 155 dp_to.align_ids = [] 156 if align_id not in dp_to.align_ids: 157 dp_to.align_ids.append(align_id)
158 159
160 -def data_names():
161 """Function for returning a list of names of data structures associated with the sequence.""" 162 163 names = [ 'align_params' ] 164 165 return names
166 167
168 -def default_value(param):
169 """Return the default values for the alignment tensor parameters. 170 171 @param param: The name of the parameter. 172 @type param: str 173 @return: The default value, which for all parameters is set to zero. 174 @rtype: float 175 """ 176 177 # Return 0.0. 178 return 0.0
179 180 # User function documentation. 181 __default_value_prompt_doc__ = """ 182 Alignment tensor parameter default values 183 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 185 ________________________________________________________________________ 186 | | | | 187 | Data type | Object name | Value | 188 |________________________|____________________|________________________| 189 | | | | 190 | Axx | 'Axx' | 0.0 | 191 | | | | 192 | Ayy | 'Ayy' | 0.0 | 193 | | | | 194 | Azz | 'Azz' | 0.0 | 195 | | | | 196 | Axxyy | 'Axxyy' | 0.0 | 197 | | | | 198 | Axy | 'Axy' | 0.0 | 199 | | | | 200 | Axz | 'Axz' | 0.0 | 201 | | | | 202 | Ayz | 'Ayz' | 0.0 | 203 | | | | 204 | alpha | 'alpha' | 0.0 | 205 | | | | 206 | beta | 'beta' | 0.0 | 207 | | | | 208 | gamma | 'gamma' | 0.0 | 209 |________________________|____________________|________________________| 210 211 """ 212 213
214 -def delete(tensor=None):
215 """Function for deleting alignment tensor data. 216 217 @param tensor: The alignment tensor identification string. 218 @type tensor: str or None 219 """ 220 221 # Test if the current data pipe exists. 222 pipes.test() 223 224 # Test if alignment tensor data exists. 225 if tensor and not align_data_exists(tensor): 226 raise RelaxNoTensorError('alignment') 227 228 # The tensor list. 229 if tensor: 230 tensors = [tensor] 231 else: 232 tensors = [] 233 for i in range(len(cdp.align_tensors)): 234 tensors.append(cdp.align_tensors[i].name) 235 236 # Loop over the tensors. 237 for tensor in tensors: 238 # Print out. 239 print("Removing the '%s' tensor." % tensor) 240 241 # Find the tensor index. 242 index = get_tensor_index(tensor=tensor) 243 244 # Delete the alignment data. 245 cdp.align_tensors.pop(index) 246 247 # Delete the alignment tensor list if empty. 248 if not len(cdp.align_tensors): 249 del(cdp.align_tensors)
250 251
252 -def display(tensor=None):
253 """Function for displaying the alignment tensor. 254 255 @keyword tensor: The alignment tensor identification string. 256 @type tensor: str or None 257 """ 258 259 # Test if the current data pipe exists. 260 pipes.test() 261 262 # Construct the tensor list. 263 tensor_list = [] 264 if not tensor: 265 for tensor_cont in cdp.align_tensors: 266 tensor_list.append(tensor_cont.name) 267 else: 268 tensor_list.append(tensor) 269 270 # Loop over the tensors. 271 for tensor in tensor_list: 272 # Test if alignment tensor data exists. 273 if not align_data_exists(tensor): 274 raise RelaxNoTensorError('alignment') 275 276 # Pull out the tensor. 277 data = get_tensor_object(tensor) 278 279 # Header. 280 head = "# Tensor: %s #" % tensor 281 print("\n\n\n" + '#' * len(head) + "\n" + head + "\n" + '#' * len(head)) 282 283 284 # The Saupe matrix. 285 ################### 286 287 title = "# Saupe order matrix." 288 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 289 290 # The parameter set {Sxx, Syy, Sxy, Sxz, Syz}. 291 print("# 5D, rank-1 notation {Sxx, Syy, Sxy, Sxz, Syz}:") 292 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Sxx, data.Syy, data.Sxy, data.Sxz, data.Syz)) 293 294 # The parameter set {Szz, Sxx-yy, Sxy, Sxz, Syz}. 295 print("# 5D, rank-1 notation {Szz, Sxx-yy, Sxy, Sxz, Syz} (the Pales default format).") 296 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Szz, data.Sxxyy, data.Sxy, data.Sxz, data.Syz)) 297 298 # 3D form. 299 print("# 3D, rank-2 notation.") 300 print("%s" % (data.S)) 301 302 303 # The alignment tensor. 304 ####################### 305 306 title = "# Alignment tensor." 307 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 308 309 # The parameter set {Axx, Ayy, Axy, Axz, Ayz}. 310 print("# 5D, rank-1 notation {Axx, Ayy, Axy, Axz, Ayz}:") 311 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Axx, data.Ayy, data.Axy, data.Axz, data.Ayz)) 312 313 # The parameter set {Azz, Axx-yy, Axy, Axz, Ayz}. 314 print("# 5D, rank-1 notation {Azz, Axx-yy, Axy, Axz, Ayz} (the Pales default format).") 315 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Azz, data.Axxyy, data.Axy, data.Axz, data.Ayz)) 316 317 # 3D form. 318 print("# 3D, rank-2 notation.") 319 print("%s" % data.A) 320 321 322 # The probability tensor. 323 ######################### 324 325 title = "# Probability tensor." 326 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 327 328 # The parameter set {Pxx, Pyy, Pxy, Pxz, Pyz}. 329 print("# 5D, rank-1 notation {Pxx, Pyy, Pxy, Pxz, Pyz}:") 330 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Pxx, data.Pyy, data.Pxy, data.Pxz, data.Pyz)) 331 332 # The parameter set {Pzz, Pxx-yy, Pxy, Pxz, Pyz}. 333 print("# 5D, rank-1 notation {Pzz, Pxx-yy, Pxy, Pxz, Pyz}.") 334 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Pzz, data.Pxxyy, data.Pxy, data.Pxz, data.Pyz)) 335 336 # 3D form. 337 print("# 3D, rank-2 notation.") 338 print("%s" % data.P) 339 340 341 # The magnetic susceptibility tensor. 342 ##################################### 343 344 title = "# Magnetic susceptibility tensor." 345 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 346 chi_tensor = True 347 348 # The field strength. 349 print("# The magnetic field strength (MHz):") 350 if hasattr(cdp, 'spectrometer_frq') and tensor in cdp.spectrometer_frq: 351 print("%s\n" % (cdp.spectrometer_frq[tensor] / 1e6)) 352 else: 353 print("Not set.\n") 354 chi_tensor = False 355 356 # The temperature. 357 print("# The temperature (K):") 358 if hasattr(cdp, 'temperature') and tensor in cdp.temperature: 359 print("%s\n" % cdp.temperature[tensor]) 360 else: 361 print("Not set.\n") 362 chi_tensor = False 363 364 # No chi tensor. 365 if not chi_tensor: 366 print("# The chi tensor:\nN/A.\n") 367 368 # Calculate the chi tensor. 369 else: 370 # Conversions. 371 chi_xx = calc_chi_tensor(data.Axx, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 372 chi_xy = calc_chi_tensor(data.Axy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 373 chi_xz = calc_chi_tensor(data.Axz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 374 chi_yy = calc_chi_tensor(data.Ayy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 375 chi_yz = calc_chi_tensor(data.Ayz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 376 chi_zz = calc_chi_tensor(data.Azz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 377 chi_xxyy = calc_chi_tensor(data.Axxyy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 378 chi = calc_chi_tensor(data.A, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 379 380 # The parameter set {chi_xx, chi_yy, chi_xy, chi_xz, chi_yz}. 381 print("# 5D, rank-1 notation {chi_xx, chi_yy, chi_xy, chi_xz, chi_yz}:") 382 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (chi_xx, chi_yy, chi_xy, chi_xz, chi_yz)) 383 384 # The parameter set {chi_zz, chi_xx-yy, chi_xy, chi_xz, chi_yz}. 385 print("# 5D, rank-1 notation {chi_zz, chi_xx-yy, chi_xy, chi_xz, chi_yz}.") 386 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (chi_zz, chi_xxyy, chi_xy, chi_xz, chi_yz)) 387 388 # 3D form. 389 print("# 3D, rank-2 notation.") 390 print("%s" % chi) 391 392 393 # The Eigensystem. 394 ################## 395 396 title = "# Eigensystem." 397 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 398 399 # Eigenvalues. 400 print("# Saupe order matrix eigenvalues {Sxx, Syy, Szz}.") 401 print("[%25.12e, %25.12e, %25.12e]\n" % (data.S_diag[0, 0], data.S_diag[1, 1], data.S_diag[2, 2])) 402 print("# Alignment tensor eigenvalues {Axx, Ayy, Azz}.") 403 print("[%25.12e, %25.12e, %25.12e]\n" % (data.A_diag[0, 0], data.A_diag[1, 1], data.A_diag[2, 2])) 404 print("# Probability tensor eigenvalues {Pxx, Pyy, Pzz}.") 405 print("[%25.12e, %25.12e, %25.12e]\n" % (data.P_diag[0, 0], data.P_diag[1, 1], data.P_diag[2, 2])) 406 if chi_tensor: 407 chi_diag = calc_chi_tensor(data.A_diag, cdp.spectrometer_frq[tensor], cdp.temperature[tensor]) 408 print("# Magnetic susceptibility eigenvalues {chi_xx, chi_yy, chi_zz}.") 409 print("[%25.12e, %25.12e, %25.12e]\n" % (chi_diag[0, 0], chi_diag[1, 1], chi_diag[2, 2])) 410 411 # Eigenvectors. 412 print("# Eigenvector x.") 413 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_x[0], data.unit_x[1], data.unit_x[2])) 414 print("# Eigenvector y.") 415 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_y[0], data.unit_y[1], data.unit_y[2])) 416 print("# Eigenvector z.") 417 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_z[0], data.unit_z[1], data.unit_z[2])) 418 419 # Rotation matrix. 420 print("# Rotation matrix.") 421 print("%s\n" % data.rotation) 422 423 # zyz. 424 print("# Euler angles in zyz notation {alpha, beta, gamma}.") 425 print("[%25.12f, %25.12f, %25.12f]\n" % (data.euler[0], data.euler[1], data.euler[2])) 426 427 428 # Geometric description. 429 ######################## 430 431 title = "# Geometric description." 432 print("\n\n" + title + '\n' + '#'*len(title) + '\n') 433 434 # The GDO. 435 print("# Generalized degree of order (GDO).") 436 print("GDO = %-25.12e\n" % gdo(data.A)) 437 438 # Anisotropy. 439 print("# Alignment tensor axial component (Aa = 3/2 * Azz, where Aii are the eigenvalues).") 440 print("Aa = %-25.12e\n" % data.Aa) 441 442 # Rhombicity. 443 print("# Rhombic component (Ar = Axx - Ayy, where Aii are the eigenvalues).") 444 print("Ar = %-25.12e\n" % data.Ar) 445 print("# Rhombicity (R = Ar / Aa).") 446 print("R = %-25.12f\n" % data.R) 447 print("# Asymmetry parameter (eta = (Axx - Ayy) / Azz, where Aii are the eigenvalues).") 448 print("eta = %-25.12f\n" % data.eta) 449 450 # Magnetic susceptibility tensor. 451 if chi_tensor: 452 # Chi tensor anisotropy. 453 print("# Magnetic susceptibility axial parameter (chi_ax = chi_zz - (chi_xx + chi_yy)/2, where chi_ii are the eigenvalues).") 454 print("chi_ax = %-25.12e\n" % (chi_diag[2, 2] - (chi_diag[0, 0] + chi_diag[1, 1])/2.0)) 455 456 # Chi tensor rhombicity. 457 print("# Magnetic susceptibility rhombicity parameter (chi_rh = chi_xx - chi_yy, where chi_ii are the eigenvalues).") 458 print("chi_rh = %-25.12e\n" % (chi_diag[0, 0] - chi_diag[1, 1])) 459 460 # Some white space. 461 print("\n\n\n")
462 463
464 -def fix(id=None, fixed=True):
465 """Fix the alignment tensor during optimisation. 466 467 @keyword id: The alignment tensor ID string. If set to None, then all alignment tensors will be fixed. 468 @type id: str or None 469 @keyword fixed: If True, the alignment tensor will be fixed during optimisation. If False, the alignment tensors will be optimised. 470 @type fixed: bool 471 """ 472 473 # Test if the current data pipe exists. 474 pipes.test() 475 476 # Loop over the tensors. 477 for i in range(len(cdp.align_tensors)): 478 # ID match. 479 if id and cdp.align_tensors[i].name == id: 480 cdp.align_tensors[i].set_fixed(fixed) 481 482 # Set all tensor flags. 483 if id == None: 484 cdp.align_tensors[i].set_fixed(fixed)
485 486
487 -def fold_angles(sim_index=None):
488 """Wrap the Euler angles and remove the glide reflection and translational symmetries. 489 490 Wrap the angles such that:: 491 492 0 <= alpha <= 2pi, 493 0 <= beta <= pi, 494 0 <= gamma <= 2pi. 495 496 For the simulated values, the angles are wrapped as:: 497 498 alpha - pi <= alpha_sim <= alpha + pi 499 beta - pi/2 <= beta_sim <= beta + pi/2 500 gamma - pi <= gamma_sim <= gamma + pi 501 502 503 @param sim_index: The simulation index. If set to None then the actual values will be folded 504 rather than the simulation values. 505 @type sim_index: int or None 506 """ 507 508 509 # Wrap the angles. 510 ################## 511 512 # Get the current angles. 513 alpha = cdp.align_tensors.alpha 514 beta = cdp.align_tensors.beta 515 gamma = cdp.align_tensors.gamma 516 517 # Simulated values. 518 if sim_index != None: 519 alpha_sim = cdp.align_tensors.alpha_sim[sim_index] 520 beta_sim = cdp.align_tensors.beta_sim[sim_index] 521 gamma_sim = cdp.align_tensors.gamma_sim[sim_index] 522 523 # Normal value. 524 if sim_index == None: 525 cdp.align_tensors.set(param='alpha', value=wrap_angles(alpha, 0.0, 2.0*pi)) 526 cdp.align_tensors.set(param='beta', value= wrap_angles(beta, 0.0, 2.0*pi)) 527 cdp.align_tensors.set(param='gamma', value=wrap_angles(gamma, 0.0, 2.0*pi)) 528 529 # Simulation values. 530 else: 531 cdp.align_tensors.set(param='alpha', value=wrap_angles(alpha_sim, alpha - pi, alpha + pi), category='sim', sim_index=sim_index) 532 cdp.align_tensors.set(param='beta', value= wrap_angles(beta_sim, beta - pi, beta + pi), category='sim', sim_index=sim_index) 533 cdp.align_tensors.set(param='gamma', value=wrap_angles(gamma_sim, gamma - pi, gamma + pi), category='sim', sim_index=sim_index) 534 535 536 # Remove the glide reflection and translational symmetries. 537 ########################################################### 538 539 # Normal value. 540 if sim_index == None: 541 # Fold beta inside 0 and pi. 542 if cdp.align_tensors.beta >= pi: 543 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha) 544 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta - pi) 545 546 # Simulation values. 547 else: 548 # Fold beta_sim inside beta-pi/2 and beta+pi/2. 549 if cdp.align_tensors.beta_sim[sim_index] >= cdp.align_tensors.beta + pi/2.0: 550 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha_sim[sim_index], category='sim', sim_index=sim_index) 551 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta_sim[sim_index] - pi, category='sim', sim_index=sim_index) 552 elif cdp.align_tensors.beta_sim[sim_index] <= cdp.align_tensors.beta - pi/2.0: 553 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha_sim[sim_index], category='sim', sim_index=sim_index) 554 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta_sim[sim_index] + pi, category='sim', sim_index=sim_index)
555 556
557 -def gdo(A):
558 """Calculate the generalized degree of order (GDO) for the given alignment tensor. 559 560 @param A: The alignment tensor. 561 @type A: rank-2, 3D numpy array 562 @return: The GDO value. 563 @rtype: float 564 """ 565 566 # The matrix norm. 567 gdo = sqrt(3.0/2.0) * norm(A) 568 569 # Return the GDO. 570 return gdo
571 572
573 -def get_align_ids():
574 """Return the list of all alignment IDs. 575 576 @return: The list of all alignment IDs. 577 @rtype: list of str 578 """ 579 580 # No pipe. 581 if cdp == None: 582 return [] 583 584 # No tensor data. 585 if not hasattr(cdp, 'align_ids'): 586 return [] 587 588 # The tensor IDs. 589 return cdp.align_ids
590 591
592 -def get_tensor_ids():
593 """Return the list of all tensor IDs. 594 595 @return: The list of all tensor IDs. 596 @rtype: list of str 597 """ 598 599 # Init. 600 ids = [] 601 602 # No pipe. 603 if cdp == None: 604 return ids 605 606 # No tensor data. 607 if not hasattr(cdp, 'align_tensors'): 608 return ids 609 610 # Loop over the tensors. 611 for i in range(len(cdp.align_tensors)): 612 if cdp.align_tensors[i].name != None: 613 ids.append(cdp.align_tensors[i].name) 614 615 # Return the object. 616 return ids
617 618
619 -def get_tensor_index(tensor=None, align_id=None, pipe=None):
620 """Function for returning the index corresponding to the 'tensor' argument. 621 622 @keyword tensor: The alignment tensor identification string. 623 @type tensor: str or None 624 @keyword align_id: Alternative to the tensor argument, used to return the tensor index for the tensors corresponding to the alignment ID string. If more than one tensor exists, then this will fail. 625 @type align_id: str or None 626 @keyword pipe: The data pipe to search for data in. 627 @type pipe: str 628 @return: The index corresponding to the 'tensor' arg. 629 @rtype: int 630 """ 631 632 # The data pipe to check. 633 if pipe == None: 634 pipe = pipes.cdp_name() 635 636 # Get the data pipe. 637 dp = pipes.get_pipe(pipe) 638 639 # Init. 640 index = None 641 count = 0 642 643 # Loop over the tensors. 644 for i in range(len(dp.align_tensors)): 645 # Tensor name match. 646 if tensor and dp.align_tensors[i].name == tensor: 647 index = i 648 count += 1 649 650 # Alignment ID match. 651 if align_id and hasattr(dp.align_tensors[i], 'align_id') and dp.align_tensors[i].align_id == align_id: 652 index = i 653 count += 1 654 655 # No match. 656 if count == 0: 657 warn(RelaxWarning("No alignment tensors match the tensor name '%s' or alignment ID '%s' in the data pipe '%s'." % (tensor, align_id, pipe))) 658 return None 659 660 # More than one match. 661 if count > 1: 662 warn(RelaxWarning("More than one alignment tensors matches the tensor name '%s' or alignment ID '%s' in the data pipe '%s'." % (tensor, align_id, pipe))) 663 return None 664 665 # Return the index. 666 return index
667 668
669 -def get_tensor_object(tensor, pipe=None):
670 """Return the AlignTensorData instance corresponding to the tensor ID. 671 672 @param tensor: The alignment tensor identification string. 673 @type tensor: str 674 @param pipe: The data pipe to search for data in. 675 @type pipe: str 676 @return: The alignment tensor object corresponding to the 'tensor' arg. 677 @rtype: AlignTensorData instance 678 """ 679 680 # The data pipe to check. 681 if pipe == None: 682 pipe = pipes.cdp_name() 683 684 # Init. 685 data = None 686 687 # Loop over the tensors. 688 for i in range(len(cdp.align_tensors)): 689 if cdp.align_tensors[i].name == tensor: 690 data = cdp.align_tensors[i] 691 692 # Return the object. 693 return data
694 695
696 -def get_tensor_object_from_align(align_id, pipe=None):
697 """Return the unique AlignTensorData instance corresponding to the alignment ID. 698 699 @param align_id: The alignment ID for the unique tensor. 700 @type align_id: str 701 @return: The alignment tensor object corresponding to the 'tensor' arg. 702 @rtype: AlignTensorData instance 703 """ 704 705 # The data pipe to check. 706 if pipe == None: 707 pipe = pipes.cdp_name() 708 709 # Init. 710 data = None 711 712 # Loop over the tensors. 713 count = 0 714 for i in range(len(cdp.align_tensors)): 715 if hasattr(cdp.align_tensors[i], 'align_id') and cdp.align_tensors[i].align_id == align_id: 716 data = cdp.align_tensors[i] 717 count += 1 718 719 # Multiple matches. 720 if count > 1: 721 raise RelaxError("Multiple alignment tensors match the alignment ID '%s'." % align_id) 722 # Return the object. 723 return data
724 725
726 -def init(tensor=None, align_id=None, params=None, scale=1.0, angle_units='deg', param_types=0, domain=None, errors=False):
727 """Function for initialising the alignment tensor. 728 729 @keyword tensor: The alignment tensor identification string. 730 @type tensor: str 731 @keyword align_id: The alignment ID string that the tensor corresponds to. 732 @type align_id: str or None 733 @keyword params: The alignment tensor parameters. 734 @type params: float 735 @keyword scale: The alignment tensor eigenvalue scaling value. 736 @type scale: float 737 @keyword angle_units: The units for the angle parameters (either 'deg' or 'rad'). 738 @type angle_units: str 739 @keyword param_types: The type of parameters supplied. The flag values correspond to, 0: {Axx, Ayy, Axy, Axz, Ayz}, and 1: {Azz, Axx-yy, Axy, Axz, Ayz}. 740 @type param_types: int 741 @keyword domain: The domain label. 742 @type domain: str or None 743 @keyword errors: A flag which determines if the alignment tensor data or its errors are being input. 744 @type errors: bool 745 """ 746 747 # Test if the current data pipe exists. 748 pipes.test() 749 750 # Parameter checks. 751 if align_id == None: 752 raise RelaxError("The alignment ID must be given.") 753 754 # Check the validity of the angle_units argument. 755 valid_types = ['deg', 'rad'] 756 if not angle_units in valid_types: 757 raise RelaxError("The alignment tensor 'angle_units' argument " + repr(angle_units) + " should be either 'deg' or 'rad'.") 758 759 # Test if alignment tensor data already exists. 760 if errors and (not hasattr(cdp, 'align_ids') or not align_id in cdp.align_ids): 761 raise RelaxNoTensorError('alignment') 762 763 # Check that the domain is defined. 764 if domain and (not hasattr(cdp, 'domain') or domain not in cdp.domain.keys()): 765 raise RelaxError("The domain '%s' has not been defined. Please use the domain user function." % domain) 766 767 # Add the align ID to the current data pipe if needed. 768 if not hasattr(cdp, 'align_ids'): 769 cdp.align_ids = [] 770 if align_id not in cdp.align_ids: 771 cdp.align_ids.append(align_id) 772 773 # Add the align_tensors object to the data pipe. 774 tensor_obj = None 775 if not errors: 776 # Initialise the super structure. 777 if not hasattr(cdp, 'align_tensors'): 778 cdp.align_tensors = AlignTensorList() 779 780 # Add the tensor, if it doesn't already exist. 781 if tensor == None or tensor not in cdp.align_tensors.names(): 782 tensor_obj = cdp.align_tensors.add_item(tensor) 783 784 # Get the tensor. 785 if not tensor_obj: 786 if tensor: 787 tensor_obj = get_tensor_object(tensor) 788 else: 789 tensor_obj = get_tensor_object_from_align(align_id) 790 791 # {Sxx, Syy, Sxy, Sxz, Syz}. 792 if param_types == 0: 793 # Unpack the tuple. 794 Sxx, Syy, Sxy, Sxz, Syz = params 795 796 # Scaling. 797 Sxx = Sxx * scale 798 Syy = Syy * scale 799 Sxy = Sxy * scale 800 Sxz = Sxz * scale 801 Syz = Syz * scale 802 803 # Set the parameters. 804 set(tensor=tensor_obj, value=[Sxx, Syy, Sxy, Sxz, Syz], param=['Sxx', 'Syy', 'Sxy', 'Sxz', 'Syz'], errors=errors) 805 806 # {Szz, Sxx-yy, Sxy, Sxz, Syz}. 807 elif param_types == 1: 808 # Unpack the tuple. 809 Szz, Sxxyy, Sxy, Sxz, Syz = params 810 811 # Scaling. 812 Szz = Szz * scale 813 Sxxyy = Sxxyy * scale 814 Sxy = Sxy * scale 815 Sxz = Sxz * scale 816 Syz = Syz * scale 817 818 # Set the parameters. 819 set(tensor=tensor_obj, value=[Szz, Sxxyy, Sxy, Sxz, Syz], param=['Szz', 'Sxxyy', 'Sxy', 'Sxz', 'Syz'], errors=errors) 820 821 # {Axx, Ayy, Axy, Axz, Ayz}. 822 elif param_types == 2: 823 # Unpack the tuple. 824 Axx, Ayy, Axy, Axz, Ayz = params 825 826 # Scaling. 827 Axx = Axx * scale 828 Ayy = Ayy * scale 829 Axy = Axy * scale 830 Axz = Axz * scale 831 Ayz = Ayz * scale 832 833 # Set the parameters. 834 set(tensor=tensor_obj, value=[Axx, Ayy, Axy, Axz, Ayz], param=['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], errors=errors) 835 836 # {Azz, Axx-yy, Axy, Axz, Ayz}. 837 elif param_types == 3: 838 # Unpack the tuple. 839 Azz, Axxyy, Axy, Axz, Ayz = params 840 841 # Scaling. 842 Azz = Azz * scale 843 Axxyy = Axxyy * scale 844 Axy = Axy * scale 845 Axz = Axz * scale 846 Ayz = Ayz * scale 847 848 # Set the parameters. 849 set(tensor=tensor_obj, value=[Azz, Axxyy, Axy, Axz, Ayz], param=['Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz'], errors=errors) 850 851 # {Axx, Ayy, Axy, Axz, Ayz}. 852 elif param_types == 4: 853 # Unpack the tuple. 854 Axx, Ayy, Axy, Axz, Ayz = params 855 856 # Get the bond length. 857 r = None 858 for spin in spin_loop(): 859 # First spin. 860 if r == None: 861 r = spin.r 862 863 # Different value. 864 if r != spin.r: 865 raise RelaxError("Not all spins have the same bond length.") 866 867 # Scaling. 868 scale = scale / kappa() * r**3 869 Axx = Axx * scale 870 Ayy = Ayy * scale 871 Axy = Axy * scale 872 Axz = Axz * scale 873 Ayz = Ayz * scale 874 875 # Set the parameters. 876 set(tensor=tensor_obj, value=[Axx, Ayy, Axy, Axz, Ayz], param=['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], errors=errors) 877 878 # {Azz, Axx-yy, Axy, Axz, Ayz}. 879 elif param_types == 5: 880 # Unpack the tuple. 881 Azz, Axxyy, Axy, Axz, Ayz = params 882 883 # Get the bond length. 884 r = None 885 for spin in spin_loop(): 886 # First spin. 887 if r == None: 888 r = spin.r 889 890 # Different value. 891 if r != spin.r: 892 raise RelaxError("Not all spins have the same bond length.") 893 894 # Scaling. 895 scale = scale / kappa() * r**3 896 Azz = Azz * scale 897 Axxyy = Axxyy * scale 898 Axy = Axy * scale 899 Axz = Axz * scale 900 Ayz = Ayz * scale 901 902 # Set the parameters. 903 set(tensor=tensor_obj, value=[Azz, Axxyy, Axy, Axz, Ayz], param=['Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz'], errors=errors) 904 905 # {Pxx, Pyy, Pxy, Pxz, Pyz}. 906 elif param_types == 6: 907 # Unpack the tuple. 908 Pxx, Pyy, Pxy, Pxz, Pyz = params 909 910 # Scaling. 911 Pxx = Pxx * scale 912 Pyy = Pyy * scale 913 Pxy = Pxy * scale 914 Pxz = Pxz * scale 915 Pyz = Pyz * scale 916 917 # Set the parameters. 918 set(tensor=tensor_obj, value=[Pxx, Pyy, Pxy, Pxz, Pyz], param=['Pxx', 'Pyy', 'Pxy', 'Pxz', 'Pyz'], errors=errors) 919 920 # {Pzz, Pxx-yy, Pxy, Pxz, Pyz}. 921 elif param_types == 7: 922 # Unpack the tuple. 923 Pzz, Pxxyy, Pxy, Pxz, Pyz = params 924 925 # Scaling. 926 Pzz = Pzz * scale 927 Pxxyy = Pxxyy * scale 928 Pxy = Pxy * scale 929 Pxz = Pxz * scale 930 Pyz = Pyz * scale 931 932 # Set the parameters. 933 set(tensor=tensor_obj, value=[Pzz, Pxxyy, Pxy, Pxz, Pyz], param=['Pzz', 'Pxxyy', 'Pxy', 'Pxz', 'Pyz'], errors=errors) 934 935 # Unknown parameter combination. 936 else: 937 raise RelaxUnknownParamCombError('param_types', param_types) 938 939 # Set the domain and alignment ID. 940 if domain: 941 set_domain(tensor=tensor, domain=domain) 942 if align_id: 943 tensor_obj.set(param='align_id', value=align_id)
944 945
946 -def map_bounds(param):
947 """The function for creating bounds for the mapping function.""" 948 949 # {Axx, Ayy, Azz, Axxyy, Axy, Axz, Ayz}. 950 if param in ['Axx', 'Ayy', 'Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz']: 951 return [-50, 50] 952 953 # alpha. 954 elif param == 'alpha': 955 return [0, 2*pi] 956 957 # beta. 958 elif param == 'beta': 959 return [0, pi] 960 961 # gamma. 962 elif param == 'gamma': 963 return [0, 2*pi]
964 965
966 -def map_labels(index, params, bounds, swap, inc):
967 """Function for creating labels, tick locations, and tick values for an OpenDX map. 968 969 @param index: The index (which isn't used here?!?). 970 @type index: int 971 @param params: The list of parameter names. 972 @type params: list of str 973 @param bounds: The bounds of the map. 974 @type bounds: list of lists (of a float and bin) 975 @param swap: An array for switching axes around. 976 @type swap: list of int 977 @param inc: The number of increments of one dimension in the map. 978 @type inc: list of int 979 """ 980 981 # Initialise. 982 labels = "{" 983 tick_locations = [] 984 tick_values = [] 985 n = len(params) 986 axis_incs = 5 987 loc_inc = inc / axis_incs 988 989 # Increment over the model parameters. 990 for i in range(n): 991 # Parameter conversion factors. 992 factor = return_conversion_factor(params[swap[i]]) 993 994 # Parameter units. 995 units = return_units(params[swap[i]]) 996 997 # Labels. 998 if units: 999 labels = labels + "\"" + params[swap[i]] + " (" + units + ")\"" 1000 else: 1001 labels = labels + "\"" + params[swap[i]] + "\"" 1002 1003 # Tick values. 1004 vals = bounds[swap[i], 0] / factor 1005 val_inc = (bounds[swap[i], 1] - bounds[swap[i], 0]) / (axis_incs * factor) 1006 1007 if i < n - 1: 1008 labels = labels + " " 1009 else: 1010 labels = labels + "}" 1011 1012 # Tick locations. 1013 string = "{" 1014 val = 0.0 1015 for j in range(axis_incs + 1): 1016 string = string + " " + repr(val) 1017 val = val + loc_inc 1018 string = string + " }" 1019 tick_locations.append(string) 1020 1021 # Tick values. 1022 string = "{" 1023 for j in range(axis_incs + 1): 1024 string = string + "\"" + "%.2f" % vals + "\" " 1025 vals = vals + val_inc 1026 string = string + "}" 1027 tick_values.append(string) 1028 1029 return labels, tick_locations, tick_values
1030 1031
1032 -def matrix_angles(basis_set=0, tensors=None):
1033 """Function for calculating the 5D angles between the alignment tensors. 1034 1035 The basis set used for the 5D vector construction changes the angles calculated. 1036 1037 @param basis_set: The basis set to use for constructing the 5D vectors. If set to 0, the 1038 basis set is {Sxx, Syy, Sxy, Sxz, Syz}. If 1, then the basis set is {Szz, 1039 Sxxyy, Sxy, Sxz, Syz}. 1040 @type basis_set: int 1041 @param tensors: An array of tensors to apply SVD to. If None, all tensors will be used. 1042 @type tensors: None or array of str 1043 """ 1044 1045 # Test that alignment tensor data exists. 1046 if not hasattr(cdp, 'align_tensors') or len(cdp.align_tensors) == 0: 1047 raise RelaxNoTensorError('alignment') 1048 1049 # Count the number of tensors. 1050 tensor_num = 0 1051 for tensor in cdp.align_tensors: 1052 if tensors and tensor.name not in tensors: 1053 continue 1054 tensor_num = tensor_num + 1 1055 1056 # Create the matrix which contains the 5D vectors. 1057 matrix = zeros((tensor_num, 5), float64) 1058 1059 # Loop over the tensors. 1060 i = 0 1061 for tensor in cdp.align_tensors: 1062 # Skip tensors. 1063 if tensors and tensor.name not in tensors: 1064 continue 1065 1066 # Unitary basis set. 1067 if basis_set == 0: 1068 # Pack the elements. 1069 matrix[i, 0] = tensor.Sxx 1070 matrix[i, 1] = tensor.Syy 1071 matrix[i, 2] = tensor.Sxy 1072 matrix[i, 3] = tensor.Sxz 1073 matrix[i, 4] = tensor.Syz 1074 1075 # Geometric basis set. 1076 elif basis_set == 1: 1077 # Pack the elements. 1078 matrix[i, 0] = tensor.Szz 1079 matrix[i, 1] = tensor.Sxxyy 1080 matrix[i, 2] = tensor.Sxy 1081 matrix[i, 3] = tensor.Sxz 1082 matrix[i, 4] = tensor.Syz 1083 1084 # Normalisation. 1085 norm = linalg.norm(matrix[i]) 1086 matrix[i] = matrix[i] / norm 1087 1088 # Increment the index. 1089 i = i + 1 1090 1091 # Initialise the matrix of angles. 1092 cdp.align_tensors.angles = zeros((tensor_num, tensor_num), float64) 1093 1094 # Header printout. 1095 sys.stdout.write("\nData pipe: " + repr(pipes.cdp_name()) + "\n") 1096 sys.stdout.write("\n5D angles in deg between the vectors ") 1097 if basis_set == 0: 1098 sys.stdout.write("{Sxx, Syy, Sxy, Sxz, Syz}") 1099 elif basis_set == 1: 1100 sys.stdout.write("{Szz, Sxx-yy, Sxy, Sxz, Syz}") 1101 sys.stdout.write(":\n") 1102 1103 # Initialise the table of data. 1104 table = [] 1105 1106 # The table header. 1107 table.append(['']) 1108 for i in range(tensor_num): 1109 if cdp.align_tensors[i].name == None: 1110 table[0].append(repr(i)) 1111 else: 1112 table[0].append(cdp.align_tensors[i].name) 1113 1114 # First loop over the rows. 1115 for i in range(tensor_num): 1116 # Add the tensor name. 1117 if cdp.align_tensors[i].name == None: 1118 table.append([repr(i)]) 1119 else: 1120 table.append([cdp.align_tensors[i].name]) 1121 1122 # Second loop over the columns. 1123 for j in range(tensor_num): 1124 # Dot product. 1125 delta = dot(matrix[i], matrix[j]) 1126 1127 # Check. 1128 if delta > 1: 1129 delta = 1 1130 1131 # The angle (in rad). 1132 cdp.align_tensors.angles[i, j] = arccos(delta) 1133 1134 # Add to the table as degrees. 1135 table[i+1].append("%8.1f" % (cdp.align_tensors.angles[i, j]*180.0/pi)) 1136 1137 # Write out the table. 1138 write_data(out=sys.stdout, data=table)
1139 1140
1141 -def num_tensors(skip_fixed=True):
1142 """Count the number of tensors. 1143 1144 @keyword skip_fixed: If set to True, then only the tensors without the fixed flag will be counted. If set to False, then all tensors will be counted. 1145 @type skip_fixed: bool 1146 @return: The number of tensors (excluding fixed tensors by default). 1147 @rtype: int 1148 """ 1149 1150 # Init. 1151 count = 0 1152 1153 # Loop over the tensors. 1154 for tensor_cont in cdp.align_tensors: 1155 # Skip fixed tensors. 1156 if skip_fixed and tensor_cont.fixed: 1157 continue 1158 1159 # Increment. 1160 count += 1 1161 1162 # Return the count. 1163 return count
1164 1165
1166 -def opt_uses_align_data(align_id=None):
1167 """Determine if the PCS or RDC data for the given alignment ID is needed for optimisation. 1168 1169 @keyword align_id: The optional alignment ID string. 1170 @type align_id: str 1171 @return: True if alignment data is to be used for optimisation, False otherwise. 1172 @rtype: bool 1173 """ 1174 1175 # No alignment IDs. 1176 if not hasattr(cdp, 'align_ids'): 1177 return False 1178 1179 # Convert the align IDs to an array, or take all IDs. 1180 if align_id: 1181 align_ids = [align_id] 1182 else: 1183 align_ids = cdp.align_ids 1184 1185 # Check the PCS and RDC. 1186 for align_id in align_ids: 1187 if pipe_control.pcs.opt_uses_pcs(align_id) or pipe_control.rdc.opt_uses_rdc(align_id): 1188 return True 1189 1190 # No alignment data is used for optimisation. 1191 return False
1192 1193
1194 -def opt_uses_tensor(tensor):
1195 """Determine if the given tensor is to be optimised. 1196 1197 @param tensor: The alignment tensor to check. 1198 @type tensor: AlignmentTensor object. 1199 @return: True if the tensor is to be optimised, False otherwise. 1200 @rtype: bool 1201 """ 1202 1203 # Combine all RDC and PCS IDs. 1204 ids = [] 1205 if hasattr(cdp, 'rdc_ids'): 1206 ids += cdp.rdc_ids 1207 if hasattr(cdp, 'pcs_ids'): 1208 ids += cdp.pcs_ids 1209 1210 # No RDC or PCS data for the alignment, so skip the tensor as it will not be optimised. 1211 if tensor.align_id not in ids: 1212 return False 1213 1214 # Fixed tensor. 1215 if tensor.fixed: 1216 return False 1217 1218 # The tensor is to be optimised. 1219 return True
1220 1221
1222 -def reduction(full_tensor=None, red_tensor=None):
1223 """Specify which tensor is a reduction of which other tensor. 1224 1225 @param full_tensor: The full alignment tensor. 1226 @type full_tensor: str 1227 @param red_tensor: The reduced alignment tensor. 1228 @type red_tensor: str 1229 """ 1230 1231 # Tensor information. 1232 match_full = False 1233 match_red = False 1234 i = 0 1235 for tensor_cont in cdp.align_tensors: 1236 # Test the tensor names. 1237 if tensor_cont.name == full_tensor: 1238 match_full = True 1239 index_full = i 1240 if tensor_cont.name == red_tensor: 1241 match_red = True 1242 index_red = i 1243 1244 # Increment. 1245 i = i + 1 1246 1247 # No match. 1248 if not match_full: 1249 raise RelaxNoTensorError('alignment', full_tensor) 1250 if not match_red: 1251 raise RelaxNoTensorError('alignment', red_tensor) 1252 1253 # Store. 1254 if not hasattr(cdp.align_tensors, 'reduction'): 1255 cdp.align_tensors.reduction = [] 1256 cdp.align_tensors.reduction.append([index_full, index_red])
1257 1258
1259 -def return_conversion_factor(param):
1260 """Function for returning the factor of conversion between different parameter units. 1261 1262 @param param: The parameter name. 1263 @type param: str 1264 @return: The conversion factor. 1265 @rtype: float 1266 """ 1267 1268 # Get the object name. 1269 object_name = return_data_name(param) 1270 1271 # {Axx, Ayy, Azz, Axxyy, Axy, Axz, Ayz}. 1272 if object_name in ['Axx', 'Ayy', 'Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz']: 1273 return 1.0 1274 1275 # Angles. 1276 elif object_name in ['alpha', 'beta', 'gamma']: 1277 return (2.0*pi) / 360.0 1278 1279 # No conversion factor. 1280 else: 1281 return 1.0
1282 1283
1284 -def return_data_name(name):
1285 """Return the parameter name. 1286 1287 @param name: The name of the parameter to return the name of. 1288 @type name: str 1289 @return: The parameter name. 1290 @rtype: str 1291 """ 1292 1293 # Enforce that the name must be a string. 1294 if not isinstance(name, str): 1295 raise RelaxStrError('name', name) 1296 1297 # Sxx. 1298 if search('^[Ss]xx$', name): 1299 return 'Sxx' 1300 1301 # Syy. 1302 if search('^[Ss]yy$', name): 1303 return 'Syy' 1304 1305 # Szz. 1306 if search('^[Ss]zz$', name): 1307 return 'Szz' 1308 1309 # Sxy. 1310 if search('^[Ss]xy$', name): 1311 return 'Sxy' 1312 1313 # Sxz. 1314 if search('^[Ss]xz$', name): 1315 return 'Sxz' 1316 1317 # Syz. 1318 if search('^[Ss]yz$', name): 1319 return 'Syz' 1320 1321 # Sxx-yy. 1322 if search('^[Ss]xxyy$', name): 1323 return 'Sxxyy' 1324 1325 # Axx. 1326 if search('^[Aa]xx$', name): 1327 return 'Axx' 1328 1329 # Ayy. 1330 if search('^[Aa]yy$', name): 1331 return 'Ayy' 1332 1333 # Azz. 1334 if search('^[Aa]zz$', name): 1335 return 'Azz' 1336 1337 # Axy. 1338 if search('^[Aa]xy$', name): 1339 return 'Axy' 1340 1341 # Axz. 1342 if search('^[Aa]xz$', name): 1343 return 'Axz' 1344 1345 # Ayz. 1346 if search('^[Aa]yz$', name): 1347 return 'Ayz' 1348 1349 # Axx-yy. 1350 if search('^[Aa]xxyy$', name): 1351 return 'Axxyy' 1352 1353 # Pxx. 1354 if search('^[Pp]xx$', name): 1355 return 'Pxx' 1356 1357 # Pyy. 1358 if search('^[Pp]yy$', name): 1359 return 'Pyy' 1360 1361 # Pzz. 1362 if search('^[Pp]zz$', name): 1363 return 'Pzz' 1364 1365 # Pxy. 1366 if search('^[Pp]xy$', name): 1367 return 'Pxy' 1368 1369 # Pxz. 1370 if search('^[Pp]xz$', name): 1371 return 'Pxz' 1372 1373 # Pyz. 1374 if search('^[Pp]yz$', name): 1375 return 'Pyz' 1376 1377 # Pxx-yy. 1378 if search('^[Pp]xxyy$', name): 1379 return 'Pxxyy' 1380 1381 # alpha. 1382 if search('^a$', name) or search('alpha', name): 1383 return 'alpha' 1384 1385 # beta. 1386 if search('^b$', name) or search('beta', name): 1387 return 'beta' 1388 1389 # gamma. 1390 if search('^g$', name) or search('gamma', name): 1391 return 'gamma' 1392 1393 # No parameter? 1394 raise RelaxUnknownParamError(name)
1395 1396 # User function documentation. 1397 __return_data_name_prompt_doc__ = """ 1398 Alignment tensor parameter string matching patterns 1399 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1400 1401 ____________________________________________________________________________________________ 1402 | | | | 1403 | Data type | Object name | Patterns | 1404 |________________________________________________________|______________|__________________| 1405 | | | | 1406 | The xx component of the Saupe order matrix - Sxx | 'Sxx' | '^[Sa]xx$' | 1407 | | | | 1408 | The yy component of the Saupe order matrix - Syy | 'Syy' | '^[Sa]yy$' | 1409 | | | | 1410 | The zz component of the Saupe order matrix - Szz | 'Szz' | '^[Sa]zz$' | 1411 | | | | 1412 | The xy component of the Saupe order matrix - Sxy | 'Sxy' | '^[Sa]xy$' | 1413 | | | | 1414 | The xz component of the Saupe order matrix - Sxz | 'Sxz' | '^[Sa]xz$' | 1415 | | | | 1416 | The yz component of the Saupe order matrix - Syz | 'Syz' | '^[Sa]yz$' | 1417 | | | | 1418 | The xx-yy component of the Saupe order matrix - Sxx-yy | 'Sxxyy' | '^[Sa]xxyy$' | 1419 | | | | 1420 | The xx component of the alignment tensor - Axx | 'Axx' | '^[Aa]xx$' | 1421 | | | | 1422 | The yy component of the alignment tensor - Ayy | 'Ayy' | '^[Aa]yy$' | 1423 | | | | 1424 | The zz component of the alignment tensor - Azz | 'Azz' | '^[Aa]zz$' | 1425 | | | | 1426 | The xy component of the alignment tensor - Axy | 'Axy' | '^[Aa]xy$' | 1427 | | | | 1428 | The xz component of the alignment tensor - Axz | 'Axz' | '^[Aa]xz$' | 1429 | | | | 1430 | The yz component of the alignment tensor - Ayz | 'Ayz' | '^[Aa]yz$' | 1431 | | | | 1432 | The xx-yy component of the alignment tensor - Axx-yy | 'Axxyy' | '^[Aa]xxyy$' | 1433 | | | | 1434 | The xx component of the probability matrix - Pxx | 'Pxx' | '^[Pa]xx$' | 1435 | | | | 1436 | The yy component of the probability matrix - Pyy | 'Pyy' | '^[Pa]yy$' | 1437 | | | | 1438 | The zz component of the probability matrix - Pzz | 'Pzz' | '^[Pa]zz$' | 1439 | | | | 1440 | The xy component of the probability matrix - Pxy | 'Pxy' | '^[Pa]xy$' | 1441 | | | | 1442 | The xz component of the probability matrix - Pxz | 'Pxz' | '^[Pa]xz$' | 1443 | | | | 1444 | The yz component of the probability matrix - Pyz | 'Pyz' | '^[Pa]yz$' | 1445 | | | | 1446 | The xx-yy component of the probability matrix - Pxx-yy | 'Pxxyy' | '^[Pa]xxyy$' | 1447 | | | | 1448 | The first Euler angle of the alignment tensor - alpha | 'alpha' | '^a$' or 'alpha' | 1449 | | | | 1450 | The second Euler angle of the alignment tensor - beta | 'beta' | '^b$' or 'beta' | 1451 | | | | 1452 | The third Euler angle of the alignment tensor - gamma | 'gamma' | '^g$' or 'gamma' | 1453 |________________________________________________________|______________|__________________| 1454 """ 1455 1456
1457 -def return_tensor(index, skip_fixed=True):
1458 """Return the tensor container for the given index, skipping fixed tensors if required. 1459 1460 @param index: The index of the tensor (if skip_fixed is True, then fixed tensors are not included in the index count). 1461 @type index: int 1462 @keyword skip_fixed: A flag which if True will exclude fixed tensors from the indexation. 1463 @type skip_fixed: bool 1464 @return: The tensor corresponding to the index. 1465 @rtype: data.align_tensor.AlignTensorData instance 1466 """ 1467 1468 # Init. 1469 count = 0 1470 1471 # Loop over the tensors. 1472 for tensor_cont in cdp.align_tensors: 1473 # Skip fixed tensors. 1474 if skip_fixed and tensor_cont.fixed: 1475 continue 1476 1477 # Index match, so return the container. 1478 if index == count: 1479 return tensor_cont 1480 1481 # Increment. 1482 count += 1 1483 1484 # Return False if the container was not found. 1485 return False
1486 1487
1488 -def return_units(param):
1489 """Function for returning a string representing the parameters units. 1490 1491 @param param: The parameter name. 1492 @type param: str 1493 @return: The string representation of the units. 1494 @rtype: str 1495 """ 1496 1497 # Get the object name. 1498 object_name = return_data_name(param) 1499 1500 # {Axx, Ayy, Azz, Axxyy, Axy, Axz, Ayz}. 1501 if object_name in ['Axx', 'Ayy', 'Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz']: 1502 return 'Hz' 1503 1504 # Angles. 1505 elif object_name in ['alpha', 'beta', 'gamma']: 1506 return 'deg'
1507 1508
1509 -def set(tensor=None, value=None, param=None, errors=False):
1510 """Set the tensor. 1511 1512 @keyword tensor: The alignment tensor object. 1513 @type tensor: AlignTensorData instance 1514 @keyword value: The list of values to set the parameters to. 1515 @type value: list of float 1516 @keyword param: The list of parameter names. 1517 @type param: list of str 1518 @keyword errors: A flag which determines if the alignment tensor data or its errors are being 1519 input. 1520 @type errors: bool 1521 """ 1522 1523 # Initialise. 1524 geo_params = [] 1525 geo_values = [] 1526 orient_params = [] 1527 orient_values = [] 1528 1529 # Loop over the parameters. 1530 for i in range(len(param)): 1531 # Get the object name. 1532 param[i] = return_data_name(param[i]) 1533 1534 # Unknown parameter. 1535 if param[i] == None: 1536 raise RelaxUnknownParamError("alignment tensor", 'None') 1537 1538 # Default value. 1539 if value[i] == None: 1540 value[i] = default_value(object_names[i]) 1541 1542 # Geometric parameter. 1543 if param[i] in ['Sxx', 'Syy', 'Szz', 'Sxxyy', 'Sxy', 'Sxz', 'Syz', 'Axx', 'Ayy', 'Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz', 'Pxx', 'Pyy', 'Pzz', 'Pxxyy', 'Pxy', 'Pxz', 'Pyz']: 1544 geo_params.append(param[i]) 1545 geo_values.append(value[i]) 1546 1547 # Orientational parameter. 1548 if param[i] in ['alpha', 'beta', 'gamma']: 1549 orient_params.append(param[i]) 1550 orient_values.append(value[i]) 1551 1552 1553 # Geometric parameters. 1554 ####################### 1555 1556 # A single geometric parameter. 1557 if len(geo_params) == 1: 1558 # Saupe order matrix. 1559 ##################### 1560 1561 # The single parameter Sxx. 1562 if geo_params[0] == 'Sxx': 1563 if errors: 1564 tensor.set(param='Sxx', value=geo_values[0], category='err') 1565 else: 1566 tensor.set(param='Sxx', value=geo_values[0]) 1567 1568 # The single parameter Syy. 1569 elif geo_params[0] == 'Syy': 1570 if errors: 1571 tensor.set(param='Syy', value=geo_values[0], category='err') 1572 else: 1573 tensor.set(param='Syy', value=geo_values[0]) 1574 1575 # The single parameter Sxy. 1576 elif geo_params[0] == 'Sxy': 1577 if errors: 1578 tensor.set(param='Sxy', value=geo_values[0], category='err') 1579 else: 1580 tensor.set(param='Sxy', value=geo_values[0]) 1581 1582 # The single parameter Sxz. 1583 elif geo_params[0] == 'Sxz': 1584 if errors: 1585 tensor.set(param='Sxz', value=geo_values[0], category='err') 1586 else: 1587 tensor.set(param='Sxz', value=geo_values[0]) 1588 1589 # The single parameter Syz. 1590 elif geo_params[0] == 'Syz': 1591 if errors: 1592 tensor.set(param='Syz', value=geo_values[0], category='err') 1593 else: 1594 tensor.set(param='Syz', value=geo_values[0]) 1595 1596 1597 # Alignment tensor. 1598 ################### 1599 1600 # The single parameter Axx. 1601 elif geo_params[0] == 'Axx': 1602 if errors: 1603 tensor.set(param='Sxx', value=3.0/2.0 * geo_values[0], category='err') 1604 else: 1605 tensor.set(param='Sxx', value=3.0/2.0 * geo_values[0]) 1606 1607 # The single parameter Ayy. 1608 elif geo_params[0] == 'Ayy': 1609 if errors: 1610 tensor.set(param='Syy', value=3.0/2.0 * geo_values[0], category='err') 1611 else: 1612 tensor.set(param='Syy', value=3.0/2.0 * geo_values[0]) 1613 1614 # The single parameter Axy. 1615 elif geo_params[0] == 'Axy': 1616 if errors: 1617 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0], category='err') 1618 else: 1619 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0]) 1620 1621 # The single parameter Axz. 1622 elif geo_params[0] == 'Axz': 1623 if errors: 1624 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0], category='err') 1625 else: 1626 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0]) 1627 1628 # The single parameter Ayz. 1629 elif geo_params[0] == 'Ayz': 1630 if errors: 1631 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0], category='err') 1632 else: 1633 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0]) 1634 1635 1636 # Probability tensor. 1637 ##################### 1638 1639 # The single parameter Pxx. 1640 elif geo_params[0] == 'Pxx': 1641 if errors: 1642 tensor.set(param='Sxx', value=3.0/2.0 * (geo_values[0] - 1.0/3.0), category='err') 1643 else: 1644 tensor.set(param='Sxx', value=3.0/2.0 * (geo_values[0] - 1.0/3.0)) 1645 1646 # The single parameter Pyy. 1647 elif geo_params[0] == 'Pyy': 1648 if errors: 1649 tensor.set(param='Syy', value=3.0/2.0 * (geo_values[0] - 1.0/3.0), category='err') 1650 else: 1651 tensor.set(param='Syy', value=3.0/2.0 * (geo_values[0] - 1.0/3.0)) 1652 1653 # The single parameter Pxy. 1654 elif geo_params[0] == 'Pxy': 1655 if errors: 1656 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0], category='err') 1657 else: 1658 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0]) 1659 1660 # The single parameter Pxz. 1661 elif geo_params[0] == 'Pxz': 1662 if errors: 1663 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0], category='err') 1664 else: 1665 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0]) 1666 1667 # The single parameter Pyz. 1668 elif geo_params[0] == 'Pyz': 1669 if errors: 1670 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0], category='err') 1671 else: 1672 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0]) 1673 1674 # Cannot set the single parameter. 1675 else: 1676 raise RelaxError("The geometric alignment parameter " + repr(geo_params[0]) + " cannot be set.") 1677 1678 # 5 geometric parameters. 1679 elif len(geo_params) == 5: 1680 # The geometric parameter set {Sxx, Syy, Sxy, Sxz, Syz}. 1681 if geo_params.count('Sxx') == 1 and geo_params.count('Syy') == 1 and geo_params.count('Sxy') == 1 and geo_params.count('Sxz') == 1 and geo_params.count('Syz') == 1: 1682 # The parameters. 1683 Sxx = geo_values[geo_params.index('Sxx')] 1684 Syy = geo_values[geo_params.index('Syy')] 1685 Sxy = geo_values[geo_params.index('Sxy')] 1686 Sxz = geo_values[geo_params.index('Sxz')] 1687 Syz = geo_values[geo_params.index('Syz')] 1688 1689 # Set the internal parameter values. 1690 if errors: 1691 tensor.set(param='Axx', value=2.0/3.0 * Sxx, category='err') 1692 tensor.set(param='Ayy', value=2.0/3.0 * Syy, category='err') 1693 tensor.set(param='Axy', value=2.0/3.0 * Sxy, category='err') 1694 tensor.set(param='Axz', value=2.0/3.0 * Sxz, category='err') 1695 tensor.set(param='Ayz', value=2.0/3.0 * Syz, category='err') 1696 else: 1697 tensor.set(param='Axx', value=2.0/3.0 * Sxx) 1698 tensor.set(param='Ayy', value=2.0/3.0 * Syy) 1699 tensor.set(param='Axy', value=2.0/3.0 * Sxy) 1700 tensor.set(param='Axz', value=2.0/3.0 * Sxz) 1701 tensor.set(param='Ayz', value=2.0/3.0 * Syz) 1702 1703 # The geometric parameter set {Szz, Sxxyy, Sxy, Sxz, Syz}. 1704 elif geo_params.count('Szz') == 1 and geo_params.count('Sxxyy') == 1 and geo_params.count('Sxy') == 1 and geo_params.count('Sxz') == 1 and geo_params.count('Syz') == 1: 1705 # The parameters. 1706 Szz = geo_values[geo_params.index('Szz')] 1707 Sxxyy = geo_values[geo_params.index('Sxxyy')] 1708 Sxy = geo_values[geo_params.index('Sxy')] 1709 Sxz = geo_values[geo_params.index('Sxz')] 1710 Syz = geo_values[geo_params.index('Syz')] 1711 1712 # Set the internal parameter values. 1713 if errors: 1714 tensor.set(param='Axx', value=2.0/3.0 * -0.5*(Szz-Sxxyy), category='err') 1715 tensor.set(param='Ayy', value=2.0/3.0 * -0.5*(Szz+Sxxyy), category='err') 1716 tensor.set(param='Axy', value=2.0/3.0 * Sxy, category='err') 1717 tensor.set(param='Axz', value=2.0/3.0 * Sxz, category='err') 1718 tensor.set(param='Ayz', value=2.0/3.0 * Syz, category='err') 1719 else: 1720 tensor.set(param='Axx', value=2.0/3.0 * -0.5*(Szz-Sxxyy)) 1721 tensor.set(param='Ayy', value=2.0/3.0 * -0.5*(Szz+Sxxyy)) 1722 tensor.set(param='Axy', value=2.0/3.0 * Sxy) 1723 tensor.set(param='Axz', value=2.0/3.0 * Sxz) 1724 tensor.set(param='Ayz', value=2.0/3.0 * Syz) 1725 1726 # The geometric parameter set {Axx, Ayy, Axy, Axz, Ayz}. 1727 elif geo_params.count('Axx') == 1 and geo_params.count('Ayy') == 1 and geo_params.count('Axy') == 1 and geo_params.count('Axz') == 1 and geo_params.count('Ayz') == 1: 1728 # The parameters. 1729 Axx = geo_values[geo_params.index('Axx')] 1730 Ayy = geo_values[geo_params.index('Ayy')] 1731 Axy = geo_values[geo_params.index('Axy')] 1732 Axz = geo_values[geo_params.index('Axz')] 1733 Ayz = geo_values[geo_params.index('Ayz')] 1734 1735 # Set the internal parameter values. 1736 if errors: 1737 tensor.set(param='Axx', value=Axx, category='err') 1738 tensor.set(param='Ayy', value=Ayy, category='err') 1739 tensor.set(param='Axy', value=Axy, category='err') 1740 tensor.set(param='Axz', value=Axz, category='err') 1741 tensor.set(param='Ayz', value=Ayz, category='err') 1742 else: 1743 tensor.set(param='Axx', value=Axx) 1744 tensor.set(param='Ayy', value=Ayy) 1745 tensor.set(param='Axy', value=Axy) 1746 tensor.set(param='Axz', value=Axz) 1747 tensor.set(param='Ayz', value=Ayz) 1748 1749 # The geometric parameter set {Azz, Axxyy, Axy, Axz, Ayz}. 1750 elif geo_params.count('Azz') == 1 and geo_params.count('Axxyy') == 1 and geo_params.count('Axy') == 1 and geo_params.count('Axz') == 1 and geo_params.count('Ayz') == 1: 1751 # The parameters. 1752 Azz = geo_values[geo_params.index('Azz')] 1753 Axxyy = geo_values[geo_params.index('Axxyy')] 1754 Axy = geo_values[geo_params.index('Axy')] 1755 Axz = geo_values[geo_params.index('Axz')] 1756 Ayz = geo_values[geo_params.index('Ayz')] 1757 1758 # Set the internal parameter values. 1759 if errors: 1760 tensor.set(param='Axx', value=-0.5*(Azz-Axxyy), category='err') 1761 tensor.set(param='Ayy', value=-0.5*(Azz+Axxyy), category='err') 1762 tensor.set(param='Axy', value=Axy, category='err') 1763 tensor.set(param='Axz', value=Axz, category='err') 1764 tensor.set(param='Ayz', value=Ayz, category='err') 1765 else: 1766 tensor.set(param='Axx', value=-0.5*(Azz-Axxyy)) 1767 tensor.set(param='Ayy', value=-0.5*(Azz+Axxyy)) 1768 tensor.set(param='Axy', value=Axy) 1769 tensor.set(param='Axz', value=Axz) 1770 tensor.set(param='Ayz', value=Ayz) 1771 1772 # The geometric parameter set {Pxx, Pyy, Pxy, Pxz, Pyz}. 1773 elif geo_params.count('Pxx') == 1 and geo_params.count('Pyy') == 1 and geo_params.count('Pxy') == 1 and geo_params.count('Pxz') == 1 and geo_params.count('Pyz') == 1: 1774 # The parameters. 1775 Pxx = geo_values[geo_params.index('Pxx')] 1776 Pyy = geo_values[geo_params.index('Pyy')] 1777 Pxy = geo_values[geo_params.index('Pxy')] 1778 Pxz = geo_values[geo_params.index('Pxz')] 1779 Pyz = geo_values[geo_params.index('Pyz')] 1780 1781 # Set the internal parameter values. 1782 if errors: 1783 tensor.set(param='Axx', value=Pxx - 1.0/3.0, category='err') 1784 tensor.set(param='Ayy', value=Pyy - 1.0/3.0, category='err') 1785 tensor.set(param='Axy', value=Pxy, category='err') 1786 tensor.set(param='Axz', value=Pxz, category='err') 1787 tensor.set(param='Ayz', value=Pyz, category='err') 1788 else: 1789 tensor.set(param='Axx', value=Pxx - 1.0/3.0) 1790 tensor.set(param='Ayy', value=Pyy - 1.0/3.0) 1791 tensor.set(param='Axy', value=Pxy) 1792 tensor.set(param='Axz', value=Pxz) 1793 tensor.set(param='Ayz', value=Pyz) 1794 1795 # The geometric parameter set {Pzz, Pxxyy, Pxy, Pxz, Pyz}. 1796 elif geo_params.count('Pzz') == 1 and geo_params.count('Pxxyy') == 1 and geo_params.count('Pxy') == 1 and geo_params.count('Pxz') == 1 and geo_params.count('Pyz') == 1: 1797 # The parameters. 1798 Pzz = geo_values[geo_params.index('Pzz')] 1799 Pxxyy = geo_values[geo_params.index('Pxxyy')] 1800 Pxy = geo_values[geo_params.index('Pxy')] 1801 Pxz = geo_values[geo_params.index('Pxz')] 1802 Pyz = geo_values[geo_params.index('Pyz')] 1803 1804 # Set the internal parameter values. 1805 if errors: 1806 tensor.set(param='Axx', value=-0.5*(Pzz-Pxxyy) - 1.0/3.0, category='err') 1807 tensor.set(param='Ayy', value=-0.5*(Pzz+Pxxyy) - 1.0/3.0, category='err') 1808 tensor.set(param='Axy', value=Pxy, category='err') 1809 tensor.set(param='Axz', value=Pxz, category='err') 1810 tensor.set(param='Ayz', value=Pyz, category='err') 1811 else: 1812 tensor.set(param='Axx', value=-0.5*(Pzz-Pxxyy) - 1.0/3.0) 1813 tensor.set(param='Ayy', value=-0.5*(Pzz+Pxxyy) - 1.0/3.0) 1814 tensor.set(param='Axy', value=Pxy) 1815 tensor.set(param='Axz', value=Pxz) 1816 tensor.set(param='Ayz', value=Pyz) 1817 1818 # Unknown parameter combination. 1819 else: 1820 raise RelaxUnknownParamCombError('geometric parameter set', geo_params) 1821 1822 1823 # Unknown geometric parameters. 1824 else: 1825 raise RelaxUnknownParamCombError('geometric parameter set', geo_params) 1826 1827 1828 # Orientational parameters. 1829 ########################### 1830 1831 # A single orientational parameter. 1832 if len(orient_params) == 1: 1833 # The single parameter alpha. 1834 if orient_params[0] == 'alpha': 1835 if errors: 1836 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err') 1837 else: 1838 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')]) 1839 1840 # The single parameter beta. 1841 elif orient_params[0] == 'beta': 1842 if errors: 1843 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err') 1844 else: 1845 tensor.set(param='beta', value=orient_values[orient_params.index('beta')]) 1846 1847 # The single parameter gamma. 1848 elif orient_params[0] == 'gamma': 1849 if errors: 1850 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err') 1851 else: 1852 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')]) 1853 1854 # Two orientational parameters. 1855 elif len(orient_params) == 2: 1856 # The orientational parameter set {alpha, beta}. 1857 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1: 1858 if errors: 1859 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err') 1860 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err') 1861 else: 1862 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')]) 1863 tensor.set(param='beta', value=orient_values[orient_params.index('beta')]) 1864 1865 # The orientational parameter set {alpha, gamma}. 1866 if orient_params.count('alpha') == 1 and orient_params.count('gamma') == 1: 1867 if errors: 1868 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err') 1869 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err') 1870 else: 1871 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')]) 1872 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')]) 1873 1874 # The orientational parameter set {beta, gamma}. 1875 if orient_params.count('beta') == 1 and orient_params.count('gamma') == 1: 1876 if errors: 1877 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err') 1878 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err') 1879 else: 1880 tensor.set(param='beta', value=orient_values[orient_params.index('beta')]) 1881 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')]) 1882 1883 # Unknown parameter combination. 1884 else: 1885 raise RelaxUnknownParamCombError('orientational parameter set', orient_params) 1886 1887 # Three orientational parameters. 1888 elif len(orient_params) == 3: 1889 # The orientational parameter set {alpha, beta, gamma}. 1890 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1: 1891 if errors: 1892 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err') 1893 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err') 1894 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err') 1895 else: 1896 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')]) 1897 tensor.set(param='beta', value=orient_values[orient_params.index('beta')]) 1898 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')]) 1899 1900 # Unknown parameter combination. 1901 else: 1902 raise RelaxUnknownParamCombError('orientational parameter set', orient_params) 1903 1904 # More than three orientational parameters. 1905 elif len(orient_params) > 3: 1906 raise RelaxUnknownParamCombError('orientational parameter set', orient_params) 1907 1908 1909 # Fold the angles in. 1910 ##################### 1911 1912 if orient_params: 1913 fold_angles()
1914 1915 # User function documentation. 1916 __set_prompt_doc__ = """ 1917 Alignment tensor set details 1918 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1919 1920 If the alignment tensor has not been setup, use the more powerful function 1921 'alignment_tensor.init' to initialise the tensor parameters. 1922 1923 The alignment tensor parameters can only be set when the data pipe corresponds to model-free 1924 analysis. The units of the parameters are: 1925 1926 Unitless for Sxx, Syy, Szz, Sxxyy, Sxy, Sxz, Syz. 1927 Unitless for Axx, Ayy, Azz, Axxyy, Axy, Axz, Ayz. 1928 Unitless for Pxx, Pyy, Pzz, Pxxyy, Pxy, Pxz, Pyz. 1929 Radians for all angles (alpha, beta, gamma). 1930 1931 If a single geometric parameter is supplied, it must be one of Bxx, Byy, Bxy, Bxz, Byz, where B 1932 is one of S, A, or P. For the parameters Bzz and Bxxyy, it is not possible to determine how to 1933 use the currently set values together with the supplied value to calculate the new internal 1934 parameters. When supplying multiple geometric parameters, the set must belong to one of 1935 1936 {Sxx, Syy, Sxy, Sxz, Syz}, 1937 {Szz, Sxxyy, Sxy, Sxz, Syz}. 1938 {Axx, Ayy, Axy, Axz, Ayz}, 1939 {Azz, Axxyy, Axy, Axz, Ayz}. 1940 {Pxx, Pyy, Pxy, Pxz, Pyz}, 1941 {Pzz, Pxxyy, Pxy, Pxz, Pyz}. 1942 """ 1943 1944
1945 -def set_align_id(tensor=None, align_id=None):
1946 """Set the align ID string for the given tensor. 1947 1948 @keyword tensor: The alignment tensor label. 1949 @type tensor: str 1950 @keyword align_id: The alignment ID string. 1951 @type align_id: str 1952 """ 1953 1954 # Loop over the tensors. 1955 match = False 1956 for tensor_cont in cdp.align_tensors: 1957 # Find the matching tensor and then store the ID. 1958 if tensor_cont.name == tensor: 1959 tensor_cont.align_id = align_id 1960 match = True 1961 1962 # The tensor label doesn't exist. 1963 if not match: 1964 raise RelaxNoTensorError('alignment', tensor)
1965 1966
1967 -def set_domain(tensor=None, domain=None):
1968 """Set the domain label for the given tensor. 1969 1970 @param tensor: The alignment tensor label. 1971 @type tensor: str 1972 @param domain: The domain label. 1973 @type domain: str 1974 """ 1975 1976 # Check that the domain is defined. 1977 if not hasattr(cdp, 'domain') or domain not in cdp.domain.keys(): 1978 raise RelaxError("The domain '%s' has not been defined. Please use the domain user function." % domain) 1979 1980 # Loop over the tensors. 1981 match = False 1982 for tensor_cont in cdp.align_tensors: 1983 # Find the matching tensor and then store the domain label. 1984 if tensor_cont.name == tensor: 1985 tensor_cont.set(param='domain', value=domain) 1986 match = True 1987 1988 # The tensor label doesn't exist. 1989 if not match: 1990 raise RelaxNoTensorError('alignment', tensor)
1991 1992
1993 -def svd(basis_set=0, tensors=None):
1994 """Function for calculating the singular values of all the loaded tensors. 1995 1996 The matrix on which SVD will be performed is:: 1997 1998 | Sxx1 Syy1 Sxy1 Sxz1 Syz1 | 1999 | Sxx2 Syy2 Sxy2 Sxz2 Syz2 | 2000 | Sxx3 Syy3 Sxy3 Sxz3 Syz3 | 2001 | . . . . . | 2002 | . . . . . | 2003 | . . . . . | 2004 | SxxN SyyN SxyN SxzN SyzN | 2005 2006 This is the default unitary basis set (selected when basis_set is 0). Alternatively a geometric 2007 basis set consisting of the stretching and skewing parameters Szz and Sxx-yy respectively 2008 replacing Sxx and Syy can be chosen by setting basis_set to 1. The matrix in this case is:: 2009 2010 | Szz1 Sxxyy1 Sxy1 Sxz1 Syz1 | 2011 | Szz2 Sxxyy2 Sxy2 Sxz2 Syz2 | 2012 | Szz3 Sxxyy3 Sxy3 Sxz3 Syz3 | 2013 | . . . . . | 2014 | . . . . . | 2015 | . . . . . | 2016 | SzzN SxxyyN SxyN SxzN SyzN | 2017 2018 The relationships between the geometric and unitary basis sets are:: 2019 2020 Szz = - Sxx - Syy, 2021 Sxxyy = Sxx - Syy, 2022 2023 The SVD values and condition number are dependendent upon the basis set chosen. 2024 2025 2026 @param basis_set: The basis set to create the 5 by n matrix on which to perform SVD. 2027 @type basis_set: int 2028 @param tensors: An array of tensors to apply SVD to. If None, all tensors will be used. 2029 @type tensors: None or array of str 2030 """ 2031 2032 # Test that alignment tensor data exists. 2033 if not hasattr(cdp, 'align_tensors') or len(cdp.align_tensors) == 0: 2034 raise RelaxNoTensorError('alignment') 2035 2036 # Count the number of tensors used in the SVD. 2037 tensor_num = 0 2038 for tensor in cdp.align_tensors: 2039 if tensors and tensor.name not in tensors: 2040 continue 2041 tensor_num = tensor_num + 1 2042 2043 # Create the matrix to apply SVD on. 2044 matrix = zeros((tensor_num, 5), float64) 2045 2046 # Pack the elements. 2047 i = 0 2048 for tensor in cdp.align_tensors: 2049 # Skip tensors. 2050 if tensors and tensor.name not in tensors: 2051 continue 2052 2053 # Unitary basis set. 2054 if basis_set == 0: 2055 matrix[i, 0] = tensor.Sxx 2056 matrix[i, 1] = tensor.Syy 2057 matrix[i, 2] = tensor.Sxy 2058 matrix[i, 3] = tensor.Sxz 2059 matrix[i, 4] = tensor.Syz 2060 2061 # Geometric basis set. 2062 elif basis_set == 1: 2063 matrix[i, 0] = tensor.Szz 2064 matrix[i, 1] = tensor.Sxxyy 2065 matrix[i, 2] = tensor.Sxy 2066 matrix[i, 3] = tensor.Sxz 2067 matrix[i, 4] = tensor.Syz 2068 2069 # Increment the index. 2070 i = i + 1 2071 2072 # SVD. 2073 u, s, vh = linalg.svd(matrix) 2074 2075 # Store the singular values. 2076 cdp.align_tensors.singular_vals = s 2077 2078 # Calculate and store the condition number. 2079 cdp.align_tensors.cond_num = s[0] / s[-1] 2080 2081 # Print out. 2082 print("\nData pipe: " + repr(pipes.cdp_name())) 2083 print("\nSingular values:") 2084 for val in s: 2085 print(" %.4e" % val) 2086 print("\nCondition number: %.2f" % cdp.align_tensors.cond_num)
2087