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