1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 """Module containing the base class for the automatic R1 and R2 analysis frames."""
26
27
28 from os import sep
29 import wx
30 from wx.lib import scrolledpanel
31
32
33 from graphics import WIZARD_IMAGE_PATH
34 from gui.fonts import font
35 from gui.message import Question
36 from gui.misc import format_table
37 from gui.string_conv import gui_to_str
38 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
39 from gui.wizards.wiz_objects import Wiz_page, Wiz_window
40 from pipe_control.mol_res_spin import are_spins_named
41 from specific_analyses.relax_disp.disp_data import has_cpmg_exp_type, has_r1rho_exp_type
42 from status import Status; status = Status()
43 from user_functions.data import Uf_info; uf_info = Uf_info()
44 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
45
46
48 """The wizard for loading peak intensity data."""
49
50 - def __init__(self, parent=None, size_x=1000, size_y=750, title="Peak intensity loading wizard", noe=False, relax_fit=False, relax_disp=False):
51 """Set up the peak intensity loading wizard.
52
53 @keyword parent: The parent window.
54 @type parent: wx.Window instance
55 @keyword size_x: The width of the wizard.
56 @type size_x: int
57 @keyword size_y: The height of the wizard.
58 @type size_y: int
59 @keyword title: The title of the wizard dialog.
60 @type title: str
61 @keyword noe: A flag which when True will enable the steady-state NOE portions of the wizard.
62 @type noe: bool
63 @keyword relax_fit: A flag which when True will enable the relaxation curve-fitting portions of the wizard.
64 @type relax_fit: bool
65 @keyword relax_disp: A flag which when True will enable the relaxation dispersion portions of the wizard.
66 @type relax_disp: bool
67 """
68
69
70 self.noe_flag = noe
71 self.relax_fit_flag = relax_fit
72 self.relax_disp_flag = relax_disp
73
74
75 app = wx.GetApp()
76 self.gui = app.gui
77
78
79 Wiz_window.__init__(self, parent=self.gui, size_x=size_x, size_y=size_y, title=title, style=wx.DEFAULT_DIALOG_STYLE)
80
81
82 wx.BeginBusyCursor()
83
84
85 self.page_indices = {}
86
87
88 if not are_spins_named():
89
90 msg = "No spins have been named. Please use the spin.name user function first, otherwise it is unlikely that any data will be loaded from the peak intensity file.\n\nThis message can be ignored if the generic file format is used and spin names have not been specified. Would you like to name the spins already loaded into the relax data store?"
91
92
93 if (status.show_gui and Question(msg, title="Incomplete setup", size=(450, 250), default=True).ShowModal() == wx.ID_YES) or not status.show_gui:
94 page = uf_store['spin.name'].create_page(self, sync=True)
95 self.page_indices['name'] = self.add_page(page, proceed_on_error=False)
96
97
98 self.page_intensity = uf_store['spectrum.read_intensities'].create_page(self, sync=True)
99 self.page_indices['read'] = self.add_page(self.page_intensity, skip_button=True, proceed_on_error=False)
100
101
102 self.page_error_type = Spectral_error_type_page(parent=self, height_desc=520)
103 self.page_indices['err_type'] = self.add_page(self.page_error_type, apply_button=False)
104 self.set_seq_next_fn(self.page_indices['err_type'], self.wizard_page_after_error_type)
105
106
107 page = uf_store['spectrum.replicated'].create_page(self, sync=True)
108 self.page_indices['repl'] = self.add_page(page, skip_button=True, proceed_on_error=False)
109 self.set_seq_next_fn(self.page_indices['repl'], self.wizard_page_after_repl)
110 page.on_init = self.wizard_update_repl
111
112
113 page = uf_store['spectrum.baseplane_rmsd'].create_page(self, sync=True)
114 self.page_indices['rmsd'] = self.add_page(page, skip_button=True, proceed_on_error=False)
115 self.set_seq_next_fn(self.page_indices['rmsd'], self.wizard_page_after_rmsd)
116 page.on_init = self.wizard_update_rmsd
117
118
119 page = uf_store['spectrum.integration_points'].create_page(self, sync=True)
120 self.page_indices['pts'] = self.add_page(page, skip_button=True, proceed_on_error=False)
121 page.on_init = self.wizard_update_pts
122
123
124 if self.noe_flag:
125
126 page = uf_store['noe.spectrum_type'].create_page(self, sync=True)
127 self.page_indices['spectrum_type'] = self.add_page(page, skip_button=False, proceed_on_error=False)
128 page.on_display_post = self.wizard_update_noe_spectrum_type
129
130
131 if self.relax_fit_flag:
132
133 page = uf_store['relax_fit.relax_time'].create_page(self, sync=True)
134 self.page_indices['relax_time'] = self.add_page(page, skip_button=False, proceed_on_error=False)
135 page.on_init = self.wizard_update_relax_fit_relax_time
136
137
138 if self.relax_disp_flag:
139
140 page = uf_store['relax_disp.exp_type'].create_page(self, sync=True)
141 self.page_indices['exp_type'] = self.add_page(page, skip_button=True, proceed_on_error=False)
142 page.on_init = self.wizard_update_relax_disp_exp_type
143
144
145 page = uf_store['spectrometer.frequency'].create_page(self, sync=True)
146 self.page_indices['spectrometer_frequency'] = self.add_page(page, skip_button=True, proceed_on_error=False)
147 page.on_init = self.wizard_update_spectrometer_frequency
148
149
150 page = uf_store['relax_disp.relax_time'].create_page(self, sync=True)
151 self.page_indices['relax_time'] = self.add_page(page, skip_button=True, proceed_on_error=False)
152 page.on_init = self.wizard_update_relax_disp_relax_time
153 self.set_seq_next_fn(self.page_indices['relax_time'], self.wizard_page_after_relax_time)
154
155
156 page = uf_store['relax_disp.cpmg_frq'].create_page(self, sync=True)
157 self.page_indices['cpmg_frq'] = self.add_page(page, skip_button=True, proceed_on_error=False)
158 page.on_init = self.wizard_update_relax_disp_cpmg_frq
159 self.set_seq_next_fn(self.page_indices['cpmg_frq'], self.wizard_page_after_cpmg_frq)
160
161
162 page = uf_store['relax_disp.spin_lock_field'].create_page(self, sync=True)
163 self.page_indices['spin_lock_field'] = self.add_page(page, skip_button=True, proceed_on_error=False)
164 page.on_init = self.wizard_update_relax_disp_spin_lock_field
165
166
167 page = uf_store['relax_disp.spin_lock_offset'].create_page(self, sync=True)
168 self.page_indices['spin_lock_offset'] = self.add_page(page, skip_button=True, proceed_on_error=False)
169 page.on_init = self.wizard_update_relax_disp_spin_lock_offset
170
171
172 if wx.IsBusy():
173 wx.EndBusyCursor()
174
175
176 self.run()
177
178
180 """Set the page after the CPMG frequency page.
181
182 This should either be the R1rho page if R1rho experiment types exist, or terminate the wizard.
183
184
185 @return: The index of the next page, which is the current page index plus one.
186 @rtype: int
187 """
188
189
190 if has_r1rho_exp_type():
191 return self.page_indices['spin_lock_field']
192
193
194 else:
195 return self._num_pages + 1
196
197
199 """Set the page after the error type choice.
200
201 @return: The index of the next page, which is the current page index plus one.
202 @rtype: int
203 """
204
205
206 if self.page_error_type.selection == 'rmsd':
207 return self.page_indices['rmsd']
208
209
210 elif self.page_error_type.selection == 'repl':
211 return self.page_indices['repl']
212
213
215 """Set the page after the relaxation time period page.
216
217 This should either be the CPMG page if CPMG experiment types exist, the R1rho page if R1rho experiment types exist, or terminate the wizard.
218
219
220 @return: The index of the next page, which is the current page index plus one.
221 @rtype: int
222 """
223
224
225 if has_cpmg_exp_type():
226 return self.page_indices['cpmg_frq']
227
228
229 elif has_r1rho_exp_type():
230 return self.page_indices['spin_lock_field']
231
232
233 else:
234 return self._num_pages + 1
235
236
238 """Set the page that comes after the spectrum.replicated page.
239
240 @return: The index of the next page.
241 @rtype: int
242 """
243
244
245 int_method = gui_to_str(self.page_intensity.uf_args['int_method'].GetValue())
246 if int_method != 'height' and self.page_error_type.selection == 'rmsd':
247 return self.page_indices['pts']
248
249
250 elif self.noe_flag:
251 return self.page_indices['spectrum_type']
252
253
254 elif self.relax_fit_flag:
255 return self.page_indices['relax_time']
256
257
258 elif self.relax_disp_flag:
259 return self.page_indices['exp_type']
260
261
262 else:
263 return self._num_pages + 1
264
265
267 """Set the page that comes after the spectrum.baseplane_rmsd page.
268
269 @return: The index of the next page.
270 @rtype: int
271 """
272
273
274 int_method = gui_to_str(self.page_intensity.uf_args['int_method'].GetValue())
275 if int_method != 'height':
276 return self.page_indices['pts']
277
278
279 elif self.noe_flag:
280 return self.page_indices['spectrum_type']
281
282
283 elif self.relax_fit_flag:
284 return self.page_indices['relax_time']
285
286
287 elif self.relax_disp_flag:
288 return self.page_indices['exp_type']
289
290
291 else:
292 return self._num_pages + 1
293
294
296 """Update the spectrum ID on the page specified by the key based on previous data.
297
298 @keyword page_key: The key of the page to update.
299 @type page_key: str
300 @keyword arg_key: The key of the page argument to change to the spectrum ID.
301 @type arg_key: str
302 @keyword index: The index for list type structures.
303 @type index: None or int
304 """
305
306
307 page = self.get_page(self.page_indices['read'])
308
309
310 id = page.uf_args['spectrum_id'].GetValue()
311
312
313 if isinstance(id, list):
314
315 if id == []:
316 return
317
318
319 id = id[0]
320
321
322 if id == 'auto':
323
324 id = 'Z_A0'
325
326
327 page = self.get_page(self.page_indices[page_key])
328 if index == None:
329 page.uf_args[arg_key].SetValue(id)
330 else:
331 page.uf_args[arg_key].SetValue(value=id, index=index)
332
333
335 """Update the noe.spectrum_type page based on previous data."""
336
337
338 self.wizard_update_ids(page_key='spectrum_type')
339
340
342 """Update the spectrum.replicated page based on previous data."""
343
344
345 self.wizard_update_ids(page_key='pts')
346
347
349 """Update the relax_disp.cpmg_frq page based on previous data."""
350
351
352 self.wizard_update_ids(page_key='cpmg_frq')
353
354
356 """Update the relax_disp.exp_type page based on previous data."""
357
358
359 self.wizard_update_ids(page_key='exp_type')
360
361
363 """Update the relax_disp.relax_time page based on previous data."""
364
365
366 self.wizard_update_ids(page_key='relax_time')
367
368
370 """Update the relax_disp.spin_lock_field page based on previous data."""
371
372
373 self.wizard_update_ids(page_key='spin_lock_field')
374
375
377 """Update the relax_disp.spin_lock_offset page based on previous data."""
378
379
380 self.wizard_update_ids(page_key='spin_lock_offset')
381
382
384 """Update the relax_fit.relax_time page based on previous data."""
385
386
387 self.wizard_update_ids(page_key='relax_time')
388
389
391 """Update the spectrum.replicated page based on previous data."""
392
393
394 self.wizard_update_ids(page_key='repl', arg_key='spectrum_ids', index=0)
395
396
398 """Update the spectrum.baseplane_rmsd page based on previous data."""
399
400
401 self.wizard_update_ids(page_key='rmsd')
402
403
405 """Update the spectrometer.frequency page based on previous data."""
406
407
408 self.wizard_update_ids(page_key='spectrometer_frequency', arg_key='id')
409
410
411
413 """The peak intensity reading wizard page for specifying the type of error to be used."""
414
415
416 image_path = WIZARD_IMAGE_PATH + 'spectrum' + sep + 'spectrum_200.png'
417 title = "Specify the type of error to be used"
418 main_text = "Please specify from where the peak intensity errors will be obtained. The is required for the execution of the spectrum.error_analysis user function which will be postponed until after clicking on the 'Execute relax' button at the end of the automatic analysis page. To understand how the errors will be propagated and analysed, the main parts of the spectrum.error_analysis user function description are given below."
419 uf_path = ['spectrum', 'error_analysis']
420
421 - def _on_select(self, event):
422 """Handle the radio button switching.
423
424 @param event: The wx event.
425 @type event: wx event
426 """
427
428
429 button = event.GetEventObject()
430
431
432 if button == self.radio_rmsd:
433 self.selection = 'rmsd'
434 elif button == self.radio_repl:
435 self.selection = 'repl'
436
437
438 - def add_contents(self, sizer):
439 """Add the specific GUI elements.
440
441 @param sizer: A sizer object.
442 @type sizer: wx.Sizer instance
443 """
444
445
446 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
447 sizer.Add(sizer2, 1, wx.ALL|wx.EXPAND, 0)
448
449
450 sizer.AddStretchSpacer()
451
452
453 sizer2.AddStretchSpacer()
454
455
456 sizer_radio = wx.BoxSizer(wx.VERTICAL)
457 sizer2.Add(sizer_radio, 1, wx.ALL|wx.EXPAND, 0)
458
459
460 self.radio_rmsd = wx.RadioButton(self, -1, "Baseplane RMSD.", style=wx.RB_GROUP)
461 sizer_radio.Add(self.radio_rmsd, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
462
463
464 sizer_radio.AddSpacer(10)
465
466
467 self.radio_repl = wx.RadioButton(self, -1, "Replicated spectra.")
468 sizer_radio.Add(self.radio_repl, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
469
470
471 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_rmsd)
472 self.Bind(wx.EVT_RADIOBUTTON, self._on_select, self.radio_repl)
473
474
475 sizer2.AddStretchSpacer(3)
476
477
478 sizer.AddStretchSpacer()
479
480
481 self.selection = 'rmsd'
482
483
484 - def add_desc(self, sizer, max_y=520):
485 """Add the description to the dialog.
486
487 @param sizer: A sizer object.
488 @type sizer: wx.Sizer instance
489 @keyword max_y: The maximum height, in number of pixels, for the description.
490 @type max_y: int
491 """
492
493
494 spacing = 15
495
496
497 sizer.AddSpacer(5)
498 sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0)
499 sizer.AddSpacer(5)
500
501
502 panel = scrolledpanel.ScrolledPanel(self, -1, name="desc")
503
504
505 panel_sizer = wx.BoxSizer(wx.VERTICAL)
506
507
508 tot_y = 0
509 text_elements = []
510 text_types = []
511
512
513 text = wx.StaticText(panel, -1, self.main_text, style=wx.TE_MULTILINE)
514 text.SetFont(font.normal)
515 text.Wrap(self._main_size - 20)
516 text_elements.append(text)
517 text_types.append('title')
518
519
520 x, y = text.GetSizeTuple()
521 tot_y += y
522 tot_y += spacing
523
524
525 uf_data = uf_info.get_uf('spectrum.error_analysis')
526
527
528 if uf_data.desc != None:
529
530 for i in range(len(uf_data.desc)):
531
532 desc = uf_data.desc[i]
533
534
535 if desc.get_title() == 'Prompt examples':
536 continue
537
538
539 for type, element in desc.element_loop(title=True):
540
541 text = ''
542 if isinstance(element, str):
543 text = element
544
545
546 if type == 'table':
547 text = format_table(uf_tables.get_table(element))
548
549
550 elif type == 'list':
551
552 for j in range(len(element)):
553 text += " - %s\n" % element[j]
554
555
556 elif type == 'item list':
557
558 for j in range(len(element)):
559
560 if element[j][0] in [None, '']:
561 text += " %s\n" % element[j][1]
562 else:
563 text += " %s: %s\n" % (element[j][0], element[j][1])
564
565
566 text_obj = wx.StaticText(panel, -1, text, style=wx.TE_MULTILINE)
567
568
569 if type == 'title':
570 text_obj.SetFont(font.subtitle)
571 elif type == 'paragraph':
572 text_obj.SetFont(font.normal)
573 elif type in ['table', 'verbatim']:
574 text_obj.SetFont(font.modern_small)
575 else:
576 text_obj.SetFont(font.normal)
577
578
579 if type in ['paragraph', 'list', 'item list']:
580 text_obj.Wrap(self._main_size - 20)
581
582
583 x, y = text_obj.GetSizeTuple()
584 tot_y += y
585
586
587 tot_y += spacing
588
589
590 if i != 0 and type == 'title':
591 tot_y += spacing
592
593
594 text_elements.append(text_obj)
595 text_types.append(type)
596
597
598 tot_y -= spacing
599 tot_y += 20
600
601
602 if tot_y > max_y:
603 panel.SetInitialSize((self._main_size, max_y))
604
605
606 else:
607 panel.SetInitialSize((self._main_size, tot_y))
608
609
610 n = len(text_elements)
611 for i in range(n):
612
613 if i > 1 and text_types[i] == 'title':
614 panel_sizer.AddSpacer(spacing)
615
616
617 panel_sizer.Add(text_elements[i], 0, wx.ALIGN_LEFT, 0)
618
619
620 if i != n - 1:
621 panel_sizer.AddSpacer(spacing)
622
623
624 panel.SetSizer(panel_sizer)
625 panel.SetAutoLayout(1)
626 panel.SetupScrolling(scroll_x=False, scroll_y=True)
627 sizer.Add(panel, 0, wx.ALL|wx.EXPAND)
628
629
630 sizer.AddSpacer(5)
631 sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0)
632 sizer.AddSpacer(5)
633