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

Source Code for Module gui.analyses.auto_model_free

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2009 Michael Bieri                                            # 
   4  # Copyright (C) 2010-2012 Edward d'Auvergne                                   # 
   5  #                                                                             # 
   6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
   7  #                                                                             # 
   8  # This program is free software: you can redistribute it and/or modify        # 
   9  # it under the terms of the GNU General Public License as published by        # 
  10  # the Free Software Foundation, either version 3 of the License, or           # 
  11  # (at your option) any later version.                                         # 
  12  #                                                                             # 
  13  # This program is distributed in the hope that it will be useful,             # 
  14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
  15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
  16  # GNU General Public License for more details.                                # 
  17  #                                                                             # 
  18  # You should have received a copy of the GNU General Public License           # 
  19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
  20  #                                                                             # 
  21  ############################################################################### 
  22   
  23  # Module docstring. 
  24  """Module for the automatic model-free protocol frame.""" 
  25   
  26  # Python module imports. 
  27  from math import ceil 
  28  from os import sep 
  29  import sys 
  30  import wx 
  31  import wx.lib.buttons 
  32  import wx.lib.mixins.listctrl 
  33   
  34  # relax module imports. 
  35  from auto_analyses import dauvergne_protocol 
  36  from data import Relax_data_store; ds = Relax_data_store() 
  37  from generic_fns.interatomic import interatomic_loop 
  38  from generic_fns.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop 
  39  from generic_fns.pipes import has_bundle, has_pipe 
  40  from graphics import fetch_icon 
  41  from physical_constants import NH_BOND_LENGTH 
  42  from relax_errors import RelaxError 
  43  from relax_string import LIST, PARAGRAPH, SECTION, SUBSECTION, TITLE 
  44  from specific_fns.setup import get_specific_fn 
  45  from status import Status; status = Status() 
  46   
  47  # relax GUI module imports. 
  48  from gui.about import About_base 
  49  from gui.analyses.base import Base_analysis 
  50  from gui.analyses.elements import Spin_ctrl, Text_ctrl 
  51  from gui.analyses.execute import Execute 
  52  from gui.base_classes import Container 
  53  from gui.components.relax_data import Relax_data_list 
  54  from gui.filedialog import RelaxDirDialog 
  55  from gui.fonts import font 
  56  from gui.message import error_message, Question, Missing_data 
  57  from gui.misc import add_border, bitmap_setup, protected_exec 
  58  from gui import paths 
  59  from gui.string_conv import gui_to_int, gui_to_str, list_to_gui, str_to_gui 
  60  from gui.uf_objects import Uf_storage; uf_store = Uf_storage() 
  61  from gui.wizard import Wiz_window 
  62   
  63   
64 -class About_window(About_base):
65 """The model-free about window.""" 66 67 # The relax background colour. 68 colour1 = '#e5feff' 69 colour2 = '#88cbff' 70 71 # Dimensions. 72 dim_x = 800 73 dim_y = 800 74 max_y = 2500 75 76 # Spacer size (px). 77 border = 10 78 79 # Window style. 80 style = wx.DEFAULT_DIALOG_STYLE 81 82 # Destroy on clicking. 83 DESTROY_ON_CLICK = False 84
85 - def __init__(self, parent):
86 """Set up the user function class.""" 87 88 # Execute the base class method. 89 super(About_window, self).__init__(parent, id=-1, title="Automatic model-free analysis about window")
90 91
92 - def build_widget(self):
93 """Build the dialog using the dauvergne_protocol docstring.""" 94 95 # A global Y offset for packing the elements together (initialise to the border position). 96 self.offset(self.border) 97 98 # Loop over the lines. 99 for i in range(len(dauvergne_protocol.doc)): 100 # The level and text. 101 level, text = dauvergne_protocol.doc[i] 102 103 # The title. 104 if level == TITLE: 105 self.draw_title(text, alt_font=font.roman_font_18) 106 107 # The section. 108 elif level == SECTION: 109 self.draw_title(text, alt_font=font.roman_font_14) 110 111 # The section. 112 elif level == SUBSECTION: 113 self.draw_title(text, alt_font=font.roman_font_12) 114 115 # Paragraphs. 116 elif level == PARAGRAPH: 117 self.draw_wrapped_text(text) 118 119 # Lists. 120 elif level == LIST: 121 # Start of list. 122 if i and dauvergne_protocol.doc[i-1][0] != LIST: 123 self.offset(10) 124 125 # The text. 126 self.draw_wrapped_text(" - %s" % text) 127 128 # End of list. 129 if i < len(dauvergne_protocol.doc) and dauvergne_protocol.doc[i+1][0] == PARAGRAPH: 130 self.offset(10) 131 132 # Add space to the bottom. 133 self.offset(self.border) 134 135 # Round the offset up to the nearest factor of the scroll inc (needed for all scrolling). 136 scroll_x, scroll_y = self.window.GetScrollPixelsPerUnit() 137 y = self.offset() 138 self.offset(-y) 139 y = int(ceil(y/float(scroll_y)) * scroll_y) 140 self.offset(y) 141 142 # Resize the window. 143 dim_x = self.dim_x 144 virt_y = self.offset() 145 self.SetSize((dim_x, self.dim_y)) 146 self.window.SetVirtualSize((dim_x, virt_y)) 147 self.window.EnableScrolling(x_scrolling=False, y_scrolling=True)
148 149 150
151 -class Auto_model_free(Base_analysis):
152 """The model-free auto-analysis GUI element.""" 153
154 - def __init__(self, parent, id=-1, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=524288, name='scrolledpanel', gui=None, analysis_name=None, pipe_name=None, pipe_bundle=None, data_index=None):
155 """Build the automatic model-free protocol GUI element. 156 157 @param parent: The parent wx element. 158 @type parent: wx object 159 @keyword id: The unique ID number. 160 @type id: int 161 @keyword pos: The position. 162 @type pos: wx.Size object 163 @keyword size: The size. 164 @type size: wx.Size object 165 @keyword style: The style. 166 @type style: int 167 @keyword name: The name for the panel. 168 @type name: unicode 169 @keyword gui: The main GUI class. 170 @type gui: gui.relax_gui.Main instance 171 @keyword analysis_name: The name of the analysis (the name in the tab part of the notebook). 172 @type analysis_name: str 173 @keyword pipe_name: The name of the original data pipe for this analysis. 174 @type pipe_name: str 175 @keyword pipe_bundle: The name of the data pipe bundle associated with this analysis. 176 @type pipe_bundle: str 177 @keyword data_index: The index of the analysis in the relax data store (set to None if no data currently exists). 178 @type data_index: None or int 179 """ 180 181 # Store the GUI main class. 182 self.gui = gui 183 184 # Init. 185 self.init_flag = True 186 187 # New data container. 188 if data_index == None: 189 # First create the data pipe if not already in existence. 190 if not has_pipe(pipe_name): 191 self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='mf', bundle=pipe_bundle) 192 193 # Create the data pipe bundle if needed. 194 if not has_bundle(pipe_bundle): 195 self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name) 196 197 # Generate a storage container in the relax data store, and alias it for easy access. 198 data_index = ds.relax_gui.analyses.add('model-free') 199 200 # Store the analysis and pipe names. 201 ds.relax_gui.analyses[data_index].analysis_name = analysis_name 202 ds.relax_gui.analyses[data_index].pipe_name = pipe_name 203 ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle 204 205 # Initialise the variables. 206 ds.relax_gui.analyses[data_index].grid_inc = None 207 ds.relax_gui.analyses[data_index].diff_tensor_grid_inc = {'sphere': 11, 'prolate': 11, 'oblate': 11, 'ellipsoid': 6} 208 ds.relax_gui.analyses[data_index].mc_sim_num = None 209 ds.relax_gui.analyses[data_index].save_dir = self.gui.launch_dir 210 ds.relax_gui.analyses[data_index].local_tm_models = ['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9'] 211 ds.relax_gui.analyses[data_index].mf_models = ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9'] 212 ds.relax_gui.analyses[data_index].max_iter = 30 213 214 # Error checking. 215 if ds.relax_gui.analyses[data_index].pipe_bundle == None: 216 raise RelaxError("The pipe bundle must be supplied.") 217 218 # Alias the data. 219 self.data = ds.relax_gui.analyses[data_index] 220 self.data_index = data_index 221 222 # Backward compatibility. 223 if not hasattr(self.data, 'local_tm_models'): 224 self.data.local_tm_models = ['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9'] 225 if not hasattr(self.data, 'mf_models'): 226 self.data.mf_models = ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9'] 227 228 # Initialise the mode selection window. 229 self.mode_win = Protocol_mode_sel_window() 230 231 # Register the method for updating the spin count for the completion of user functions. 232 self.observer_register() 233 234 # Execute the base class method to build the panel. 235 super(Auto_model_free, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
236 237
238 - def _about(self, event=None):
239 """The about window. 240 241 @keyword event: The wx event. 242 @type event: wx event 243 """ 244 245 # Initialise the dialog. 246 self.about_dialog = About_window(self) 247 248 # Show the dialog. 249 if status.show_gui: 250 self.about_dialog.Show()
251 252
253 - def activate(self):
254 """Activate or deactivate certain elements of the analysis in response to the execution lock.""" 255 256 # Flag for enabling or disabling the elements. 257 enable = False 258 if not status.exec_lock.locked(): 259 enable = True 260 261 # Activate or deactivate the elements. 262 wx.CallAfter(self.field_results_dir.Enable, enable) 263 wx.CallAfter(self.spin_systems.Enable, enable) 264 wx.CallAfter(self.relax_data.Enable, enable) 265 wx.CallAfter(self.button_dipole_pair.Enable, enable) 266 wx.CallAfter(self.button_csa.Enable, enable) 267 wx.CallAfter(self.button_isotope_heteronuc.Enable, enable) 268 wx.CallAfter(self.button_isotope_proton.Enable, enable) 269 wx.CallAfter(self.local_tm_model_field.Enable, enable) 270 wx.CallAfter(self.mf_model_field.Enable, enable) 271 wx.CallAfter(self.grid_inc.Enable, enable) 272 wx.CallAfter(self.mc_sim_num.Enable, enable) 273 wx.CallAfter(self.max_iter.Enable, enable) 274 wx.CallAfter(self.mode.Enable, enable) 275 wx.CallAfter(self.button_exec_relax.Enable, enable)
276 277
278 - def add_values(self, box):
279 """Create and add the value.set buttons for the model-free analysis. 280 281 @param box: The box element to pack the GUI element into. 282 @type box: wx.BoxSizer instance 283 """ 284 285 # Sizer. 286 sizer = wx.BoxSizer(wx.HORIZONTAL) 287 288 # Dipole-dipole relaxation setup button. 289 self.button_dipole_pair = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Dipolar relaxation") 290 self.button_dipole_pair.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.dipole_pair", "22x22"), wx.BITMAP_TYPE_ANY)) 291 self.button_dipole_pair.SetFont(font.normal) 292 self.button_dipole_pair.SetSize((-1, 25)) 293 self.button_dipole_pair.SetToolTipString("Define the magnetic dipole-dipole relaxation mechanism.") 294 self.gui.Bind(wx.EVT_BUTTON, self.setup_dipole_pair, self.button_dipole_pair) 295 sizer.Add(self.button_dipole_pair, 1, wx.ALL|wx.EXPAND, 0) 296 297 # CSA button. 298 self.button_csa = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " CSA relaxation") 299 self.button_csa.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.align_tensor", "22x22"), wx.BITMAP_TYPE_ANY)) 300 self.button_csa.SetFont(font.normal) 301 self.button_csa.SetSize((-1, 25)) 302 self.button_csa.SetToolTipString("Define the Chemical Shift Anisotropy (CSA) relaxation mechanism via the value.set user function.") 303 self.gui.Bind(wx.EVT_BUTTON, self.value_set_csa, self.button_csa) 304 sizer.Add(self.button_csa, 1, wx.ALL|wx.EXPAND, 0) 305 306 # Isotope type button (heteronucleus). 307 self.button_isotope_heteronuc = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " X isotope") 308 self.button_isotope_heteronuc.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.nuclear_symbol", "22x22"), wx.BITMAP_TYPE_ANY)) 309 self.button_isotope_heteronuc.SetFont(font.normal) 310 self.button_isotope_heteronuc.SetSize((-1, 25)) 311 self.button_isotope_heteronuc.SetToolTipString("Set the nuclear isotope types of the heteronuclear spins via the spin.isotope user function.") 312 self.gui.Bind(wx.EVT_BUTTON, self.spin_isotope_heteronuc, self.button_isotope_heteronuc) 313 sizer.Add(self.button_isotope_heteronuc, 1, wx.ALL|wx.EXPAND, 0) 314 315 # Isotope type button (proton). 316 self.button_isotope_proton = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " H isotope") 317 self.button_isotope_proton.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.nuclear_symbol", "22x22"), wx.BITMAP_TYPE_ANY)) 318 self.button_isotope_proton.SetFont(font.normal) 319 self.button_isotope_proton.SetSize((-1, 25)) 320 self.button_isotope_proton.SetToolTipString("Set the nuclear isotope types of the proton spins via the spin.isotope user function.") 321 self.gui.Bind(wx.EVT_BUTTON, self.spin_isotope_proton, self.button_isotope_proton) 322 sizer.Add(self.button_isotope_proton, 1, wx.ALL|wx.EXPAND, 0) 323 324 # Add the element to the box. 325 box.Add(sizer, 0, wx.ALL|wx.EXPAND, 0)
326 327
328 - def assemble_data(self):
329 """Assemble the data required for the auto-analysis. 330 331 See the docstring for auto_analyses.dauvernge_protocol for details. All data is taken from the relax data store, so data upload from the GUI to there must have been previously performed. 332 333 @return: A container with all the data required for the auto-analysis. 334 @rtype: class instance, list of str 335 """ 336 337 # The data container. 338 data = Container() 339 missing = [] 340 341 # The pipe name and bundle. 342 data.pipe_name = self.data.pipe_name 343 data.pipe_bundle = self.data.pipe_bundle 344 345 # The model-free models (do not change these unless absolutely necessary). 346 data.local_tm_models = self.local_tm_model_field.GetValue() 347 data.mf_models = self.mf_model_field.GetValue() 348 349 # Automatic looping over all rounds until convergence (must be a boolean value of True or False). 350 data.conv_loop = True 351 352 # Increment size. 353 data.inc = gui_to_int(self.grid_inc.GetValue()) 354 if hasattr(self.data, 'diff_tensor_grid_inc'): 355 data.diff_tensor_grid_inc = self.data.diff_tensor_grid_inc 356 else: 357 data.diff_tensor_grid_inc = {'sphere': 11, 'prolate': 11, 'oblate': 11, 'ellipsoid': 6} 358 359 # The number of Monte Carlo simulations to be used for error analysis at the end of the analysis. 360 data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue()) 361 362 # Number of maximum iterations. 363 data.max_iter = self.data.max_iter 364 365 # Results directory. 366 data.save_dir = self.data.save_dir 367 368 # Check if sequence data is loaded 369 if not exists_mol_res_spin_data(): 370 missing.append("Sequence data") 371 372 # Relaxation data. 373 if not hasattr(cdp, 'ri_ids') or len(cdp.ri_ids) == 0: 374 missing.append("Relaxation data") 375 376 # Insufficient data. 377 if hasattr(cdp, 'ri_ids') and len(cdp.ri_ids) <= 3: 378 missing.append("Insufficient relaxation data, 4 or more data sets are essential for the execution of the dauvergne_protocol auto-analysis.") 379 380 # Interatomic data containers. 381 if not hasattr(cdp, 'interatomic') or len(cdp.interatomic) == 0: 382 missing.append("Interatomic data (for the dipole-dipole interaction)") 383 384 # Get the mode. 385 mode = gui_to_str(self.mode.GetValue()) 386 387 # Solve for all global models. 388 if mode == 'Fully automated': 389 # The global model list. 390 data.global_models = ['local_tm', 'sphere', 'prolate', 'oblate', 'ellipsoid', 'final'] 391 392 # Any global model selected. 393 else: 394 data.global_models = [mode] 395 396 # Check for vectors. 397 vector_check = False 398 if 'prolate' in data.global_models or 'oblate' in data.global_models or 'ellipsoid' in data.global_models: 399 vector_check = True 400 401 # Spin variables. 402 for spin, spin_id in spin_loop(return_id=True): 403 # Skip deselected spins. 404 if not spin.select: 405 continue 406 407 # The message skeleton. 408 msg = "Spin '%s' - %s (try the %s user function)." % (spin_id, "%s", "%s") 409 410 # Test if the nuclear isotope type has been set. 411 if not hasattr(spin, 'isotope') or spin.isotope == None: 412 missing.append(msg % ("nuclear isotope data", "spin.isotope")) 413 414 # Test if the CSA value has been set for the heteronuclei. 415 if spin.isotope in ['15N', '13C'] and (not hasattr(spin, 'csa') or spin.csa == None): 416 missing.append(msg % ("CSA data", "value.set")) 417 418 # Interatomic data container variables. 419 for interatom in interatomic_loop(): 420 # Get the spin containers. 421 spin1 = return_spin(interatom.spin_id1) 422 spin2 = return_spin(interatom.spin_id2) 423 424 # Skip deselected spins. 425 if not spin1.select: 426 continue 427 if not spin2.select: 428 continue 429 430 # The message skeleton. 431 msg = "Spin pair '%s' and '%s' - %s (try the %s user function)." % (interatom.spin_id1, interatom.spin_id2, "%s", "%s") 432 433 # Test if the interatomic distance has been set. 434 if not hasattr(interatom, 'r') or interatom.r == None: 435 missing.append(msg % ("bond length data", "value.set")) 436 437 # Test if the unit vectors have been loaded. 438 if vector_check and (not hasattr(interatom, 'vector') or interatom.vector == None): 439 missing.append(msg % ("unit vectors", "dipole_pair.unit_vectors")) 440 441 # Return the container and list of missing data. 442 return data, missing
443 444
445 - def build_left_box(self):
446 """Construct the left hand box to pack into the main model-free box. 447 448 @return: The left hand box element containing the bitmap and about button to pack into the main model-free box. 449 @rtype: wx.BoxSizer instance 450 """ 451 452 # Build the left hand box. 453 left_box = wx.BoxSizer(wx.VERTICAL) 454 455 # The images. 456 bitmaps = [paths.ANALYSIS_IMAGE_PATH+"model_free"+sep+"model_free_200x200.png", 457 paths.IMAGE_PATH+'modelfree.png'] 458 459 # Add the model-free bitmap picture. 460 for i in range(len(bitmaps)): 461 # The bitmap. 462 bitmap = wx.StaticBitmap(self, -1, bitmap_setup(bitmaps[i])) 463 464 # Add it. 465 left_box.Add(bitmap, 0, wx.ALL, 0) 466 467 # A spacer. 468 left_box.AddStretchSpacer() 469 470 # A button sizer, with some initial spacing. 471 button_sizer = wx.BoxSizer(wx.HORIZONTAL) 472 473 # An about button. 474 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, "About") 475 button.SetBitmapLabel(wx.Bitmap(paths.icon_22x22.about, wx.BITMAP_TYPE_ANY)) 476 button.SetFont(font.normal) 477 button.SetToolTipString("Information about this automatic analysis") 478 479 # Bind the click. 480 self.Bind(wx.EVT_BUTTON, self._about, button) 481 482 # A cursor for the button. 483 cursor = wx.StockCursor(wx.CURSOR_QUESTION_ARROW) 484 button.SetCursor(cursor) 485 486 # Pack the button. 487 button_sizer.Add(button, 0, 0, 0) 488 left_box.Add(button_sizer, 0, wx.ALL, 0) 489 490 # Return the packed box. 491 return left_box
492 493
494 - def build_right_box(self):
495 """Construct the right hand box to pack into the main model-free box. 496 497 @return: The right hand box element containing all model-free GUI elements (excluding the bitmap) to pack into the main model-free box. 498 @rtype: wx.BoxSizer instance 499 """ 500 501 # Use a vertical packing of elements. 502 box = wx.BoxSizer(wx.VERTICAL) 503 504 # Add the frame title. 505 self.add_title(box, "Setup for model-free analysis") 506 507 # Display the data pipe. 508 Text_ctrl(box, self, text="The data pipe bundle:", default=self.data.pipe_bundle, tooltip="This is the data pipe bundle associated with this analysis.", editable=False, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 509 510 # Add the results directory GUI element. 511 self.field_results_dir = Text_ctrl(box, self, text="Results directory", icon=paths.icon_16x16.open_folder, default=self.data.save_dir, fn=self.results_directory, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 512 513 # Add the spin GUI element. 514 self.add_spin_systems(box, self) 515 516 # Add the relaxation data list GUI element, with spacing. 517 box.AddSpacer(10) 518 self.relax_data = Relax_data_list(gui=self.gui, parent=self, box=box, id=str(self.data_index)) 519 box.AddSpacer(10) 520 521 # Add the value.set buttons. 522 self.add_values(box) 523 box.AddSpacer(10) 524 525 # Add the local tau_m models GUI element, with spacing. 526 self.local_tm_model_field = Local_tm_list(self, box) 527 self.local_tm_model_field.set_value(self.data.local_tm_models) 528 529 # Add the model-free models GUI element, with spacing. 530 self.mf_model_field = Mf_list(self, box) 531 self.mf_model_field.set_value(self.data.mf_models) 532 533 # The optimisation settings. 534 self.grid_inc = Spin_ctrl(box, self, text="Grid search increments:", default=11, min=1, max=100, tooltip="This is the number of increments per dimension of the grid search performed prior to numerical optimisation.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 535 self.mc_sim_num = Spin_ctrl(box, self, text="Monte Carlo simulation number:", default=500, min=1, max=100000, tooltip="This is the number of Monte Carlo simulations performed for error propagation and analysis.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 536 537 # Add maximum iteration selector. 538 self.max_iter = Spin_ctrl(box, self, text="Maximum interations", default=self.data.max_iter, min=25, max=100, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 539 540 # The calculation mode. 541 self.mode = Text_ctrl(box, self, text="Protocol mode:", default='Fully automated', tooltip="Select if the dauvergne_protocol analysis will be fully automated or whether the individual global models will be optimised one by one.", icon=paths.icon_16x16.system_run, fn=self.mode_dialog, editable=False, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 542 543 # Stretchable spacing (with a minimal space). 544 box.AddSpacer(30) 545 box.AddStretchSpacer() 546 547 # Add the execution GUI element. 548 self.button_exec_relax = self.add_execute_relax(box, self.execute) 549 550 # Return the box. 551 return box
552 553
554 - def delete(self):
555 """Unregister the spin count from the user functions.""" 556 557 # Unregister the observer methods. 558 self.observer_register(remove=True) 559 560 # Clean up the relaxation data list object. 561 self.relax_data.delete()
562 563
564 - def execute(self, event=None):
565 """Set up, execute, and process the automatic model-free protocol. 566 567 @keyword event: The wx event. 568 @type event: wx event 569 """ 570 571 # Flush the GUI interpreter internal queue to make sure all user functions are complete. 572 self.gui.interpreter.flush() 573 574 # relax execution lock. 575 if status.exec_lock.locked(): 576 error_message("relax is currently executing.", "relax execution lock") 577 event.Skip() 578 return 579 580 # User warning to close windows. 581 self.gui.close_windows() 582 583 # Synchronise the frame data to the relax data store. 584 self.sync_ds(upload=True) 585 586 # Assemble all the data needed for the auto-analysis. 587 data, missing = self.assemble_data() 588 589 # Missing data. 590 if len(missing): 591 Missing_data(missing) 592 return 593 594 # Display the relax controller, and go to the end of the log window. 595 self.gui.show_controller(None) 596 self.gui.controller.log_panel.on_goto_end(None) 597 598 # Start the thread. 599 self.thread = Execute_mf(self.gui, data, self.data_index) 600 self.thread.start() 601 602 # Terminate the event. 603 event.Skip()
604 605
606 - def mode_dialog(self, event=None):
607 """The calculation mode selection. 608 609 @keyword event: The wx event. 610 @type event: wx event 611 """ 612 613 # Show the model selector window. 614 if status.show_gui: 615 self.mode_win.ShowModal() 616 617 # Set the model. 618 self.mode.SetValue(str_to_gui(self.mode_win.select))
619 620
621 - def observer_register(self, remove=False):
622 """Register and unregister methods with the observer objects. 623 624 @keyword remove: If set to True, then the methods will be unregistered. 625 @type remove: False 626 """ 627 628 # Register. 629 if not remove: 630 status.observers.gui_uf.register(self.data.pipe_bundle, self.update_spin_count, method_name='update_spin_count') 631 status.observers.exec_lock.register(self.data.pipe_bundle, self.activate, method_name='activate') 632 633 # Unregister. 634 else: 635 # The model-free methods. 636 status.observers.gui_uf.unregister(self.data.pipe_bundle) 637 status.observers.exec_lock.unregister(self.data.pipe_bundle) 638 639 # The embedded objects methods. 640 self.relax_data.observer_register(remove=True)
641 642
643 - def results_directory(self, event=None):
644 """The results directory selection. 645 646 @keyword event: The wx event. 647 @type event: wx event 648 """ 649 650 # The dialog. 651 dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue()) 652 653 # Show the dialog and catch if no file has been selected. 654 if status.show_gui and dialog.ShowModal() != wx.ID_OK: 655 # Don't do anything. 656 return 657 658 # The path (don't do anything if not set). 659 path = gui_to_str(dialog.get_path()) 660 if not path: 661 return 662 663 # Store the path. 664 self.data.save_dir = path 665 666 # Place the path in the text box. 667 self.field_results_dir.SetValue(str_to_gui(path))
668 669
670 - def setup_dipole_pair(self, event=None):
671 """Create the wizard for the dipole-dipole interaction. 672 673 @keyword event: The wx event. 674 @type event: wx event 675 """ 676 677 # Change the cursor to busy. 678 wx.BeginBusyCursor() 679 680 # Create the wizard. 681 self.dipole_wizard = Wiz_window(parent=self.gui, size_x=1000, size_y=750, title="Dipole-dipole interaction setup") 682 683 # Structural data. 684 if not hasattr(cdp, 'structure'): 685 # Create the PDB reading page. 686 page = uf_store['structure.read_pdb'].create_page(self.dipole_wizard) 687 self.dipole_wizard.add_page(page, skip_button=True) 688 689 # Create the position reading page. 690 page = uf_store['structure.get_pos'].create_page(self.dipole_wizard) 691 self.dipole_wizard.add_page(page, skip_button=True) 692 693 # Create the dipole_pair.define page. 694 page = uf_store['dipole_pair.define'].create_page(self.dipole_wizard) 695 page.SetValue('spin_id1', '@N') 696 page.SetValue('spin_id2', '@H') 697 self.dipole_wizard.add_page(page) 698 699 # Create the dipole_pair.set_dist page. 700 page = uf_store['dipole_pair.set_dist'].create_page(self.dipole_wizard) 701 page.SetValue('spin_id1', '@N*') 702 page.SetValue('spin_id2', '@H*') 703 page.SetValue('ave_dist', NH_BOND_LENGTH) 704 self.dipole_wizard.add_page(page) 705 706 # Create the dipole_pair.unit_vectors page. 707 page = uf_store['dipole_pair.unit_vectors'].create_page(self.dipole_wizard) 708 self.dipole_wizard.add_page(page) 709 710 # Reset the cursor. 711 if wx.IsBusy(): 712 wx.EndBusyCursor() 713 714 # Execute the wizard. 715 self.dipole_wizard.run()
716 717
718 - def spin_isotope_heteronuc(self, event=None):
719 """Set the nuclear isotope types of the heteronuclear spins via the spin.isotope user function. 720 721 @keyword event: The wx event. 722 @type event: wx event 723 """ 724 725 # Call the user function. 726 uf_store['spin.isotope'](isotope='15N', spin_id='@N*')
727 728
729 - def spin_isotope_proton(self, event=None):
730 """Set the nuclear isotope types of the proton spins via the spin.isotope user function. 731 732 @keyword event: The wx event. 733 @type event: wx event 734 """ 735 736 # Call the user function. 737 uf_store['spin.isotope'](isotope='1H', spin_id='@H*')
738 739
740 - def sync_ds(self, upload=False):
741 """Synchronise the analysis frame and the relax data store, both ways. 742 743 This method allows the frame information to be uploaded into the relax data store, or for the information in the relax data store to be downloaded by the frame. 744 745 @keyword upload: A flag which if True will cause the frame to send data to the relax data store. If False, data will be downloaded from the relax data store to update the frame. 746 @type upload: bool 747 """ 748 749 # The local tau_m models to use. 750 if upload: 751 self.data.local_tm_models = self.local_tm_model_field.GetValue() 752 else: 753 self.local_tm_model_field.set_value(self.data.local_tm_models) 754 755 # The model-free models to use. 756 if upload: 757 self.data.mf_models = self.mf_model_field.GetValue() 758 else: 759 self.mf_model_field.set_value(self.data.mf_models) 760 761 # The grid incs. 762 if upload: 763 self.data.grid_inc = gui_to_int(self.grid_inc.GetValue()) 764 elif hasattr(self.data, 'grid_inc'): 765 self.grid_inc.SetValue(int(self.data.grid_inc)) 766 767 # The MC sim number. 768 if upload: 769 self.data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue()) 770 elif hasattr(self.data, 'mc_sim_num'): 771 self.mc_sim_num.SetValue(int(self.data.mc_sim_num)) 772 773 # The results directory. 774 if upload: 775 self.data.save_dir = str(self.field_results_dir.GetValue()) 776 else: 777 self.field_results_dir.SetValue(str_to_gui(self.data.save_dir)) 778 779 # Maximum iterations. 780 if upload: 781 self.data.max_iter = gui_to_int(self.max_iter.GetValue()) 782 else: 783 self.max_iter.SetValue(int(self.data.max_iter))
784 785
786 - def value_set_csa(self, event=None):
787 """Set the CSA via the value.set uf. 788 789 @keyword event: The wx event. 790 @type event: wx event 791 """ 792 793 # Get the default value. 794 val = get_specific_fn('default_value')('csa') 795 796 # Call the user function. 797 uf_store['value.set'](val=val, param='csa', spin_id='@N*')
798 799 800
801 -class Execute_mf(Execute):
802 """The model-free analysis execution object.""" 803
804 - def run_analysis(self):
805 """Execute the calculation.""" 806 807 # Start the protocol. 808 dauvergne_protocol.dAuvergne_protocol(pipe_name=self.data.pipe_name, pipe_bundle=self.data.pipe_bundle, results_dir=self.data.save_dir, diff_model=self.data.global_models, mf_models=self.data.mf_models, local_tm_models=self.data.local_tm_models, grid_inc=self.data.inc, diff_tensor_grid_inc=self.data.diff_tensor_grid_inc, mc_sim_num=self.data.mc_sim_num, max_iter=self.data.max_iter, conv_loop=self.data.conv_loop)
809 810 811
812 -class Local_tm_list:
813 """The model-free model list GUI element.""" 814 815 # Some class variables. 816 desc = u'Local \u03C4m models:' 817 models = [ 818 "tm0", 819 "tm1", 820 "tm2", 821 "tm3", 822 "tm4", 823 "tm5", 824 "tm6", 825 "tm7", 826 "tm8", 827 "tm9" 828 ] 829 params = [ 830 "{local_tm}", 831 "{local_tm, S2}", 832 "{local_tm, S2, te}", 833 "{local_tm, S2, Rex}", 834 "{local_tm, S2, te, Rex}", 835 "{local_tm, S2, S2f, ts}", 836 "{local_tm, S2, tf, S2f, ts}", 837 "{local_tm, S2, S2f, ts, Rex}", 838 "{local_tm, S2, tf, S2f, ts, Rex}", 839 "{local_tm, Rex}" 840 ] 841
842 - def __init__(self, parent, box):
843 """Build the combo box list widget for a list of list selections. 844 845 @param parent: The parent GUI element. 846 @type parent: wx object instance 847 @param box: The sizer to put the combo box widget into. 848 @type box: wx.Sizer instance 849 """ 850 851 # Store some args. 852 self.parent = parent 853 854 # Initialise all models as being selected. 855 self.select = [] 856 for i in range(len(self.models)): 857 self.select.append(True) 858 859 # Initialise the model selection window. 860 self.model_win = Model_sel_window(self.models, self.params) 861 862 # Horizontal packing for this element. 863 sizer = wx.BoxSizer(wx.HORIZONTAL) 864 865 # Add a label. 866 label = self.parent.add_static_text(sizer, self.parent, text=self.desc, width=self.parent.width_text) 867 868 # Spacer. 869 sizer.AddSpacer((self.parent.spacer_horizontal, -1)) 870 871 # The text input field. 872 self.field = self.parent.add_text_control(sizer, self.parent, text=list_to_gui(self.GetValue()), editable=False) 873 874 # Spacer. 875 sizer.AddSpacer((self.parent.spacer_horizontal, -1)) 876 877 # Add the button. 878 self.button = self.parent.add_button_open(sizer, self.parent, icon=paths.icon_16x16.flag_blue, text="Modify", fn=self.modify, width=self.parent.width_button, height=label.GetSize()[1]+8) 879 880 # Add the contents to the main box. 881 box.Add(sizer, 0, wx.ALL|wx.EXPAND, 0)
882 883
884 - def Enable(self, enable=True):
885 """Enable or disable the element. 886 887 @keyword enable: The flag specifying if the element should be enabled or disabled. 888 @type enable: bool 889 """ 890 891 # Call the control and button's method. 892 self.field.Enable(enable) 893 self.button.Enable(enable)
894 895
896 - def GetValue(self):
897 """Return the list of model-free models. 898 899 @return: The list of model-free models. 900 @rtype: list of str 901 """ 902 903 # Initialise. 904 model_list = [] 905 906 # Add the models if they are selected. 907 for i in range(len(self.models)): 908 if self.select[i]: 909 model_list.append(self.models[i]) 910 911 # Return the list. 912 return model_list
913 914
915 - def set_value(self, value):
916 """Store the list of model-free models. 917 918 @param value: The list of model-free models. 919 @type value: list of str 920 """ 921 922 # First set all models as being deselected. 923 for i in range(len(self.models)): 924 self.select[i] = False 925 926 # Select all models in the list. 927 for model in value: 928 # The model index. 929 index = self.models.index(model) 930 931 # Set the selected flag. 932 self.select[index] = True 933 934 # Update the button. 935 self.update_button() 936 937 # Update the GUI element. 938 self.field.SetValue(list_to_gui(self.GetValue()))
939 940
941 - def modify(self, event=None):
942 """Modify the model-free model selection. 943 944 @keyword event: The wx event. 945 @type event: wx event 946 """ 947 948 # First state that this should not be done. 949 msg = "The model-free models used in dauvergne_protocol auto-analysis should almost never be changed! The consequences will be unpredictable. Please proceed only if you are sure of what you are doing. Would you like to modify the model-free model list?" 950 if status.show_gui and not Question(msg, title="Warning - do not change!", size=(420, 210), default=False).ShowModal() == wx.ID_YES: 951 return 952 953 # Set the model selector window selections. 954 self.model_win.set_selection(self.select) 955 956 # Show the model selector window. 957 if status.show_gui: 958 self.model_win.ShowModal() 959 self.model_win.Close() 960 961 # Set the values. 962 self.select = self.model_win.get_selection() 963 964 # Update the button. 965 self.update_button() 966 967 # Update the GUI element. 968 self.field.SetValue(list_to_gui(self.GetValue()))
969 970
971 - def update_button(self):
972 """Update the button bitmap as needed.""" 973 974 # Change the flag to red to indicate to the user that changing the models is a bad thing! 975 if False in self.select: 976 self.button.SetBitmapLabel(wx.Bitmap(paths.icon_16x16.flag_red, wx.BITMAP_TYPE_ANY)) 977 978 # Otherwise set it to blue (in case all models are selected again). 979 else: 980 self.button.SetBitmapLabel(wx.Bitmap(paths.icon_16x16.flag_blue, wx.BITMAP_TYPE_ANY))
981 982 983
984 -class Mf_list(Local_tm_list):
985 """The model-free model list GUI element.""" 986 987 # Some class variables. 988 desc = "Model-free models:" 989 models = [ 990 "m0", 991 "m1", 992 "m2", 993 "m3", 994 "m4", 995 "m5", 996 "m6", 997 "m7", 998 "m8", 999 "m9" 1000 ] 1001 params = [ 1002 "{}", 1003 "{S2}", 1004 "{S2, te}", 1005 "{S2, Rex}", 1006 "{S2, te, Rex}", 1007 "{S2, S2f, ts}", 1008 "{S2, tf, S2f, ts}", 1009 "{S2, S2f, ts, Rex}", 1010 "{S2, tf, S2f, ts, Rex}", 1011 "{Rex}" 1012 ]
1013 1014 1015
1016 -class Model_sel_window(wx.Dialog):
1017 """The model-free model selector window object.""" 1018
1019 - def __init__(self, models, params):
1020 """Set up the model-free model selector window. 1021 1022 @param models: The list of model-free models. 1023 @type models: list of str 1024 @param params: The list of parameters corresponding to the models. 1025 @type params: list of str 1026 """ 1027 1028 # Set up the dialog. 1029 wx.Dialog.__init__(self, None, id=-1, title="Model-free model selector") 1030 1031 # Initialise some values 1032 size_x = 500 1033 size_y = 300 1034 border = 10 1035 width = size_x - 2*border 1036 1037 # Set the frame properties. 1038 self.SetSize((size_x, size_y)) 1039 self.Centre() 1040 self.SetFont(font.normal) 1041 1042 # The main box sizer. 1043 main_sizer = wx.BoxSizer(wx.VERTICAL) 1044 1045 # Pack the sizer into the frame. 1046 self.SetSizer(main_sizer) 1047 1048 # Build the central sizer, with borders. 1049 sizer = add_border(main_sizer, border=border, packing=wx.VERTICAL) 1050 1051 # Add a list control. 1052 self.model_list = ModelSelListCtrl(self) 1053 1054 # The headers. 1055 self.model_list.InsertColumn(0, "Model-free model") 1056 self.model_list.InsertColumn(1, "Parameters") 1057 1058 # The widths. 1059 self.model_list.SetColumnWidth(0, int(0.4*width)) 1060 self.model_list.SetColumnWidth(1, int(0.5*width)) 1061 1062 # Add the models and parameters. 1063 for i in range(len(models)): 1064 # Set the text. 1065 self.model_list.Append((str_to_gui(models[i]), str_to_gui(params[i]))) 1066 1067 # Set all selections to True. 1068 self.model_list.CheckItem(i) 1069 1070 # Add the table to the sizer. 1071 sizer.Add(self.model_list, 1, wx.ALL|wx.EXPAND, 0)
1072 1073
1074 - def get_selection(self):
1075 """Return the selection as a list of booleans. 1076 1077 @return: The list of models selected. 1078 @rtype: list of bool 1079 """ 1080 1081 # Init. 1082 select = [] 1083 1084 # Loop over the entries. 1085 for i in range(self.model_list.GetItemCount()): 1086 select.append(self.model_list.IsChecked(i)) 1087 1088 # Return the list. 1089 return select
1090 1091
1092 - def set_selection(self, select):
1093 """Set the selection. 1094 1095 @param select: The list of selections. 1096 @type select: list of bool 1097 """ 1098 1099 # Loop over the entries. 1100 for i in range(self.model_list.GetItemCount()): 1101 self.model_list.CheckItem(i, check=select[i])
1102 1103 1104
1105 -class ModelSelListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.CheckListCtrlMixin):
1106 """A special list control with checkboxes.""" 1107
1108 - def __init__(self, parent):
1109 """Initialise the control. 1110 1111 @param parent: The parent window. 1112 @type parent: wx.Frame instance 1113 """ 1114 1115 # Execute the list control __init__() method. 1116 wx.ListCtrl.__init__(self, parent, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT) 1117 1118 # Execute the CheckListCtrlMixin __init__() method. 1119 wx.lib.mixins.listctrl.CheckListCtrlMixin.__init__(self)
1120 1121 1122
1123 -class Protocol_mode_sel_window(wx.Dialog):
1124 """The protocol mode selector window object.""" 1125
1126 - def __init__(self):
1127 """Set up the window.""" 1128 1129 # Set up the dialog. 1130 wx.Dialog.__init__(self, None, id=-1, title="Protocol mode selection") 1131 1132 # Initialise some values 1133 size_x = 600 1134 size_y = 600 1135 border = 10 1136 self.select = 'Fully automated' 1137 1138 # Set the frame properties. 1139 self.SetSize((size_x, size_y)) 1140 self.Centre() 1141 self.SetFont(font.normal) 1142 1143 # The main box sizer. 1144 main_sizer = wx.BoxSizer(wx.VERTICAL) 1145 1146 # Pack the sizer into the frame. 1147 self.SetSizer(main_sizer) 1148 1149 # Build the central sizer, with borders. 1150 sizer = add_border(main_sizer, border=border, packing=wx.HORIZONTAL) 1151 1152 # Build the automatic part. 1153 self.build_auto(sizer) 1154 1155 # Line separator. 1156 sizer.Add(wx.StaticLine(self, -1, style=wx.LI_VERTICAL), 0, wx.EXPAND|wx.ALL, border) 1157 1158 # Build the manual part. 1159 self.build_manual(sizer)
1160 1161
1162 - def build_auto(self, sizer):
1163 """Build the fully automated part of the window. 1164 1165 @param sizer: The sizer to pack the elements into. 1166 @type sizer: wx.BoxSizer instance 1167 """ 1168 1169 # Create a vertical sizer for the elements. 1170 sub_sizer = wx.BoxSizer(wx.VERTICAL) 1171 1172 # The title. 1173 title = wx.StaticText(self, -1, "Fully automated") 1174 title.SetFont(font.subtitle) 1175 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 1176 1177 # Spacing. 1178 sub_sizer.AddStretchSpacer() 1179 1180 # The button. 1181 button = wx.BitmapButton(self, -1, wx.Bitmap(paths.icon_48x48.go_bottom, wx.BITMAP_TYPE_ANY)) 1182 button.SetMinSize((80, 80)) 1183 button.SetToolTipString("Perform a fully automated analysis, looping over global models I to V and terminating with the final run. Please click on the 'About' button for more information.") 1184 sub_sizer.Add(button, 3, wx.EXPAND, 0) 1185 self.Bind(wx.EVT_BUTTON, self.select_full_analysis, button) 1186 1187 # Spacing. 1188 sub_sizer.AddStretchSpacer() 1189 1190 # Add the sub-sizer. 1191 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
1192 1193
1194 - def build_manual(self, sizer):
1195 """Build the manual part of the window. 1196 1197 @param sizer: The sizer to pack the elements into. 1198 @type sizer: wx.BoxSizer instance 1199 """ 1200 1201 # Create a vertical sizer for the elements. 1202 sub_sizer = wx.BoxSizer(wx.VERTICAL) 1203 1204 # The title. 1205 title = wx.StaticText(self, -1, "Manual modes") 1206 title.SetFont(font.subtitle) 1207 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 1208 1209 # Spacing. 1210 sub_sizer.AddSpacer(10) 1211 1212 # The local_tm button. 1213 button = wx.Button(self, -1, u"Local \u03C4m") 1214 button.SetToolTipString("Optimise global model I, the local tm models. Please click on the 'About' button for more information.") 1215 button.SetFont(font.normal) 1216 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1217 self.Bind(wx.EVT_BUTTON, self.select_local_tm, button) 1218 1219 # The sphere button. 1220 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Sphere")) 1221 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'sphere.png', wx.BITMAP_TYPE_ANY)) 1222 button.SetFont(font.normal) 1223 button.SetToolTipString("Optimise global model II, the spherical diffusion model. Please click on the 'About' button for more information.") 1224 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1225 self.Bind(wx.EVT_BUTTON, self.select_sphere, button) 1226 1227 # The prolate spheroid button. 1228 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Prolate spheroid")) 1229 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'prolate.png', wx.BITMAP_TYPE_ANY)) 1230 button.SetFont(font.normal) 1231 button.SetToolTipString("Optimise global model III, the prolate spheroid diffusion model. Please click on the 'About' button for more information.") 1232 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1233 self.Bind(wx.EVT_BUTTON, self.select_prolate, button) 1234 1235 # The oblate spheroid button. 1236 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Oblate spheroid")) 1237 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'oblate.png', wx.BITMAP_TYPE_ANY)) 1238 button.SetFont(font.normal) 1239 button.SetToolTipString("Optimise global model IV, the oblate spheroid diffusion model. Please click on the 'About' button for more information.") 1240 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1241 self.Bind(wx.EVT_BUTTON, self.select_oblate, button) 1242 1243 # The ellipsoid button. 1244 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Ellipsoid")) 1245 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'ellipsoid.png', wx.BITMAP_TYPE_ANY)) 1246 button.SetFont(font.normal) 1247 button.SetToolTipString("Optimise global model V, the ellipsoid diffusion model. Please click on the 'About' button for more information.") 1248 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1249 self.Bind(wx.EVT_BUTTON, self.select_ellipsoid, button) 1250 1251 # The final button. 1252 button = wx.Button(self, -1, str_to_gui("Final")) 1253 button.SetToolTipString("The final run of the protocol. Please click on the 'About' button for more information.") 1254 button.SetFont(font.normal) 1255 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1256 self.Bind(wx.EVT_BUTTON, self.select_final, button) 1257 1258 # Add the sub-sizer. 1259 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
1260 1261
1262 - def select_ellipsoid(self, event=None):
1263 """The ellipsoid global model has been selected. 1264 1265 @keyword event: The wx event. 1266 @type event: wx event 1267 """ 1268 1269 # Set the value. 1270 self.select = 'ellipsoid' 1271 1272 # Close the dialog. 1273 self.Close()
1274 1275
1276 - def select_final(self, event=None):
1277 """The final stage of the protocol has been selected. 1278 1279 @keyword event: The wx event. 1280 @type event: wx event 1281 """ 1282 1283 # Set the value. 1284 self.select = 'final' 1285 1286 # Close the dialog. 1287 self.Close()
1288 1289
1290 - def select_full_analysis(self, event=None):
1291 """The full analysis has been selected. 1292 1293 @keyword event: The wx event. 1294 @type event: wx event 1295 """ 1296 1297 # Set the value. 1298 self.select = 'Fully automated' 1299 1300 # Close the dialog. 1301 self.Close()
1302 1303
1304 - def select_local_tm(self, event=None):
1305 """The local_tm global model has been selected. 1306 1307 @keyword event: The wx event. 1308 @type event: wx event 1309 """ 1310 1311 # Set the value. 1312 self.select = 'local_tm' 1313 1314 # Close the dialog. 1315 self.Close()
1316 1317
1318 - def select_prolate(self, event=None):
1319 """The prolate global model has been selected. 1320 1321 @keyword event: The wx event. 1322 @type event: wx event 1323 """ 1324 1325 # Set the value. 1326 self.select = 'prolate' 1327 1328 # Close the dialog. 1329 self.Close()
1330 1331
1332 - def select_oblate(self, event=None):
1333 """The oblate global model has been selected. 1334 1335 @keyword event: The wx event. 1336 @type event: wx event 1337 """ 1338 1339 # Set the value. 1340 self.select = 'oblate' 1341 1342 # Close the dialog. 1343 self.Close()
1344 1345
1346 - def select_sphere(self, event=None):
1347 """The sphere global model has been selected. 1348 1349 @keyword event: The wx event. 1350 @type event: wx event 1351 """ 1352 1353 # Set the value. 1354 self.select = 'sphere' 1355 1356 # Close the dialog. 1357 self.Close()
1358