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 import sys
31 from warnings import warn
32
33
34 from data_store.align_tensor import AlignTensorList
35 from lib.alignment.alignment_tensor import calc_chi_tensor, kappa
36 from lib.errors import RelaxError, RelaxNoTensorError, RelaxTensorError, RelaxUnknownParamCombError, RelaxUnknownParamError
37 from lib.geometry.angles import wrap_angles
38 from lib.io import write_data
39 from lib.warnings import RelaxWarning
40 import pipe_control
41 from pipe_control import pipes
42
43
45 """Function for determining if alignment data exists in the current data pipe.
46
47 @param tensor: The alignment tensor identification string.
48 @type tensor: str
49 @param pipe: The data pipe to search for data in.
50 @type pipe: str
51 @return: The answer to the question.
52 @rtype: bool
53 """
54
55
56 if pipe == None:
57 pipe = pipes.cdp_name()
58
59
60 pipe = pipes.get_pipe(pipe)
61
62
63 if hasattr(pipe, 'align_tensors'):
64 for data in pipe.align_tensors:
65 if data.name == tensor:
66 return True
67 else:
68 return False
69
70
72 """Determine if all alignment tensors are fixed.
73
74 @return: True if all tensors are fixed, False otherwise.
75 @rtype: bool
76 """
77
78
79 for i in range(len(cdp.align_tensors)):
80
81 if not cdp.align_tensors[i].fixed:
82 return False
83
84
85 return True
86
87
88 -def copy(tensor_from=None, pipe_from=None, tensor_to=None, pipe_to=None):
89 """Function for copying alignment tensor data from one data pipe to another.
90
91 @param tensor_from: The identification string of the alignment tensor to copy the data from.
92 @type tensor_from: str
93 @param pipe_from: The data pipe to copy the alignment tensor data from. This defaults to the current data pipe.
94 @type pipe_from: str
95 @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.
96 @type tensor_to: str or None
97 @param pipe_to: The data pipe to copy the alignment tensor data to. This defaults to the current data pipe.
98 @type pipe_to: str
99 """
100
101
102 if tensor_from == tensor_to and pipe_from == None and pipe_to == None:
103 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None when the tensor names are the same.")
104 elif pipe_from == None:
105 pipe_from = pipes.cdp_name()
106 elif pipe_to == None:
107 pipe_to = pipes.cdp_name()
108
109
110 if tensor_to == None:
111 tensor_to = tensor_from
112
113
114 pipes.test(pipe_from)
115 pipes.test(pipe_to)
116
117
118 dp_from = pipes.get_pipe(pipe_from)
119 dp_to = pipes.get_pipe(pipe_to)
120
121
122 if not align_data_exists(tensor_from, pipe_from):
123 raise RelaxNoTensorError('alignment')
124
125
126 if align_data_exists(tensor_to, pipe_to):
127 raise RelaxTensorError('alignment')
128
129
130 if not hasattr(dp_to, 'align_tensors'):
131 dp_to.align_tensors = AlignTensorList()
132
133
134 if tensor_to not in dp_to.align_tensors.names():
135 dp_to.align_tensors.add_item(tensor_to)
136
137
138 index_from = get_tensor_index(tensor=tensor_from, pipe=pipe_from)
139 index_to = get_tensor_index(tensor=tensor_to, pipe=pipe_to)
140
141
142 if index_to == None:
143 dp_to.align_tensors.append(deepcopy(dp_from.align_tensors[index_from]))
144 index_to = len(dp_to.align_tensors) - 1
145 else:
146 dp_to.align_tensors[index_to] = deepcopy(dp_from.align_tensors[index_from])
147
148
149 dp_to.align_tensors[index_to].set('name', tensor_to)
150
151
152 align_id = dp_from.align_tensors[index_from].align_id
153 if not hasattr(dp_to, 'align_ids'):
154 dp_to.align_ids = []
155 if align_id not in dp_to.align_ids:
156 dp_to.align_ids.append(align_id)
157
158
160 """Function for deleting alignment tensor data.
161
162 @param tensor: The alignment tensor identification string.
163 @type tensor: str or None
164 """
165
166
167 pipes.test()
168
169
170 if tensor and not align_data_exists(tensor):
171 raise RelaxNoTensorError('alignment')
172
173
174 if tensor:
175 tensors = [tensor]
176 else:
177 tensors = []
178 for i in range(len(cdp.align_tensors)):
179 tensors.append(cdp.align_tensors[i].name)
180
181
182 for tensor in tensors:
183
184 print("Removing the '%s' tensor." % tensor)
185
186
187 index = get_tensor_index(tensor=tensor)
188
189
190 cdp.align_tensors.pop(index)
191
192
193 if not len(cdp.align_tensors):
194 del(cdp.align_tensors)
195
196
198 """Function for displaying the alignment tensor.
199
200 @keyword tensor: The alignment tensor identification string.
201 @type tensor: str or None
202 """
203
204
205 pipes.test()
206
207
208 tensor_list = []
209 if not tensor:
210 for tensor_cont in cdp.align_tensors:
211 tensor_list.append(tensor_cont.name)
212 else:
213 tensor_list.append(tensor)
214
215
216 for tensor in tensor_list:
217
218 if not align_data_exists(tensor):
219 raise RelaxNoTensorError('alignment')
220
221
222 data = get_tensor_object(tensor)
223
224
225 head = "# Tensor: %s #" % tensor
226 print("\n\n\n" + '#' * len(head) + "\n" + head + "\n" + '#' * len(head))
227
228
229
230
231
232 title = "# Saupe order matrix."
233 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
234
235
236 print("# 5D, rank-1 notation {Sxx, Syy, Sxy, Sxz, Syz}:")
237 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Sxx, data.Syy, data.Sxy, data.Sxz, data.Syz))
238
239
240 print("# 5D, rank-1 notation {Szz, Sxx-yy, Sxy, Sxz, Syz} (the Pales default format).")
241 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Szz, data.Sxxyy, data.Sxy, data.Sxz, data.Syz))
242
243
244 print("# 3D, rank-2 notation.")
245 print("%s" % (data.S))
246
247
248
249
250
251 title = "# Alignment tensor."
252 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
253
254
255 print("# 5D, rank-1 notation {Axx, Ayy, Axy, Axz, Ayz}:")
256 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Axx, data.Ayy, data.Axy, data.Axz, data.Ayz))
257
258
259 print("# 5D, rank-1 notation {Azz, Axx-yy, Axy, Axz, Ayz} (the Pales default format).")
260 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Azz, data.Axxyy, data.Axy, data.Axz, data.Ayz))
261
262
263 print("# 3D, rank-2 notation.")
264 print("%s" % data.A)
265
266
267
268
269
270 title = "# Probability tensor."
271 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
272
273
274 print("# 5D, rank-1 notation {Pxx, Pyy, Pxy, Pxz, Pyz}:")
275 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Pxx, data.Pyy, data.Pxy, data.Pxz, data.Pyz))
276
277
278 print("# 5D, rank-1 notation {Pzz, Pxx-yy, Pxy, Pxz, Pyz}.")
279 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (data.Pzz, data.Pxxyy, data.Pxy, data.Pxz, data.Pyz))
280
281
282 print("# 3D, rank-2 notation.")
283 print("%s" % data.P)
284
285
286
287
288
289 title = "# Magnetic susceptibility tensor."
290 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
291 chi_tensor = True
292
293
294 print("# The magnetic field strength (MHz):")
295 if hasattr(cdp, 'spectrometer_frq') and tensor in cdp.spectrometer_frq:
296 print("%s\n" % (cdp.spectrometer_frq[tensor] / 1e6))
297 else:
298 print("Not set.\n")
299 chi_tensor = False
300
301
302 print("# The temperature (K):")
303 if hasattr(cdp, 'temperature') and tensor in cdp.temperature:
304 print("%s\n" % cdp.temperature[tensor])
305 else:
306 print("Not set.\n")
307 chi_tensor = False
308
309
310 if not chi_tensor:
311 print("# The chi tensor:\nN/A.\n")
312
313
314 else:
315
316 chi_xx = calc_chi_tensor(data.Axx, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
317 chi_xy = calc_chi_tensor(data.Axy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
318 chi_xz = calc_chi_tensor(data.Axz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
319 chi_yy = calc_chi_tensor(data.Ayy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
320 chi_yz = calc_chi_tensor(data.Ayz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
321 chi_zz = calc_chi_tensor(data.Azz, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
322 chi_xxyy = calc_chi_tensor(data.Axxyy, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
323 chi = calc_chi_tensor(data.A, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
324
325
326 print("# 5D, rank-1 notation {chi_xx, chi_yy, chi_xy, chi_xz, chi_yz}:")
327 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (chi_xx, chi_yy, chi_xy, chi_xz, chi_yz))
328
329
330 print("# 5D, rank-1 notation {chi_zz, chi_xx-yy, chi_xy, chi_xz, chi_yz}.")
331 print("[%25.12e, %25.12e, %25.12e, %25.12e, %25.12e]\n" % (chi_zz, chi_xxyy, chi_xy, chi_xz, chi_yz))
332
333
334 print("# 3D, rank-2 notation.")
335 print("%s" % chi)
336
337
338
339
340
341 title = "# Eigensystem."
342 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
343
344
345 print("# Saupe order matrix eigenvalues {Sxx, Syy, Szz}.")
346 print("[%25.12e, %25.12e, %25.12e]\n" % (data.S_diag[0, 0], data.S_diag[1, 1], data.S_diag[2, 2]))
347 print("# Alignment tensor eigenvalues {Axx, Ayy, Azz}.")
348 print("[%25.12e, %25.12e, %25.12e]\n" % (data.A_diag[0, 0], data.A_diag[1, 1], data.A_diag[2, 2]))
349 print("# Probability tensor eigenvalues {Pxx, Pyy, Pzz}.")
350 print("[%25.12e, %25.12e, %25.12e]\n" % (data.P_diag[0, 0], data.P_diag[1, 1], data.P_diag[2, 2]))
351 if chi_tensor:
352 chi_diag = calc_chi_tensor(data.A_diag, cdp.spectrometer_frq[tensor], cdp.temperature[tensor])
353 print("# Magnetic susceptibility eigenvalues {chi_xx, chi_yy, chi_zz}.")
354 print("[%25.12e, %25.12e, %25.12e]\n" % (chi_diag[0, 0], chi_diag[1, 1], chi_diag[2, 2]))
355
356
357 print("# Eigenvector x.")
358 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_x[0], data.unit_x[1], data.unit_x[2]))
359 print("# Eigenvector y.")
360 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_y[0], data.unit_y[1], data.unit_y[2]))
361 print("# Eigenvector z.")
362 print("[%25.12f, %25.12f, %25.12f]\n" % (data.unit_z[0], data.unit_z[1], data.unit_z[2]))
363
364
365 print("# Rotation matrix.")
366 print("%s\n" % data.rotation)
367
368
369 print("# Euler angles in zyz notation {alpha, beta, gamma}.")
370 print("[%25.12f, %25.12f, %25.12f]\n" % (data.euler[0], data.euler[1], data.euler[2]))
371
372
373
374
375
376 title = "# Geometric description."
377 print("\n\n" + title + '\n' + '#'*len(title) + '\n')
378
379
380 print("# Generalized degree of order (GDO).")
381 print("GDO = %-25.12e\n" % gdo(data.A))
382
383
384 print("# Alignment tensor axial component (Aa = 3/2 * Azz, where Aii are the eigenvalues).")
385 print("Aa = %-25.12e\n" % data.Aa)
386
387
388 print("# Rhombic component (Ar = Axx - Ayy, where Aii are the eigenvalues).")
389 print("Ar = %-25.12e\n" % data.Ar)
390 print("# Rhombicity (R = Ar / Aa).")
391 print("R = %-25.12f\n" % data.R)
392 print("# Asymmetry parameter (eta = (Axx - Ayy) / Azz, where Aii are the eigenvalues).")
393 print("eta = %-25.12f\n" % data.eta)
394
395
396 if chi_tensor:
397
398 print("# Magnetic susceptibility axial parameter (chi_ax = chi_zz - (chi_xx + chi_yy)/2, where chi_ii are the eigenvalues).")
399 print("chi_ax = %-25.12e\n" % (chi_diag[2, 2] - (chi_diag[0, 0] + chi_diag[1, 1])/2.0))
400
401
402 print("# Magnetic susceptibility rhombicity parameter (chi_rh = chi_xx - chi_yy, where chi_ii are the eigenvalues).")
403 print("chi_rh = %-25.12e\n" % (chi_diag[0, 0] - chi_diag[1, 1]))
404
405
406 print("\n\n\n")
407
408
409 -def fix(id=None, fixed=True):
410 """Fix the alignment tensor during optimisation.
411
412 @keyword id: The alignment tensor ID string. If set to None, then all alignment tensors will be fixed.
413 @type id: str or None
414 @keyword fixed: If True, the alignment tensor will be fixed during optimisation. If False, the alignment tensors will be optimised.
415 @type fixed: bool
416 """
417
418
419 pipes.test()
420
421
422 for i in range(len(cdp.align_tensors)):
423
424 if id and cdp.align_tensors[i].name == id:
425 cdp.align_tensors[i].set_fixed(fixed)
426
427
428 if id == None:
429 cdp.align_tensors[i].set_fixed(fixed)
430
431
433 """Wrap the Euler angles and remove the glide reflection and translational symmetries.
434
435 Wrap the angles such that::
436
437 0 <= alpha <= 2pi,
438 0 <= beta <= pi,
439 0 <= gamma <= 2pi.
440
441 For the simulated values, the angles are wrapped as::
442
443 alpha - pi <= alpha_sim <= alpha + pi
444 beta - pi/2 <= beta_sim <= beta + pi/2
445 gamma - pi <= gamma_sim <= gamma + pi
446
447
448 @param sim_index: The simulation index. If set to None then the actual values will be folded
449 rather than the simulation values.
450 @type sim_index: int or None
451 """
452
453
454
455
456
457
458 alpha = cdp.align_tensors.alpha
459 beta = cdp.align_tensors.beta
460 gamma = cdp.align_tensors.gamma
461
462
463 if sim_index != None:
464 alpha_sim = cdp.align_tensors.alpha_sim[sim_index]
465 beta_sim = cdp.align_tensors.beta_sim[sim_index]
466 gamma_sim = cdp.align_tensors.gamma_sim[sim_index]
467
468
469 if sim_index == None:
470 cdp.align_tensors.set(param='alpha', value=wrap_angles(alpha, 0.0, 2.0*pi))
471 cdp.align_tensors.set(param='beta', value= wrap_angles(beta, 0.0, 2.0*pi))
472 cdp.align_tensors.set(param='gamma', value=wrap_angles(gamma, 0.0, 2.0*pi))
473
474
475 else:
476 cdp.align_tensors.set(param='alpha', value=wrap_angles(alpha_sim, alpha - pi, alpha + pi), category='sim', sim_index=sim_index)
477 cdp.align_tensors.set(param='beta', value= wrap_angles(beta_sim, beta - pi, beta + pi), category='sim', sim_index=sim_index)
478 cdp.align_tensors.set(param='gamma', value=wrap_angles(gamma_sim, gamma - pi, gamma + pi), category='sim', sim_index=sim_index)
479
480
481
482
483
484
485 if sim_index == None:
486
487 if cdp.align_tensors.beta >= pi:
488 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha)
489 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta - pi)
490
491
492 else:
493
494 if cdp.align_tensors.beta_sim[sim_index] >= cdp.align_tensors.beta + pi/2.0:
495 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha_sim[sim_index], category='sim', sim_index=sim_index)
496 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta_sim[sim_index] - pi, category='sim', sim_index=sim_index)
497 elif cdp.align_tensors.beta_sim[sim_index] <= cdp.align_tensors.beta - pi/2.0:
498 cdp.align_tensors.set(param='alpha', value=pi - cdp.align_tensors.alpha_sim[sim_index], category='sim', sim_index=sim_index)
499 cdp.align_tensors.set(param='beta', value=cdp.align_tensors.beta_sim[sim_index] + pi, category='sim', sim_index=sim_index)
500
501
503 """Calculate the generalized degree of order (GDO) for the given alignment tensor.
504
505 @param A: The alignment tensor.
506 @type A: rank-2, 3D numpy array
507 @return: The GDO value.
508 @rtype: float
509 """
510
511
512 gdo = sqrt(3.0/2.0) * norm(A)
513
514
515 return gdo
516
517
519 """Return the list of all alignment IDs.
520
521 @return: The list of all alignment IDs.
522 @rtype: list of str
523 """
524
525
526 if cdp == None:
527 return []
528
529
530 if not hasattr(cdp, 'align_ids'):
531 return []
532
533
534 return cdp.align_ids
535
536
538 """Return the list of all tensor IDs.
539
540 @return: The list of all tensor IDs.
541 @rtype: list of str
542 """
543
544
545 ids = []
546
547
548 if cdp == None:
549 return ids
550
551
552 if not hasattr(cdp, 'align_tensors'):
553 return ids
554
555
556 for i in range(len(cdp.align_tensors)):
557 if cdp.align_tensors[i].name != None:
558 ids.append(cdp.align_tensors[i].name)
559
560
561 return ids
562
563
565 """Function for returning the index corresponding to the 'tensor' argument.
566
567 @keyword tensor: The alignment tensor identification string.
568 @type tensor: str or None
569 @keyword align_id: Alternative to the tensor argument, used to return the tensor index for the tensors corresponding to the alignment ID string. If more than one tensor exists, then this will fail.
570 @type align_id: str or None
571 @keyword pipe: The data pipe to search for data in.
572 @type pipe: str
573 @return: The index corresponding to the 'tensor' arg.
574 @rtype: int
575 """
576
577
578 if pipe == None:
579 pipe = pipes.cdp_name()
580
581
582 dp = pipes.get_pipe(pipe)
583
584
585 index = None
586 count = 0
587
588
589 for i in range(len(dp.align_tensors)):
590
591 if tensor and dp.align_tensors[i].name == tensor:
592 index = i
593 count += 1
594
595
596 if align_id and hasattr(dp.align_tensors[i], 'align_id') and dp.align_tensors[i].align_id == align_id:
597 index = i
598 count += 1
599
600
601 if count == 0:
602 warn(RelaxWarning("No alignment tensors match the tensor name '%s' or alignment ID '%s' in the data pipe '%s'." % (tensor, align_id, pipe)))
603 return None
604
605
606 if count > 1:
607 warn(RelaxWarning("More than one alignment tensors matches the tensor name '%s' or alignment ID '%s' in the data pipe '%s'." % (tensor, align_id, pipe)))
608 return None
609
610
611 return index
612
613
615 """Return the AlignTensorData instance corresponding to the tensor ID.
616
617 @param tensor: The alignment tensor identification string.
618 @type tensor: str
619 @param pipe: The data pipe to search for data in.
620 @type pipe: str
621 @return: The alignment tensor object corresponding to the 'tensor' arg.
622 @rtype: AlignTensorData instance
623 """
624
625
626 if pipe == None:
627 pipe = pipes.cdp_name()
628
629
630 data = None
631
632
633 for i in range(len(cdp.align_tensors)):
634 if cdp.align_tensors[i].name == tensor:
635 data = cdp.align_tensors[i]
636
637
638 return data
639
640
642 """Return the unique AlignTensorData instance corresponding to the alignment ID.
643
644 @param align_id: The alignment ID for the unique tensor.
645 @type align_id: str
646 @return: The alignment tensor object corresponding to the 'tensor' arg.
647 @rtype: AlignTensorData instance
648 """
649
650
651 if pipe == None:
652 pipe = pipes.cdp_name()
653
654
655 data = None
656
657
658 count = 0
659 for i in range(len(cdp.align_tensors)):
660 if hasattr(cdp.align_tensors[i], 'align_id') and cdp.align_tensors[i].align_id == align_id:
661 data = cdp.align_tensors[i]
662 count += 1
663
664
665 if count > 1:
666 raise RelaxError("Multiple alignment tensors match the alignment ID '%s'." % align_id)
667
668 return data
669
670
671 -def init(tensor=None, align_id=None, params=None, scale=1.0, angle_units='deg', param_types=0, domain=None, errors=False):
672 """Function for initialising the alignment tensor.
673
674 @keyword tensor: The alignment tensor identification string.
675 @type tensor: str
676 @keyword align_id: The alignment ID string that the tensor corresponds to.
677 @type align_id: str or None
678 @keyword params: The alignment tensor parameters.
679 @type params: float
680 @keyword scale: The alignment tensor eigenvalue scaling value.
681 @type scale: float
682 @keyword angle_units: The units for the angle parameters (either 'deg' or 'rad').
683 @type angle_units: str
684 @keyword param_types: The type of parameters supplied. The flag values correspond to, 0: {Axx, Ayy, Axy, Axz, Ayz}, and 1: {Azz, Axx-yy, Axy, Axz, Ayz}.
685 @type param_types: int
686 @keyword domain: The domain label.
687 @type domain: str or None
688 @keyword errors: A flag which determines if the alignment tensor data or its errors are being input.
689 @type errors: bool
690 """
691
692
693 pipes.test()
694
695
696 if align_id == None:
697 raise RelaxError("The alignment ID must be given.")
698
699
700 valid_types = ['deg', 'rad']
701 if not angle_units in valid_types:
702 raise RelaxError("The alignment tensor 'angle_units' argument " + repr(angle_units) + " should be either 'deg' or 'rad'.")
703
704
705 if errors and (not hasattr(cdp, 'align_ids') or not align_id in cdp.align_ids):
706 raise RelaxNoTensorError('alignment')
707
708
709 if domain and (not hasattr(cdp, 'domain') or domain not in cdp.domain.keys()):
710 raise RelaxError("The domain '%s' has not been defined. Please use the domain user function." % domain)
711
712
713 if not hasattr(cdp, 'align_ids'):
714 cdp.align_ids = []
715 if align_id not in cdp.align_ids:
716 cdp.align_ids.append(align_id)
717
718
719 tensor_obj = None
720 if not errors:
721
722 if not hasattr(cdp, 'align_tensors'):
723 cdp.align_tensors = AlignTensorList()
724
725
726 if tensor == None or tensor not in cdp.align_tensors.names():
727 tensor_obj = cdp.align_tensors.add_item(tensor)
728
729
730 if not tensor_obj:
731 if tensor:
732 tensor_obj = get_tensor_object(tensor)
733 else:
734 tensor_obj = get_tensor_object_from_align(align_id)
735
736
737 if param_types == 0:
738
739 Sxx, Syy, Sxy, Sxz, Syz = params
740
741
742 Sxx = Sxx * scale
743 Syy = Syy * scale
744 Sxy = Sxy * scale
745 Sxz = Sxz * scale
746 Syz = Syz * scale
747
748
749 set(tensor=tensor_obj, value=[Sxx, Syy, Sxy, Sxz, Syz], param=['Sxx', 'Syy', 'Sxy', 'Sxz', 'Syz'], errors=errors)
750
751
752 elif param_types == 1:
753
754 Szz, Sxxyy, Sxy, Sxz, Syz = params
755
756
757 Szz = Szz * scale
758 Sxxyy = Sxxyy * scale
759 Sxy = Sxy * scale
760 Sxz = Sxz * scale
761 Syz = Syz * scale
762
763
764 set(tensor=tensor_obj, value=[Szz, Sxxyy, Sxy, Sxz, Syz], param=['Szz', 'Sxxyy', 'Sxy', 'Sxz', 'Syz'], errors=errors)
765
766
767 elif param_types == 2:
768
769 Axx, Ayy, Axy, Axz, Ayz = params
770
771
772 Axx = Axx * scale
773 Ayy = Ayy * scale
774 Axy = Axy * scale
775 Axz = Axz * scale
776 Ayz = Ayz * scale
777
778
779 set(tensor=tensor_obj, value=[Axx, Ayy, Axy, Axz, Ayz], param=['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], errors=errors)
780
781
782 elif param_types == 3:
783
784 Azz, Axxyy, Axy, Axz, Ayz = params
785
786
787 Azz = Azz * scale
788 Axxyy = Axxyy * scale
789 Axy = Axy * scale
790 Axz = Axz * scale
791 Ayz = Ayz * scale
792
793
794 set(tensor=tensor_obj, value=[Azz, Axxyy, Axy, Axz, Ayz], param=['Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz'], errors=errors)
795
796
797 elif param_types == 4:
798
799 Axx, Ayy, Axy, Axz, Ayz = params
800
801
802 r = None
803 for spin in spin_loop():
804
805 if r == None:
806 r = spin.r
807
808
809 if r != spin.r:
810 raise RelaxError("Not all spins have the same bond length.")
811
812
813 scale = scale / kappa() * r**3
814 Axx = Axx * scale
815 Ayy = Ayy * scale
816 Axy = Axy * scale
817 Axz = Axz * scale
818 Ayz = Ayz * scale
819
820
821 set(tensor=tensor_obj, value=[Axx, Ayy, Axy, Axz, Ayz], param=['Axx', 'Ayy', 'Axy', 'Axz', 'Ayz'], errors=errors)
822
823
824 elif param_types == 5:
825
826 Azz, Axxyy, Axy, Axz, Ayz = params
827
828
829 r = None
830 for spin in spin_loop():
831
832 if r == None:
833 r = spin.r
834
835
836 if r != spin.r:
837 raise RelaxError("Not all spins have the same bond length.")
838
839
840 scale = scale / kappa() * r**3
841 Azz = Azz * scale
842 Axxyy = Axxyy * scale
843 Axy = Axy * scale
844 Axz = Axz * scale
845 Ayz = Ayz * scale
846
847
848 set(tensor=tensor_obj, value=[Azz, Axxyy, Axy, Axz, Ayz], param=['Azz', 'Axxyy', 'Axy', 'Axz', 'Ayz'], errors=errors)
849
850
851 elif param_types == 6:
852
853 Pxx, Pyy, Pxy, Pxz, Pyz = params
854
855
856 Pxx = Pxx * scale
857 Pyy = Pyy * scale
858 Pxy = Pxy * scale
859 Pxz = Pxz * scale
860 Pyz = Pyz * scale
861
862
863 set(tensor=tensor_obj, value=[Pxx, Pyy, Pxy, Pxz, Pyz], param=['Pxx', 'Pyy', 'Pxy', 'Pxz', 'Pyz'], errors=errors)
864
865
866 elif param_types == 7:
867
868 Pzz, Pxxyy, Pxy, Pxz, Pyz = params
869
870
871 Pzz = Pzz * scale
872 Pxxyy = Pxxyy * scale
873 Pxy = Pxy * scale
874 Pxz = Pxz * scale
875 Pyz = Pyz * scale
876
877
878 set(tensor=tensor_obj, value=[Pzz, Pxxyy, Pxy, Pxz, Pyz], param=['Pzz', 'Pxxyy', 'Pxy', 'Pxz', 'Pyz'], errors=errors)
879
880
881 else:
882 raise RelaxUnknownParamCombError('param_types', param_types)
883
884
885 if domain:
886 set_domain(tensor=tensor, domain=domain)
887 if align_id:
888 tensor_obj.set(param='align_id', value=align_id)
889
890
892 """Function for calculating the 5D angles between the alignment tensors.
893
894 The basis set used for the 5D vector construction changes the angles calculated.
895
896 @param basis_set: The basis set to use for constructing the 5D vectors. If set to 0, the
897 basis set is {Sxx, Syy, Sxy, Sxz, Syz}. If 1, then the basis set is {Szz,
898 Sxxyy, Sxy, Sxz, Syz}.
899 @type basis_set: int
900 @param tensors: An array of tensors to apply SVD to. If None, all tensors will be used.
901 @type tensors: None or array of str
902 """
903
904
905 if not hasattr(cdp, 'align_tensors') or len(cdp.align_tensors) == 0:
906 raise RelaxNoTensorError('alignment')
907
908
909 tensor_num = 0
910 for tensor in cdp.align_tensors:
911 if tensors and tensor.name not in tensors:
912 continue
913 tensor_num = tensor_num + 1
914
915
916 matrix = zeros((tensor_num, 5), float64)
917
918
919 i = 0
920 for tensor in cdp.align_tensors:
921
922 if tensors and tensor.name not in tensors:
923 continue
924
925
926 if basis_set == 0:
927
928 matrix[i, 0] = tensor.Sxx
929 matrix[i, 1] = tensor.Syy
930 matrix[i, 2] = tensor.Sxy
931 matrix[i, 3] = tensor.Sxz
932 matrix[i, 4] = tensor.Syz
933
934
935 elif basis_set == 1:
936
937 matrix[i, 0] = tensor.Szz
938 matrix[i, 1] = tensor.Sxxyy
939 matrix[i, 2] = tensor.Sxy
940 matrix[i, 3] = tensor.Sxz
941 matrix[i, 4] = tensor.Syz
942
943
944 norm = linalg.norm(matrix[i])
945 matrix[i] = matrix[i] / norm
946
947
948 i = i + 1
949
950
951 cdp.align_tensors.angles = zeros((tensor_num, tensor_num), float64)
952
953
954 sys.stdout.write("\nData pipe: " + repr(pipes.cdp_name()) + "\n")
955 sys.stdout.write("\n5D angles in deg between the vectors ")
956 if basis_set == 0:
957 sys.stdout.write("{Sxx, Syy, Sxy, Sxz, Syz}")
958 elif basis_set == 1:
959 sys.stdout.write("{Szz, Sxx-yy, Sxy, Sxz, Syz}")
960 sys.stdout.write(":\n")
961
962
963 table = []
964
965
966 table.append([''])
967 for i in range(tensor_num):
968 if cdp.align_tensors[i].name == None:
969 table[0].append(repr(i))
970 else:
971 table[0].append(cdp.align_tensors[i].name)
972
973
974 for i in range(tensor_num):
975
976 if cdp.align_tensors[i].name == None:
977 table.append([repr(i)])
978 else:
979 table.append([cdp.align_tensors[i].name])
980
981
982 for j in range(tensor_num):
983
984 delta = dot(matrix[i], matrix[j])
985
986
987 if delta > 1:
988 delta = 1
989
990
991 cdp.align_tensors.angles[i, j] = arccos(delta)
992
993
994 table[i+1].append("%8.1f" % (cdp.align_tensors.angles[i, j]*180.0/pi))
995
996
997 write_data(out=sys.stdout, data=table)
998
999
1001 """Count the number of tensors.
1002
1003 @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.
1004 @type skip_fixed: bool
1005 @return: The number of tensors (excluding fixed tensors by default).
1006 @rtype: int
1007 """
1008
1009
1010 count = 0
1011
1012
1013 for tensor_cont in cdp.align_tensors:
1014
1015 if skip_fixed and tensor_cont.fixed:
1016 continue
1017
1018
1019 count += 1
1020
1021
1022 return count
1023
1024
1026 """Determine if the PCS or RDC data for the given alignment ID is needed for optimisation.
1027
1028 @keyword align_id: The optional alignment ID string.
1029 @type align_id: str
1030 @return: True if alignment data is to be used for optimisation, False otherwise.
1031 @rtype: bool
1032 """
1033
1034
1035 if not hasattr(cdp, 'align_ids'):
1036 return False
1037
1038
1039 if align_id:
1040 align_ids = [align_id]
1041 else:
1042 align_ids = cdp.align_ids
1043
1044
1045 for align_id in align_ids:
1046 if pipe_control.pcs.opt_uses_pcs(align_id) or pipe_control.rdc.opt_uses_rdc(align_id):
1047 return True
1048
1049
1050 return False
1051
1052
1054 """Determine if the given tensor is to be optimised.
1055
1056 @param tensor: The alignment tensor to check.
1057 @type tensor: AlignmentTensor object.
1058 @return: True if the tensor is to be optimised, False otherwise.
1059 @rtype: bool
1060 """
1061
1062
1063 ids = []
1064 if hasattr(cdp, 'rdc_ids'):
1065 ids += cdp.rdc_ids
1066 if hasattr(cdp, 'pcs_ids'):
1067 ids += cdp.pcs_ids
1068
1069
1070 if tensor.align_id not in ids:
1071 return False
1072
1073
1074 if tensor.fixed:
1075 return False
1076
1077
1078 return True
1079
1080
1081 -def reduction(full_tensor=None, red_tensor=None):
1082 """Specify which tensor is a reduction of which other tensor.
1083
1084 @param full_tensor: The full alignment tensor.
1085 @type full_tensor: str
1086 @param red_tensor: The reduced alignment tensor.
1087 @type red_tensor: str
1088 """
1089
1090
1091 match_full = False
1092 match_red = False
1093 i = 0
1094 for tensor_cont in cdp.align_tensors:
1095
1096 if tensor_cont.name == full_tensor:
1097 match_full = True
1098 index_full = i
1099 if tensor_cont.name == red_tensor:
1100 match_red = True
1101 index_red = i
1102
1103
1104 i = i + 1
1105
1106
1107 if not match_full:
1108 raise RelaxNoTensorError('alignment', full_tensor)
1109 if not match_red:
1110 raise RelaxNoTensorError('alignment', red_tensor)
1111
1112
1113 if not hasattr(cdp.align_tensors, 'reduction'):
1114 cdp.align_tensors.reduction = []
1115 cdp.align_tensors.reduction.append([index_full, index_red])
1116
1117
1119 """Return the tensor container for the given index, skipping fixed tensors if required.
1120
1121 @param index: The index of the tensor (if skip_fixed is True, then fixed tensors are not included in the index count).
1122 @type index: int
1123 @keyword skip_fixed: A flag which if True will exclude fixed tensors from the indexation.
1124 @type skip_fixed: bool
1125 @return: The tensor corresponding to the index.
1126 @rtype: data.align_tensor.AlignTensorData instance
1127 """
1128
1129
1130 count = 0
1131
1132
1133 for tensor_cont in cdp.align_tensors:
1134
1135 if skip_fixed and tensor_cont.fixed:
1136 continue
1137
1138
1139 if index == count:
1140 return tensor_cont
1141
1142
1143 count += 1
1144
1145
1146 return False
1147
1148
1149 -def set(tensor=None, value=None, param=None, errors=False):
1150 """Set the tensor.
1151
1152 @keyword tensor: The alignment tensor object.
1153 @type tensor: AlignTensorData instance
1154 @keyword value: The list of values to set the parameters to.
1155 @type value: list of float
1156 @keyword param: The list of parameter names.
1157 @type param: list of str
1158 @keyword errors: A flag which determines if the alignment tensor data or its errors are being
1159 input.
1160 @type errors: bool
1161 """
1162
1163
1164 geo_params = []
1165 geo_values = []
1166 orient_params = []
1167 orient_values = []
1168
1169
1170 for i in range(len(param)):
1171
1172 if param[i] == None:
1173 raise RelaxUnknownParamError("alignment tensor", 'None')
1174
1175
1176 if value[i] == None:
1177 value[i] = 0.0
1178
1179
1180 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']:
1181 geo_params.append(param[i])
1182 geo_values.append(value[i])
1183
1184
1185 if param[i] in ['alpha', 'beta', 'gamma']:
1186 orient_params.append(param[i])
1187 orient_values.append(value[i])
1188
1189
1190
1191
1192
1193
1194 if len(geo_params) == 1:
1195
1196
1197
1198
1199 if geo_params[0] == 'Sxx':
1200 if errors:
1201 tensor.set(param='Sxx', value=geo_values[0], category='err')
1202 else:
1203 tensor.set(param='Sxx', value=geo_values[0])
1204
1205
1206 elif geo_params[0] == 'Syy':
1207 if errors:
1208 tensor.set(param='Syy', value=geo_values[0], category='err')
1209 else:
1210 tensor.set(param='Syy', value=geo_values[0])
1211
1212
1213 elif geo_params[0] == 'Sxy':
1214 if errors:
1215 tensor.set(param='Sxy', value=geo_values[0], category='err')
1216 else:
1217 tensor.set(param='Sxy', value=geo_values[0])
1218
1219
1220 elif geo_params[0] == 'Sxz':
1221 if errors:
1222 tensor.set(param='Sxz', value=geo_values[0], category='err')
1223 else:
1224 tensor.set(param='Sxz', value=geo_values[0])
1225
1226
1227 elif geo_params[0] == 'Syz':
1228 if errors:
1229 tensor.set(param='Syz', value=geo_values[0], category='err')
1230 else:
1231 tensor.set(param='Syz', value=geo_values[0])
1232
1233
1234
1235
1236
1237
1238 elif geo_params[0] == 'Axx':
1239 if errors:
1240 tensor.set(param='Sxx', value=3.0/2.0 * geo_values[0], category='err')
1241 else:
1242 tensor.set(param='Sxx', value=3.0/2.0 * geo_values[0])
1243
1244
1245 elif geo_params[0] == 'Ayy':
1246 if errors:
1247 tensor.set(param='Syy', value=3.0/2.0 * geo_values[0], category='err')
1248 else:
1249 tensor.set(param='Syy', value=3.0/2.0 * geo_values[0])
1250
1251
1252 elif geo_params[0] == 'Axy':
1253 if errors:
1254 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0], category='err')
1255 else:
1256 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0])
1257
1258
1259 elif geo_params[0] == 'Axz':
1260 if errors:
1261 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0], category='err')
1262 else:
1263 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0])
1264
1265
1266 elif geo_params[0] == 'Ayz':
1267 if errors:
1268 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0], category='err')
1269 else:
1270 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0])
1271
1272
1273
1274
1275
1276
1277 elif geo_params[0] == 'Pxx':
1278 if errors:
1279 tensor.set(param='Sxx', value=3.0/2.0 * (geo_values[0] - 1.0/3.0), category='err')
1280 else:
1281 tensor.set(param='Sxx', value=3.0/2.0 * (geo_values[0] - 1.0/3.0))
1282
1283
1284 elif geo_params[0] == 'Pyy':
1285 if errors:
1286 tensor.set(param='Syy', value=3.0/2.0 * (geo_values[0] - 1.0/3.0), category='err')
1287 else:
1288 tensor.set(param='Syy', value=3.0/2.0 * (geo_values[0] - 1.0/3.0))
1289
1290
1291 elif geo_params[0] == 'Pxy':
1292 if errors:
1293 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0], category='err')
1294 else:
1295 tensor.set(param='Sxy', value=3.0/2.0 * geo_values[0])
1296
1297
1298 elif geo_params[0] == 'Pxz':
1299 if errors:
1300 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0], category='err')
1301 else:
1302 tensor.set(param='Sxz', value=3.0/2.0 * geo_values[0])
1303
1304
1305 elif geo_params[0] == 'Pyz':
1306 if errors:
1307 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0], category='err')
1308 else:
1309 tensor.set(param='Syz', value=3.0/2.0 * geo_values[0])
1310
1311
1312 else:
1313 raise RelaxError("The geometric alignment parameter " + repr(geo_params[0]) + " cannot be set.")
1314
1315
1316 elif len(geo_params) == 5:
1317
1318 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:
1319
1320 Sxx = geo_values[geo_params.index('Sxx')]
1321 Syy = geo_values[geo_params.index('Syy')]
1322 Sxy = geo_values[geo_params.index('Sxy')]
1323 Sxz = geo_values[geo_params.index('Sxz')]
1324 Syz = geo_values[geo_params.index('Syz')]
1325
1326
1327 if errors:
1328 tensor.set(param='Axx', value=2.0/3.0 * Sxx, category='err')
1329 tensor.set(param='Ayy', value=2.0/3.0 * Syy, category='err')
1330 tensor.set(param='Axy', value=2.0/3.0 * Sxy, category='err')
1331 tensor.set(param='Axz', value=2.0/3.0 * Sxz, category='err')
1332 tensor.set(param='Ayz', value=2.0/3.0 * Syz, category='err')
1333 else:
1334 tensor.set(param='Axx', value=2.0/3.0 * Sxx)
1335 tensor.set(param='Ayy', value=2.0/3.0 * Syy)
1336 tensor.set(param='Axy', value=2.0/3.0 * Sxy)
1337 tensor.set(param='Axz', value=2.0/3.0 * Sxz)
1338 tensor.set(param='Ayz', value=2.0/3.0 * Syz)
1339
1340
1341 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:
1342
1343 Szz = geo_values[geo_params.index('Szz')]
1344 Sxxyy = geo_values[geo_params.index('Sxxyy')]
1345 Sxy = geo_values[geo_params.index('Sxy')]
1346 Sxz = geo_values[geo_params.index('Sxz')]
1347 Syz = geo_values[geo_params.index('Syz')]
1348
1349
1350 if errors:
1351 tensor.set(param='Axx', value=2.0/3.0 * -0.5*(Szz-Sxxyy), category='err')
1352 tensor.set(param='Ayy', value=2.0/3.0 * -0.5*(Szz+Sxxyy), category='err')
1353 tensor.set(param='Axy', value=2.0/3.0 * Sxy, category='err')
1354 tensor.set(param='Axz', value=2.0/3.0 * Sxz, category='err')
1355 tensor.set(param='Ayz', value=2.0/3.0 * Syz, category='err')
1356 else:
1357 tensor.set(param='Axx', value=2.0/3.0 * -0.5*(Szz-Sxxyy))
1358 tensor.set(param='Ayy', value=2.0/3.0 * -0.5*(Szz+Sxxyy))
1359 tensor.set(param='Axy', value=2.0/3.0 * Sxy)
1360 tensor.set(param='Axz', value=2.0/3.0 * Sxz)
1361 tensor.set(param='Ayz', value=2.0/3.0 * Syz)
1362
1363
1364 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:
1365
1366 Axx = geo_values[geo_params.index('Axx')]
1367 Ayy = geo_values[geo_params.index('Ayy')]
1368 Axy = geo_values[geo_params.index('Axy')]
1369 Axz = geo_values[geo_params.index('Axz')]
1370 Ayz = geo_values[geo_params.index('Ayz')]
1371
1372
1373 if errors:
1374 tensor.set(param='Axx', value=Axx, category='err')
1375 tensor.set(param='Ayy', value=Ayy, category='err')
1376 tensor.set(param='Axy', value=Axy, category='err')
1377 tensor.set(param='Axz', value=Axz, category='err')
1378 tensor.set(param='Ayz', value=Ayz, category='err')
1379 else:
1380 tensor.set(param='Axx', value=Axx)
1381 tensor.set(param='Ayy', value=Ayy)
1382 tensor.set(param='Axy', value=Axy)
1383 tensor.set(param='Axz', value=Axz)
1384 tensor.set(param='Ayz', value=Ayz)
1385
1386
1387 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:
1388
1389 Azz = geo_values[geo_params.index('Azz')]
1390 Axxyy = geo_values[geo_params.index('Axxyy')]
1391 Axy = geo_values[geo_params.index('Axy')]
1392 Axz = geo_values[geo_params.index('Axz')]
1393 Ayz = geo_values[geo_params.index('Ayz')]
1394
1395
1396 if errors:
1397 tensor.set(param='Axx', value=-0.5*(Azz-Axxyy), category='err')
1398 tensor.set(param='Ayy', value=-0.5*(Azz+Axxyy), category='err')
1399 tensor.set(param='Axy', value=Axy, category='err')
1400 tensor.set(param='Axz', value=Axz, category='err')
1401 tensor.set(param='Ayz', value=Ayz, category='err')
1402 else:
1403 tensor.set(param='Axx', value=-0.5*(Azz-Axxyy))
1404 tensor.set(param='Ayy', value=-0.5*(Azz+Axxyy))
1405 tensor.set(param='Axy', value=Axy)
1406 tensor.set(param='Axz', value=Axz)
1407 tensor.set(param='Ayz', value=Ayz)
1408
1409
1410 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:
1411
1412 Pxx = geo_values[geo_params.index('Pxx')]
1413 Pyy = geo_values[geo_params.index('Pyy')]
1414 Pxy = geo_values[geo_params.index('Pxy')]
1415 Pxz = geo_values[geo_params.index('Pxz')]
1416 Pyz = geo_values[geo_params.index('Pyz')]
1417
1418
1419 if errors:
1420 tensor.set(param='Axx', value=Pxx - 1.0/3.0, category='err')
1421 tensor.set(param='Ayy', value=Pyy - 1.0/3.0, category='err')
1422 tensor.set(param='Axy', value=Pxy, category='err')
1423 tensor.set(param='Axz', value=Pxz, category='err')
1424 tensor.set(param='Ayz', value=Pyz, category='err')
1425 else:
1426 tensor.set(param='Axx', value=Pxx - 1.0/3.0)
1427 tensor.set(param='Ayy', value=Pyy - 1.0/3.0)
1428 tensor.set(param='Axy', value=Pxy)
1429 tensor.set(param='Axz', value=Pxz)
1430 tensor.set(param='Ayz', value=Pyz)
1431
1432
1433 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:
1434
1435 Pzz = geo_values[geo_params.index('Pzz')]
1436 Pxxyy = geo_values[geo_params.index('Pxxyy')]
1437 Pxy = geo_values[geo_params.index('Pxy')]
1438 Pxz = geo_values[geo_params.index('Pxz')]
1439 Pyz = geo_values[geo_params.index('Pyz')]
1440
1441
1442 if errors:
1443 tensor.set(param='Axx', value=-0.5*(Pzz-Pxxyy) - 1.0/3.0, category='err')
1444 tensor.set(param='Ayy', value=-0.5*(Pzz+Pxxyy) - 1.0/3.0, category='err')
1445 tensor.set(param='Axy', value=Pxy, category='err')
1446 tensor.set(param='Axz', value=Pxz, category='err')
1447 tensor.set(param='Ayz', value=Pyz, category='err')
1448 else:
1449 tensor.set(param='Axx', value=-0.5*(Pzz-Pxxyy) - 1.0/3.0)
1450 tensor.set(param='Ayy', value=-0.5*(Pzz+Pxxyy) - 1.0/3.0)
1451 tensor.set(param='Axy', value=Pxy)
1452 tensor.set(param='Axz', value=Pxz)
1453 tensor.set(param='Ayz', value=Pyz)
1454
1455
1456 else:
1457 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
1458
1459
1460
1461 else:
1462 raise RelaxUnknownParamCombError('geometric parameter set', geo_params)
1463
1464
1465
1466
1467
1468
1469 if len(orient_params) == 1:
1470
1471 if orient_params[0] == 'alpha':
1472 if errors:
1473 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err')
1474 else:
1475 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1476
1477
1478 elif orient_params[0] == 'beta':
1479 if errors:
1480 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err')
1481 else:
1482 tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1483
1484
1485 elif orient_params[0] == 'gamma':
1486 if errors:
1487 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err')
1488 else:
1489 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1490
1491
1492 elif len(orient_params) == 2:
1493
1494 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1:
1495 if errors:
1496 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err')
1497 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err')
1498 else:
1499 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1500 tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1501
1502
1503 if orient_params.count('alpha') == 1 and orient_params.count('gamma') == 1:
1504 if errors:
1505 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err')
1506 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err')
1507 else:
1508 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1509 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1510
1511
1512 if orient_params.count('beta') == 1 and orient_params.count('gamma') == 1:
1513 if errors:
1514 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err')
1515 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err')
1516 else:
1517 tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1518 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1519
1520
1521 else:
1522 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1523
1524
1525 elif len(orient_params) == 3:
1526
1527 if orient_params.count('alpha') == 1 and orient_params.count('beta') == 1:
1528 if errors:
1529 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')], category='err')
1530 tensor.set(param='beta', value=orient_values[orient_params.index('beta')], category='err')
1531 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')], category='err')
1532 else:
1533 tensor.set(param='alpha', value=orient_values[orient_params.index('alpha')])
1534 tensor.set(param='beta', value=orient_values[orient_params.index('beta')])
1535 tensor.set(param='gamma', value=orient_values[orient_params.index('gamma')])
1536
1537
1538 else:
1539 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1540
1541
1542 elif len(orient_params) > 3:
1543 raise RelaxUnknownParamCombError('orientational parameter set', orient_params)
1544
1545
1546
1547
1548
1549 if orient_params:
1550 fold_angles()
1551
1552
1554 """Set the align ID string for the given tensor.
1555
1556 @keyword tensor: The alignment tensor label.
1557 @type tensor: str
1558 @keyword align_id: The alignment ID string.
1559 @type align_id: str
1560 """
1561
1562
1563 match = False
1564 for tensor_cont in cdp.align_tensors:
1565
1566 if tensor_cont.name == tensor:
1567 tensor_cont.align_id = align_id
1568 match = True
1569
1570
1571 if not match:
1572 raise RelaxNoTensorError('alignment', tensor)
1573
1574
1575 -def set_domain(tensor=None, domain=None):
1576 """Set the domain label for the given tensor.
1577
1578 @param tensor: The alignment tensor label.
1579 @type tensor: str
1580 @param domain: The domain label.
1581 @type domain: str
1582 """
1583
1584
1585 if not hasattr(cdp, 'domain') or domain not in cdp.domain.keys():
1586 raise RelaxError("The domain '%s' has not been defined. Please use the domain user function." % domain)
1587
1588
1589 match = False
1590 for tensor_cont in cdp.align_tensors:
1591
1592 if tensor_cont.name == tensor:
1593 tensor_cont.set(param='domain', value=domain)
1594 match = True
1595
1596
1597 if not match:
1598 raise RelaxNoTensorError('alignment', tensor)
1599
1600
1601 -def svd(basis_set=0, tensors=None):
1602 """Function for calculating the singular values of all the loaded tensors.
1603
1604 The matrix on which SVD will be performed is::
1605
1606 | Sxx1 Syy1 Sxy1 Sxz1 Syz1 |
1607 | Sxx2 Syy2 Sxy2 Sxz2 Syz2 |
1608 | Sxx3 Syy3 Sxy3 Sxz3 Syz3 |
1609 | . . . . . |
1610 | . . . . . |
1611 | . . . . . |
1612 | SxxN SyyN SxyN SxzN SyzN |
1613
1614 This is the default unitary basis set (selected when basis_set is 0). Alternatively a geometric
1615 basis set consisting of the stretching and skewing parameters Szz and Sxx-yy respectively
1616 replacing Sxx and Syy can be chosen by setting basis_set to 1. The matrix in this case is::
1617
1618 | Szz1 Sxxyy1 Sxy1 Sxz1 Syz1 |
1619 | Szz2 Sxxyy2 Sxy2 Sxz2 Syz2 |
1620 | Szz3 Sxxyy3 Sxy3 Sxz3 Syz3 |
1621 | . . . . . |
1622 | . . . . . |
1623 | . . . . . |
1624 | SzzN SxxyyN SxyN SxzN SyzN |
1625
1626 The relationships between the geometric and unitary basis sets are::
1627
1628 Szz = - Sxx - Syy,
1629 Sxxyy = Sxx - Syy,
1630
1631 The SVD values and condition number are dependendent upon the basis set chosen.
1632
1633
1634 @param basis_set: The basis set to create the 5 by n matrix on which to perform SVD.
1635 @type basis_set: int
1636 @param tensors: An array of tensors to apply SVD to. If None, all tensors will be used.
1637 @type tensors: None or array of str
1638 """
1639
1640
1641 if not hasattr(cdp, 'align_tensors') or len(cdp.align_tensors) == 0:
1642 raise RelaxNoTensorError('alignment')
1643
1644
1645 tensor_num = 0
1646 for tensor in cdp.align_tensors:
1647 if tensors and tensor.name not in tensors:
1648 continue
1649 tensor_num = tensor_num + 1
1650
1651
1652 matrix = zeros((tensor_num, 5), float64)
1653
1654
1655 i = 0
1656 for tensor in cdp.align_tensors:
1657
1658 if tensors and tensor.name not in tensors:
1659 continue
1660
1661
1662 if basis_set == 0:
1663 matrix[i, 0] = tensor.Sxx
1664 matrix[i, 1] = tensor.Syy
1665 matrix[i, 2] = tensor.Sxy
1666 matrix[i, 3] = tensor.Sxz
1667 matrix[i, 4] = tensor.Syz
1668
1669
1670 elif basis_set == 1:
1671 matrix[i, 0] = tensor.Szz
1672 matrix[i, 1] = tensor.Sxxyy
1673 matrix[i, 2] = tensor.Sxy
1674 matrix[i, 3] = tensor.Sxz
1675 matrix[i, 4] = tensor.Syz
1676
1677
1678 i = i + 1
1679
1680
1681 u, s, vh = linalg.svd(matrix)
1682
1683
1684 cdp.align_tensors.singular_vals = s
1685
1686
1687 cdp.align_tensors.cond_num = s[0] / s[-1]
1688
1689
1690 print("\nData pipe: " + repr(pipes.cdp_name()))
1691 print("\nSingular values:")
1692 for val in s:
1693 print(" %.4e" % val)
1694 print("\nCondition number: %.2f" % cdp.align_tensors.cond_num)
1695