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.wizards.wiz_objects import Wiz_page, Wiz_window
37 from lib.text.gui import r1, r2
38
39
41 """The analysis selection wizard."""
42
44 """Run through the analysis selection wizard, returning the results.
45
46 @return: The analysis type, analysis name, data pipe name, data pipe bundle name, and user function on_execute method list.
47 @rtype: tuple of str
48 """
49
50
51 wx.Yield()
52 wx.BeginBusyCursor()
53
54
55 self.wizard = Wiz_window(size_x=850, size_y=700, title='Analysis selection wizard')
56
57
58 self.wizard.TEXT_FINISH = " Start"
59
60
61 self.new_page = New_analysis_page(self.wizard)
62 self.wizard.add_page(self.new_page, apply_button=False)
63
64
65 self.pipe_page = Data_pipe_page(self.wizard, height_desc=400)
66 self.wizard.add_page(self.pipe_page, apply_button=False)
67
68
69 if wx.IsBusy():
70 wx.EndBusyCursor()
71
72
73 setup = self.wizard.run(modal=True)
74 if setup != wx.ID_OK:
75 return
76
77
78 return self.get_data()
79
80
82 """Assemble and return the analysis type, analysis name, and pipe name.
83
84 @return: The analysis type, analysis name, data pipe name, data pipe bundle name, and list of user function on_execute methods.
85 @rtype: str, str, str, str, list of methods
86 """
87
88
89 analysis_type = gui_to_str(self.wizard.analysis_type)
90 analysis_name = gui_to_str(self.new_page.analysis_name.GetValue())
91 pipe_name = gui_to_str(self.pipe_page.pipe_name.GetValue())
92 pipe_bundle = gui_to_str(self.pipe_page.pipe_bundle.GetValue())
93
94
95 uf_exec = []
96
97
98 return analysis_type, analysis_name, pipe_name, pipe_bundle, uf_exec
99
100
101
102 -class Data_pipe_page(Wiz_page):
103 """The panel for setting the data pipe name."""
104
105
106 image_path = WIZARD_IMAGE_PATH + 'pipe.png'
107 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)
108 title = 'Data pipe set up'
109
110 - def add_contents(self, sizer):
111 """Add the specific GUI elements (dummy method).
112
113 @param sizer: A sizer object.
114 @type sizer: wx.Sizer instance
115 """
116
117
118 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)
119
120
121 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)
122
123
124 sizer.AddStretchSpacer(3)
125
126
127 - def on_display(self):
128 """Update the pipe name."""
129
130
131 name = "%s (%s)" % (self.parent.analysis_type, asctime(localtime()))
132
133
134 self.pipe_name.SetValue(str_to_gui("origin - %s" % name))
135 self.pipe_bundle.SetValue(str_to_gui(name))
136
137
138
172
173
174
175 -class New_analysis_page(Wiz_page):
176 """The panel for selection of the new analysis."""
177
178
179 image_path = IMAGE_PATH + "relax.gif"
180 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)
181 title = "Start a new analysis"
182
183 - def add_artwork(self, sizer):
184 """Add the artwork to the dialog.
185
186 @param sizer: A sizer object.
187 @type sizer: wx.Sizer instance
188 """
189
190
191 sizer2 = wx.BoxSizer(wx.VERTICAL)
192
193
194 sizer2.AddSpacer(30)
195
196
197 self.image = wx.StaticBitmap(self, -1, bitmap_setup(self.image_path))
198 sizer2.Add(self.image, 0, wx.TOP|wx.ALIGN_CENTER_HORIZONTAL, 0)
199
200
201 sizer.Add(sizer2)
202
203
204 sizer.AddSpacer(self.art_spacing)
205
206
208 """The widget of analysis buttons.
209
210 @param box: A sizer object.
211 @type box: wx.BoxSizer instance
212 """
213
214
215 size = (170, 170)
216
217
218 self._select_flag = False
219
220
221 sizer1 = wx.BoxSizer(wx.HORIZONTAL)
222 sizer2 = wx.BoxSizer(wx.HORIZONTAL)
223
224
225 self.button_ids = {'noe': wx.NewId(),
226 'r1': wx.NewId(),
227 'r2': wx.NewId(),
228 'consist_test': wx.NewId(),
229 'mf': wx.NewId(),
230 'custom': wx.NewId()}
231
232
233 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)
234
235
236 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)
237
238
239 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)
240
241
242 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", fn=self.select_consist_test, disabled=True)
243
244
245 self.button_mf = self.create_button(id=self.button_ids['mf'], box=sizer2, size=size, bmp=ANALYSIS_IMAGE_PATH+"model_free"+sep+"model_free_150x150.png", tooltip="Model-free analysis", fn=self.select_mf)
246
247
248 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", fn=self.select_custom, disabled=True)
249
250
251 box.Add(sizer1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
252 box.Add(sizer2, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
253
254
255 - def add_contents(self, sizer):
256 """Add the specific GUI elements (dummy method).
257
258 @param sizer: A sizer object.
259 @type sizer: wx.Sizer instance
260 """
261
262
263 self.add_buttons(sizer)
264
265
266 sizer.AddStretchSpacer(2)
267
268
269 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)
270
271
272 - def create_button(self, id=-1, box=None, size=None, bmp=None, text='', tooltip='', fn=None, disabled=False):
273 """Create a button for the new analysis selector panel.
274
275 @keyword id: The unique ID number.
276 @type id: int
277 @keyword box: The box sizer to place the button into.
278 @type box: wx.BoxSizer instance
279 @keyword size: The size of the button.
280 @type size: tuple of int
281 @keyword bmp: The full path of the bitmap image to use for the button.
282 @type bmp: str
283 @keyword text: The text for the button.
284 @type text: str
285 @keyword tooltip: The button tooltip text.
286 @type tooltip: str
287 @keyword fn: The function to bind the button click to.
288 @type fn: method
289 @return: The button.
290 @rtype: wx.lib.buttons.ThemedGenBitmapTextToggleButton instance
291 """
292
293
294 if bmp:
295 image = wx.Bitmap(bmp, wx.BITMAP_TYPE_ANY)
296 button = New_analysis_button(self, id, image)
297 else:
298 button = New_analysis_button(self, id)
299
300
301 button.SetToolTipString(tooltip)
302
303
304 button.SetMinSize(size)
305
306
307 box.Add(button)
308
309
310 if fn != None:
311 self.Bind(wx.EVT_BUTTON, fn, button)
312
313
314 if disabled:
315 button.Disable()
316
317
318 return button
319
320
321 - def on_display(self):
322 """Disable the next button until an analysis is selected."""
323
324
325 self.parent.block_next(not self._select_flag)
326
327
328 - def select_consist_test(self, event):
329 """NOE analysis selection.
330
331 @param event: The wx event.
332 @type event: wx event
333 """
334
335
336 self.toggle(self.button_consist_test)
337
338
339 self.parent.analysis_type = 'consistency test'
340
341
342 - def select_custom(self, event):
343 """NOE analysis selection.
344
345 @param event: The wx event.
346 @type event: wx event
347 """
348
349
350 self.toggle(self.button_custom)
351
352
353 self.parent.analysis_type = 'custom'
354
355
356 - def select_mf(self, event):
357 """NOE analysis selection.
358
359 @param event: The wx event.
360 @type event: wx event
361 """
362
363
364 self.toggle(self.button_mf)
365
366
367 self.analysis_name.SetValue(str_to_gui('Model-free'))
368
369
370 self.parent.analysis_type = 'mf'
371
372
373 - def select_noe(self, event):
374 """NOE analysis selection.
375
376 @param event: The wx event.
377 @type event: wx event
378 """
379
380
381 self.toggle(self.button_noe)
382
383
384 self.analysis_name.SetValue(str_to_gui('Steady-state NOE'))
385
386
387 self.parent.analysis_type = 'noe'
388
389
390 - def select_r1(self, event):
391 """NOE analysis selection.
392
393 @param event: The wx event.
394 @type event: wx event
395 """
396
397
398 self.toggle(self.button_r1)
399
400
401 self.analysis_name.SetValue(str_to_gui("R1 relaxation"))
402
403
404 self.parent.analysis_type = 'r1'
405
406
407 - def select_r2(self, event):
408 """NOE analysis selection.
409
410 @param event: The wx event.
411 @type event: wx event
412 """
413
414
415 self.toggle(self.button_r2)
416
417
418 self.analysis_name.SetValue(str_to_gui("R2 relaxation"))
419
420
421 self.parent.analysis_type = 'r2'
422
423
424 - def toggle(self, button):
425 """Toggle all buttons off except the selected one.
426
427 @param button: The button of the selected analysis.
428 @type button: wx.ToggleButton instance
429 """
430
431
432 self.Freeze()
433
434
435 self._select_flag = True
436
437
438 self.button_noe.SetValue(False)
439 self.button_r1.SetValue(False)
440 self.button_r2.SetValue(False)
441 self.button_consist_test.SetValue(False)
442 self.button_mf.SetValue(False)
443 self.button_custom.SetValue(False)
444
445
446 button.SetValue(True)
447
448
449 self.Refresh()
450
451
452 self.Thaw()
453
454
455 self.parent.block_next(not self._select_flag)
456