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