1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """The align_tensor user function definitions."""
24
25
26 from graphics import WIZARD_IMAGE_PATH
27 from pipe_control import align_tensor, pipes
28 from user_functions.data import Uf_info; uf_info = Uf_info()
29 from user_functions.objects import Desc_container
30
31
32
33 uf_class = uf_info.add_class('align_tensor')
34 uf_class.title = "Class for manipulating the alignment tensor."
35 uf_class.menu_text = "&align_tensor"
36 uf_class.gui_icon = "relax.align_tensor"
37
38
39
40 uf = uf_info.add_uf('align_tensor.copy')
41 uf.title = "Copy alignment tensor data."
42 uf.title_short = "Alignment tensor copying."
43 uf.add_keyarg(
44 name = "tensor_from",
45 default = None,
46 py_type = "str",
47 desc_short = "source tensor ID",
48 desc = "The identification string of the alignment tensor to copy the data from.",
49 can_be_none = True
50 )
51 uf.add_keyarg(
52 name = "pipe_from",
53 default = None,
54 py_type = "str",
55 desc_short = "source data pipe",
56 desc = "The name of the data pipe to copy the alignment tensor data from.",
57 wiz_element_type = 'combo',
58 wiz_combo_iter = pipes.pipe_names,
59 can_be_none = True
60 )
61 uf.add_keyarg(
62 name = "tensor_to",
63 default = None,
64 py_type = "str",
65 desc_short = "destination tensor ID",
66 desc = "The identification string of the alignment tensor to copy the data to.",
67 can_be_none = True
68 )
69 uf.add_keyarg(
70 name = "pipe_to",
71 default = None,
72 py_type = "str",
73 desc_short = "destination data pipe",
74 desc = "The name of the data pipe to copy the alignment tensor data to.",
75 wiz_element_type = 'combo',
76 wiz_combo_iter = pipes.pipe_names,
77 can_be_none = True
78 )
79
80 uf.desc.append(Desc_container())
81 uf.desc[-1].add_paragraph("This will copy the alignment tensor data to a new tensor or a new data pipe. The destination data pipe must not contain any alignment tensor data corresponding to the tensor_to label. If the source or destination data pipes are not supplied, then both will default to the current data pipe. Both the source and destination tensor IDs must be supplied.")
82
83 uf.desc.append(Desc_container("Prompt examples"))
84 uf.desc[-1].add_paragraph("To copy the alignment tensor data corresponding to 'Pf1' from the data pipe 'old' to the current data pipe, type one of:")
85 uf.desc[-1].add_prompt("relax> align_tensor.copy('Pf1', 'old')")
86 uf.desc[-1].add_prompt("relax> align_tensor.copy(tensor_from='Pf1', pipe_from='old')")
87 uf.desc[-1].add_paragraph("To copy the alignment tensor data corresponding to 'Otting' from the current data pipe to the data pipe new, type one of:")
88 uf.desc[-1].add_prompt("relax> align_tensor.copy('Otting', pipe_to='new')")
89 uf.desc[-1].add_prompt("relax> align_tensor.copy(tensor_from='Otting', pipe_to='new')")
90 uf.desc[-1].add_paragraph("To copy the alignment tensor data of 'Otting' to that of 'Otting new', type one of:")
91 uf.desc[-1].add_prompt("relax> align_tensor.copy('Otting', tensor_to='Otting new')")
92 uf.desc[-1].add_prompt("relax> align_tensor.copy(tensor_from='Pf1', tensor_to='Otting new')")
93 uf.backend = align_tensor.copy
94 uf.menu_text = "©"
95 uf.gui_icon = "oxygen.actions.list-add"
96 uf.wizard_size = (800, 600)
97 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
98
99
100
101 uf = uf_info.add_uf('align_tensor.delete')
102 uf.title = "Delete alignment tensor data from the relax data store."
103 uf.title_short = "Alignment tensor pipe deletion."
104 uf.add_keyarg(
105 name = "tensor",
106 py_type = "str",
107 desc_short = "tensor",
108 desc = "The alignment tensor identification string.",
109 wiz_element_type = 'combo',
110 wiz_combo_iter = align_tensor.get_tensor_ids,
111 wiz_read_only = True,
112 can_be_none = True
113 )
114
115 uf.desc.append(Desc_container())
116 uf.desc[-1].add_paragraph("This will delete the specified alignment tensor data from the current data pipe. If no tensor is specified, all tensors will be deleted.")
117 uf.backend = align_tensor.delete
118 uf.menu_text = "&delete"
119 uf.gui_icon = "oxygen.actions.list-remove"
120 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
121
122
123
124 uf = uf_info.add_uf('align_tensor.display')
125 uf.title = "Display the alignment tensor information in full detail."
126 uf.title_short = "Align tensor display."
127 uf.display = True
128 uf.add_keyarg(
129 name = "tensor",
130 py_type = "str",
131 desc_short = "tensor",
132 desc = "The alignment tensor identification string.",
133 wiz_element_type = 'combo',
134 wiz_combo_iter = align_tensor.get_tensor_ids,
135 wiz_read_only = True,
136 can_be_none = True
137 )
138 uf.desc.append(Desc_container())
139 uf.desc[-1].add_paragraph("This will show all information relating to the alignment tensor, including the different tensor forms:")
140 uf.desc[-1].add_list_element("Probability tensor.")
141 uf.desc[-1].add_list_element("Saupe order matrix.")
142 uf.desc[-1].add_list_element("Alignment tensor.")
143 uf.desc[-1].add_list_element("Magnetic susceptibility tensor.")
144 uf.desc[-1].add_paragraph("All possible tensor parameters and information will also be shown (Eigensystem, GDO, Aa, Ar, R, eta, chi_ax, chi_rh, etc). The printout will be extensive.")
145 uf.desc[-1].add_paragraph("If no tensor is specified, all tensors will be displayed.")
146 uf.backend = align_tensor.display
147 uf.menu_text = "dis&play"
148 uf.gui_icon = "oxygen.actions.document-preview"
149 uf.wizard_height_desc = 400
150 uf.wizard_size = (800, 600)
151 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
152
153
154
155 uf = uf_info.add_uf('align_tensor.fix')
156 uf.title = "Fix all alignment tensors so that they do not change during optimisation."
157 uf.title_short = "Fix alignment tensors."
158 uf.add_keyarg(
159 name = "id",
160 py_type = "str",
161 desc_short = "tensor ID",
162 desc = "The alignment tensor identification string.",
163 wiz_element_type = 'combo',
164 wiz_combo_iter = align_tensor.get_tensor_ids,
165 wiz_read_only = True,
166 can_be_none = True
167 )
168 uf.add_keyarg(
169 name = "fixed",
170 default = True,
171 py_type = "bool",
172 desc_short = "fixed flag",
173 desc = "The flag specifying if the tensors should be fixed or variable."
174 )
175 uf.desc.append(Desc_container())
176 uf.desc[-1].add_paragraph("If the ID string is left unset, then all alignment tensors will be fixed.")
177 uf.backend = align_tensor.fix
178 uf.menu_text = "&fix"
179 uf.gui_icon = "oxygen.status.object-locked"
180 uf.wizard_size = (800, 500)
181 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
182
183
184
185 uf = uf_info.add_uf('align_tensor.init')
186 uf.title = "Initialise an alignment tensor."
187 uf.title_short = "Alignment tensor initialisation."
188 uf.add_keyarg(
189 name = "tensor",
190 py_type = "str",
191 desc_short = "tensor ID",
192 desc = "The optional alignment tensor ID string, required if multiple tensors exist per alignment.",
193 can_be_none = True
194 )
195 uf.add_keyarg(
196 name = "align_id",
197 py_type = "str",
198 desc_short = "alignment ID",
199 desc = "The alignment ID string that the tensor corresponds to.",
200 wiz_element_type = "combo",
201 wiz_combo_iter = align_tensor.get_tensor_ids,
202 wiz_read_only = False
203 )
204 uf.add_keyarg(
205 name = "domain",
206 py_type = "str",
207 desc_short = "domain ID",
208 desc = "The optional domain ID string that the tensor corresponds to.",
209 can_be_none = True
210 )
211 uf.add_keyarg(
212 name = "params",
213 py_type = "num_tuple",
214 desc_short = "alignment tensor parameters",
215 dim = 5,
216 desc = "The alignment tensor data.",
217 wiz_read_only = False,
218 can_be_none = True
219 )
220 uf.add_keyarg(
221 name = "scale",
222 default = 1.0,
223 py_type = "float",
224 desc_short = "scale",
225 desc = "The alignment tensor eigenvalue scaling value."
226 )
227 uf.add_keyarg(
228 name = "angle_units",
229 default = "deg",
230 py_type = "str",
231 desc_short = "angle units",
232 desc = "The units for the angle parameters."
233 )
234 uf.add_keyarg(
235 name = "param_types",
236 default = 2,
237 py_type = "int",
238 desc_short = "parameter types",
239 desc = "A flag to select different parameter combinations.",
240 wiz_element_type = "combo",
241 wiz_combo_choices = [
242 "{Sxx, Syy, Sxy, Sxz, Syz}",
243 "{Szz, Sxx-yy, Sxy, Sxz, Syz}",
244 "{Axx, Ayy, Axy, Axz, Ayz}",
245 "{Azz, Axx-yy, Axy, Axz, Ayz}",
246 "{Axx, Ayy, Axy, Axz, Ayz}",
247 "{Azz, Axx-yy, Axy, Axz, Ayz}",
248 "{Pxx, Pyy, Pxy, Pxz, Pyz}",
249 "{Pzz, Pxx-yy, Pxy, Pxz, Pyz}"
250 ],
251 wiz_combo_data = [
252 0,
253 1,
254 2,
255 3,
256 4,
257 5,
258 6,
259 7
260 ],
261 wiz_read_only = True
262 )
263 uf.add_keyarg(
264 name = "errors",
265 default = False,
266 py_type = "bool",
267 desc_short = "errors flag",
268 desc = "A flag which determines if the alignment tensor data or its errors are being input."
269 )
270 uf.desc.append(Desc_container())
271 uf.desc[-1].add_paragraph("The tensor ID is only required if there are multiple unique tensors per alignment. An example is if internal domain motions cause multiple parts of the molecule to align differently. The tensor ID is optional and in the case of only a single tensor per alignment, the tensor can be identified using the alignment ID instead.")
272 uf.desc[-1].add_paragraph("The alignment tensor parameters should be a tuple of floating point numbers (a list surrounded by round brakets). These correspond to the parameters of the tensor which can be specified by the parameter types whereby the values correspond to:")
273 uf.desc[-1].add_item_list_element("0", "{Sxx, Syy, Sxy, Sxz, Syz} (unitless),")
274 uf.desc[-1].add_item_list_element("1", "{Szz, Sxx-yy, Sxy, Sxz, Syz} (Pales default format),")
275 uf.desc[-1].add_item_list_element("2", "{Axx, Ayy, Axy, Axz, Ayz} (unitless),")
276 uf.desc[-1].add_item_list_element("3", "{Azz, Axx-yy, Axy, Axz, Ayz} (unitless),")
277 uf.desc[-1].add_item_list_element("4", "{Axx, Ayy, Axy, Axz, Ayz} (units of Hertz),")
278 uf.desc[-1].add_item_list_element("5", "{Azz, Axx-yy, Axy, Axz, Ayz} (units of Hertz),")
279 uf.desc[-1].add_item_list_element("6", "{Pxx, Pyy, Pxy, Pxz, Pyz} (unitless),")
280 uf.desc[-1].add_item_list_element("7", "{Pzz, Pxx-yy, Pxy, Pxz, Pyz} (unitless).")
281 uf.desc[-1].add_paragraph("Other formats may be added later. The relationship between the Saupe order matrix S and the alignment tensor A is")
282 uf.desc[-1].add_item_list_element(None, "S = 3/2 A.")
283 uf.desc[-1].add_paragraph("The probability matrix P is related to the alignment tensor A by")
284 uf.desc[-1].add_item_list_element(None, "A = P - 1/3 I,")
285 uf.desc[-1].add_paragraph("where I is the identity matrix. For the alignment tensor to be supplied in Hertz, the bond vectors must all be of equal length.")
286
287 uf.desc.append(Desc_container("Prompt examples"))
288 uf.desc[-1].add_paragraph("To set a rhombic tensor for the domain labelled 'domain 1' with the alignment named 'super media', type one of:")
289 uf.desc[-1].add_prompt("relax> align_tensor.init('domain 1', 'super media', (-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)")
290 uf.desc[-1].add_prompt("relax> align_tensor.init(tensor='domain 1', align_id='super media', params=(-8.6322e-05, -5.5786e-04, -3.1732e-05, 2.2927e-05, 2.8599e-04), param_types=1)")
291 uf.backend = align_tensor.init
292 uf.menu_text = "&init"
293 uf.wizard_height_desc = 370
294 uf.wizard_size = (1000, 750)
295 uf.gui_icon = "relax.align_tensor"
296 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
297
298
299
300 uf = uf_info.add_uf('align_tensor.matrix_angles')
301 uf.title = "Calculate the angles between all alignment tensors."
302 uf.title_short = "Alignment tensor angle calculation."
303 uf.display = True
304 uf.add_keyarg(
305 name = "basis_set",
306 default = "matrix",
307 py_type = "str",
308 desc_short = "basis set",
309 desc = "The basis set to operate with.",
310 wiz_element_type = "combo",
311 wiz_combo_choices = ["Standard inter-matrix angles", "Irreducible 5D {A-2, A-1, A0, A1, A2}", "Unitary 9D {Sxx, Sxy, Sxz, ..., Szz}", "Unitary 5D {Sxx, Syy, Sxy, Sxz, Syz}", "Geometric 5D {Szz, Sxxyy, Sxy, Sxz, Syz}"],
312 wiz_combo_data = ["matrix", "irreducible 5D", "unitary 9D", "unitary 5D", "geometric 5D"]
313 )
314 uf.add_keyarg(
315 name = "tensors",
316 py_type = "str_list",
317 desc_short = "alignment tensor IDs",
318 desc = "A list of the tensors to apply the calculation to. If None, all tensors are used.",
319 wiz_element_type = "combo_list",
320 wiz_combo_iter = align_tensor.get_tensor_ids,
321 wiz_read_only = True,
322 can_be_none = True
323 )
324 uf.add_keyarg(
325 name = "angle_units",
326 default = "deg",
327 py_type = "str",
328 desc_short = "angle units",
329 desc = "The units for the angle parameters, either 'deg' or 'rad'.",
330 wiz_element_type = "combo",
331 wiz_combo_choices = ["Degrees", "Radian"],
332 wiz_combo_data = ["deg", "rad"]
333 )
334 uf.add_keyarg(
335 name = "precision",
336 default = 1,
337 py_type = "int",
338 min = 1,
339 max = 100,
340 desc_short = "printout precision",
341 desc = "The precision of the printed out angles. The number corresponds to the number of figures to print after the decimal point."
342 )
343
344 uf.desc.append(Desc_container())
345 uf.desc[-1].add_paragraph("This will calculate the inter-matrix angles between all loaded alignment tensors for the current data pipe. For the vector basis sets, the matrices are first mapped to vector form and then then the inter-vector angles rather than inter-matrix angles are calculated. The angles are dependent upon the basis set - linear maps produce identical results whereas non-linear maps result in different angles. The basis set can be one of:")
346 uf.desc[-1].add_item_list_element("'matrix'", "The standard inter-matrix angles. This default option is a linear map, hence angles are preserved. The angle is calculated via the arccos of the Euclidean inner product of the alignment matrices in rank-2, 3D form divided by the Frobenius norm ||A||_F of the matrices.")
347 uf.desc[-1].add_item_list_element("'irreducible 5D'", "The inter-tensor vector angles for the irreducible spherical tensor 5D basis set {A-2, A-1, A0, A1, A2}. This is a linear map, hence angles are preserved. These are the spherical harmonic decomposition coefficients.")
348 uf.desc[-1].add_item_list_element("'unitary 9D'", "The inter-tensor vector angles for the unitary 9D basis set {Sxx, Sxy, Sxz, Syx, Syy, Syz, Szx, Szy, Szz}. This is a linear map, hence angles are preserved.")
349 uf.desc[-1].add_item_list_element("'unitary 5D'", "The inter-tensor vector angles for the unitary 5D basis set {Sxx, Syy, Sxy, Sxz, Syz}. This is a non-linear map, hence angles are not preserved.")
350 uf.desc[-1].add_item_list_element("'geometric 5D'", "The inter-tensor vector angles for the geometric 5D basis set {Szz, Sxxyy, Sxy, Sxz, Syz}. This is a non-linear map, hence angles are not preserved. This is also the Pales standard notation.")
351 uf.desc[-1].add_paragraph("The full matrix angle via the Euclidean inner product is defined as")
352 uf.desc[-1].add_verbatim("""\
353 / <A1 , A2> \
354 theta = arccos | ------------- | ,
355 \ ||A1||.||A2|| / \
356 """)
357 uf.desc[-1].add_paragraph("where <a,b> is the Euclidean inner product and ||a|| is the Frobenius norm of the matrix. For the irreducible spherical tensor 5D basis set, the Am components are defined as")
358 uf.desc[-1].add_verbatim("""\
359 / 4pi \ 1/2
360 A0 = | --- | Szz ,
361 \ 5 /
362
363 / 8pi \ 1/2
364 A+/-1 = +/- | --- | (Sxz +/- iSyz) ,
365 \ 15 /
366
367 / 2pi \ 1/2
368 A+/-2 = | --- | (Sxx - Syy +/- 2iSxy) ,
369 \ 15 / \
370 """)
371 uf.desc[-1].add_paragraph("and, for this complex notation, the angle is")
372 uf.desc[-1].add_verbatim("""\
373 / Re(<A1|A2>) \
374 theta = arccos | ----------- | ,
375 \ |A1|.|A2| / \
376 """)
377 uf.desc[-1].add_paragraph("where the inner product is defined as")
378 uf.desc[-1].add_verbatim("""\
379 ___
380 \ 1 2*
381 <A1|A2> = > Am . Am ,
382 /__
383 m=-2,2 \
384 """)
385 uf.desc[-1].add_paragraph("and where Am* = (-1)^m A-m, and the norm is defined as |A1| = Re(sqrt(<A1|A1>)). For all other basis sets whereby the map is real matrix -> real vector, the inter-tensor angle is defined as")
386 uf.desc[-1].add_verbatim("""\
387 / <A1|A2> \
388 theta = arccos | --------- | ,
389 \ |A1|.|A2| / \
390 """)
391 uf.desc[-1].add_paragraph("where the inner product <A1|A2> is simply the vector dot product and |A1| is the vector length.")
392 uf.backend = align_tensor.matrix_angles
393 uf.menu_text = "&matrix_angles"
394 uf.gui_icon = "oxygen.categories.applications-education"
395 uf.wizard_height_desc = 450
396 uf.wizard_size = (1000, 750)
397 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
398
399
400
401 uf = uf_info.add_uf('align_tensor.reduction')
402 uf.title = "Specify that one tensor is a reduction of another."
403 uf.title_short = "Specify tensor reductions."
404 uf.add_keyarg(
405 name = "full_tensor",
406 py_type = "str",
407 desc_short = "full tensor",
408 desc = "The full alignment tensor.",
409 wiz_element_type = 'combo',
410 wiz_combo_iter = align_tensor.get_tensor_ids,
411 wiz_read_only = True
412 )
413 uf.add_keyarg(
414 name = "red_tensor",
415 py_type = "str",
416 desc_short = "reduced tensor",
417 desc = "The reduced alignment tensor.",
418 wiz_element_type = 'combo',
419 wiz_combo_iter = align_tensor.get_tensor_ids,
420 wiz_read_only = True
421 )
422
423 uf.desc.append(Desc_container())
424 uf.desc[-1].add_paragraph("Prior to optimisation of the N-state model and Frame Order theories using alignment tensors, which tensor is a reduction of which other tensor must be specified through this user function.")
425
426 uf.desc.append(Desc_container("Prompt examples"))
427 uf.desc[-1].add_paragraph("To state that the alignment tensor loaded as 'chi3 C-dom' is a reduction of 'chi3 N-dom', type:")
428 uf.desc[-1].add_prompt("relax> align_tensor.reduction(full_tensor='chi3 N-dom', red_tensor='chi3 C-dom')")
429 uf.backend = align_tensor.reduction
430 uf.menu_text = "&reduction"
431 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
432
433
434
435 uf = uf_info.add_uf('align_tensor.set_domain')
436 uf.title = "Set the domain label for the alignment tensor."
437 uf.title_short = "Tensor domain labelling."
438 uf.add_keyarg(
439 name = "tensor",
440 py_type = "str",
441 desc_short = "tensor ID",
442 desc = "The alignment tensor to assign the domain label to.",
443 wiz_element_type = 'combo',
444 wiz_combo_iter = align_tensor.get_tensor_ids,
445 wiz_read_only = True,
446 )
447 uf.add_keyarg(
448 name = "domain",
449 py_type = "str",
450 desc_short = "domain",
451 desc = "The domain label."
452 )
453
454 uf.desc.append(Desc_container())
455 uf.desc[-1].add_paragraph("Prior to optimisation of the N-state model or Frame Order theories, the domain to which each alignment tensor belongs must be specified.")
456
457 uf.desc.append(Desc_container("Prompt examples"))
458 uf.desc[-1].add_paragraph("To link the alignment tensor loaded as 'chi3 C-dom' to the C-terminal domain 'C', type:")
459 uf.desc[-1].add_prompt("relax> align_tensor.set_domain(tensor='chi3 C-dom', domain='C')")
460 uf.backend = align_tensor.set_domain
461 uf.menu_text = "&set_domain"
462 uf.gui_icon = "oxygen.actions.edit-select"
463 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
464
465
466
467 uf = uf_info.add_uf('align_tensor.svd')
468 uf.title = "Calculate the singular values and condition number for all alignment tensors."
469 uf.title_short = "Alignment tensor SVD calculation."
470 uf.display = True
471 uf.add_keyarg(
472 name = "basis_set",
473 default = "irreducible 5D",
474 py_type = "str",
475 desc_short = "basis set",
476 desc = "The basis set to operate with.",
477 wiz_element_type = "combo",
478 wiz_combo_choices = ["Irreducible 5D {A-2, A-1, A0, A1, A2}", "Unitary 9D {Sxx, Sxy, Sxz, ..., Szz}", "Unitary 5D {Sxx, Syy, Sxy, Sxz, Syz}", "Geometric 5D {Szz, Sxxyy, Sxy, Sxz, Syz}"],
479 wiz_combo_data = ["irreducible 5D", "unitary 9D", "unitary 5D", "geometric 5D"]
480 )
481 uf.add_keyarg(
482 name = "tensors",
483 py_type = "str_list",
484 desc_short = "alignment tensor IDs",
485 desc = "A list of the tensors to apply the calculation to. If None, all tensors are used.",
486 wiz_element_type = "combo_list",
487 wiz_combo_iter = align_tensor.get_tensor_ids,
488 wiz_read_only = True,
489 can_be_none = True
490 )
491 uf.add_keyarg(
492 name = "precision",
493 default = 4,
494 py_type = "int",
495 min = 1,
496 max = 100,
497 desc_short = "printout precision",
498 desc = "The precision of the printed out singular values and condition numbers. The number corresponds to the number of figures to print after the decimal point."
499 )
500
501 uf.desc.append(Desc_container())
502 uf.desc[-1].add_paragraph("This will perform a singular value decomposition for all alignment tensors and calculate the condition number. The singular values and condition number are dependent on the basis set - linear maps produce identical results whereas non-linear maps result in different values. The basis set can be one of:")
503 uf.desc[-1].add_item_list_element("'irreducible 5D'", "The irreducible spherical tensor 5D basis set {A-2, A-1, A0, A1, A2}. This is a linear map, hence angles, singular values, and condition number are preserved. These are the spherical harmonic decomposition coefficients.")
504 uf.desc[-1].add_item_list_element("'unitary 9D'", "The unitary 9D basis set {Sxx, Sxy, Sxz, Syx, Syy, Syz, Szx, Szy, Szz}. This is a linear map, hence angles, singular values, and condition number are preserved.")
505 uf.desc[-1].add_item_list_element("'unitary 5D'", "The unitary 5D basis set {Sxx, Syy, Sxy, Sxz, Syz}. This is a non-linear map, hence angles, singular values, and condition number are not preserved.")
506 uf.desc[-1].add_item_list_element("'geometric 5D'", "The geometric 5D basis set {Szz, Sxxyy, Sxy, Sxz, Syz}. This is a non-linear map, hence angles, singular values, and condition number are not preserved. This is also the Pales standard notation.")
507 uf.desc[-1].add_paragraph("If the selected basis set is the default of 'irreducible 5D', the matrix on which SVD will be performed will be:")
508 uf.desc[-1].add_verbatim("""\
509 | A-2(1) A-1(1) A0(1) A1(1) A2(1) |
510 | A-2(2) A-1(2) A0(2) A1(2) A2(2) |
511 | A-2(3) A-1(3) A0(3) A1(3) A2(3) |
512 | . . . . . |
513 | . . . . . |
514 | . . . . . |
515 | A-2(N) A-1(N) A0(N) A1(N) A2(N) |\
516 """)
517 uf.desc[-1].add_paragraph("If the selected basis set is 'unitary 9D', the matrix on which SVD will be performed will be:")
518 uf.desc[-1].add_verbatim("""\
519 | Sxx1 Sxy1 Sxz1 Syx1 Syy1 Syz1 Szx1 Szy1 Szz1 |
520 | Sxx2 Sxy2 Sxz2 Syx2 Syy2 Syz2 Szx2 Szy2 Szz2 |
521 | Sxx3 Sxy3 Sxz3 Syx3 Syy3 Syz3 Szx3 Szy3 Szz3 |
522 | . . . . . . . . . |
523 | . . . . . . . . . |
524 | . . . . . . . . . |
525 | SxxN SxyN SxzN SyxN SyyN SyzN SzxN SzyN SzzN |\
526 """)
527 uf.desc[-1].add_paragraph("Otherwise if the selected basis set is 'unitary 5D', the matrix for SVD is:")
528 uf.desc[-1].add_verbatim("""\
529 | Sxx1 Syy1 Sxy1 Sxz1 Syz1 |
530 | Sxx2 Syy2 Sxy2 Sxz2 Syz2 |
531 | Sxx3 Syy3 Sxy3 Sxz3 Syz3 |
532 | . . . . . |
533 | . . . . . |
534 | . . . . . |
535 | SxxN SyyN SxyN SxzN SyzN |\
536 """)
537 uf.desc[-1].add_paragraph("Or if the selected basis set is 'geometric 5D', the stretching and skewing parameters Szz and Sxx-yy will be used instead and the matrix is:")
538 uf.desc[-1].add_verbatim("""\
539 | Szz1 Sxxyy1 Sxy1 Sxz1 Syz1 |
540 | Szz2 Sxxyy2 Sxy2 Sxz2 Syz2 |
541 | Szz3 Sxxyy3 Sxy3 Sxz3 Syz3 |
542 | . . . . . |
543 | . . . . . |
544 | . . . . . |
545 | SzzN SxxyyN SxyN SxzN SyzN |\
546 """)
547 uf.desc[-1].add_paragraph("For the irreducible spherical tensor basis set, the Am components are defined as")
548 uf.desc[-1].add_verbatim("""\
549 / 4pi \ 1/2
550 A0 = | --- | Szz ,
551 \ 5 /
552
553 / 8pi \ 1/2
554 A+/-1 = +/- | --- | (Sxz +/- iSyz) ,
555 \ 15 /
556
557 / 2pi \ 1/2
558 A+/-2 = | --- | (Sxx - Syy +/- 2iSxy) .
559 \ 15 / \
560 """)
561 uf.desc[-1].add_paragraph("The relationships between the geometric and unitary basis sets are")
562 uf.desc[-1].add_verbatim("""\
563 Szz = - Sxx - Syy,
564 Sxxyy = Sxx - Syy.\
565 """)
566 uf.backend = align_tensor.svd
567 uf.menu_text = "s&vd"
568 uf.gui_icon = "oxygen.categories.applications-education"
569 uf.wizard_height_desc = 500
570 uf.wizard_size = (1000, 750)
571 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
572