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