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 R1 and R2 analysis frames."""
25
26
27 import wx
28
29
30 from auto_analyses.relax_fit import Relax_fit
31 from data_store import Relax_data_store; ds = Relax_data_store()
32 from graphics import fetch_icon
33 from gui.analyses.base import Base_analysis
34 from gui.analyses.elements.spin_element import Spin_ctrl
35 from gui.analyses.elements.text_element import Text_ctrl
36 from gui.analyses.execute import Execute
37 from gui.base_classes import Container
38 from gui.components.spectrum import Spectra_list
39 from gui.filedialog import RelaxDirDialog
40 from gui.fonts import font
41 from gui.message import error_message, Missing_data
42 from gui.string_conv import gui_to_int, gui_to_str, str_to_gui
43 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
44 from gui.wizards.peak_intensity import Peak_intensity_wizard
45 from pipe_control.mol_res_spin import exists_mol_res_spin_data
46 from pipe_control.pipes import has_bundle, has_pipe
47 from status import Status; status = Status()
48
49
51 """The base class for the R1 and R2 frames."""
52
53
54 analysis_type = None
55 bitmap = None
56 label = None
57
58 - 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, uf_exec=[], data_index=None):
59 """Build the automatic R1 and R2 analysis GUI frame elements.
60
61 @param parent: The parent wx element.
62 @type parent: wx object
63 @keyword id: The unique ID number.
64 @type id: int
65 @keyword pos: The position.
66 @type pos: wx.Size object
67 @keyword size: The size.
68 @type size: wx.Size object
69 @keyword style: The style.
70 @type style: int
71 @keyword name: The name for the panel.
72 @type name: unicode
73 @keyword gui: The main GUI class.
74 @type gui: gui.relax_gui.Main instance
75 @keyword analysis_name: The name of the analysis (the name in the tab part of the notebook).
76 @type analysis_name: str
77 @keyword pipe_name: The name of the data pipe associated with this analysis.
78 @type pipe_name: str
79 @keyword pipe_bundle: The name of the data pipe bundle associated with this analysis.
80 @type pipe_bundle: str
81 @keyword uf_exec: The list of user function on_execute methods returned from the new analysis wizard.
82 @type uf_exec: list of methods
83 @keyword data_index: The index of the analysis in the relax data store (set to None if no data currently exists).
84 @type data_index: None or int
85 """
86
87
88 self.gui = gui
89
90
91 self.init_flag = True
92
93
94 if data_index == None:
95
96 if not has_pipe(pipe_name):
97 self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='relax_fit', bundle=pipe_bundle)
98
99
100 if not has_bundle(pipe_bundle):
101 self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name)
102
103
104 data_index = ds.relax_gui.analyses.add(self.label)
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 ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle
110
111
112 ds.relax_gui.analyses[data_index].frq = ''
113 ds.relax_gui.analyses[data_index].grid_inc = None
114 ds.relax_gui.analyses[data_index].mc_sim_num = None
115 ds.relax_gui.analyses[data_index].save_dir = self.gui.system_cwd_path
116
117
118 self.data = ds.relax_gui.analyses[data_index]
119 self.data_index = data_index
120
121
122 self.observer_register()
123
124
125 super(Auto_rx, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
126
127
144
145
172
173
175 """Assemble the data required for the auto-analysis.
176
177 See the docstring for auto_analyses.relax_fit for details. All data is taken from the relax data store, so data upload from the GUI to there must have been previously performed.
178
179 @return: A container with all the data required for the auto-analysis.
180 @rtype: class instance, list of str
181 """
182
183
184 data = Container()
185 missing = []
186
187
188 data.pipe_name = self.data.pipe_name
189 data.pipe_bundle = self.data.pipe_bundle
190
191
192 frq = gui_to_str(self.field_nmr_frq.GetValue())
193 if frq == None:
194 missing.append('NMR frequency')
195
196
197 data.file_root = '%s.%s' % (self.analysis_type, frq)
198
199
200 if not exists_mol_res_spin_data():
201 missing.append("Sequence data")
202
203
204 if not hasattr(cdp, 'spectrum_ids') or len(cdp.spectrum_ids) < 3:
205 missing.append("Spectral data")
206
207
208 data.inc = gui_to_int(self.grid_inc.GetValue())
209
210
211 data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
212
213
214 data.save_dir = self.data.save_dir
215
216
217 return data, missing
218
219
221 """Construct the right hand box to pack into the main Rx box.
222
223 @return: The right hand box element containing all Rx GUI elements (excluding the bitmap) to pack into the main Rx box.
224 @rtype: wx.BoxSizer instance
225 """
226
227
228 box = wx.BoxSizer(wx.VERTICAL)
229
230
231 self.add_title(box, "%s relaxation analysis" % self.gui_label)
232
233
234 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)
235
236
237 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 %s values will be located in the file '%s.600.out'." % (self.gui_label, self.label.lower()), width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
238
239
240 self.field_results_dir = Text_ctrl(box, self, text="Results directory:", icon=fetch_icon('oxygen.actions.document-open-folder', "16x16"), default=self.data.save_dir, tooltip="The directory in which all automatically created files will be saved.", tooltip_button="Select the results directory.", fn=self.results_directory, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
241
242
243 self.add_spin_systems(box, self)
244
245
246 box.AddSpacer(20)
247 self.peak_intensity = Spectra_list(gui=self.gui, parent=self, box=box, id=str(self.data_index), fn_add=self.peak_wizard_launch, relax_fit_flag=True)
248 box.AddSpacer(10)
249
250
251 box.AddSpacer(10)
252 self.add_buttons(box=box)
253 box.AddSpacer(10)
254
255
256 self.grid_inc = Spin_ctrl(box, self, text="Grid search increments:", default=21, min=1, max=100, tooltip="This is the number of increments per dimension of the grid search performed prior to numerical optimisation.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
257 self.mc_sim_num = Spin_ctrl(box, self, text="Monte Carlo simulation number:", default=500, min=1, max=100000, tooltip="This is the number of Monte Carlo simulations performed for error propagation and analysis. For best results, at least 500 is recommended.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
258
259
260 box.AddSpacer(30)
261 box.AddStretchSpacer()
262
263
264 self.button_exec_relax = self.add_execute_analysis(box, self.execute)
265
266
267 return box
268
269
271 """Unregister the spin count from the user functions."""
272
273
274 self.observer_register(remove=True)
275
276
277 self.peak_intensity.delete()
278
279
280 if hasattr(self, 'peak_wizard'):
281 self.peak_wizard.Destroy()
282 del self.peak_wizard
283
284
285 if hasattr(self, 'missing_data'):
286 self.missing_data.Destroy()
287 del self.missing_data
288
289
330
331
352
353
355 """Launch the peak loading wizard.
356
357 @param event: The wx event.
358 @type event: wx event
359 """
360
361
362 if hasattr(self, 'peak_wizard'):
363 self.peak_wizard.Destroy()
364
365
366 self.peak_wizard = Peak_intensity_wizard(relax_fit=True)
367
368
370 """The results directory selection.
371
372 @param event: The wx event.
373 @type event: wx event
374 """
375
376
377 dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue())
378
379
380 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
381
382 return
383
384
385 path = gui_to_str(dialog.get_path())
386 if not path:
387 return
388
389
390 self.data.save_dir = path
391
392
393 self.field_results_dir.SetValue(str_to_gui(path))
394
395
397 """Launch the relax_fit.select_model user function.
398
399 @keyword event: The wx event.
400 @type event: wx event
401 """
402
403
404 uf_store['relax_fit.select_model'](wx_wizard_modal=True)
405
406
408 """Synchronise the analysis frame and the relax data store, both ways.
409
410 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.
411
412 @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.
413 @type upload: bool
414 """
415
416
417 if upload:
418 self.data.frq = gui_to_str(self.field_nmr_frq.GetValue())
419 else:
420 self.field_nmr_frq.SetValue(str_to_gui(self.data.frq))
421
422
423 if upload:
424 self.data.grid_inc = gui_to_int(self.grid_inc.GetValue())
425 elif hasattr(self.data, 'grid_inc'):
426 self.grid_inc.SetValue(int(self.data.grid_inc))
427
428
429 if upload:
430 self.data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
431 elif hasattr(self.data, 'mc_sim_num'):
432 self.mc_sim_num.SetValue(int(self.data.mc_sim_num))
433
434
435 if upload:
436 self.data.save_dir = gui_to_str(self.field_results_dir.GetValue())
437 else:
438 self.field_results_dir.SetValue(str_to_gui(self.data.save_dir))
439
440
441
443 """The Rx analysis execution object."""
444
453