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