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