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