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

Source Code for Module user_functions.pcs

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2002-2004,2007-2013,2015,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 pcs user function definitions.""" 
 24   
 25  # relax module imports. 
 26  from graphics import WIZARD_IMAGE_PATH 
 27  from pipe_control import align_tensor, pcs, pipes 
 28  from pipe_control.mol_res_spin import get_spin_ids 
 29  from user_functions.data import Uf_info; uf_info = Uf_info() 
 30  from user_functions.objects import Desc_container 
 31  from user_functions.wildcards import WILDCARD_GRACE_ALL 
 32   
 33   
 34  # The user function class. 
 35  uf_class = uf_info.add_class('pcs') 
 36  uf_class.title = "Class for handling pseudo-contact shifts." 
 37  uf_class.menu_text = "&pcs" 
 38  uf_class.gui_icon = "relax.align_tensor" 
 39   
 40   
 41  # The pcs.back_calc user function. 
 42  uf = uf_info.add_uf('pcs.back_calc') 
 43  uf.title = "Back calculate the pseudo-contact shifts." 
 44  uf.title_short = "PCS back calculation." 
 45  uf.display = True 
 46  uf.add_keyarg( 
 47      name = "align_id", 
 48      basic_types = ["str"], 
 49      desc_short = "alignment ID string", 
 50      desc = "The alignment ID string.", 
 51      wiz_element_type = 'combo', 
 52      wiz_combo_iter = align_tensor.get_align_ids, 
 53      wiz_read_only = True, 
 54      can_be_none = True 
 55  ) 
 56  # Description. 
 57  uf.desc.append(Desc_container()) 
 58  uf.desc[-1].add_paragraph("This will back calculate the pseudo-contact shifts if the paramagnetic centre, temperature and magnetic field strength has been specified, an alignment tensor is present, and atomic positions have been loaded into the relax data store.") 
 59  uf.backend = pcs.back_calc 
 60  uf.menu_text = "&back_calc" 
 61  uf.gui_icon = "oxygen.categories.applications-education" 
 62  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
 63  uf.wizard_apply_button = False 
 64   
 65   
 66  # The pcs.calc_q_factors user function. 
 67  uf = uf_info.add_uf('pcs.calc_q_factors') 
 68  uf.title = "Calculate the PCS Q factor for the selected spins." 
 69  uf.title_short = "PCS Q factor calculation." 
 70  uf.display = True 
 71  uf.add_keyarg( 
 72      name = "spin_id", 
 73      basic_types = ["str"], 
 74      desc_short = "spin ID string", 
 75      desc = "The spin ID string for restricting to subset of all selected spins.", 
 76      can_be_none = True 
 77  ) 
 78  uf.add_keyarg( 
 79      name = "verbosity", 
 80      default = 1, 
 81      basic_types = ["int"], 
 82      desc_short = "verbosity level", 
 83      desc = "The amount of information to print out.  Set to zero to silence the user function, or one to see all messages." 
 84  ) 
 85  # Description. 
 86  uf.desc.append(Desc_container()) 
 87  uf.desc[-1].add_paragraph("For this to work, the back-calculated PCS data must first be generated by the analysis specific code.  Otherwise a warning will be given.") 
 88  # Prompt examples. 
 89  uf.desc.append(Desc_container("Prompt examples")) 
 90  uf.desc[-1].add_paragraph("To calculate the PCS Q factor for only the spins '@H26', '@H27', and '@H28', type one of:") 
 91  uf.desc[-1].add_prompt("relax> pcs.calc_q_factors('@H26 & @H27 & @H28')") 
 92  uf.desc[-1].add_prompt("relax> pcs.calc_q_factors(spin_id='@H26 & @H27 & @H28')") 
 93  uf.backend = pcs.q_factors 
 94  uf.menu_text = "&calc_q_factors" 
 95  uf.gui_icon = "oxygen.categories.applications-education" 
 96  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
 97  uf.wizard_apply_button = False 
 98   
 99   
100  # The pcs.copy user function. 
101  uf = uf_info.add_uf('pcs.copy') 
102  uf.title = "Copy PCS data from one data pipe to another." 
103  uf.title_short = "PCS copying." 
104  uf.add_keyarg( 
105      name = "pipe_from", 
106      basic_types = ["str"], 
107      desc_short = "source pipe", 
108      desc = "The name of the pipe to copy the PCS data from.", 
109      wiz_element_type = 'combo', 
110      wiz_combo_iter = pipes.pipe_names, 
111      can_be_none = True 
112  ) 
113  uf.add_keyarg( 
114      name = "pipe_to", 
115      basic_types = ["str"], 
116      desc_short = "destination pipe", 
117      desc = "The name of the pipe to copy the PCS data to.", 
118      wiz_element_type = 'combo', 
119      wiz_combo_iter = pipes.pipe_names, 
120      can_be_none = True 
121  ) 
122  uf.add_keyarg( 
123      name = "align_id", 
124      basic_types = ["str"], 
125      desc_short = "alignment ID string", 
126      desc = "The alignment ID string.", 
127      wiz_element_type = 'combo', 
128      wiz_combo_iter = align_tensor.get_align_ids, 
129      wiz_read_only = True, 
130      can_be_none = True 
131  ) 
132  uf.add_keyarg( 
133      name = "back_calc", 
134      default = True, 
135      basic_types = ["bool"], 
136      desc_short = "back-calculated data flag", 
137      desc = "A flag which if True will cause any back-calculated PCSs present to also be copied with the real values and errors." 
138  ) 
139  # Description. 
140  uf.desc.append(Desc_container()) 
141  uf.desc[-1].add_paragraph("This function will copy PCS data from 'pipe_from' to 'pipe_to'.  If align_id is not given then all PCS data will be copied, otherwise only a specific data set will be.") 
142  # Prompt examples. 
143  uf.desc.append(Desc_container("Prompt examples")) 
144  uf.desc[-1].add_paragraph("To copy all PCS data from pipe 'm1' to pipe 'm9', type one of:") 
145  uf.desc[-1].add_prompt("relax> pcs.copy('m1', 'm9')") 
146  uf.desc[-1].add_prompt("relax> pcs.copy(pipe_from='m1', pipe_to='m9')") 
147  uf.desc[-1].add_prompt("relax> pcs.copy('m1', 'm9', None)") 
148  uf.desc[-1].add_prompt("relax> pcs.copy(pipe_from='m1', pipe_to='m9', align_id=None)") 
149  uf.desc[-1].add_paragraph("To copy only the 'Th' PCS data from 'm3' to 'm6', type one of:") 
150  uf.desc[-1].add_prompt("relax> pcs.copy('m3', 'm6', 'Th')") 
151  uf.desc[-1].add_prompt("relax> pcs.copy(pipe_from='m3', pipe_to='m6', align_id='Th')") 
152  uf.backend = pcs.copy 
153  uf.menu_text = "cop&y" 
154  uf.gui_icon = "oxygen.actions.list-add" 
155  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
156   
157   
158  # The pcs.corr_plot user function. 
159  uf = uf_info.add_uf('pcs.corr_plot') 
160  uf.title = "Generate a correlation plot of the measured vs. the back-calculated PCSs." 
161  uf.title_short = "Correlation plot generation." 
162  uf.add_keyarg( 
163      name = "format", 
164      default = "grace", 
165      basic_types = ["str"], 
166      desc_short = "format", 
167      desc = "The format of the plot data.", 
168      wiz_element_type = "combo", 
169      wiz_combo_choices = ["grace"], 
170      wiz_read_only = True, 
171      can_be_none = True 
172  ) 
173  uf.add_keyarg( 
174      name = "title", 
175      basic_types = ["str"], 
176      desc_short = "alternative plot title", 
177      desc = "The title for the plot, overriding the default.", 
178      can_be_none = True 
179  ) 
180  uf.add_keyarg( 
181      name = "subtitle", 
182      basic_types = ["str"], 
183      desc_short = "alternative plot subtitle", 
184      desc = "The subtitle for the plot, overriding the default.", 
185      can_be_none = True 
186  ) 
187  uf.add_keyarg( 
188      name = "file", 
189      default = "pcs_corr_plot.agr", 
190      arg_type = "file sel write", 
191      desc_short = "Grace file name", 
192      desc = "The name of the Grace file to create.", 
193      wiz_filesel_wildcard = WILDCARD_GRACE_ALL, 
194  ) 
195  uf.add_keyarg( 
196      name = "dir", 
197      arg_type = "dir", 
198      desc_short = "directory name", 
199      desc = "The directory name.", 
200      can_be_none = True 
201  ) 
202  uf.add_keyarg( 
203      name = "force", 
204      default = False, 
205      basic_types = ["bool"], 
206      desc_short = "force flag", 
207      desc = "A flag which if True will cause the file to be overwritten." 
208  ) 
209  # Description. 
210  uf.desc.append(Desc_container()) 
211  uf.desc[-1].add_paragraph("Two formats are currently supported.  If format is set to 'grace', then a Grace plot file will be created.  If the format is not set then a plain text list of the measured and back-calculated data will be created.") 
212  # Prompt examples. 
213  uf.desc.append(Desc_container("Prompt examples")) 
214  uf.desc[-1].add_paragraph("To create a Grace plot of the data, type:") 
215  uf.desc[-1].add_prompt("relax> pcs.corr_plot()") 
216  uf.desc[-1].add_paragraph("To create a plain text list of the measured and back-calculated data, type one of:") 
217  uf.desc[-1].add_prompt("relax> pcs.corr_plot(None)") 
218  uf.desc[-1].add_prompt("relax> pcs.corr_plot(format=None)") 
219  uf.backend = pcs.corr_plot 
220  uf.menu_text = "corr_&plot" 
221  uf.gui_icon = "relax.grace_icon" 
222  uf.wizard_size = (800, 500) 
223  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
224  uf.wizard_apply_button = False 
225   
226   
227  # The pcs.delete user function. 
228  uf = uf_info.add_uf('pcs.delete') 
229  uf.title = "Delete the PCS data corresponding to the alignment ID." 
230  uf.title_short = "PCS deletion." 
231  uf.add_keyarg( 
232      name = "align_id", 
233      basic_types = ["str"], 
234      desc_short = "alignment ID string", 
235      desc = "The alignment ID string of the data to delete.", 
236      wiz_element_type = 'combo', 
237      wiz_combo_iter = align_tensor.get_align_ids, 
238      wiz_read_only = True, 
239      can_be_none = True 
240  ) 
241  # Description. 
242  uf.desc.append(Desc_container()) 
243  uf.desc[-1].add_paragraph("This will delete all PCS data associated with the alignment ID in the current data pipe.") 
244  # Prompt examples. 
245  uf.desc.append(Desc_container("Prompt examples")) 
246  uf.desc[-1].add_paragraph("To delete the PCS data corresponding to align_id='PH_gel', type:") 
247  uf.desc[-1].add_prompt("relax> pcs.delete('PH_gel')") 
248  uf.backend = pcs.delete 
249  uf.menu_text = "&delete" 
250  uf.gui_icon = "oxygen.actions.list-remove" 
251  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
252   
253   
254  # The pcs.display user function. 
255  uf = uf_info.add_uf('pcs.display') 
256  uf.title = "Display the PCS data corresponding to the alignment ID." 
257  uf.title_short = "PCS data display." 
258  uf.display = True 
259  uf.add_keyarg( 
260      name = "align_id", 
261      basic_types = ["str"], 
262      desc_short = "alignment ID string", 
263      desc = "The alignment ID string.", 
264      wiz_element_type = 'combo', 
265      wiz_combo_iter = align_tensor.get_align_ids, 
266      wiz_read_only = True 
267  ) 
268  uf.add_keyarg( 
269      name = "bc", 
270      default = False, 
271      basic_types = ["bool"], 
272      desc_short = "back-calculation flag", 
273      desc = "A flag which if set will display the back-calculated rather than measured RDCs." 
274  ) 
275  # Description. 
276  uf.desc.append(Desc_container()) 
277  uf.desc[-1].add_paragraph("This will display all of the PCS data associated with the alignment ID in the current data pipe.") 
278  # Prompt examples. 
279  uf.desc.append(Desc_container("Prompt examples")) 
280  uf.desc[-1].add_paragraph("To display the 'phage' PCS data, type:") 
281  uf.desc[-1].add_prompt("relax> pcs.display('phage')") 
282  uf.backend = pcs.display 
283  uf.menu_text = "di&splay" 
284  uf.gui_icon = "oxygen.actions.document-preview" 
285  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
286   
287   
288  # The pcs.read user function. 
289  uf = uf_info.add_uf('pcs.read') 
290  uf.title = "Read the PCS data from file." 
291  uf.title_short = "PCS data reading." 
292  uf.add_keyarg( 
293      name = "align_id", 
294      basic_types = ["str"], 
295      desc_short = "alignment ID string", 
296      desc = "The alignment ID string.", 
297      wiz_element_type = 'combo', 
298      wiz_combo_iter = align_tensor.get_align_ids 
299  ) 
300  uf.add_keyarg( 
301      name = "file", 
302      arg_type = "file sel read", 
303      desc_short = "file name", 
304      desc = "The name of the file containing the PCS data.", 
305  ) 
306  uf.add_keyarg( 
307      name = "dir", 
308      arg_type = "dir", 
309      desc_short = "directory name", 
310      desc = "The directory where the file is located.", 
311      can_be_none = True 
312  ) 
313  uf.add_keyarg( 
314      name = "spin_id_col", 
315      basic_types = ["int"], 
316      arg_type = "free format", 
317      desc_short = "spin ID column", 
318      desc = "The spin ID string column (an alternative to the mol, res, and spin name and number columns).", 
319      can_be_none = True 
320  ) 
321  uf.add_keyarg( 
322      name = "mol_name_col", 
323      basic_types = ["int"], 
324      arg_type = "free format", 
325      desc_short = "molecule name column", 
326      desc = "The molecule name column (alternative to the spin_id_col).", 
327      can_be_none = True 
328  ) 
329  uf.add_keyarg( 
330      name = "res_num_col", 
331      basic_types = ["int"], 
332      arg_type = "free format", 
333      desc_short = "residue number column", 
334      desc = "The residue number column (alternative to the spin_id_col).", 
335      can_be_none = True 
336  ) 
337  uf.add_keyarg( 
338      name = "res_name_col", 
339      basic_types = ["int"], 
340      arg_type = "free format", 
341      desc_short = "residue name column", 
342      desc = "The residue name column (alternative to the spin_id_col).", 
343      can_be_none = True 
344  ) 
345  uf.add_keyarg( 
346      name = "spin_num_col", 
347      basic_types = ["int"], 
348      arg_type = "free format", 
349      desc_short = "spin number column", 
350      desc = "The spin number column (alternative to the spin_id_col).", 
351      can_be_none = True 
352  ) 
353  uf.add_keyarg( 
354      name = "spin_name_col", 
355      basic_types = ["int"], 
356      arg_type = "free format", 
357      desc_short = "spin name column", 
358      desc = "The spin name column (alternative to the spin_id_col).", 
359      can_be_none = True 
360  ) 
361  uf.add_keyarg( 
362      name = "data_col", 
363      basic_types = ["int"], 
364      arg_type = "free format", 
365      desc_short = "data column", 
366      desc = "The PCS data column.", 
367      can_be_none = True 
368  ) 
369  uf.add_keyarg( 
370      name = "error_col", 
371      basic_types = ["int"], 
372      arg_type = "free format", 
373      desc_short = "error column", 
374      desc = "The experimental error column.", 
375      can_be_none = True 
376  ) 
377  uf.add_keyarg( 
378      name = "sep", 
379      basic_types = ["str"], 
380      arg_type = "free format", 
381      desc_short = "column separator", 
382      desc = "The column separator (the default is white space).", 
383      can_be_none = True 
384  ) 
385  uf.add_keyarg( 
386      name = "spin_id", 
387      basic_types = ["str"], 
388      desc_short = "spin ID string", 
389      desc = "The spin ID string to restrict the loading of data to certain spin subsets.", 
390      can_be_none = True 
391  ) 
392  # Description. 
393  uf.desc.append(Desc_container()) 
394  uf.desc[-1].add_paragraph("This will read PCS data from a file and associate it with an alignment ID, either a new ID or a preexisting one with no PCS data.") 
395  uf.desc[-1].add_paragraph("The spin system can be identified in the file using two different formats.  The first is the spin ID string column which can include the molecule name, the residue name and number, and the spin name and number.  Alternatively the molecule name, residue number and name, and spin number and name columns can be supplied allowing this information to be in separate columns.  Note that the numbering of columns starts at one.  The spin ID can be used to restrict the reading to certain spin types, for example only 15N spins when only residue information is in the file.") 
396  # Prompt examples. 
397  uf.desc.append(Desc_container("Prompt examples")) 
398  uf.desc[-1].add_paragraph("The following commands will read the PCS data out of the file 'Tb.txt' where the columns are separated by the symbol ',', and store the PCSs under the ID 'Tb'.") 
399  uf.desc[-1].add_prompt("relax> pcs.read('Tb', 'Tb.txt', sep=',')") 
400  uf.desc[-1].add_paragraph("To read the 15N and 1H PCSs from the file 'Eu.txt', where the 15N values are in the 4th column and the 1H in the 9th, type both the following:") 
401  uf.desc[-1].add_prompt("relax> pcs.read('Tb', 'Tb.txt', spin_id='@N', res_num_col=1, data_col=4)") 
402  uf.desc[-1].add_prompt("relax> pcs.read('Tb', 'Tb.txt', spin_id='@H', res_num_col=1, data_col=9)") 
403  uf.backend = pcs.read 
404  uf.menu_text = "&read" 
405  uf.gui_icon = "oxygen.actions.document-open" 
406  uf.wizard_size = (900, 600) 
407  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
408   
409   
410  # The pcs.set_errors user function. 
411  uf = uf_info.add_uf('pcs.set_errors') 
412  uf.title = "Set the errors for the PCSs." 
413  uf.title_short = "PCS error setting." 
414  uf.add_keyarg( 
415      name = "align_id", 
416      basic_types = ["str"], 
417      desc_short = "alignment ID string", 
418      desc = "The optional alignment ID string.", 
419      wiz_element_type = 'combo', 
420      wiz_combo_iter = align_tensor.get_align_ids, 
421      wiz_read_only = True, 
422      can_be_none = True 
423  ) 
424  uf.add_keyarg( 
425      name = "spin_id", 
426      arg_type = "spin ID", 
427      desc_short = "spin ID string", 
428      desc = "The optional spin ID string.", 
429      wiz_combo_iter = get_spin_ids, 
430      can_be_none = True 
431  ) 
432  uf.add_keyarg( 
433      name = "sd", 
434      default = 0.1, 
435      basic_types = ["number"], 
436      desc_short = "PCS error (ppm)", 
437      desc = "The PCS standard deviation value in ppm." 
438  ) 
439  # Description. 
440  uf.desc.append(Desc_container()) 
441  uf.desc[-1].add_paragraph("If the PCS errors have not already been read from a PCS data file or if they need to be changed, then the errors can be set via this user function.") 
442  uf.backend = pcs.set_errors 
443  uf.menu_text = "&set_errors" 
444  uf.gui_icon = "oxygen.actions.edit-rename" 
445  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
446   
447   
448  # The pcs.structural_noise user function. 
449  uf = uf_info.add_uf('pcs.structural_noise') 
450  uf.title = "Determine the PCS error due to structural noise via simulation." 
451  uf.title_short = "PCS structural noise simulation." 
452  uf.display = True 
453  uf.add_keyarg( 
454      name = "align_id", 
455      basic_types = ["str"], 
456      desc_short = "alignment ID string", 
457      desc = "The optional alignment ID string.", 
458      wiz_element_type = 'combo', 
459      wiz_combo_iter = align_tensor.get_align_ids, 
460      wiz_read_only = True, 
461      can_be_none = True 
462  ) 
463  uf.add_keyarg( 
464      name = "rmsd", 
465      default = 0.2, 
466      basic_types = ["float"], 
467      desc_short = "structural RMSD", 
468      desc = "The atomic position RMSD, in Angstrom, to randomise the spin positions with for the simulations." 
469  ) 
470  uf.add_keyarg( 
471      name = "sim_num", 
472      default = 1000, 
473      min = 3, 
474      max = 10000000, 
475      basic_types = ["int"], 
476      desc_short = "simulation number N", 
477      desc = "The number of simulations, N, to perform to determine the structural noise component of the PCS errors." 
478  ) 
479  uf.add_keyarg( 
480      name = "file", 
481      arg_type = "file sel write", 
482      desc_short = "Grace file name", 
483      desc = "The optional name of the Grace file to plot the structural errors verses the paramagnetic centre to spin distances.", 
484      wiz_filesel_wildcard = WILDCARD_GRACE_ALL, 
485      can_be_none = True 
486  ) 
487  uf.add_keyarg( 
488      name = "dir", 
489      arg_type = "dir", 
490      desc_short = "directory name", 
491      desc = "The directory name to place the Grace file into.", 
492      can_be_none = True 
493  ) 
494  uf.add_keyarg( 
495      name = "force", 
496      default = False, 
497      basic_types = ["bool"], 
498      desc_short = "force flag", 
499      desc = "A flag which if True will cause the file to be overwritten." 
500  ) 
501  # Description. 
502  uf.desc.append(Desc_container()) 
503  uf.desc[-1].add_paragraph("The analysis of the pseudo-contact shift is influenced by two significant sources of noise - that of the NMR experiment and structural noise from the 3D molecular structure used.  The closer the spin to the paramagnetic centre, the greater the influence of structural noise.  This distance dependence is governed by the equation:") 
504  uf.desc[-1].add_verbatim(""" 
505                   sqrt(3) * abs(delta) * RMSD 
506      sigma_dist = --------------------------- , 
507                              r 
508  """) 
509  uf.desc[-1].add_paragraph("where sigma_dist is the distance component of the structural noise as a standard deviation, delta is the PCS value, RMSD is the atomic position root-mean-square deviation, and r is the paramagnetic centre to spin distance.  When close to the paramagnetic centre, this error source can exceed that of the NMR experiment.  The equation for the angular component of the structural noise is more complicated.  The PCS error is influenced by distance, angle in the alignment frame, and the magnetic susceptibility tensor.") 
510  uf.desc[-1].add_paragraph("For the simulation the following must already be set up in the current data pipe:") 
511  uf.desc[-1].add_list_element("The position of the paramagnetic centre.") 
512  uf.desc[-1].add_list_element("The alignment and magnetic susceptibility tensor.") 
513  uf.desc[-1].add_paragraph("The protocol for the simulation is as follows:") 
514  uf.desc[-1].add_list_element("The lanthanide or paramagnetic centre position will be fixed.  Its motion is assumed to be on the femto- to pico- and nanosecond timescales.  Hence the motion is averaged over the evolution of the PCS and can be ignored.") 
515  uf.desc[-1].add_list_element("The positions of the nuclear spins will be randomised N times.  For each simulation a random unit vector will be generated.  Then a random distance along the unit vector will be generated by sampling from a Gaussian distribution centered at zero, the original spin position, with a standard deviation set to the given RMSD.  Both positive and negative displacements will be used.") 
516  uf.desc[-1].add_list_element("The PCS for the randomised position will be back calculated.") 
517  uf.desc[-1].add_list_element("The PCS standard deviation will be calculated from the N randomised PCS values.") 
518  uf.desc[-1].add_paragraph("The standard deviation will both be stored in the spin container data structure in the relax data store as well as being added to the already present PCS error (using variance addition).  This will then be used in any optimisations involving the PCS.") 
519  uf.desc[-1].add_paragraph("If the alignment ID string is not supplied, the procedure will be applied to the PCS data from all alignments.") 
520  uf.backend = pcs.structural_noise 
521  uf.menu_text = "&structural_noise" 
522  uf.wizard_size = (1000, 700) 
523  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
524  uf.wizard_apply_button = False 
525   
526   
527  # The pcs.weight user function. 
528  uf = uf_info.add_uf('pcs.weight') 
529  uf.title = "Set optimisation weights on the PCS data." 
530  uf.title_short = "PCS weighting." 
531  uf.add_keyarg( 
532      name = "align_id", 
533      basic_types = ["str"], 
534      desc_short = "alignment ID string", 
535      desc = "The alignment ID string.", 
536      wiz_element_type = 'combo', 
537      wiz_combo_iter = align_tensor.get_align_ids, 
538      wiz_read_only = True 
539  ) 
540  uf.add_keyarg( 
541      name = "spin_id", 
542      basic_types = ["str"], 
543      desc_short = "spin ID string", 
544      desc = "The spin ID string.", 
545      can_be_none = True 
546  ) 
547  uf.add_keyarg( 
548      name = "weight", 
549      default = 1.0, 
550      basic_types = ["number"], 
551      desc_short = "weight", 
552      desc = "The weighting value." 
553  ) 
554  # Description. 
555  uf.desc.append(Desc_container()) 
556  uf.desc[-1].add_paragraph("This can be used to force the PCS to contribute more or less to the chi-squared optimisation statistic.  The higher the value, the more importance the PCS will have.") 
557  uf.backend = pcs.weight 
558  uf.menu_text = "wei&ght" 
559  uf.wizard_size = (700, 500) 
560  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
561   
562   
563  # The pcs.write user function. 
564  uf = uf_info.add_uf('pcs.write') 
565  uf.title = "Write the PCS data to file." 
566  uf.title_short = "PCS data writing." 
567  uf.add_keyarg( 
568      name = "align_id", 
569      basic_types = ["str"], 
570      desc_short = "alignment ID string", 
571      desc = "The alignment ID string.", 
572      wiz_element_type = 'combo', 
573      wiz_combo_iter = align_tensor.get_align_ids, 
574      wiz_read_only = True 
575  ) 
576  uf.add_keyarg( 
577      name = "file", 
578      arg_type = "file sel write", 
579      desc_short = "file name", 
580      desc = "The name of the file.", 
581  ) 
582  uf.add_keyarg( 
583      name = "dir", 
584      arg_type = "dir", 
585      desc_short = "directory name", 
586      desc = "The directory name.", 
587      can_be_none = True 
588  ) 
589  uf.add_keyarg( 
590      name = "bc", 
591      default = False, 
592      basic_types = ["bool"], 
593      desc_short = "back-calculation flag", 
594      desc = "A flag which if set will write out the back-calculated rather than measured RDCs." 
595  ) 
596  uf.add_keyarg( 
597      name = "force", 
598      default = False, 
599      basic_types = ["bool"], 
600      desc_short = "force flag", 
601      desc = "A flag which if True will cause the file to be overwritten." 
602  ) 
603  # Description. 
604  uf.desc.append(Desc_container()) 
605  uf.desc[-1].add_paragraph("If no directory name is given, the file will be placed in the current working directory.  The alignment ID is required for selecting which PCS data set will be written to file.") 
606  uf.backend = pcs.write 
607  uf.menu_text = "&write" 
608  uf.gui_icon = "oxygen.actions.document-save" 
609  uf.wizard_size = (800, 600) 
610  uf.wizard_image = WIZARD_IMAGE_PATH + 'align_tensor.png' 
611