Package gui :: Package analyses :: Module wizard
[hide private]
[frames] | no frames]

Source Code for Module gui.analyses.wizard

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2011-2012 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Module for the analysis selection wizard.""" 
 25   
 26  # Python module imports. 
 27  from os import sep 
 28  from time import asctime, localtime 
 29  import wx 
 30  from wx.lib import buttons 
 31   
 32  # relax GUI module imports. 
 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   
39 -class Analysis_wizard:
40 """The analysis selection wizard.""" 41
42 - def run(self):
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 # Change the cursor to busy. 50 wx.Yield() 51 wx.BeginBusyCursor() 52 53 # Set up the wizard. 54 self.wizard = Wiz_window(size_x=850, size_y=700, title='Analysis selection wizard') 55 56 # Change the finish button. 57 self.wizard.TEXT_FINISH = " Start" 58 59 # Add the new analysis panel. 60 self.new_page = New_analysis_page(self.wizard) 61 self.wizard.add_page(self.new_page, apply_button=False) 62 63 # Add the data pipe name panel. 64 self.pipe_page = Data_pipe_page(self.wizard) 65 self.wizard.add_page(self.pipe_page, apply_button=False) 66 67 # Reset the cursor. 68 if wx.IsBusy(): 69 wx.EndBusyCursor() 70 71 # Execute the wizard. 72 setup = self.wizard.run(modal=True) 73 if setup != wx.ID_OK: 74 return 75 76 # Return the analysis type, analysis name, and pipe name. 77 return self.get_data()
78 79
80 - def get_data(self):
81 """Assemble and return the analysis type, analysis name, and pipe name. 82 83 @return: The analysis type, analysis name, and data pipe name. 84 @rtype: tuple of str 85 """ 86 87 # Get the data. 88 analysis_type = gui_to_str(self.wizard.analysis_type) 89 analysis_name = gui_to_str(self.new_page.analysis_name.GetValue()) 90 pipe_name = gui_to_str(self.pipe_page.pipe_name.GetValue()) 91 92 # Return it. 93 return analysis_type, analysis_name, pipe_name
94 95 96
97 -class Data_pipe_page(Wiz_page):
98 """The panel for setting the data pipe name.""" 99 100 # Class variables. 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 # The pipe name input. 113 self.pipe_name = self.input_field(sizer, "The data pipe name:") 114 115 # Spacing. 116 sizer.AddStretchSpacer(3)
117 118
119 - def on_display(self):
120 """Update the pipe name.""" 121 122 # Generate a name for the data pipe based on the type and time. 123 name = "%s (%s)" % (self.parent.analysis_type, asctime(localtime())) 124 125 # Update the field. 126 self.pipe_name.SetValue(str_to_gui(name))
127 128 129
130 -class New_analysis_button(buttons.ThemedGenBitmapTextToggleButton):
131 """A special button for the new analysis panel.""" 132
133 - def OnLeftDown(self, event):
134 """Catch left button mouse down events to ignore when the button is toggled. 135 136 @param event: The wx event. 137 @type event: wx event 138 """ 139 140 # Do nothing on a click if already selected. 141 if self.GetValue(): 142 event.Skip() 143 144 # Otherwise, perform the normal operations. 145 else: 146 super(buttons.ThemedGenBitmapTextToggleButton, self).OnLeftDown(event)
147 148
149 - def OnMouse(self, event):
150 """Catch mouse events, specifically entry into the window. 151 152 @param event: The wx event. 153 @type event: wx event 154 """ 155 156 # Do nothing if entering the button when it is selected. 157 if event.GetEventType() == wx.EVT_ENTER_WINDOW.typeId and self.GetValue(): 158 event.Skip() 159 160 # Otherwise, perform the normal operations. 161 else: 162 super(buttons.ThemedGenBitmapTextToggleButton, self).OnMouse(event)
163 164 165
166 -class New_analysis_page(Wiz_page):
167 """The panel for selection of the new analysis.""" 168 169 # Class variables. 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 # Create a vertical box. 182 sizer2 = wx.BoxSizer(wx.VERTICAL) 183 184 # Add a spacer. 185 sizer2.AddSpacer(30) 186 187 # Add the graphics. 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 # Nest the sizers. 192 sizer.Add(sizer2) 193 194 # A spacer. 195 sizer.AddSpacer(self.art_spacing)
196 197
198 - def add_buttons(self, box):
199 """The widget of analysis buttons. 200 201 @param box: A sizer object. 202 @type box: wx.BoxSizer instance 203 """ 204 205 # The sizes. 206 size = (170, 170) 207 208 # No button is initially selected. 209 self._select_flag = False 210 211 # The horizontal spacers. 212 sizer1 = wx.BoxSizer(wx.HORIZONTAL) 213 sizer2 = wx.BoxSizer(wx.HORIZONTAL) 214 215 # A set of unique IDs for the buttons. 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 # The NOE button. 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 # The R1 button. 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 # The R2 button. 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 # Consistency testing. 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 # The model-free button. 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 # The custom analysis button. 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 # Add the sizers. 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 # Add the button widget. 254 self.add_buttons(sizer) 255 256 # Add a spacer. 257 sizer.AddStretchSpacer(2) 258 259 # Add the analysis name field. 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 # Generate the button. 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 # Set the tool tip. 292 button.SetToolTipString(tooltip) 293 294 # Button properties. 295 button.SetMinSize(size) 296 297 # Add to the given sizer. 298 box.Add(button) 299 300 # Bind the click. 301 self.Bind(wx.EVT_BUTTON, fn, button) 302 303 # The button is disabled. 304 if disabled: 305 button.Disable() 306 307 # Return the button. 308 return button
309 310
311 - def on_display(self):
312 """Disable the next button until an analysis is selected.""" 313 314 # Turn off the next button. 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 # Toggle all buttons off. 326 self.toggle(self.button_consist_test) 327 328 # Set the analysis type. 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 # Toggle all buttons off. 340 self.toggle(self.button_custom) 341 342 # Set the analysis type. 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 # Toggle all buttons off. 354 self.toggle(self.button_mf) 355 356 # Update the analysis name. 357 self.analysis_name.SetValue(str_to_gui('Model-free')) 358 359 # Set the analysis type. 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 # Toggle all buttons off. 371 self.toggle(self.button_noe) 372 373 # Update the analysis name. 374 self.analysis_name.SetValue(str_to_gui('Steady-state NOE')) 375 376 # Set the analysis type. 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 # Toggle all buttons off. 388 self.toggle(self.button_r1) 389 390 # Update the analysis name. 391 self.analysis_name.SetValue(str_to_gui('R1 relaxation')) 392 393 # Set the analysis type. 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 # Toggle all buttons off. 405 self.toggle(self.button_r2) 406 407 # Update the analysis name. 408 self.analysis_name.SetValue(str_to_gui('R2 relaxation')) 409 410 # Set the analysis type. 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 # First freeze the wizard. 422 self.Freeze() 423 424 # The button is selected. 425 self._select_flag = True 426 427 # Deselect all. 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 # Turn on the selected button. 436 button.SetValue(True) 437 438 # Refresh the GUI element. 439 self.Refresh() 440 441 # Unfreeze. 442 self.Thaw() 443 444 # Unblock forwards movement. 445 self.parent.block_next(not self._select_flag)
446