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 NOE analysis frames."""
26
27
28 from os import sep
29 import sys
30 import wx
31
32
33 from auto_analyses.noe import NOE_calc
34 from data import Relax_data_store; ds = Relax_data_store()
35 from generic_fns.mol_res_spin import are_spins_named, exists_mol_res_spin_data
36 from generic_fns.pipes import has_bundle, has_pipe
37 from status import Status; status = Status()
38
39
40 from gui.analyses.base import Base_analysis, Spectral_error_type_page
41 from gui.analyses.elements import Text_ctrl
42 from gui.analyses.execute import Execute
43 from gui.analyses.results_analysis import color_code_noe
44 from gui.base_classes import Container
45 from gui.components.spectrum import Spectra_list
46 from gui.filedialog import RelaxDirDialog
47 from gui.message import error_message, Missing_data, Question
48 from gui.misc import protected_exec
49 from gui import paths
50 from gui.string_conv import gui_to_str, str_to_gui
51 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
52 from gui.wizard import Wiz_window
53
54
55
57 """The base class for the noe frames."""
58
59
60 analysis_type = None
61 bitmap = [paths.ANALYSIS_IMAGE_PATH+"noe_200x200.png",
62 paths.IMAGE_PATH+'noe.png']
63 label = None
64
65 - def __init__(self, parent, id=-1, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=524288, name='scrolledpanel', gui=None, analysis_name=None, pipe_name=None, pipe_bundle=None, data_index=None):
66 """Build the automatic NOE analysis GUI frame elements.
67
68 @param parent: The parent wx element.
69 @type parent: wx object
70 @keyword id: The unique ID number.
71 @type id: int
72 @keyword pos: The position.
73 @type pos: wx.Size object
74 @keyword size: The size.
75 @type size: wx.Size object
76 @keyword style: The style.
77 @type style: int
78 @keyword name: The name for the panel.
79 @type name: unicode
80 @keyword gui: The main GUI class.
81 @type gui: gui.relax_gui.Main instance
82 @keyword analysis_name: The name of the analysis (the name in the tab part of the notebook).
83 @type analysis_name: str
84 @keyword pipe_name: The name of the data pipe associated with this analysis.
85 @type pipe_name: str
86 @keyword pipe_bundle: The name of the data pipe bundle associated with this analysis.
87 @type pipe_bundle: str
88 @keyword data_index: The index of the analysis in the relax data store (set to None if no data currently exists).
89 @type data_index: None or int
90 """
91
92
93 self.gui = gui
94
95
96 self.init_flag = True
97
98
99 if data_index == None:
100
101 if not has_pipe(pipe_name):
102 self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='noe', bundle=pipe_bundle)
103
104
105 if not has_bundle(pipe_bundle):
106 self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name)
107
108
109 data_index = ds.relax_gui.analyses.add('NOE')
110
111
112 ds.relax_gui.analyses[data_index].analysis_name = analysis_name
113 ds.relax_gui.analyses[data_index].pipe_name = pipe_name
114 ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle
115
116
117 ds.relax_gui.analyses[data_index].frq = ''
118 ds.relax_gui.analyses[data_index].save_dir = self.gui.launch_dir
119
120
121 self.data = ds.relax_gui.analyses[data_index]
122 self.data_index = data_index
123
124
125 self.observer_register()
126
127
128 super(Auto_noe, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
129
130
132 """Activate or deactivate certain elements of the analysis in response to the execution lock."""
133
134
135 enable = False
136 if not status.exec_lock.locked():
137 enable = True
138
139
140 wx.CallAfter(self.field_nmr_frq.Enable, enable)
141 wx.CallAfter(self.field_results_dir.Enable, enable)
142 wx.CallAfter(self.spin_systems.Enable, enable)
143 wx.CallAfter(self.peak_intensity.Enable, enable)
144 wx.CallAfter(self.button_exec_relax.Enable, enable)
145
146
148 """Assemble the data required for the Auto_noe class.
149
150 @return: A container with all the data required for the auto-analysis.
151 @rtype: class instance, list of str
152 """
153
154
155 data = Container()
156 missing = []
157
158
159 data.pipe_name = self.data.pipe_name
160 data.pipe_bundle = self.data.pipe_bundle
161
162
163 frq = gui_to_str(self.field_nmr_frq.GetValue())
164 if frq == None:
165 missing.append('NMR frequency')
166
167
168 data.file_root = 'noe.%s' % frq
169
170
171 data.save_dir = self.data.save_dir
172
173
174 if not exists_mol_res_spin_data():
175 missing.append("Sequence data")
176
177
178 if not hasattr(cdp, 'spectrum_ids') or len(cdp.spectrum_ids) < 2:
179 missing.append("Spectral data")
180
181
182 return data, missing
183
184
186 """Construct the right hand box to pack into the main NOE box.
187
188 @return: The right hand box element containing all NOE GUI elements (excluding the bitmap) to pack into the main Rx box.
189 @rtype: wx.BoxSizer instance
190 """
191
192
193 box = wx.BoxSizer(wx.VERTICAL)
194
195
196 self.add_title(box, "Setup for steady-state NOE analysis")
197
198
199 Text_ctrl(box, self, text="The data pipe bundle:", default=self.data.pipe_bundle, tooltip="This is the data pipe bundle associated with this analysis.", editable=False, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
200
201
202 self.field_nmr_frq = Text_ctrl(box, self, text="NMR frequency label [MHz]", default=self.data.frq, tooltip="This label is added to the output files. For example if the label is '600', the NOE values will be located in the file 'noe.600.out'.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
203
204
205 self.field_results_dir = Text_ctrl(box, self, text="Results directory", icon=paths.icon_16x16.open_folder, default=self.data.save_dir, fn=self.results_directory, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
206
207
208 self.add_spin_systems(box, self)
209
210
211 box.AddSpacer(40)
212 self.peak_intensity = Spectra_list(gui=self.gui, parent=self, box=box, id=str(self.data_index), fn_add=self.peak_wizard)
213
214
215 box.AddSpacer(30)
216 box.AddStretchSpacer()
217
218
219 self.button_exec_relax = self.add_execute_relax(box, self.execute)
220
221
222 return box
223
224
226 """Unregister the spin count from the user functions."""
227
228
229 self.observer_register(remove=True)
230
231
232 self.peak_intensity.delete()
233
234
275
276
297
298
300 """Launch the NOE peak loading wizard.
301
302 @param event: The wx event.
303 @type event: wx event
304 """
305
306
307 wx.BeginBusyCursor()
308
309
310 self.wizard = Wiz_window(parent=self.gui, size_x=1000, size_y=750, title="Set up the NOE peak intensities")
311 self.page_indices = {}
312
313
314 if not are_spins_named():
315
316 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?"
317
318
319 if status.show_gui and Question(msg, title="Incomplete setup", size=(450, 250), default=True).ShowModal() == wx.ID_YES:
320 page = uf_store['spin.name'].create_page(self.wizard, sync=True)
321 self.page_indices['read'] = self.wizard.add_page(page, proceed_on_error=False)
322
323
324
325 self.page_intensity = uf_store['spectrum.read_intensities'].create_page(self.wizard, sync=True)
326 self.page_indices['read'] = self.wizard.add_page(self.page_intensity, skip_button=True, proceed_on_error=False)
327
328
329 self.page_error_type = Spectral_error_type_page(parent=self.wizard, height_desc=520)
330 self.page_indices['err_type'] = self.wizard.add_page(self.page_error_type, apply_button=False)
331 self.wizard.set_seq_next_fn(self.page_indices['err_type'], self.wizard_page_after_error_type)
332
333
334 page = uf_store['spectrum.replicated'].create_page(self.wizard, sync=True)
335 self.page_indices['repl'] = self.wizard.add_page(page, skip_button=True, proceed_on_error=False)
336 self.wizard.set_seq_next_fn(self.page_indices['repl'], self.wizard_page_after_repl)
337 page.on_display_post = self.wizard_update_repl
338
339
340 page = uf_store['spectrum.baseplane_rmsd'].create_page(self.wizard, sync=True)
341 self.page_indices['rmsd'] = self.wizard.add_page(page, skip_button=True, proceed_on_error=False)
342 self.wizard.set_seq_next_fn(self.page_indices['rmsd'], self.wizard_page_after_rmsd)
343 page.on_display_post = self.wizard_update_rmsd
344
345
346 page = uf_store['spectrum.integration_points'].create_page(self.wizard, sync=True)
347 self.page_indices['pts'] = self.wizard.add_page(page, skip_button=True, proceed_on_error=False)
348 page.on_display_post = self.wizard_update_pts
349
350
351 page = uf_store['noe.spectrum_type'].create_page(self.wizard, sync=True)
352 self.page_indices['spectrum_type'] = self.wizard.add_page(page, skip_button=False, proceed_on_error=False)
353 page.on_display_post = self.wizard_update_spectrum_type
354
355
356 if wx.IsBusy():
357 wx.EndBusyCursor()
358
359
360 self.wizard.run()
361
362
364 """The results directory selection.
365
366 @param event: The wx event.
367 @type event: wx event
368 """
369
370
371 dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue())
372
373
374 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
375
376 return
377
378
379 path = gui_to_str(dialog.get_path())
380 if not path:
381 return
382
383
384 self.data.save_dir = path
385
386
387 self.field_results_dir.SetValue(str_to_gui(path))
388
389
391 """Synchronise the noe analysis frame and the relax data store, both ways.
392
393 This method allows the frame information to be uploaded into the relax data store, or for the information in the relax data store to be downloaded by the frame.
394
395 @keyword upload: A flag which if True will cause the frame to send data to the relax data store. If False, data will be downloaded from the relax data store to update the frame.
396 @type upload: bool
397 """
398
399
400 if upload:
401 self.data.frq = gui_to_str(self.field_nmr_frq.GetValue())
402 else:
403 self.field_nmr_frq.SetValue(str_to_gui(self.data.frq))
404
405
406 if upload:
407 self.data.save_dir = gui_to_str(self.field_results_dir.GetValue())
408 else:
409 self.field_results_dir.SetValue(str_to_gui(self.data.save_dir))
410
411
413 """Set the page after the error type choice.
414
415 @return: The index of the next page, which is the current page index plus one.
416 @rtype: int
417 """
418
419
420 if self.page_error_type.selection == 'rmsd':
421 return self.page_indices['rmsd']
422
423
424 elif self.page_error_type.selection == 'repl':
425 return self.page_indices['repl']
426
427
429 """Set the page that comes after the spectrum.replicated page.
430
431 @return: The index of the next page.
432 @rtype: int
433 """
434
435
436 int_method = gui_to_str(self.page_intensity.uf_args['int_method'].GetValue())
437 if int_method != 'height':
438 return self.page_indices['pts']
439
440
441 else:
442 return self.page_indices['spectrum_type']
443
444
446 """Set the page that comes after the spectrum.baseplane_rmsd page.
447
448 @return: The index of the next page.
449 @rtype: int
450 """
451
452
453 int_method = gui_to_str(self.page_intensity.uf_args['int_method'].GetValue())
454 if int_method != 'height':
455 return self.page_indices['pts']
456
457
458 else:
459 return self.page_indices['spectrum_type']
460
461
463 """Update the spectrum.replicated page based on previous data."""
464
465
466 page = self.wizard.get_page(self.page_indices['read'])
467
468
469 id = page.uf_args['spectrum_id'].GetValue()
470
471
472 page = self.wizard.get_page(self.page_indices['pts'])
473 page.uf_args['spectrum_id'].SetValue(id)
474
475
477 """Update the spectrum.replicated page based on previous data."""
478
479
480 page = self.wizard.get_page(self.page_indices['read'])
481
482
483 id = page.uf_args['spectrum_id'].GetValue()
484
485
486 page = self.wizard.get_page(self.page_indices['repl'])
487 page.uf_args['spectrum_ids'].SetValue(value=id, index=0)
488
489
491 """Update the spectrum.baseplane_rmsd page based on previous data."""
492
493
494 page = self.wizard.get_page(self.page_indices['read'])
495
496
497 id = page.uf_args['spectrum_id'].GetValue()
498
499
500 page = self.wizard.get_page(self.page_indices['rmsd'])
501 page.uf_args['spectrum_id'].SetValue(id)
502
503
505 """Update the noe.spectrum_type page based on previous data."""
506
507
508 page = self.wizard.get_page(self.page_indices['read'])
509
510
511 id = page.uf_args['spectrum_id'].GetValue()
512
513
514 page = self.wizard.get_page(self.page_indices['spectrum_type'])
515 page.uf_args['spectrum_id'].SetValue(id)
516
517
518
520 """The NOE analysis execution object."""
521
540