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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["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 basic_types = ["number"],
214 container_types = ["tuple"],
215 dim = (5,),
216 desc_short = "alignment tensor parameters",
217 desc = "The alignment tensor data.",
218 wiz_read_only = False,
219 can_be_none = True
220 )
221 uf.add_keyarg(
222 name = "scale",
223 default = 1.0,
224 basic_types = ["float"],
225 desc_short = "scale",
226 desc = "The alignment tensor eigenvalue scaling value."
227 )
228 uf.add_keyarg(
229 name = "angle_units",
230 default = "deg",
231 basic_types = ["str"],
232 desc_short = "angle units",
233 desc = "The units for the angle parameters."
234 )
235 uf.add_keyarg(
236 name = "param_types",
237 default = 2,
238 basic_types = ["int"],
239 desc_short = "parameter types",
240 desc = "A flag to select different parameter combinations.",
241 wiz_element_type = "combo",
242 wiz_combo_choices = [
243 "{Sxx, Syy, Sxy, Sxz, Syz}",
244 "{Szz, Sxx-yy, Sxy, Sxz, Syz}",
245 "{Axx, Ayy, Axy, Axz, Ayz}",
246 "{Azz, Axx-yy, Axy, Axz, Ayz}",
247 "{Axx, Ayy, Axy, Axz, Ayz}",
248 "{Azz, Axx-yy, Axy, Axz, Ayz}",
249 "{Pxx, Pyy, Pxy, Pxz, Pyz}",
250 "{Pzz, Pxx-yy, Pxy, Pxz, Pyz}"
251 ],
252 wiz_combo_data = [
253 0,
254 1,
255 2,
256 3,
257 4,
258 5,
259 6,
260 7
261 ],
262 wiz_read_only = True
263 )
264 uf.add_keyarg(
265 name = "errors",
266 default = False,
267 basic_types = ["bool"],
268 desc_short = "errors flag",
269 desc = "A flag which determines if the alignment tensor data or its errors are being input."
270 )
271 uf.desc.append(Desc_container())
272 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.")
273 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:")
274 uf.desc[-1].add_item_list_element("0", "{Sxx, Syy, Sxy, Sxz, Syz} (unitless),")
275 uf.desc[-1].add_item_list_element("1", "{Szz, Sxx-yy, Sxy, Sxz, Syz} (Pales default format),")
276 uf.desc[-1].add_item_list_element("2", "{Axx, Ayy, Axy, Axz, Ayz} (unitless),")
277 uf.desc[-1].add_item_list_element("3", "{Azz, Axx-yy, Axy, Axz, Ayz} (unitless),")
278 uf.desc[-1].add_item_list_element("4", "{Axx, Ayy, Axy, Axz, Ayz} (units of Hertz),")
279 uf.desc[-1].add_item_list_element("5", "{Azz, Axx-yy, Axy, Axz, Ayz} (units of Hertz),")
280 uf.desc[-1].add_item_list_element("6", "{Pxx, Pyy, Pxy, Pxz, Pyz} (unitless),")
281 uf.desc[-1].add_item_list_element("7", "{Pzz, Pxx-yy, Pxy, Pxz, Pyz} (unitless).")
282 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")
283 uf.desc[-1].add_item_list_element(None, "S = 3/2 A.")
284 uf.desc[-1].add_paragraph("The probability matrix P is related to the alignment tensor A by")
285 uf.desc[-1].add_item_list_element(None, "A = P - 1/3 I,")
286 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.")
287
288 uf.desc.append(Desc_container("Prompt examples"))
289 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:")
290 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)")
291 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)")
292 uf.backend = align_tensor.init
293 uf.menu_text = "&init"
294 uf.wizard_height_desc = 370
295 uf.wizard_size = (1000, 750)
296 uf.gui_icon = "relax.align_tensor"
297 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
298
299
300
301 uf = uf_info.add_uf('align_tensor.matrix_angles')
302 uf.title = "Calculate the angles between all alignment tensors."
303 uf.title_short = "Alignment tensor angle calculation."
304 uf.display = True
305 uf.add_keyarg(
306 name = "basis_set",
307 default = "matrix",
308 basic_types = ["str"],
309 desc_short = "basis set",
310 desc = "The basis set to operate with.",
311 wiz_element_type = "combo",
312 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}"],
313 wiz_combo_data = ["matrix", "irreducible 5D", "unitary 9D", "unitary 5D", "geometric 5D"]
314 )
315 uf.add_keyarg(
316 name = "tensors",
317 basic_types = ["str"],
318 container_types = ["list"],
319 dim = (None,),
320 desc_short = "alignment tensor IDs",
321 desc = "A list of the tensors to apply the calculation to. If None, all tensors are used.",
322 wiz_element_type = "combo_list",
323 wiz_combo_iter = align_tensor.get_tensor_ids,
324 wiz_read_only = True,
325 can_be_none = True
326 )
327 uf.add_keyarg(
328 name = "angle_units",
329 default = "deg",
330 basic_types = ["str"],
331 desc_short = "angle units",
332 desc = "The units for the angle parameters, either 'deg' or 'rad'.",
333 wiz_element_type = "combo",
334 wiz_combo_choices = ["Degrees", "Radian"],
335 wiz_combo_data = ["deg", "rad"]
336 )
337 uf.add_keyarg(
338 name = "precision",
339 default = 1,
340 basic_types = ["int"],
341 min = 1,
342 max = 100,
343 desc_short = "printout precision",
344 desc = "The precision of the printed out angles. The number corresponds to the number of figures to print after the decimal point."
345 )
346
347 uf.desc.append(Desc_container())
348 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:")
349 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.")
350 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.")
351 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.")
352 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.")
353 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.")
354 uf.desc[-1].add_paragraph("The full matrix angle via the Euclidean inner product is defined as")
355 uf.desc[-1].add_verbatim(r"""\
356 / <A1 , A2> \
357 theta = arccos | ------------- | ,
358 \ ||A1||.||A2|| / \
359 """)
360 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")
361 uf.desc[-1].add_verbatim(r"""\
362 / 4pi \ 1/2
363 A0 = | --- | Szz ,
364 \ 5 /
365
366 / 8pi \ 1/2
367 A+/-1 = +/- | --- | (Sxz +/- iSyz) ,
368 \ 15 /
369
370 / 2pi \ 1/2
371 A+/-2 = | --- | (Sxx - Syy +/- 2iSxy) ,
372 \ 15 / \
373 """)
374 uf.desc[-1].add_paragraph("and, for this complex notation, the angle is")
375 uf.desc[-1].add_verbatim(r"""\
376 / Re(<A1|A2>) \
377 theta = arccos | ----------- | ,
378 \ |A1|.|A2| / \
379 """)
380 uf.desc[-1].add_paragraph("where the inner product is defined as")
381 uf.desc[-1].add_verbatim(r"""\
382 ___
383 \ 1 2*
384 <A1|A2> = > Am . Am ,
385 /__
386 m=-2,2 \
387 """)
388 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")
389 uf.desc[-1].add_verbatim(r"""\
390 / <A1|A2> \
391 theta = arccos | --------- | ,
392 \ |A1|.|A2| / \
393 """)
394 uf.desc[-1].add_paragraph("where the inner product <A1|A2> is simply the vector dot product and |A1| is the vector length.")
395 uf.backend = align_tensor.matrix_angles
396 uf.menu_text = "&matrix_angles"
397 uf.gui_icon = "oxygen.categories.applications-education"
398 uf.wizard_height_desc = 450
399 uf.wizard_size = (1000, 750)
400 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
401
402
403
404 uf = uf_info.add_uf('align_tensor.reduction')
405 uf.title = "Specify that one tensor is a reduction of another."
406 uf.title_short = "Specify tensor reductions."
407 uf.add_keyarg(
408 name = "full_tensor",
409 basic_types = ["str"],
410 desc_short = "full tensor",
411 desc = "The full alignment tensor.",
412 wiz_element_type = 'combo',
413 wiz_combo_iter = align_tensor.get_tensor_ids,
414 wiz_read_only = True
415 )
416 uf.add_keyarg(
417 name = "red_tensor",
418 basic_types = ["str"],
419 desc_short = "reduced tensor",
420 desc = "The reduced alignment tensor.",
421 wiz_element_type = 'combo',
422 wiz_combo_iter = align_tensor.get_tensor_ids,
423 wiz_read_only = True
424 )
425
426 uf.desc.append(Desc_container())
427 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.")
428
429 uf.desc.append(Desc_container("Prompt examples"))
430 uf.desc[-1].add_paragraph("To state that the alignment tensor loaded as 'chi3 C-dom' is a reduction of 'chi3 N-dom', type:")
431 uf.desc[-1].add_prompt("relax> align_tensor.reduction(full_tensor='chi3 N-dom', red_tensor='chi3 C-dom')")
432 uf.backend = align_tensor.reduction
433 uf.menu_text = "&reduction"
434 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
435
436
437
438 uf = uf_info.add_uf('align_tensor.set_domain')
439 uf.title = "Set the domain label for the alignment tensor."
440 uf.title_short = "Tensor domain labelling."
441 uf.add_keyarg(
442 name = "tensor",
443 basic_types = ["str"],
444 desc_short = "tensor ID",
445 desc = "The alignment tensor to assign the domain label to.",
446 wiz_element_type = 'combo',
447 wiz_combo_iter = align_tensor.get_tensor_ids,
448 wiz_read_only = True,
449 )
450 uf.add_keyarg(
451 name = "domain",
452 basic_types = ["str"],
453 desc_short = "domain",
454 desc = "The domain label."
455 )
456
457 uf.desc.append(Desc_container())
458 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.")
459
460 uf.desc.append(Desc_container("Prompt examples"))
461 uf.desc[-1].add_paragraph("To link the alignment tensor loaded as 'chi3 C-dom' to the C-terminal domain 'C', type:")
462 uf.desc[-1].add_prompt("relax> align_tensor.set_domain(tensor='chi3 C-dom', domain='C')")
463 uf.backend = align_tensor.set_domain
464 uf.menu_text = "&set_domain"
465 uf.gui_icon = "oxygen.actions.edit-select"
466 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
467
468
469
470 uf = uf_info.add_uf('align_tensor.svd')
471 uf.title = "Calculate the singular values and condition number for all alignment tensors."
472 uf.title_short = "Alignment tensor SVD calculation."
473 uf.display = True
474 uf.add_keyarg(
475 name = "basis_set",
476 default = "irreducible 5D",
477 basic_types = ["str"],
478 desc_short = "basis set",
479 desc = "The basis set to operate with.",
480 wiz_element_type = "combo",
481 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}"],
482 wiz_combo_data = ["irreducible 5D", "unitary 9D", "unitary 5D", "geometric 5D"]
483 )
484 uf.add_keyarg(
485 name = "tensors",
486 basic_types = ["str"],
487 container_types = ["list"],
488 dim = (5,),
489 desc_short = "alignment tensor IDs",
490 desc = "A list of the tensors to apply the calculation to. If None, all tensors are used.",
491 wiz_element_type = "combo_list",
492 wiz_combo_iter = align_tensor.get_tensor_ids,
493 wiz_read_only = True,
494 can_be_none = True
495 )
496 uf.add_keyarg(
497 name = "precision",
498 default = 4,
499 basic_types = ["int"],
500 min = 1,
501 max = 100,
502 desc_short = "printout precision",
503 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."
504 )
505
506 uf.desc.append(Desc_container())
507 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:")
508 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.")
509 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.")
510 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.")
511 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.")
512 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:")
513 uf.desc[-1].add_verbatim("""\
514 | A-2(1) A-1(1) A0(1) A1(1) A2(1) |
515 | A-2(2) A-1(2) A0(2) A1(2) A2(2) |
516 | A-2(3) A-1(3) A0(3) A1(3) A2(3) |
517 | . . . . . |
518 | . . . . . |
519 | . . . . . |
520 | A-2(N) A-1(N) A0(N) A1(N) A2(N) |\
521 """)
522 uf.desc[-1].add_paragraph("If the selected basis set is 'unitary 9D', the matrix on which SVD will be performed will be:")
523 uf.desc[-1].add_verbatim("""\
524 | Sxx1 Sxy1 Sxz1 Syx1 Syy1 Syz1 Szx1 Szy1 Szz1 |
525 | Sxx2 Sxy2 Sxz2 Syx2 Syy2 Syz2 Szx2 Szy2 Szz2 |
526 | Sxx3 Sxy3 Sxz3 Syx3 Syy3 Syz3 Szx3 Szy3 Szz3 |
527 | . . . . . . . . . |
528 | . . . . . . . . . |
529 | . . . . . . . . . |
530 | SxxN SxyN SxzN SyxN SyyN SyzN SzxN SzyN SzzN |\
531 """)
532 uf.desc[-1].add_paragraph("Otherwise if the selected basis set is 'unitary 5D', the matrix for SVD is:")
533 uf.desc[-1].add_verbatim("""\
534 | Sxx1 Syy1 Sxy1 Sxz1 Syz1 |
535 | Sxx2 Syy2 Sxy2 Sxz2 Syz2 |
536 | Sxx3 Syy3 Sxy3 Sxz3 Syz3 |
537 | . . . . . |
538 | . . . . . |
539 | . . . . . |
540 | SxxN SyyN SxyN SxzN SyzN |\
541 """)
542 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:")
543 uf.desc[-1].add_verbatim("""\
544 | Szz1 Sxxyy1 Sxy1 Sxz1 Syz1 |
545 | Szz2 Sxxyy2 Sxy2 Sxz2 Syz2 |
546 | Szz3 Sxxyy3 Sxy3 Sxz3 Syz3 |
547 | . . . . . |
548 | . . . . . |
549 | . . . . . |
550 | SzzN SxxyyN SxyN SxzN SyzN |\
551 """)
552 uf.desc[-1].add_paragraph("For the irreducible spherical tensor basis set, the Am components are defined as")
553 uf.desc[-1].add_verbatim(r"""\
554 / 4pi \ 1/2
555 A0 = | --- | Szz ,
556 \ 5 /
557
558 / 8pi \ 1/2
559 A+/-1 = +/- | --- | (Sxz +/- iSyz) ,
560 \ 15 /
561
562 / 2pi \ 1/2
563 A+/-2 = | --- | (Sxx - Syy +/- 2iSxy) .
564 \ 15 / \
565 """)
566 uf.desc[-1].add_paragraph("The relationships between the geometric and unitary basis sets are")
567 uf.desc[-1].add_verbatim("""\
568 Szz = - Sxx - Syy,
569 Sxxyy = Sxx - Syy.\
570 """)
571 uf.backend = align_tensor.svd
572 uf.menu_text = "s&vd"
573 uf.gui_icon = "oxygen.categories.applications-education"
574 uf.wizard_height_desc = 500
575 uf.wizard_size = (1000, 750)
576 uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png'
577