1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the analysis selection wizard."""
24
25
26 from os import sep
27 from time import asctime, localtime
28 import wx
29 from wx.lib import buttons
30
31
32 from graphics import ANALYSIS_IMAGE_PATH, IMAGE_PATH, WIZARD_IMAGE_PATH
33 from gui.input_elements.value import Value
34 from gui.misc import bitmap_setup
35 from gui.string_conv import gui_to_str, str_to_gui
36 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
37 from gui.wizards.wiz_objects import Wiz_page, Wiz_window
38 from lib.text.gui import r1, r2
39
40
42 """The analysis selection wizard."""
43
45 """Run through the analysis selection wizard, returning the results.
46
47 @return: The analysis type, analysis name, data pipe name, data pipe bundle name, and user function on_execute method list.
48 @rtype: tuple of str
49 """
50
51
52 wx.Yield()
53 wx.BeginBusyCursor()
54
55
56 self.wizard = Wiz_window(size_x=1000, size_y=700, title='Analysis selection wizard')
57
58
59 self.wizard.TEXT_FINISH = " Start"
60
61
62 self.new_page = New_analysis_page(self.wizard)
63 self.wizard.add_page(self.new_page, apply_button=False)
64 self.wizard.set_seq_next_fn(0, self.wizard_page_after_analysis)
65
66
67 self.pipe_page = Data_pipe_page(self.wizard, height_desc=400)
68 self.wizard.add_page(self.pipe_page, apply_button=False)
69
70
71 if wx.IsBusy():
72 wx.EndBusyCursor()
73
74
75 setup = self.wizard.run(modal=True)
76 if setup != wx.ID_OK:
77 return
78
79
80 return self.get_data()
81
82
84 """Assemble and return the analysis type, analysis name, and pipe name.
85
86 @return: The analysis type, analysis name, data pipe name, data pipe bundle name, and list of user function on_execute methods.
87 @rtype: str, str, str, str, list of methods
88 """
89
90
91 analysis_type = gui_to_str(self.wizard.analysis_type)
92 analysis_name = gui_to_str(self.new_page.analysis_name.GetValue())
93 pipe_name = gui_to_str(self.pipe_page.pipe_name.GetValue())
94 pipe_bundle = gui_to_str(self.pipe_page.pipe_bundle.GetValue())
95
96
97 uf_exec = []
98
99
100 return analysis_type, analysis_name, pipe_name, pipe_bundle, uf_exec
101
102
104 """Set the page after the data pipe setup.
105
106 @return: The index of the next page, which is the current page index plus one.
107 @rtype: int
108 """
109
110
111 analysis_name = gui_to_str(self.new_page.analysis_name.GetValue())
112
113
114 return 1
115
116
117
118 -class Data_pipe_page(Wiz_page):
119 """The panel for setting the data pipe name."""
120
121
122 image_path = WIZARD_IMAGE_PATH + 'pipe.png'
123 main_text = "Select the name of the data pipe used at the start of the analysis and the name of the data pipe bundle to be associated with this analysis. All data in relax is kept within a special structure known as the relax data store. This store is composed of multiple data pipes, each being associated with a specific analysis type. Data pipe bundles are simple groupings of the pipes within the data store and each analysis tab is coupled to a specific bundle.\n\nSimple analyses such as the steady-state NOE and the %s and %s curve-fitting will be located within a single data pipe. More complex analyses such as the automated model-free analysis will be spread across multiple data pipes, internally created by forking the original data pipe which holds the input data, all grouped together within a single bundle.\n\nThe initialisation of a new analysis will call the pipe.create user function with the pipe name and pipe bundle as given below." % (r1, r2)
124 title = 'Data pipe set up'
125
126 - def add_contents(self, sizer):
127 """Add the specific GUI elements (dummy method).
128
129 @param sizer: A sizer object.
130 @type sizer: wx.Sizer instance
131 """
132
133
134 self.pipe_name = Value(name='pipe_name', parent=self, value_type='str', sizer=sizer, desc="The starting data pipe for the analysis:", divider=self._div_left, height_element=self.height_element)
135
136
137 self.pipe_bundle = Value(name='pipe_bundle', parent=self, value_type='str', sizer=sizer, desc="The data pipe bundle:", divider=self._div_left, height_element=self.height_element)
138
139
140 sizer.AddStretchSpacer(3)
141
142
143 - def on_display(self):
144 """Update the pipe name."""
145
146
147 name = "%s (%s)" % (self.parent.analysis_type, asctime(localtime()))
148
149
150 self.pipe_name.SetValue(str_to_gui("origin - %s" % name))
151 self.pipe_bundle.SetValue(str_to_gui(name))
152
153
154
188
189
190
191 -class New_analysis_page(Wiz_page):
192 """The panel for selection of the new analysis."""
193
194
195 image_path = IMAGE_PATH + "relax.gif"
196 main_text = "A number of automatic analyses to be preformed using relax in GUI mode. Although not as flexible or powerful as the prompt/scripting modes, this provides a quick and easy setup and execution for a number of analysis types. These currently include the calculation of the steady-state NOE, the exponential curve-fitting for the %s and %s relaxation rates, and for a full and automatic model-free analysis using the d'Auvergne and Gooley, 2008b protocol. All analyses perform error propagation using the gold standard Monte Calro simulations. Please select from one of the following analysis types:" % (r1, r2)
197 title = "Start a new analysis"
198
199 - def add_artwork(self, sizer):
200 """Add the artwork to the dialog.
201
202 @param sizer: A sizer object.
203 @type sizer: wx.Sizer instance
204 """
205
206
207 sizer2 = wx.BoxSizer(wx.VERTICAL)
208
209
210 sizer2.AddSpacer(30)
211
212
213 self.image = wx.StaticBitmap(self, -1, bitmap_setup(self.image_path))
214 sizer2.Add(self.image, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 0)
215
216
217 sizer.Add(sizer2)
218
219
220 sizer.AddSpacer(self.art_spacing)
221
222
224 """The widget of analysis buttons.
225
226 @param box: A sizer object.
227 @type box: wx.BoxSizer instance
228 """
229
230
231 size = (170, 170)
232
233
234 self._select_flag = False
235
236
237 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
238 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
239
240
241 self.button_ids = {'noe': wx.NewId(),
242 'r1': wx.NewId(),
243 'r2': wx.NewId(),
244 'mf': wx.NewId(),
245 'relax_disp': wx.NewId(),
246 'consist_test': wx.NewId(),
247 'custom': wx.NewId(),
248 'reserved': wx.NewId()}
249
250
251 self.button_noe = self.create_button(id=self.button_ids['noe'], box=sizer1, size=size, bmp=ANALYSIS_IMAGE_PATH+"noe_150x150.png", tooltip="Steady-state NOE analysis", fn=self.select_noe)
252
253
254 self.button_r1 = self.create_button(id=self.button_ids['r1'], box=sizer1, size=size, bmp=ANALYSIS_IMAGE_PATH+"r1_150x150.png", tooltip="%s relaxation curve-fitting analysis" % r1, fn=self.select_r1)
255
256
257 self.button_r2 = self.create_button(id=self.button_ids['r2'], box=sizer1, size=size, bmp=ANALYSIS_IMAGE_PATH+"r2_150x150.png", tooltip="%s relaxation curve-fitting analysis" % r2, fn=self.select_r2)
258
259
260 self.button_mf = self.create_button(id=self.button_ids['mf'], box=sizer1, size=size, bmp=ANALYSIS_IMAGE_PATH+"model_free"+sep+"model_free_150x150.png", tooltip="Model-free analysis", fn=self.select_mf)
261
262
263 self.button_disp = self.create_button(id=self.button_ids['relax_disp'], box=sizer2, size=size, bmp=ANALYSIS_IMAGE_PATH+"relax_disp_150x150.png", tooltip="Relaxation dispersion analysis", fn=self.select_disp)
264
265
266 self.button_consist_test = self.create_button(id=self.button_ids['consist_test'], box=sizer2, size=size, bmp=ANALYSIS_IMAGE_PATH+"consistency_testing_150x70.png", tooltip="Relaxation data consistency testing (disabled)", fn=self.select_consist_test, disabled=True)
267
268
269 self.button_custom = self.create_button(id=self.button_ids['custom'], box=sizer2, size=size, bmp=ANALYSIS_IMAGE_PATH+"custom_150x150.png", tooltip="Custom analysis (disabled)", fn=self.select_custom, disabled=True)
270
271
272 self.button_reserved = self.create_button(id=self.button_ids['reserved'], box=sizer2, size=size, bmp=ANALYSIS_IMAGE_PATH+"blank_150x150.png", tooltip=None, fn=None, disabled=True)
273
274
275 box.Add(sizer1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
276 box.Add(sizer2, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
277
278
279 - def add_contents(self, sizer):
280 """Add the specific GUI elements (dummy method).
281
282 @param sizer: A sizer object.
283 @type sizer: wx.Sizer instance
284 """
285
286
287 self.add_buttons(sizer)
288
289
290 sizer.AddStretchSpacer(2)
291
292
293 self.analysis_name = Value(name='analysis_name', parent=self, value_type='str', sizer=sizer, desc="The name of the new analysis:", tooltip='The name of the analysis can be changed to any text.', divider=self._div_left, height_element=self.height_element)
294
295
296 - def create_button(self, id=-1, box=None, size=None, bmp=None, text='', tooltip='', fn=None, disabled=False):
297 """Create a button for the new analysis selector panel.
298
299 @keyword id: The unique ID number.
300 @type id: int
301 @keyword box: The box sizer to place the button into.
302 @type box: wx.BoxSizer instance
303 @keyword size: The size of the button.
304 @type size: tuple of int
305 @keyword bmp: The full path of the bitmap image to use for the button.
306 @type bmp: str
307 @keyword text: The text for the button.
308 @type text: str
309 @keyword tooltip: The button tooltip text.
310 @type tooltip: str or None
311 @keyword fn: The function to bind the button click to.
312 @type fn: method
313 @return: The button.
314 @rtype: wx.lib.buttons.ThemedGenBitmapTextToggleButton instance
315 """
316
317
318 if bmp:
319 image = wx.Bitmap(bmp, wx.BITMAP_TYPE_ANY)
320 button = New_analysis_button(self, id, image)
321 else:
322 button = New_analysis_button(self, id)
323
324
325 if tooltip != None:
326 button.SetToolTipString(tooltip)
327
328
329 button.SetMinSize(size)
330
331
332 box.Add(button)
333
334
335 if fn != None:
336 self.Bind(wx.EVT_BUTTON, fn, button)
337
338
339 if disabled:
340 button.Disable()
341
342
343 return button
344
345
346 - def on_display(self):
347 """Disable the next button until an analysis is selected."""
348
349
350 self.parent.block_next(not self._select_flag)
351
352
353 - def select_consist_test(self, event):
354 """NOE analysis selection.
355
356 @param event: The wx event.
357 @type event: wx event
358 """
359
360
361 self.toggle(self.button_consist_test)
362
363
364 self.parent.analysis_type = 'consistency test'
365
366
367 - def select_custom(self, event):
368 """NOE analysis selection.
369
370 @param event: The wx event.
371 @type event: wx event
372 """
373
374
375 self.toggle(self.button_custom)
376
377
378 self.parent.analysis_type = 'custom'
379
380
381 - def select_disp(self, event):
382 """Relaxation dispersion analysis selection.
383
384 @param event: The wx event.
385 @type event: wx event
386 """
387
388
389 self.toggle(self.button_disp)
390
391
392 self.analysis_name.SetValue(str_to_gui('Relaxation dispersion'))
393
394
395 self.parent.analysis_type = 'relax_disp'
396
397
398 - def select_mf(self, event):
399 """NOE analysis selection.
400
401 @param event: The wx event.
402 @type event: wx event
403 """
404
405
406 self.toggle(self.button_mf)
407
408
409 self.analysis_name.SetValue(str_to_gui('Model-free'))
410
411
412 self.parent.analysis_type = 'mf'
413
414
415 - def select_noe(self, event):
416 """NOE analysis selection.
417
418 @param event: The wx event.
419 @type event: wx event
420 """
421
422
423 self.toggle(self.button_noe)
424
425
426 self.analysis_name.SetValue(str_to_gui('Steady-state NOE'))
427
428
429 self.parent.analysis_type = 'noe'
430
431
432 - def select_r1(self, event):
433 """NOE analysis selection.
434
435 @param event: The wx event.
436 @type event: wx event
437 """
438
439
440 self.toggle(self.button_r1)
441
442
443 self.analysis_name.SetValue(str_to_gui("R1 relaxation"))
444
445
446 self.parent.analysis_type = 'r1'
447
448
449 - def select_r2(self, event):
450 """NOE analysis selection.
451
452 @param event: The wx event.
453 @type event: wx event
454 """
455
456
457 self.toggle(self.button_r2)
458
459
460 self.analysis_name.SetValue(str_to_gui("R2 relaxation"))
461
462
463 self.parent.analysis_type = 'r2'
464
465
466 - def toggle(self, button):
467 """Toggle all buttons off except the selected one.
468
469 @param button: The button of the selected analysis.
470 @type button: wx.ToggleButton instance
471 """
472
473
474 self.Freeze()
475
476
477 self._select_flag = True
478
479
480 self.button_noe.SetValue(False)
481 self.button_r1.SetValue(False)
482 self.button_r2.SetValue(False)
483 self.button_mf.SetValue(False)
484 self.button_disp.SetValue(False)
485 self.button_consist_test.SetValue(False)
486 self.button_custom.SetValue(False)
487 self.button_reserved.SetValue(False)
488
489
490 button.SetValue(True)
491
492
493 self.Refresh()
494
495
496 self.Thaw()
497
498
499 self.parent.block_next(not self._select_flag)
500