Package user_functions :: Module align_tensor
[hide private]
[frames] | no frames]

Source Code for Module user_functions.align_tensor

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2007-2012,2014,2019 Edward d'Auvergne                         # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """The align_tensor user function definitions.""" 
 24   
 25  # relax module imports. 
 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  # The user function class. 
 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  # The align_tensor.copy user function. 
 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  # Description. 
 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  # Prompt examples. 
 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 = "&copy" 
 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  # The align_tensor.delete user function. 
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  # Description. 
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  # The align_tensor.display user function. 
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  # The align_tensor.fix user function. 
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  # The align_tensor.init user function. 
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  # Prompt examples. 
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  # The align_tensor.matrix_angles user function. 
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  # Description. 
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("""\ 
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("""\ 
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("""\ 
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("""\ 
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("""\ 
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  # The align_tensor.reduction user function. 
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  # Description. 
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  # Prompt examples. 
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  # The align_tensor.set_domain user function. 
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  # Description. 
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  # Prompt examples. 
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  # The align_tensor.svd user function. 
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  # Description. 
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("""\ 
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