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