1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """Module containing the classes for GUI components involving spectral data."""
25
26
27 import wx
28 import wx.lib.buttons
29
30
31 from graphics import fetch_icon
32 from gui.components.base_list import Base_list
33 from gui.string_conv import float_to_gui, gui_to_str, str_to_gui
34 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
35 from lib.compat import u
36 from pipe_control.spectrum import replicated_flags, replicated_ids
37 from status import Status; status = Status()
38 from specific_analyses.relax_disp.data import is_cpmg_exp_type, is_r1rho_exp_type
39 from user_functions.data import Uf_info; uf_info = Uf_info()
40
41
43 """The GUI element for listing loaded spectral data."""
44
45 - def __init__(self, gui=None, parent=None, box=None, id=None, fn_add=None, proportion=0, button_placement='default', noe_flag=False, relax_fit_flag=False, relax_disp_flag=False):
46 """Build the spectral list GUI element.
47
48 @keyword gui: The main GUI object.
49 @type gui: wx.Frame instance
50 @keyword parent: The parent GUI element that this is to be attached to (the panel object).
51 @type parent: wx object
52 @keyword data: The data storage container.
53 @type data: class instance
54 @keyword box: The vertical box sizer to pack this GUI component into.
55 @type box: wx.BoxSizer instance
56 @keyword id: A unique identification string. This is used to register the update method with the GUI user function observer object.
57 @type id: str
58 @keyword fn_add: The function to execute when clicking on the 'Add' button.
59 @type fn_add: func
60 @keyword proportion: The window proportion parameter.
61 @type proportion: bool
62 @keyword button_placement: Override the button visibility and placement. The value of 'default' will leave the buttons at the default setting. The value of 'top' will place the buttons at the top, 'bottom' will place them at the bottom, and None will turn off the buttons.
63 @type button_placement: str or None
64 @keyword noe_flag: A flag which when True will enable the steady-state NOE portions of the wizard.
65 @type noe_flag: bool
66 @keyword relax_fit_flag: A flag which when True will enable the relaxation curve-fitting portions of the wizard.
67 @type relax_fit_flag: bool
68 @keyword relax_disp_flag: A flag which when True will enable the relaxation dispersion portions of the wizard.
69 @type relax_disp_flag: bool
70 """
71
72
73 self.fn_add = fn_add
74 self.noe_flag = noe_flag
75 self.relax_fit_flag = relax_fit_flag
76 self.relax_disp_flag = relax_disp_flag
77
78
79 super(Spectra_list, self).__init__(gui=gui, parent=parent, box=box, id=id, proportion=proportion, button_placement=button_placement)
80
81
83 """Launch the relax_disp.cpmg_setup user function.
84
85 @keyword event: The wx event.
86 @type event: wx event
87 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
88 @type item: None or int
89 """
90
91
92 if item == None:
93 item = self.element.GetFirstSelected()
94
95
96 id = gui_to_str(self.element.GetItemText(item))
97
98
99 frq = None
100 frq_flag = False
101 if hasattr(cdp, 'cpmg_frqs') and id in cdp.cpmg_frqs.keys():
102 frq = cdp.cpmg_frqs[id]
103 frq_flag = True
104
105
106 even = True
107 even_flag = False
108 if hasattr(cdp, 'ncyc_even') and id in cdp.ncyc_even.keys():
109 even = cdp.ncyc_even[id]
110 even_flag = True
111
112
113 if frq_flag:
114 uf_store['relax_disp.cpmg_setup'](spectrum_id=id, cpmg_frq=frq, ncyc_even=even)
115 else:
116 uf_store['relax_disp.cpmg_setup'](spectrum_id=id, ncyc_even=even)
117
118
120 """Launch the relax_disp.exp_type user function.
121
122 @keyword event: The wx event.
123 @type event: wx event
124 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
125 @type item: None or int
126 """
127
128
129 if item == None:
130 item = self.element.GetFirstSelected()
131
132
133 id = gui_to_str(self.element.GetItemText(item))
134
135
136 exp_type = None
137 if hasattr(cdp, 'exp_type') and id in cdp.exp_type.keys():
138 exp_type = cdp.exp_type[id]
139
140
141 if exp_type == None:
142 uf_store['relax_disp.exp_type'](spectrum_id=id)
143 else:
144 uf_store['relax_disp.exp_type'](spectrum_id=id, exp_type=exp_type)
145
146
148 """Launch the relax_disp.relax_time user function.
149
150 @keyword event: The wx event.
151 @type event: wx event
152 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
153 @type item: None or int
154 """
155
156
157 if item == None:
158 item = self.element.GetFirstSelected()
159
160
161 id = gui_to_str(self.element.GetItemText(item))
162
163
164 time = None
165 if hasattr(cdp, 'relax_times') and id in cdp.relax_times.keys():
166 time = cdp.relax_times[id]
167
168
169 if time == None:
170 uf_store['relax_disp.relax_time'](spectrum_id=id)
171 else:
172 uf_store['relax_disp.relax_time'](time=time, spectrum_id=id)
173
174
176 """Launch the relax_disp.spin_lock_field user function.
177
178 @keyword event: The wx event.
179 @type event: wx event
180 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
181 @type item: None or int
182 """
183
184
185 if item == None:
186 item = self.element.GetFirstSelected()
187
188
189 id = gui_to_str(self.element.GetItemText(item))
190
191
192 nu1 = None
193 nu1_flag = False
194 if hasattr(cdp, 'spin_lock_nu1') and id in cdp.spin_lock_nu1.keys():
195 nu1 = cdp.spin_lock_nu1[id]
196 nu1_flag = True
197
198
199 if nu1_flag:
200 uf_store['relax_disp.spin_lock_field'](field=nu1, spectrum_id=id)
201 else:
202 uf_store['relax_disp.spin_lock_field'](spectrum_id=id)
203
204
206 """Launch the relax_fit.relax_time user function.
207
208 @keyword event: The wx event.
209 @type event: wx event
210 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
211 @type item: None or int
212 """
213
214
215 if item == None:
216 item = self.element.GetFirstSelected()
217
218
219 id = gui_to_str(self.element.GetItemText(item))
220
221
222 time = None
223 if hasattr(cdp, 'relax_times') and id in cdp.relax_times.keys():
224 time = cdp.relax_times[id]
225
226
227 if time == None:
228 uf_store['relax_fit.relax_time'](spectrum_id=id)
229 else:
230 uf_store['relax_fit.relax_time'](time=time, spectrum_id=id)
231
232
234 """Launch the spectrometer.frequency user function.
235
236 @keyword event: The wx event.
237 @type event: wx event
238 @keyword item: This is for debugging purposes only, to allow the GUI tests to select items without worrying about OS dependent wxPython bugs.
239 @type item: None or int
240 """
241
242
243 if item == None:
244 item = self.element.GetFirstSelected()
245
246
247 id = gui_to_str(self.element.GetItemText(item))
248
249
250 frq = None
251 if hasattr(cdp, 'spectrometer_frq') and id in cdp.spectrometer_frq:
252 frq = cdp.spectrometer_frq[id]
253
254
255 if frq == None:
256 uf_store['spectrometer.frequency'](id=id)
257 else:
258 uf_store['spectrometer.frequency'](frq=frq, id=id)
259
260
262 """Launch the spectrum.baseplane_rmsd user function.
263
264 @param event: The wx event.
265 @type event: wx event
266 """
267
268
269 item = self.element.GetFirstSelected()
270
271
272 id = gui_to_str(self.element.GetItemText(item))
273
274
275 uf_store['spectrum.baseplane_rmsd'](spectrum_id=id)
276
277
279 """Launch the spectrum.delete user function.
280
281 @param event: The wx event.
282 @type event: wx event
283 """
284
285
286 item = self.element.GetFirstSelected()
287
288
289 if item == -1:
290 id = None
291
292
293 else:
294
295 id = gui_to_str(self.element.GetItemText(item))
296
297
298 uf_store['spectrum.delete'](spectrum_id=id)
299
300
302 """Launch the spectrum.integration_points user function.
303
304 @param event: The wx event.
305 @type event: wx event
306 """
307
308
309 item = self.element.GetFirstSelected()
310
311
312 id = gui_to_str(self.element.GetItemText(item))
313
314
315 uf_store['spectrum.integration_points'](spectrum_id=id)
316
317
319 """Launch the spectrum.replicated user function.
320
321 @param event: The wx event.
322 @type event: wx event
323 """
324
325
326 item = self.element.GetFirstSelected()
327
328
329 id = gui_to_str(self.element.GetItemText(item))
330
331
332 replicates = replicated_ids(id)
333
334
335 if replicates == []:
336 uf_store['spectrum.replicated'](spectrum_ids=id)
337 else:
338 uf_store['spectrum.replicated'](spectrum_ids=replicates)
339
340
342 """Add the dispersion point info to the element.
343
344 This is either the CPMG pulse frequency or the spin-lock field strength. Both share the same column.
345
346 @param index: The column index for the data.
347 @type index: int
348 @return: True if the data exists, False otherwise.
349 @rtype: bool
350 """
351
352
353 self.element.InsertColumn(index, u("\u03BDCPMG (Hz) or Spin-lock \u03BD1 (Hz)"))
354
355
356 if not hasattr(cdp, 'spectrum_ids'):
357 return True
358
359
360 for i in range(len(cdp.spectrum_ids)):
361
362 if hasattr(cdp, 'cpmg_frqs') and cdp.spectrum_ids[i] in cdp.cpmg_frqs.keys():
363 self.element.SetStringItem(i, index, float_to_gui(cdp.cpmg_frqs[cdp.spectrum_ids[i]]))
364
365
366 if hasattr(cdp, 'spin_lock_nu1') and cdp.spectrum_ids[i] in cdp.spin_lock_nu1.keys():
367 self.element.SetStringItem(i, index, float_to_gui(cdp.spin_lock_nu1[cdp.spectrum_ids[i]]))
368
369
370 return True
371
372
374 """Add the experiment type info to the element.
375
376 @param index: The column index for the data.
377 @type index: int
378 @return: True if the data exists, False otherwise.
379 @rtype: bool
380 """
381
382
383 self.element.InsertColumn(index, u("Experiment type"))
384
385
386 if not hasattr(cdp, 'spectrum_ids') or not hasattr(cdp, 'exp_type'):
387 return True
388
389
390 for i in range(len(cdp.spectrum_ids)):
391
392 if cdp.spectrum_ids[i] not in cdp.exp_type.keys():
393 continue
394
395
396 self.element.SetStringItem(i, index, float_to_gui(cdp.exp_type[cdp.spectrum_ids[i]]))
397
398
399 return True
400
401
403 """Add the spectrometer frequency info to the element.
404
405 @param index: The column index for the data.
406 @type index: int
407 @return: True if the frequency data exists, False otherwise.
408 @rtype: bool
409 """
410
411
412 self.element.InsertColumn(index, u("\u03C9H (MHz)"))
413
414
415 if not hasattr(cdp, 'spectrum_ids'):
416 return True
417 if not hasattr(cdp, 'spectrometer_frq') or not len(cdp.spectrometer_frq):
418 return True
419
420
421 for i in range(len(cdp.spectrum_ids)):
422
423 if cdp.spectrum_ids[i] not in cdp.spectrometer_frq:
424 continue
425
426
427 self.element.SetStringItem(i, index, float_to_gui(cdp.spectrometer_frq[cdp.spectrum_ids[i]]/1e6))
428
429
430 return True
431
432
434 """Create the popup menu.
435
436 @keyword id: The spectrum ID string for the row that was clicked on.
437 @type id: str
438 @return: The popup menu.
439 @rtype: list of dict of wxID, str, str, method
440 """
441
442
443 popup_menus = [
444 {
445 'id': wx.NewId(),
446 'text': "Set the &baseplane RMSD",
447 'icon': fetch_icon(uf_info.get_uf('spectrum.baseplane_rmsd').gui_icon),
448 'method': self.action_spectrum_baseplane_rmsd
449 }, {
450 'id': wx.NewId(),
451 'text': "&Delete the peak intensities",
452 'icon': fetch_icon(uf_info.get_uf('spectrum.delete').gui_icon),
453 'method': self.action_spectrum_delete
454 }, {
455 'id': wx.NewId(),
456 'text': "Set the number of integration &points",
457 'icon': fetch_icon(uf_info.get_uf('spectrum.integration_points').gui_icon),
458 'method': self.action_spectrum_integration_points
459 }, {
460 'id': wx.NewId(),
461 'text': "Specify which spectra are &replicated",
462 'icon': fetch_icon(uf_info.get_uf('spectrum.replicated').gui_icon),
463 'method': self.action_spectrum_replicated
464 }
465 ]
466 if self.relax_disp_flag:
467 popup_menus.append({
468 'id': wx.NewId(),
469 'text': "Set the &experiment type",
470 'icon': None,
471 'method': self.action_relax_disp_exp_type
472 })
473 if self.relax_fit_flag:
474 popup_menus.append({
475 'id': wx.NewId(),
476 'text': "Set the relaxation &time",
477 'icon': fetch_icon(uf_info.get_uf('relax_fit.relax_time').gui_icon),
478 'method': self.action_relax_fit_relax_time
479 })
480 if self.relax_disp_flag:
481 popup_menus.append({
482 'id': wx.NewId(),
483 'text': "Set the relaxation &time",
484 'icon': fetch_icon(uf_info.get_uf('relax_disp.relax_time').gui_icon),
485 'method': self.action_relax_disp_relax_time
486 })
487 popup_menus.append({
488 'id': wx.NewId(),
489 'text': "Set the spectrometer &frequency",
490 'icon': fetch_icon("relax.spectrometer"),
491 'method': self.action_spectrometer_frq
492 })
493 if self.relax_disp_flag and is_r1rho_exp_type(id):
494 popup_menus.append({
495 'id': wx.NewId(),
496 'text': u("Set the spin-&lock field strength \u03BD1"),
497 'icon': fetch_icon("relax.relax_disp"),
498 'method': self.action_relax_disp_spin_lock_field
499 })
500 if self.relax_disp_flag and is_cpmg_exp_type(id):
501 popup_menus.append({
502 'id': wx.NewId(),
503 'text': u("Set the &CPMG pulse sequence information"),
504 'icon': fetch_icon("relax.relax_disp"),
505 'method': self.action_relax_disp_cpmg_setup
506 })
507
508
509 return popup_menus
510
511
513 """Add the NOE spectral type info to the element.
514
515 @param index: The column index for the data.
516 @type index: int
517 @return: True if a spectrum type exists, False otherwise.
518 @rtype: bool
519 """
520
521
522 if not hasattr(cdp, 'spectrum_type') or not len(cdp.spectrum_type):
523 return False
524
525
526 self.element.InsertColumn(index, str_to_gui("NOE spectrum type"))
527
528
529 table = {
530 'sat': 'Saturated',
531 'ref': 'Reference'
532 }
533
534
535 if not hasattr(cdp, 'spectrum_ids'):
536 return True
537
538
539 for i in range(len(cdp.spectrum_ids)):
540
541 if cdp.spectrum_ids[i] not in cdp.spectrum_type.keys():
542 continue
543
544
545 self.element.SetStringItem(i, index, str_to_gui(table[cdp.spectrum_type[cdp.spectrum_ids[i]]]))
546
547
548 return True
549
550
552 """Add the relaxation delay time info to the element.
553
554 @param index: The column index for the data.
555 @type index: int
556 @return: True if relaxation times exist, False otherwise.
557 @rtype: bool
558 """
559
560
561 if not hasattr(cdp, 'relax_times') or not len(cdp.relax_times):
562 return False
563
564
565 self.element.InsertColumn(index, str_to_gui("Delay times (s)"))
566
567
568 if not hasattr(cdp, 'spectrum_ids'):
569 return True
570
571
572 for i in range(len(cdp.spectrum_ids)):
573
574 if cdp.spectrum_ids[i] not in cdp.relax_times.keys():
575 continue
576
577
578 self.element.SetStringItem(i, index, float_to_gui(cdp.relax_times[cdp.spectrum_ids[i]]))
579
580
581 return True
582
583
585 """Add the replicated spectra info to the element.
586
587 @param index: The column index for the data.
588 @type index: int
589 @return: True if relaxation times exist, False otherwise.
590 @rtype: bool
591 """
592
593
594 if not hasattr(cdp, 'replicates') or not len(cdp.replicates):
595 return False
596
597
598 repl = replicated_flags()
599
600
601 self.element.InsertColumn(index, str_to_gui("Replicate IDs"))
602
603
604 if not hasattr(cdp, 'spectrum_ids'):
605 return True
606
607
608 for i in range(len(cdp.spectrum_ids)):
609
610 if not repl[cdp.spectrum_ids[i]]:
611 continue
612
613
614 id_list = replicated_ids(cdp.spectrum_ids[i])
615
616
617 text = ''
618 for j in range(len(id_list)):
619
620 text = "%s%s" % (text, id_list[j])
621
622
623 if j < len(id_list)-1:
624 text = "%s, " % text
625
626
627 self.element.SetStringItem(i, index, str_to_gui(text))
628
629
630 return True
631
632
634 """Override the base variables."""
635
636
637 self.title = "Spectra list"
638 self.observer_base_name = "spectra list"
639
640
641 self.columns = []
642
643
644 self.button_placement = 'top'
645 self.button_info = [
646 {
647 'object': 'button_add',
648 'label': ' Add',
649 'icon': fetch_icon('oxygen.actions.list-add-relax-blue', "22x22"),
650 'method': self.fn_add,
651 'tooltip': "Read a spectral data file."
652 }, {
653 'object': 'button_delete',
654 'label': ' Delete',
655 'icon': fetch_icon('oxygen.actions.list-remove', "22x22"),
656 'method': self.action_spectrum_delete,
657 'tooltip': "Delete loaded relaxation data from the relax data store."
658 }
659 ]
660
661
663 """Method called from self.build_element_safe() to update the list data."""
664
665
666 index = 1
667
668
669 self.element.DeleteAllItems()
670 self.element.DeleteAllColumns()
671
672
673 self.element.InsertColumn(0, str_to_gui("Spectrum ID"))
674
675
676 n = 0
677 if hasattr(cdp, 'spectrum_ids'):
678
679 n = len(cdp.spectrum_ids)
680
681
682 for i in range(n):
683 self.element.InsertStringItem(i, str_to_gui(cdp.spectrum_ids[i]))
684
685
686 if self.noe_spectrum_type(index):
687 index += 1
688
689
690 if self.relax_disp_flag and self.add_exp_type(index):
691 index += 1
692
693
694 if self.relax_disp_flag and self.add_frqs(index):
695 index += 1
696
697
698 if self.relax_disp_flag and self.add_disp_point(index):
699 index += 1
700
701
702 if (self.relax_fit_flag or self.relax_disp_flag) and self.relax_times(index):
703 index += 1
704
705
706 if self.replicates(index):
707 index += 1
708