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

Source Code for Module generic_fns.align_tensor

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