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