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

Source Code for Module data_store.align_tensor

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2003-2015 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  """The alignment tensor objects of the relax data store.""" 
  24   
  25  # Python module imports. 
  26  from math import pi, sqrt 
  27  from numpy import eye, float64, zeros 
  28  from numpy.linalg import det, eig, eigvals 
  29  from re import search 
  30   
  31  # relax module imports. 
  32  from data_store.data_classes import Element 
  33  from lib.float import nan 
  34  from lib.geometry.rotations import R_to_euler_zyz 
  35  from lib.errors import RelaxError 
  36  from lib.xml import fill_object_contents, xml_to_object 
  37   
  38   
  39  # Constants (once off calculations for speed). 
  40  fact_A2 = sqrt(2.0*pi / 15.0) 
  41  fact_A1 = sqrt(8.0*pi / 15.0) 
  42  fact_A0 = sqrt(4.0*pi / 5.0) 
  43   
  44   
45 -def calc_A(Axx, Ayy, Azz, Axy, Axz, Ayz):
46 """Function for calculating the alignment tensor (in the structural frame). 47 48 @param Axx: The Axx tensor element. 49 @type Axx: float 50 @param Ayy: The Ayy tensor element. 51 @type Ayy: float 52 @param Azz: The Azz tensor element. 53 @type Azz: float 54 @param Axy: The Axy tensor element. 55 @type Axy: float 56 @param Axz: The Axz tensor element. 57 @type Axz: float 58 @param Ayz: The Ayz tensor element. 59 @type Ayz: float 60 @return: The alignment tensor (within the structural frame). 61 @rtype: 3x3 numpy float64 array 62 """ 63 64 # Initialise the tensor. 65 tensor = zeros((3, 3), float64) 66 67 # Populate the diagonal elements. 68 tensor[0, 0] = Axx 69 tensor[1, 1] = Ayy 70 tensor[2, 2] = Azz 71 72 # Populate the off diagonal elements. 73 tensor[0, 1] = tensor[1, 0] = Axy 74 tensor[0, 2] = tensor[2, 0] = Axz 75 tensor[1, 2] = tensor[2, 1] = Ayz 76 77 # Return the tensor. 78 return tensor
79 80
81 -def calc_A_5D(Axx, Ayy, Azz, Axy, Axz, Ayz):
82 """Function for calculating the alignment tensor in the 5D vector notation. 83 84 @param Axx: The Axx tensor element. 85 @type Axx: float 86 @param Ayy: The Ayy tensor element. 87 @type Ayy: float 88 @param Azz: The Azz tensor element. 89 @type Azz: float 90 @param Axy: The Axy tensor element. 91 @type Axy: float 92 @param Axz: The Axz tensor element. 93 @type Axz: float 94 @param Ayz: The Ayz tensor element. 95 @type Ayz: float 96 @return: The alignment 5D tensor (within the structural frame). 97 @rtype: numpy rank-1 5D tensor 98 """ 99 100 # Initialise the tensor. 101 tensor = zeros(5, float64) 102 103 # Populate the tensor. 104 tensor[0] = Axx 105 tensor[1] = Ayy 106 tensor[2] = Axy 107 tensor[3] = Axz 108 tensor[4] = Ayz 109 110 # Return the tensor. 111 return tensor
112 113
114 -def calc_A_diag(A):
115 """Calculate the diagonalised alignment tensor. 116 117 The diagonalised alignment tensor is defined as:: 118 119 | Axx' 0 0 | 120 tensor = | 0 Ayy' 0 |. 121 | 0 0 Azz'| 122 123 The diagonalised alignment tensor is calculated by eigenvalue decomposition. 124 125 126 @param A: The full alignment tensor. 127 @type A: numpy array ((3, 3), float64) 128 @return: The diagonalised alignment tensor. 129 @rtype: numpy array ((3, 3), float64) 130 """ 131 132 # The eigenvalues. 133 vals = eigvals(A) 134 135 # Find the |x| < |y| < |z| indices. 136 abs_vals = abs(vals).tolist() 137 Axx_index = abs_vals.index(min(abs_vals)) 138 Azz_index = abs_vals.index(max(abs_vals)) 139 last_index = list(range(3)) 140 last_index.pop(max(Axx_index, Azz_index)) 141 last_index.pop(min(Axx_index, Azz_index)) 142 Ayy_index = last_index[0] 143 144 # Empty tensor. 145 tensor_diag = zeros((3, 3), float64) 146 147 # Fill the elements. 148 tensor_diag[0, 0] = vals[Axx_index] 149 tensor_diag[1, 1] = vals[Ayy_index] 150 tensor_diag[2, 2] = vals[Azz_index] 151 152 # Return the tensor. 153 return tensor_diag
154 155
156 -def calc_Aa(A_diag):
157 """Calculate the anisotropic parameter Aa. 158 159 This is given by:: 160 161 Aa = 3/2Azz = Szz, 162 163 where Azz and Szz are the eigenvalues. 164 165 166 @param A_diag: The full alignment tensor, diagonalised. 167 @type A_diag: numpy array ((3, 3), float64) 168 @return: The Aa parameter 169 @rtype: float 170 """ 171 172 # Return Aa. 173 return 1.5 * A_diag[2, 2]
174 175
176 -def calc_Ar(A_diag):
177 """Calculate the rhombic parameter Ar. 178 179 This is given by:: 180 181 Ar = Axx - Ayy, 182 183 where Axx and Ayy are the eigenvalues. 184 185 186 @param A_diag: The full alignment tensor, diagonalised. 187 @type A_diag: numpy array ((3, 3), float64) 188 @return: The Ar parameter 189 @rtype: float 190 """ 191 192 # Return Ar. 193 return A_diag[0, 0] - A_diag[1, 1]
194 195
196 -def calc_Axxyy(Axx, Ayy):
197 """Function for calculating the Axx-yy value. 198 199 The equation for calculating the parameter is:: 200 201 Axx-yy = Axx - Ayy. 202 203 @param Axx: The Axx component of the alignment tensor. 204 @type Axx: float 205 @param Ayy: The Ayy component of the alignment tensor. 206 @type Ayy: float 207 @return: The Axx-yy component of the alignment tensor. 208 @rtype: float 209 """ 210 211 # Calculate and return the Axx-yy value. 212 return Axx - Ayy
213 214
215 -def calc_Azz(Axx, Ayy):
216 """Function for calculating the Azz value. 217 218 The equation for calculating the parameter is:: 219 220 Azz = - Axx - Ayy. 221 222 @param Axx: The Axx component of the alignment tensor. 223 @type Axx: float 224 @param Ayy: The Ayy component of the alignment tensor. 225 @type Ayy: float 226 @return: The Azz component of the alignment tensor. 227 @rtype: float 228 """ 229 230 # Calculate and return the Azz value. 231 return - Axx - Ayy
232 233
234 -def calc_eigvals(A):
235 """Calculate the eigenvalues and eigenvectors of the alignment tensor (A). 236 237 @param A: The full alignment tensor. 238 @type A: numpy array ((3, 3), float64) 239 @return: The eigensystem. 240 @rtype: tuple of numpy array (float64) 241 """ 242 243 # The eigenvalues. 244 vals = eigvals(A) 245 246 # Find the |x| < |y| < |z| indices. 247 abs_vals = abs(vals).tolist() 248 x_index = abs_vals.index(min(abs_vals)) 249 z_index = abs_vals.index(max(abs_vals)) 250 last_index = list(range(3)) 251 last_index.pop(max(x_index, z_index)) 252 last_index.pop(min(x_index, z_index)) 253 y_index = last_index[0] 254 255 # Return the sorted eigenvalues. 256 return [vals[x_index], vals[y_index], vals[z_index]]
257 258
259 -def calc_eta(A_diag):
260 """Calculate the asymmetry parameter eta. 261 262 This is given by:: 263 264 eta = (Axx - Ayy) / Azz 265 266 where Aii are the eigenvalues. 267 268 269 @param A_diag: The full alignment tensor, diagonalised. 270 @type A_diag: numpy array ((3, 3), float64) 271 @return: The eta parameter 272 @rtype: float 273 """ 274 275 # Zero Azz value, so return NaN. 276 if A_diag[2, 2] == 0: 277 return nan 278 279 # Return eta. 280 return (A_diag[0, 0] - A_diag[1, 1]) / A_diag[2, 2]
281 282
283 -def calc_euler(rotation):
284 """Calculate the zyz notation Euler angles. 285 286 @param rotation: The rotation matrix. 287 @type rotation: numpy 3D, rank-2 array 288 @return: The Euler angles alpha, beta, and gamma in zyz notation. 289 @rtype: tuple of float 290 """ 291 292 return R_to_euler_zyz(rotation)
293 294
295 -def calc_S(Sxx, Syy, Szz, Sxy, Sxz, Syz):
296 """Function for calculating the alignment tensor (in the structural frame). 297 298 @param Sxx: The Sxx tensor element. 299 @type Sxx: float 300 @param Syy: The Syy tensor element. 301 @type Syy: float 302 @param Szz: The Szz tensor element. 303 @type Szz: float 304 @param Sxy: The Sxy tensor element. 305 @type Sxy: float 306 @param Sxz: The Sxz tensor element. 307 @type Sxz: float 308 @param Syz: The Syz tensor element. 309 @type Syz: float 310 @return: The alignment tensor (within the structural frame). 311 @rtype: 3x3 numpy float64 array 312 """ 313 314 # Initialise the tensor. 315 tensor = zeros((3, 3), float64) 316 317 # Populate the diagonal elements. 318 tensor[0, 0] = Sxx 319 tensor[1, 1] = Syy 320 tensor[2, 2] = Szz 321 322 # Populate the off diagonal elements. 323 tensor[0, 1] = tensor[1, 0] = Sxy 324 tensor[0, 2] = tensor[2, 0] = Sxz 325 tensor[1, 2] = tensor[2, 1] = Syz 326 327 # Return the tensor. 328 return tensor
329 330
331 -def calc_S_5D(Sxx, Syy, Szz, Sxy, Sxz, Syz):
332 """Function for calculating the alignment tensor in the 5D vector notation. 333 334 @param Sxx: The Sxx tensor element. 335 @type Sxx: float 336 @param Syy: The Syy tensor element. 337 @type Syy: float 338 @param Szz: The Szz tensor element. 339 @type Szz: float 340 @param Sxy: The Sxy tensor element. 341 @type Sxy: float 342 @param Sxz: The Sxz tensor element. 343 @type Sxz: float 344 @param Syz: The Syz tensor element. 345 @type Syz: float 346 @return: The alignment 5D tensor (within the structural frame). 347 @rtype: numpy rank-1 5D tensor 348 """ 349 350 # Initialise the tensor. 351 tensor = zeros(5, float64) 352 353 # Populate the tensor. 354 tensor[0] = Sxx 355 tensor[1] = Syy 356 tensor[2] = Sxy 357 tensor[3] = Sxz 358 tensor[4] = Syz 359 360 # Return the tensor. 361 return tensor
362 363
364 -def calc_S_diag(tensor):
365 """Calculate the diagonalised alignment tensor. 366 367 The diagonalised alignment tensor is defined as:: 368 369 | Sxx' 0 0 | 370 tensor = | 0 Syy' 0 |. 371 | 0 0 Szz'| 372 373 The diagonalised alignment tensor is calculated by eigenvalue decomposition. 374 375 376 @param tensor: The full alignment tensor in its eigenframe. 377 @type tensor: numpy array ((3, 3), float64) 378 @return: The diagonalised alignment tensor. 379 @rtype: numpy array ((3, 3), float64) 380 """ 381 382 # The eigenvalues. 383 vals = eigvals(tensor) 384 385 # Find the |x| < |y| < |z| indices. 386 abs_vals = abs(vals).tolist() 387 Sxx_index = abs_vals.index(min(abs_vals)) 388 Szz_index = abs_vals.index(max(abs_vals)) 389 last_index = list(range(3)) 390 last_index.pop(max(Sxx_index, Szz_index)) 391 last_index.pop(min(Sxx_index, Szz_index)) 392 Syy_index = last_index[0] 393 394 # Empty tensor. 395 tensor_diag = zeros((3, 3), float64) 396 397 # Fill the elements. 398 tensor_diag[0, 0] = vals[Sxx_index] 399 tensor_diag[1, 1] = vals[Syy_index] 400 tensor_diag[2, 2] = vals[Szz_index] 401 402 # Return the tensor. 403 return tensor_diag
404 405
406 -def calc_A0(Szz):
407 """Function for calculating the A0 irreducible component of the Saupe order matrix. 408 409 The equation for calculating the parameter is:: 410 411 / 4pi \ 1/2 412 A0 = | --- | Szz . 413 \ 5 / 414 415 416 @param Szz: The Szz component of the Saupe order matrix. 417 @type Szz: float 418 @return: The A0 irreducible component of the Saupe order matrix. 419 @rtype: float 420 """ 421 422 # Calculate and return the A0 value. 423 return fact_A0 * Szz
424 425
426 -def calc_A1(Sxz, Syz):
427 """Function for calculating the A1 irreducible component of the Saupe order matrix. 428 429 The equation for calculating the parameter is:: 430 431 / 8pi \ 1/2 432 A1 = | --- | (Sxz + iSyz) . 433 \ 15 / 434 435 436 @param Sxz: The Sxz component of the Saupe order matrix. 437 @type Sxz: float 438 @param Syz: The Syz component of the Saupe order matrix. 439 @type Syz: float 440 @return: The A1 irreducible component of the Saupe order matrix. 441 @rtype: float 442 """ 443 444 # Calculate and return the A1 value. 445 return fact_A1 * (Sxz + 1.j*Syz)
446 447
448 -def calc_A2(Sxx, Syy, Sxy):
449 """Function for calculating the A2 irreducible component of the Saupe order matrix. 450 451 The equation for calculating the parameter is:: 452 453 / 2pi \ 1/2 454 A2 = | --- | (Sxx - Syy + 2iSxy) . 455 \ 15 / 456 457 458 @param Sxx: The Sxx component of the Saupe order matrix. 459 @type Sxx: float 460 @param Syy: The Syy component of the Saupe order matrix. 461 @type Syy: float 462 @return: The A2 irreducible component of the Saupe order matrix. 463 @rtype: float 464 """ 465 466 # Calculate and return the A2 value. 467 return fact_A2 * (Sxx - Syy + 2.j*Sxy)
468 469
470 -def calc_Am1(Sxz, Syz):
471 """Function for calculating the A-1 irreducible component of the Saupe order matrix. 472 473 The equation for calculating the parameter is:: 474 475 / 8pi \ 1/2 476 A-1 = - | --- | (Sxz - iSyz) . 477 \ 15 / 478 479 480 @param Sxz: The Sxz component of the Saupe order matrix. 481 @type Sxz: float 482 @param Syz: The Syz component of the Saupe order matrix. 483 @type Syz: float 484 @return: The A-1 irreducible component of the Saupe order matrix. 485 @rtype: float 486 """ 487 488 # Calculate and return the A-1 value. 489 return -fact_A1 * (Sxz - 1.j*Syz)
490 491
492 -def calc_Am2(Sxx, Syy, Sxy):
493 """Function for calculating the A-2 irreducible component of the Saupe order matrix. 494 495 The equation for calculating the parameter is:: 496 497 / 2pi \ 1/2 498 A-2 = | --- | (Sxx - Syy - 2iSxy) , 499 \ 15 / 500 501 502 @param Sxx: The Sxx component of the Saupe order matrix. 503 @type Sxx: float 504 @param Syy: The Syy component of the Saupe order matrix. 505 @type Syy: float 506 @return: The A-2 irreducible component of the Saupe order matrix. 507 @rtype: float 508 """ 509 510 # Calculate and return the A-2 value. 511 return fact_A2 * (Sxx - Syy - 2.j*Sxy)
512 513
514 -def calc_Sxx(Axx):
515 """Function for calculating the Axx value. 516 517 The equation for calculating the parameter is:: 518 519 Sxx = 3/2 Axx. 520 521 @param Axx: The Axx component of the alignment tensor. 522 @type Axx: float 523 @rtype: float 524 """ 525 526 # Calculate and return the Axx value. 527 return 3.0/2.0 * Axx
528 529
530 -def calc_Sxxyy(Sxx, Syy):
531 """Function for calculating the Sxx-yy value. 532 533 The equation for calculating the parameter is:: 534 535 Sxx-yy = Sxx - Syy. 536 537 @param Sxx: The Sxx component of the Saupe order matrix. 538 @type Sxx: float 539 @param Syy: The Syy component of the Saupe order matrix. 540 @type Syy: float 541 @return: The Sxx-yy component of the Saupe order matrix. 542 @rtype: float 543 """ 544 545 # Calculate and return the Sxx-yy value. 546 return Sxx - Syy
547 548
549 -def calc_Sxy(Axy):
550 """Function for calculating the Axy value. 551 552 The equation for calculating the parameter is:: 553 554 Sxy = 3/2 Axy. 555 556 @param Axy: The Axy component of the alignment tensor. 557 @type Axy: float 558 @rtype: float 559 """ 560 561 # Calculate and return the Axy value. 562 return 3.0/2.0 * Axy
563 564
565 -def calc_Sxz(Axz):
566 """Function for calculating the Axz value. 567 568 The equation for calculating the parameter is:: 569 570 Sxz = 3/2 Axz. 571 572 @param Axz: The Axz component of the alignment tensor. 573 @type Axz: float 574 @rtype: float 575 """ 576 577 # Calculate and return the Axz value. 578 return 3.0/2.0 * Axz
579 580
581 -def calc_Syy(Ayy):
582 """Function for calculating the Ayy value. 583 584 The equation for calculating the parameter is:: 585 586 Syy = 3/2 Ayy. 587 588 @param Ayy: The Ayy component of the alignment tensor. 589 @type Ayy: float 590 @rtype: float 591 """ 592 593 # Calculate and return the Ayy value. 594 return 3.0/2.0 * Ayy
595 596
597 -def calc_Syz(Ayz):
598 """Function for calculating the Ayz value. 599 600 The equation for calculating the parameter is:: 601 602 Syz = 3/2 Ayz. 603 604 @param Ayz: The Ayz component of the alignment tensor. 605 @type Ayz: float 606 @rtype: float 607 """ 608 609 # Calculate and return the Ayz value. 610 return 3.0/2.0 * Ayz
611 612
613 -def calc_Szz(Sxx, Syy):
614 """Function for calculating the Szz value. 615 616 The equation for calculating the parameter is:: 617 618 Szz = - Sxx - Syy. 619 620 @param Sxx: The Sxx component of the Saupe order matrix. 621 @type Sxx: float 622 @param Syy: The Syy component of the Saupe order matrix. 623 @type Syy: float 624 @return: The Szz component of the Saupe order matrix. 625 @rtype: float 626 """ 627 628 # Calculate and return the Szz value. 629 return - Sxx - Syy
630 631
632 -def calc_P(Axx, Ayy, Azz, Axy, Axz, Ayz):
633 """Function for calculating the alignment tensor (in the structural frame). 634 635 @param Axx: The Axx tensor element. 636 @type Axx: float 637 @param Ayy: The Ayy tensor element. 638 @type Ayy: float 639 @param Azz: The Azz tensor element. 640 @type Azz: float 641 @param Axy: The Axy tensor element. 642 @type Axy: float 643 @param Axz: The Axz tensor element. 644 @type Axz: float 645 @param Ayz: The Ayz tensor element. 646 @type Ayz: float 647 @return: The alignment tensor (within the structural frame). 648 @rtype: 3x3 numpy float64 array 649 """ 650 651 # Initialise the tensor. 652 tensor = zeros((3, 3), float64) 653 654 # Populate the diagonal elements. 655 tensor[0, 0] = Axx 656 tensor[1, 1] = Ayy 657 tensor[2, 2] = Azz 658 659 # Populate the off diagonal elements. 660 tensor[0, 1] = tensor[1, 0] = Axy 661 tensor[0, 2] = tensor[2, 0] = Axz 662 tensor[1, 2] = tensor[2, 1] = Ayz 663 664 # Add 1/3 the identity matrix. 665 tensor = tensor + eye(3)/3.0 666 667 # Return the tensor. 668 return tensor
669 670
671 -def calc_P_5D(Axx, Ayy, Azz, Axy, Axz, Ayz):
672 """Function for calculating the alignment tensor in the 5D vector notation. 673 674 @param Axx: The Axx tensor element. 675 @type Axx: float 676 @param Ayy: The Ayy tensor element. 677 @type Ayy: float 678 @param Azz: The Azz tensor element. 679 @type Azz: float 680 @param Axy: The Axy tensor element. 681 @type Axy: float 682 @param Axz: The Axz tensor element. 683 @type Axz: float 684 @param Ayz: The Ayz tensor element. 685 @type Ayz: float 686 @return: The alignment 5D tensor (within the structural frame). 687 @rtype: numpy rank-1 5D tensor 688 """ 689 690 # Initialise the tensor. 691 tensor = zeros(5, float64) 692 693 # Populate the tensor. 694 tensor[0] = Axx + 1.0/3.0 695 tensor[1] = Ayy + 1.0/3.0 696 tensor[2] = Axy 697 tensor[3] = Axz 698 tensor[4] = Ayz 699 700 # Return the tensor. 701 return tensor
702 703
704 -def calc_P_diag(tensor):
705 """Calculate the diagonalised alignment tensor. 706 707 The diagonalised alignment tensor is defined as:: 708 709 | Pxx' 0 0 | 710 tensor = | 0 Pyy' 0 |. 711 | 0 0 Pzz'| 712 713 The diagonalised alignment tensor is calculated by eigenvalue decomposition. 714 715 716 @param tensor: The full alignment tensor in its eigenframe. 717 @type tensor: numpy array ((3, 3), float64) 718 @return: The diagonalised alignment tensor. 719 @rtype: numpy array ((3, 3), float64) 720 """ 721 722 # The eigenvalues. 723 vals = eigvals(tensor) 724 725 # Find the |x| < |y| < |z| indices. 726 abs_vals = abs(vals).tolist() 727 Pxx_index = abs_vals.index(min(abs_vals)) 728 Pzz_index = abs_vals.index(max(abs_vals)) 729 last_index = list(range(3)) 730 last_index.pop(max(Pxx_index, Pzz_index)) 731 last_index.pop(min(Pxx_index, Pzz_index)) 732 Pyy_index = last_index[0] 733 734 # Empty tensor. 735 tensor_diag = zeros((3, 3), float64) 736 737 # Fill the elements. 738 tensor_diag[0, 0] = vals[Pxx_index] 739 tensor_diag[1, 1] = vals[Pyy_index] 740 tensor_diag[2, 2] = vals[Pzz_index] 741 742 # Add 1/3 the identity matrix. 743 tensor = tensor + eye(3)/3.0 744 745 # Return the tensor. 746 return tensor_diag
747 748
749 -def calc_Pxx(Axx):
750 """Function for calculating the Pxx value. 751 752 The equation for calculating the parameter is:: 753 754 Pxx = Axx + 1/3. 755 756 @param Axx: The Axx component of the alignment tensor. 757 @type Axx: float 758 @rtype: float 759 """ 760 761 # Calculate and return the Pxx value. 762 return Axx + 1.0/3.0
763 764
765 -def calc_Pxxyy(Pxx, Pyy):
766 """Function for calculating the Pxx-yy value. 767 768 The equation for calculating the parameter is:: 769 770 Pxx-yy = Pxx - Pyy. 771 772 @param Pxx: The Pxx component of the alignment tensor. 773 @type Pxx: float 774 @param Pyy: The Pyy component of the alignment tensor. 775 @type Pyy: float 776 @return: The Pxx-yy component of the alignment tensor. 777 @rtype: float 778 """ 779 780 # Calculate and return the Pxx-yy value. 781 return Pxx - Pyy
782 783
784 -def calc_Pxy(Axy):
785 """Function for calculating the Pxy value. 786 787 The equation for calculating the parameter is:: 788 789 Pxy = Axy. 790 791 @param Axy: The Axy component of the alignment tensor. 792 @type Axy: float 793 @rtype: float 794 """ 795 796 # Calculate and return the Pxy value. 797 return Axy
798 799
800 -def calc_Pxz(Axz):
801 """Function for calculating the Pxz value. 802 803 The equation for calculating the parameter is:: 804 805 Pxz = Axz. 806 807 @param Axz: The Axz component of the alignment tensor. 808 @type Axz: float 809 @rtype: float 810 """ 811 812 # Calculate and return the Pxz value. 813 return Axz
814 815
816 -def calc_Pyy(Ayy):
817 """Function for calculating the Pyy value. 818 819 The equation for calculating the parameter is:: 820 821 Pyy = Ayy + 1/3. 822 823 @param Ayy: The Ayy component of the alignment tensor. 824 @type Ayy: float 825 @rtype: float 826 """ 827 828 # Calculate and return the Pyy value. 829 return Ayy + 1.0/3.0
830 831
832 -def calc_Pyz(Ayz):
833 """Function for calculating the Pyz value. 834 835 The equation for calculating the parameter is:: 836 837 Pyz = Ayz. 838 839 @param Ayz: The Ayz component of the alignment tensor. 840 @type Ayz: float 841 @rtype: float 842 """ 843 844 # Calculate and return the Pyz value. 845 return Ayz
846 847
848 -def calc_Pzz(Pxx, Pyy):
849 """Function for calculating the Pzz value. 850 851 The equation for calculating the parameter is:: 852 853 Pzz = 1 - Pxx - Pyy. 854 855 @param Pxx: The Pxx component of the alignment tensor. 856 @type Pxx: float 857 @param Pyy: The Pyy component of the alignment tensor. 858 @type Pyy: float 859 @return: The Pzz component of the alignment tensor. 860 @rtype: float 861 """ 862 863 # Calculate and return the Pzz value. 864 return 1.0 - Pxx - Pyy
865 866
867 -def calc_R(Aa, Ar):
868 """Calculate the rhombicity parameter R. 869 870 This is given by:: 871 872 R = Ar / Aa. 873 874 875 @param Aa: The Aa parameter. 876 @type Aa: float 877 @param Ar: The Ar parameter. 878 @type Ar: float 879 @return: The R parameter. 880 @rtype: float 881 """ 882 883 # Zero Aa value, so return NaN. 884 if Aa == 0: 885 return nan 886 887 # Return R. 888 return Ar / Aa
889 890
891 -def calc_rotation(A):
892 """Calculate the rotation matrix from the molecular frame to the tensor frame. 893 894 This is defined by:: 895 896 | Azz | >= | Ayy | >= | Axx |. 897 898 899 @param A: The full alignment tensor. 900 @type A: numpy array ((3, 3), float64) 901 @return: The array of x, y, and z indices. 902 @rtype: list 903 """ 904 905 # The eigenvalues. 906 vals, rot = eig(A) 907 908 # Find the |x| < |y| < |z| indices. 909 abs_vals = abs(vals).tolist() 910 x_index = abs_vals.index(min(abs_vals)) 911 z_index = abs_vals.index(max(abs_vals)) 912 last_index = list(range(3)) 913 last_index.pop(max(x_index, z_index)) 914 last_index.pop(min(x_index, z_index)) 915 y_index = last_index[0] 916 917 # Empty rotation matrix for index permutations. 918 rot_perm = zeros((3, 3), float64) 919 920 # Permute the rotation matrix. 921 perm = [x_index, y_index, z_index] 922 for i in range(3): 923 for j in range(3): 924 rot_perm[i, j] = rot[i, perm[j]] 925 926 # Switch from the left handed to right handed universe if required. 927 if abs(det(rot_perm) - 1.0) > 1e-7: 928 rot_perm[:, 0] = -rot_perm[:, 0] 929 930 # Return the permuted rotation matrix. 931 return rot_perm
932 933
934 -def calc_unit_x(rotation):
935 """Calculate the x unit vector. 936 937 This is given by the eigenvalue decomposition. 938 939 940 @param rotation: The rotation matrix. 941 @type rotation: numpy 3D, rank-2 array 942 @return: The x unit vector. 943 @rtype: numpy array (float64) 944 """ 945 946 # Return the x unit vector. 947 return rotation[:, 0]
948 949
950 -def calc_unit_y(rotation):
951 """Calculate the y unit vector. 952 953 This is given by the eigenvalue decomposition. 954 955 956 @param rotation: The rotation matrix. 957 @type rotation: numpy 3D, rank-2 array 958 @return: The y unit vector. 959 @rtype: numpy array (float64) 960 """ 961 962 # Return the y unit vector. 963 return rotation[:, 1]
964 965
966 -def calc_unit_z(rotation):
967 """Calculate the z unit vector. 968 969 This is given by the eigenvalue decomposition. 970 971 972 @param rotation: The rotation matrix. 973 @type rotation: numpy 3D, rank-2 array 974 @return: The z unit vector. 975 @rtype: numpy array (float64) 976 """ 977 978 # Return the z unit vector. 979 return rotation[:, 2]
980 981
982 -def dependency_generator():
983 """Generator for the automatic updating the alignment tensor data structures. 984 985 @return: This generator successively yields three objects, the target object to update, the list of parameters which if modified cause the target to be updated, and the list of parameters that the target depends upon. 986 """ 987 988 # Primary objects (only dependant on the modifiable objects). 989 yield ('A', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Axx', 'Ayy', 'Azz', 'Axy', 'Axz', 'Ayz']) 990 yield ('A_5D', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Axx', 'Ayy', 'Azz', 'Axy', 'Axz', 'Ayz']) 991 yield ('Axxyy', ['Axx', 'Ayy'], ['Axx', 'Ayy']) 992 yield ('Azz', ['Axx', 'Ayy'], ['Axx', 'Ayy']) 993 994 yield ('P', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Axx', 'Ayy', 'Azz', 'Axy', 'Axz', 'Ayz']) 995 yield ('P_5D', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Axx', 'Ayy', 'Azz', 'Axy', 'Axz', 'Ayz']) 996 yield ('Pxx', ['Axx'], ['Axx']) 997 yield ('Pxxyy', ['Axx', 'Ayy'], ['Axx', 'Ayy']) 998 yield ('Pxy', ['Axy'], ['Axy']) 999 yield ('Pxz', ['Axz'], ['Axz']) 1000 yield ('Pyy', ['Ayy'], ['Ayy']) 1001 yield ('Pyz', ['Ayz'], ['Ayz']) 1002 1003 yield ('Sxx', ['Axx'], ['Axx']) 1004 yield ('Sxy', ['Axy'], ['Axy']) 1005 yield ('Sxz', ['Axz'], ['Axz']) 1006 yield ('Syy', ['Ayy'], ['Ayy']) 1007 yield ('Syz', ['Ayz'], ['Ayz']) 1008 1009 # Secondary objects (dependant on the primary objects). 1010 yield ('A_diag', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A']) 1011 yield ('eigvals', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A']) 1012 yield ('rotation', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A']) 1013 1014 yield ('P_diag', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['P']) 1015 yield ('Pzz', ['Axx', 'Ayy'], ['Pxx', 'Pyy']) 1016 1017 yield ('S', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Sxx', 'Syy', 'Szz', 'Sxy', 'Sxz', 'Syz']) 1018 yield ('S_5D', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Sxx', 'Syy', 'Szz', 'Sxy', 'Sxz', 'Syz']) 1019 yield ('S_diag', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['S']) 1020 yield ('Sxxyy', ['Axx', 'Ayy'], ['Sxx', 'Syy']) 1021 yield ('Szz', ['Axx', 'Ayy'], ['Sxx', 'Syy']) 1022 1023 yield ('Am2', ['Axx', 'Ayy', 'Axy'], ['Sxx', 'Syy', 'Sxy']) 1024 yield ('Am1', ['Axy', 'Ayz'], ['Sxz', 'Syz']) 1025 yield ('A0', ['Axx', 'Ayy'], ['Szz']) 1026 yield ('A1', ['Axy', 'Ayz'], ['Sxz', 'Syz']) 1027 yield ('A2', ['Axx', 'Ayy', 'Axy'], ['Sxx', 'Syy', 'Sxy']) 1028 1029 # Tertiary objects (dependant on the secondary objects). 1030 yield ('Aa', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A_diag']) 1031 yield ('Ar', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A_diag']) 1032 yield ('eta', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['A_diag']) 1033 1034 yield ('unit_x', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['rotation']) 1035 yield ('unit_y', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['rotation']) 1036 yield ('unit_z', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['rotation']) 1037 1038 yield ('euler', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['rotation']) 1039 1040 # Quaternary objects (dependant on the tertiary objects). 1041 yield ('R', ['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], ['Aa', 'Ar'])
1042 1043 1044 1045 # Alignment tensor specific data. 1046 ################################# 1047
1048 -class AlignTensorList(list):
1049 """List type data container for holding all the alignment tensors. 1050 1051 The elements of the list should be AlignTensorData instances. 1052 """ 1053
1054 - def __repr__(self):
1055 """Replacement function for displaying an instance of this class.""" 1056 1057 text = "Alignment tensors.\n\n" 1058 text = text + "%-8s%-20s\n" % ("Index", "Name") 1059 for i in range(len(self)): 1060 text = text + "%-8i%-20s\n" % (i, self[i].name) 1061 text = text + "\nThese can be accessed by typing 'pipe.align_tensor[index]'.\n" 1062 return text
1063 1064
1065 - def add_item(self, name):
1066 """Append a new AlignTensorData instance to the list. 1067 1068 @param name: The tensor ID string. 1069 @type name: str 1070 @return: The tensor object. 1071 @rtype: AlignTensorData instance 1072 """ 1073 1074 # Create the instance. 1075 obj = AlignTensorData(name) 1076 1077 # Append the object. 1078 self.append(obj) 1079 1080 # Return the object. 1081 return obj
1082 1083
1084 - def from_xml(self, align_tensor_super_node, file_version=1):
1085 """Recreate the alignment tensor data structure from the XML alignment tensor node. 1086 1087 @param align_tensor_super_node: The alignment tensor XML nodes. 1088 @type align_tensor_super_node: xml.dom.minicompat.Element instance 1089 @keyword file_version: The relax XML version of the XML file. 1090 @type file_version: int 1091 """ 1092 1093 # Recreate all the alignment tensor data structures. 1094 xml_to_object(align_tensor_super_node, self, file_version=file_version, blacklist=['align_tensor']) 1095 1096 # Get the individual tensors. 1097 align_tensor_nodes = align_tensor_super_node.getElementsByTagName('align_tensor') 1098 1099 # Loop over the child nodes. 1100 for align_tensor_node in align_tensor_nodes: 1101 # Add the alignment tensor data container. 1102 self.add_item(align_tensor_node.getAttribute('name')) 1103 1104 # A temporary object to pack the structures from the XML data into. 1105 temp_obj = Element() 1106 1107 # Recreate all the other data structures (into the temporary object). 1108 xml_to_object(align_tensor_node, temp_obj, file_version=file_version) 1109 1110 # Loop over all modifiable objects in the temporary object and make soft copies of them. 1111 for name in self[-1]._mod_attr: 1112 # Skip if missing from the object. 1113 if not hasattr(temp_obj, name): 1114 continue 1115 1116 # The category. 1117 if search('_err$', name): 1118 category = 'err' 1119 param = name.replace('_err', '') 1120 elif search('_sim$', name): 1121 category = 'sim' 1122 param = name.replace('_sim', '') 1123 else: 1124 category = 'val' 1125 param = name 1126 1127 # Get the object. 1128 value = getattr(temp_obj, name) 1129 1130 # Normal parameters. 1131 if category == 'val': 1132 self[-1].set(param=param, value=value, category=category, update=False) 1133 1134 # Errors. 1135 elif category == 'err': 1136 self[-1].set(param=param, value=value, category=category, update=False) 1137 1138 # Simulation objects objects. 1139 else: 1140 # Set the simulation number if needed. 1141 if not hasattr(self[-1], '_sim_num') or self[-1]._sim_num == None: 1142 self[-1].set_sim_num(len(value)) 1143 1144 # Recreate the list elements. 1145 for i in range(len(value)): 1146 self[-1].set(param=param, value=value[i], category=category, sim_index=i, update=False) 1147 1148 # Update the data structures. 1149 for target, update_if_set, depends in dependency_generator(): 1150 self[-1]._update_object(param, target, update_if_set, depends, category) 1151 1152 # Delete the temporary object. 1153 del temp_obj
1154 1155
1156 - def names(self):
1157 """Return a list of the alignment tensor names.""" 1158 1159 # Loop over the tensors. 1160 names = [] 1161 for i in range(len(self)): 1162 names.append(self[i].name) 1163 1164 # Return the list. 1165 return names
1166 1167
1168 - def to_xml(self, doc, element):
1169 """Create an XML element for the alignment tensors. 1170 1171 @param doc: The XML document object. 1172 @type doc: xml.dom.minidom.Document instance 1173 @param element: The element to add the alignment tensors XML element to. 1174 @type element: XML element object 1175 """ 1176 1177 # Create the alignment tensors element and add it to the higher level element. 1178 tensor_list_element = doc.createElement('align_tensors') 1179 element.appendChild(tensor_list_element) 1180 1181 # Set the alignment tensor attributes. 1182 tensor_list_element.setAttribute('desc', 'Alignment tensor list') 1183 1184 # Add all simple python objects within the PipeContainer to the pipe element. 1185 fill_object_contents(doc, tensor_list_element, object=self, blacklist=list(self.__class__.__dict__.keys())+list(list.__dict__.keys())) 1186 1187 # Loop over the tensors. 1188 for i in range(len(self)): 1189 # Create an XML element for a single tensor. 1190 tensor_element = doc.createElement('align_tensor') 1191 tensor_list_element.appendChild(tensor_element) 1192 tensor_element.setAttribute('index', repr(i)) 1193 tensor_element.setAttribute('desc', 'Alignment tensor') 1194 1195 # The blacklist. 1196 blacklist = ['type', 'is_empty'] + list(self[i].__class__.__dict__.keys()) 1197 for name in dir(self): 1198 if name not in self[i]._mod_attr: 1199 blacklist.append(name) 1200 1201 # Add all simple python objects within the PipeContainer to the pipe element. 1202 fill_object_contents(doc, tensor_element, object=self[i], blacklist=blacklist)
1203 1204
1205 -class AlignTensorData(Element):
1206 """An empty data container for the alignment tensor elements.""" 1207 1208 # List of modifiable attributes. 1209 _mod_attr = [ 1210 'name', 1211 'Axx', 'Axx_sim', 'Axx_err', 1212 'Ayy', 'Ayy_sim', 'Ayy_err', 1213 'Axy', 'Axy_sim', 'Axy_err', 1214 'Axz', 'Axz_sim', 'Axz_err', 1215 'Ayz', 'Ayz_sim', 'Ayz_err', 1216 'align_id', 1217 'domain', 1218 'red', 1219 'fixed' 1220 ] 1221
1222 - def __init__(self, name, fixed=False):
1223 """Set up the tensor data. 1224 1225 @param name: The tensor ID string. 1226 @type name: str 1227 @keyword fixed: The optimisation flag. 1228 @type fixed: bool 1229 """ 1230 1231 # Store the values. 1232 self.__dict__['name'] = name 1233 self.__dict__['fixed'] = fixed 1234 1235 # The number of simulations. 1236 self.__dict__['_sim_num'] = None
1237 1238
1239 - def __setattr__(self, name, value):
1240 """Make this object read-only.""" 1241 1242 raise RelaxError("The alignment tensor is a read-only object. The alignment tensor set() method must be used instead.")
1243 1244
1245 - def _update_object(self, param_name, target, update_if_set, depends, category, sim_index=None):
1246 """Function for updating the target object, its error, and the MC simulations. 1247 1248 If the base name of the object is not within the 'update_if_set' list, this function returns 1249 without doing anything (to avoid wasting time). Dependant upon the category the object 1250 (target), its error (target+'_err'), or all Monte Carlo simulations (target+'_sim') are 1251 updated. 1252 1253 @param param_name: The parameter name which is being set in the __setattr__() function. 1254 @type param_name: str 1255 @param target: The name of the object to update. 1256 @type target: str 1257 @param update_if_set: If the parameter being set by the __setattr__() function is not within this list of parameters, don't waste time updating the target. 1258 @param depends: An array of names objects that the target is dependent upon. 1259 @type depends: array of str 1260 @param category: The category of the object to update (one of 'val', 'err', or 'sim'). 1261 @type category: str 1262 @keyword sim_index: The index for a Monte Carlo simulation for simulated parameter. 1263 @type sim_index: int or None 1264 @return: None 1265 """ 1266 1267 # Only update if the parameter name is within the 'update_if_set' list. 1268 if not param_name in update_if_set: 1269 return 1270 1271 # Get the function for calculating the value. 1272 fn = globals()['calc_'+target] 1273 1274 1275 # The value. 1276 ############ 1277 1278 if category == 'val': 1279 # Get all the dependencies if possible. 1280 missing_dep = 0 1281 deps = () 1282 for dep_name in depends: 1283 # Test if the object exists. 1284 if not hasattr(self, dep_name): 1285 missing_dep = 1 1286 break 1287 1288 # Get the object and place it into the 'deps' tuple. 1289 deps = deps+(getattr(self, dep_name),) 1290 1291 # Only update the object if its dependencies exist. 1292 if not missing_dep: 1293 # Calculate the value. 1294 value = fn(*deps) 1295 1296 # Set the attribute. 1297 self.__dict__[target] = value 1298 1299 1300 # The error. 1301 ############ 1302 1303 if category == 'err': 1304 # Get all the dependencies if possible. 1305 missing_dep = 0 1306 deps = () 1307 for dep_name in depends: 1308 # Test if the error object exists. 1309 if not hasattr(self, dep_name+'_err'): 1310 missing_dep = 1 1311 break 1312 1313 # Get the object and place it into the 'deps' tuple. 1314 deps = deps+(getattr(self, dep_name+'_err'),) 1315 1316 # Only update the error object if its dependencies exist. 1317 if not missing_dep: 1318 # Calculate the value. 1319 value = fn(*deps) 1320 1321 # Set the attribute. 1322 self.__dict__[target+'_err'] = value 1323 1324 1325 # The Monte Carlo simulations. 1326 ############################## 1327 1328 if category == 'sim': 1329 # The simulation indices. 1330 if sim_index != None: 1331 sim_indices = [sim_index] 1332 else: 1333 sim_indices = range(self._sim_num) 1334 1335 # Get all the dependencies if possible. 1336 missing_dep = 0 1337 deps = [] 1338 for dep_name in depends: 1339 # Modify the dependency name. 1340 if dep_name != 'type': 1341 dep_name = dep_name+'_sim' 1342 1343 # Test if the MC sim object exists. 1344 if not hasattr(self, dep_name): 1345 missing_dep = 1 1346 break 1347 1348 # Get the object and place it into the 'deps' tuple. 1349 deps.append(getattr(self, dep_name)) 1350 1351 # Only create the MC simulation object if its dependencies exist. 1352 if not missing_dep: 1353 # Initialise an empty array to store the MC simulation object elements (if it doesn't already exist). 1354 if not target+'_sim' in self.__dict__: 1355 self.__dict__[target+'_sim'] = AlignTensorSimList(elements=self._sim_num) 1356 1357 # Repackage the deps structure. 1358 args = [] 1359 skip = False 1360 for i in sim_indices: 1361 args.append(()) 1362 1363 # Loop over the dependent structures. 1364 for j in range(len(deps)): 1365 # None, so skip. 1366 if deps[j] == None or deps[j][i] == None: 1367 skip = True 1368 1369 # String data type. 1370 if isinstance(deps[j], str): 1371 args[-1] = args[-1] + (deps[j],) 1372 1373 # List data type. 1374 else: 1375 args[-1] = args[-1] + (deps[j][i],) 1376 1377 # Loop over the sims and set the values. 1378 if not skip: 1379 for i in sim_indices: 1380 # Calculate the value. 1381 value = fn(*args[sim_indices.index(i)]) 1382 1383 # Set the attribute. 1384 self.__dict__[target+'_sim']._set(value=value, sim_index=i)
1385 1386
1387 - def set(self, param=None, value=None, category='val', sim_index=None, update=True):
1388 """Set a alignment tensor parameter. 1389 1390 @keyword param: The name of the parameter to set. 1391 @type param: str 1392 @keyword value: The parameter value. 1393 @type value: anything 1394 @keyword category: The type of parameter to set. This can be 'val' for the normal parameter, 'err' for the parameter error, or 'sim' for Monte Carlo or other simulated parameters. 1395 @type category: str 1396 @keyword sim_index: The index for a Monte Carlo simulation for simulated parameter. 1397 @type sim_index: int or None 1398 @keyword update: A flag which if True will cause all the alignment tensor objects to be updated correctly. This can be turned off for speed, as long as the _update_object() method is called prior to using the tensor. 1399 @type update: bool 1400 """ 1401 1402 # Check the type. 1403 if category not in ['val', 'err', 'sim']: 1404 raise RelaxError("The category of the parameter '%s' is incorrectly set to %s - it must be one of 'val', 'err' or 'sim'." % (param, category)) 1405 1406 # Test if the attribute that is trying to be set is modifiable. 1407 if not param in self._mod_attr: 1408 raise RelaxError("The object '%s' is not modifiable." % param) 1409 1410 # Set a parameter value. 1411 if category == 'val': 1412 self.__dict__[param] = value 1413 1414 # Set an error. 1415 elif category == 'err': 1416 self.__dict__[param+'_err'] = value 1417 1418 # Set a simulation value. 1419 else: 1420 # Check that the simulation number has been set. 1421 if self._sim_num == None: 1422 raise RelaxError("The alignment tensor simulation number has not yet been specified, therefore a simulation value cannot be set.") 1423 1424 # The simulation parameter name. 1425 sim_param = param+'_sim' 1426 1427 # No object, so create it. 1428 if not hasattr(self, sim_param): 1429 self.__dict__[sim_param] = AlignTensorSimList(elements=self._sim_num) 1430 1431 # The object. 1432 obj = getattr(self, sim_param) 1433 1434 # Set the value. 1435 obj._set(value=value, sim_index=sim_index) 1436 1437 # Skip the updating process for certain objects. 1438 if param in ['type']: 1439 return 1440 1441 # Update the data structures. 1442 if update: 1443 for target, update_if_set, depends in dependency_generator(): 1444 self._update_object(param, target, update_if_set, depends, category, sim_index=sim_index)
1445 1446
1447 - def set_fixed(self, flag):
1448 """Set if the alignment tensor should be fixed during optimisation or not. 1449 1450 @param flag: The fixed flag. 1451 @type flag: bool 1452 """ 1453 1454 self.__dict__['fixed'] = flag
1455 1456
1457 - def set_sim_num(self, sim_number=None):
1458 """Set the number of Monte Carlo simulations for the construction of the simulation structures. 1459 1460 @keyword sim_number: The number of Monte Carlo simulations. 1461 @type sim_number: int 1462 """ 1463 1464 # Store the value. 1465 self.__dict__['_sim_num'] = sim_number
1466 1467 1468
1469 -class AlignTensorSimList(list):
1470 """Empty data container for Monte Carlo simulation alignment tensor data.""" 1471
1472 - def __init__(self, elements=None):
1473 """Initialise the Monte Carlo simulation parameter list. 1474 1475 @keyword elements: The number of elements to initialise the length of the list to. 1476 @type elements: None or int 1477 """ 1478 1479 # Initialise a length. 1480 for i in range(elements): 1481 self._append(None)
1482 1483
1484 - def __setitem__(self, slice_obj, value):
1485 """This is a read-only object!""" 1486 1487 raise RelaxError("The alignment tensor is a read-only object. The alignment tensor set() method must be used instead.")
1488 1489
1490 - def _append(self, value):
1491 """The secret append method. 1492 1493 @param value: The value to append to the list. 1494 @type value: anything 1495 """ 1496 1497 # Execute the base class method. 1498 super(AlignTensorSimList, self).append(value)
1499 1500
1501 - def _set(self, value=None, sim_index=None):
1502 """Replacement secret method for __setitem__(). 1503 1504 @keyword value: The value to set. 1505 @type value: anything 1506 @keyword sim_index: The index of the simulation value to set. 1507 @type sim_index: int 1508 """ 1509 1510 # Execute the base class method. 1511 super(AlignTensorSimList, self).__setitem__(sim_index, value)
1512