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