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 # Once completed, change the main pipe of the analysis to the final data pipe. 811 ds.relax_gui.analyses[self.data_index].pipe_name = 'final'
812 813 814
815 -class Local_tm_list:
816 """The model-free model list GUI element.""" 817 818 # Some class variables. 819 desc = u'Local \u03C4m models:' 820 models = [ 821 "tm0", 822 "tm1", 823 "tm2", 824 "tm3", 825 "tm4", 826 "tm5", 827 "tm6", 828 "tm7", 829 "tm8", 830 "tm9" 831 ] 832 params = [ 833 "{local_tm}", 834 "{local_tm, S2}", 835 "{local_tm, S2, te}", 836 "{local_tm, S2, Rex}", 837 "{local_tm, S2, te, Rex}", 838 "{local_tm, S2, S2f, ts}", 839 "{local_tm, S2, tf, S2f, ts}", 840 "{local_tm, S2, S2f, ts, Rex}", 841 "{local_tm, S2, tf, S2f, ts, Rex}", 842 "{local_tm, Rex}" 843 ] 844
845 - def __init__(self, parent, box):
846 """Build the combo box list widget for a list of list selections. 847 848 @param parent: The parent GUI element. 849 @type parent: wx object instance 850 @param box: The sizer to put the combo box widget into. 851 @type box: wx.Sizer instance 852 """ 853 854 # Store some args. 855 self.parent = parent 856 857 # Initialise all models as being selected. 858 self.select = [] 859 for i in range(len(self.models)): 860 self.select.append(True) 861 862 # Initialise the model selection window. 863 self.model_win = Model_sel_window(self.models, self.params) 864 865 # Horizontal packing for this element. 866 sizer = wx.BoxSizer(wx.HORIZONTAL) 867 868 # Add a label. 869 label = self.parent.add_static_text(sizer, self.parent, text=self.desc, width=self.parent.width_text) 870 871 # Spacer. 872 sizer.AddSpacer((self.parent.spacer_horizontal, -1)) 873 874 # The text input field. 875 self.field = self.parent.add_text_control(sizer, self.parent, text=list_to_gui(self.GetValue()), editable=False) 876 877 # Spacer. 878 sizer.AddSpacer((self.parent.spacer_horizontal, -1)) 879 880 # Add the button. 881 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) 882 883 # Add the contents to the main box. 884 box.Add(sizer, 0, wx.ALL|wx.EXPAND, 0)
885 886
887 - def Enable(self, enable=True):
888 """Enable or disable the element. 889 890 @keyword enable: The flag specifying if the element should be enabled or disabled. 891 @type enable: bool 892 """ 893 894 # Call the control and button's method. 895 self.field.Enable(enable) 896 self.button.Enable(enable)
897 898
899 - def GetValue(self):
900 """Return the list of model-free models. 901 902 @return: The list of model-free models. 903 @rtype: list of str 904 """ 905 906 # Initialise. 907 model_list = [] 908 909 # Add the models if they are selected. 910 for i in range(len(self.models)): 911 if self.select[i]: 912 model_list.append(self.models[i]) 913 914 # Return the list. 915 return model_list
916 917
918 - def set_value(self, value):
919 """Store the list of model-free models. 920 921 @param value: The list of model-free models. 922 @type value: list of str 923 """ 924 925 # First set all models as being deselected. 926 for i in range(len(self.models)): 927 self.select[i] = False 928 929 # Select all models in the list. 930 for model in value: 931 # The model index. 932 index = self.models.index(model) 933 934 # Set the selected flag. 935 self.select[index] = True 936 937 # Update the button. 938 self.update_button() 939 940 # Update the GUI element. 941 self.field.SetValue(list_to_gui(self.GetValue()))
942 943
944 - def modify(self, event=None):
945 """Modify the model-free model selection. 946 947 @keyword event: The wx event. 948 @type event: wx event 949 """ 950 951 # First state that this should not be done. 952 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?" 953 if status.show_gui and not Question(msg, title="Warning - do not change!", size=(420, 210), default=False).ShowModal() == wx.ID_YES: 954 return 955 956 # Set the model selector window selections. 957 self.model_win.set_selection(self.select) 958 959 # Show the model selector window. 960 if status.show_gui: 961 self.model_win.ShowModal() 962 self.model_win.Close() 963 964 # Set the values. 965 self.select = self.model_win.get_selection() 966 967 # Update the button. 968 self.update_button() 969 970 # Update the GUI element. 971 self.field.SetValue(list_to_gui(self.GetValue()))
972 973
974 - def update_button(self):
975 """Update the button bitmap as needed.""" 976 977 # Change the flag to red to indicate to the user that changing the models is a bad thing! 978 if False in self.select: 979 self.button.SetBitmapLabel(wx.Bitmap(paths.icon_16x16.flag_red, wx.BITMAP_TYPE_ANY)) 980 981 # Otherwise set it to blue (in case all models are selected again). 982 else: 983 self.button.SetBitmapLabel(wx.Bitmap(paths.icon_16x16.flag_blue, wx.BITMAP_TYPE_ANY))
984 985 986
987 -class Mf_list(Local_tm_list):
988 """The model-free model list GUI element.""" 989 990 # Some class variables. 991 desc = "Model-free models:" 992 models = [ 993 "m0", 994 "m1", 995 "m2", 996 "m3", 997 "m4", 998 "m5", 999 "m6", 1000 "m7", 1001 "m8", 1002 "m9" 1003 ] 1004 params = [ 1005 "{}", 1006 "{S2}", 1007 "{S2, te}", 1008 "{S2, Rex}", 1009 "{S2, te, Rex}", 1010 "{S2, S2f, ts}", 1011 "{S2, tf, S2f, ts}", 1012 "{S2, S2f, ts, Rex}", 1013 "{S2, tf, S2f, ts, Rex}", 1014 "{Rex}" 1015 ]
1016 1017 1018
1019 -class Model_sel_window(wx.Dialog):
1020 """The model-free model selector window object.""" 1021
1022 - def __init__(self, models, params):
1023 """Set up the model-free model selector window. 1024 1025 @param models: The list of model-free models. 1026 @type models: list of str 1027 @param params: The list of parameters corresponding to the models. 1028 @type params: list of str 1029 """ 1030 1031 # Set up the dialog. 1032 wx.Dialog.__init__(self, None, id=-1, title="Model-free model selector") 1033 1034 # Initialise some values 1035 size_x = 500 1036 size_y = 300 1037 border = 10 1038 width = size_x - 2*border 1039 1040 # Set the frame properties. 1041 self.SetSize((size_x, size_y)) 1042 self.Centre() 1043 self.SetFont(font.normal) 1044 1045 # The main box sizer. 1046 main_sizer = wx.BoxSizer(wx.VERTICAL) 1047 1048 # Pack the sizer into the frame. 1049 self.SetSizer(main_sizer) 1050 1051 # Build the central sizer, with borders. 1052 sizer = add_border(main_sizer, border=border, packing=wx.VERTICAL) 1053 1054 # Add a list control. 1055 self.model_list = ModelSelListCtrl(self) 1056 1057 # The headers. 1058 self.model_list.InsertColumn(0, "Model-free model") 1059 self.model_list.InsertColumn(1, "Parameters") 1060 1061 # The widths. 1062 self.model_list.SetColumnWidth(0, int(0.4*width)) 1063 self.model_list.SetColumnWidth(1, int(0.5*width)) 1064 1065 # Add the models and parameters. 1066 for i in range(len(models)): 1067 # Set the text. 1068 self.model_list.Append((str_to_gui(models[i]), str_to_gui(params[i]))) 1069 1070 # Set all selections to True. 1071 self.model_list.CheckItem(i) 1072 1073 # Add the table to the sizer. 1074 sizer.Add(self.model_list, 1, wx.ALL|wx.EXPAND, 0)
1075 1076
1077 - def get_selection(self):
1078 """Return the selection as a list of booleans. 1079 1080 @return: The list of models selected. 1081 @rtype: list of bool 1082 """ 1083 1084 # Init. 1085 select = [] 1086 1087 # Loop over the entries. 1088 for i in range(self.model_list.GetItemCount()): 1089 select.append(self.model_list.IsChecked(i)) 1090 1091 # Return the list. 1092 return select
1093 1094
1095 - def set_selection(self, select):
1096 """Set the selection. 1097 1098 @param select: The list of selections. 1099 @type select: list of bool 1100 """ 1101 1102 # Loop over the entries. 1103 for i in range(self.model_list.GetItemCount()): 1104 self.model_list.CheckItem(i, check=select[i])
1105 1106 1107
1108 -class ModelSelListCtrl(wx.ListCtrl, wx.lib.mixins.listctrl.CheckListCtrlMixin):
1109 """A special list control with checkboxes.""" 1110
1111 - def __init__(self, parent):
1112 """Initialise the control. 1113 1114 @param parent: The parent window. 1115 @type parent: wx.Frame instance 1116 """ 1117 1118 # Execute the list control __init__() method. 1119 wx.ListCtrl.__init__(self, parent, -1, style=wx.BORDER_SUNKEN|wx.LC_REPORT) 1120 1121 # Execute the CheckListCtrlMixin __init__() method. 1122 wx.lib.mixins.listctrl.CheckListCtrlMixin.__init__(self)
1123 1124 1125
1126 -class Protocol_mode_sel_window(wx.Dialog):
1127 """The protocol mode selector window object.""" 1128
1129 - def __init__(self):
1130 """Set up the window.""" 1131 1132 # Set up the dialog. 1133 wx.Dialog.__init__(self, None, id=-1, title="Protocol mode selection") 1134 1135 # Initialise some values 1136 size_x = 600 1137 size_y = 600 1138 border = 10 1139 self.select = 'Fully automated' 1140 1141 # Set the frame properties. 1142 self.SetSize((size_x, size_y)) 1143 self.Centre() 1144 self.SetFont(font.normal) 1145 1146 # The main box sizer. 1147 main_sizer = wx.BoxSizer(wx.VERTICAL) 1148 1149 # Pack the sizer into the frame. 1150 self.SetSizer(main_sizer) 1151 1152 # Build the central sizer, with borders. 1153 sizer = add_border(main_sizer, border=border, packing=wx.HORIZONTAL) 1154 1155 # Build the automatic part. 1156 self.build_auto(sizer) 1157 1158 # Line separator. 1159 sizer.Add(wx.StaticLine(self, -1, style=wx.LI_VERTICAL), 0, wx.EXPAND|wx.ALL, border) 1160 1161 # Build the manual part. 1162 self.build_manual(sizer)
1163 1164
1165 - def build_auto(self, sizer):
1166 """Build the fully automated part of the window. 1167 1168 @param sizer: The sizer to pack the elements into. 1169 @type sizer: wx.BoxSizer instance 1170 """ 1171 1172 # Create a vertical sizer for the elements. 1173 sub_sizer = wx.BoxSizer(wx.VERTICAL) 1174 1175 # The title. 1176 title = wx.StaticText(self, -1, "Fully automated") 1177 title.SetFont(font.subtitle) 1178 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 1179 1180 # Spacing. 1181 sub_sizer.AddStretchSpacer() 1182 1183 # The button. 1184 button = wx.BitmapButton(self, -1, wx.Bitmap(paths.icon_48x48.go_bottom, wx.BITMAP_TYPE_ANY)) 1185 button.SetMinSize((80, 80)) 1186 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.") 1187 sub_sizer.Add(button, 3, wx.EXPAND, 0) 1188 self.Bind(wx.EVT_BUTTON, self.select_full_analysis, button) 1189 1190 # Spacing. 1191 sub_sizer.AddStretchSpacer() 1192 1193 # Add the sub-sizer. 1194 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
1195 1196
1197 - def build_manual(self, sizer):
1198 """Build the manual part of the window. 1199 1200 @param sizer: The sizer to pack the elements into. 1201 @type sizer: wx.BoxSizer instance 1202 """ 1203 1204 # Create a vertical sizer for the elements. 1205 sub_sizer = wx.BoxSizer(wx.VERTICAL) 1206 1207 # The title. 1208 title = wx.StaticText(self, -1, "Manual modes") 1209 title.SetFont(font.subtitle) 1210 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 1211 1212 # Spacing. 1213 sub_sizer.AddSpacer(10) 1214 1215 # The local_tm button. 1216 button = wx.Button(self, -1, u"Local \u03C4m") 1217 button.SetToolTipString("Optimise global model I, the local tm models. Please click on the 'About' button for more information.") 1218 button.SetFont(font.normal) 1219 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1220 self.Bind(wx.EVT_BUTTON, self.select_local_tm, button) 1221 1222 # The sphere button. 1223 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Sphere")) 1224 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'sphere.png', wx.BITMAP_TYPE_ANY)) 1225 button.SetFont(font.normal) 1226 button.SetToolTipString("Optimise global model II, the spherical diffusion model. Please click on the 'About' button for more information.") 1227 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1228 self.Bind(wx.EVT_BUTTON, self.select_sphere, button) 1229 1230 # The prolate spheroid button. 1231 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Prolate spheroid")) 1232 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'prolate.png', wx.BITMAP_TYPE_ANY)) 1233 button.SetFont(font.normal) 1234 button.SetToolTipString("Optimise global model III, the prolate spheroid diffusion model. Please click on the 'About' button for more information.") 1235 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1236 self.Bind(wx.EVT_BUTTON, self.select_prolate, button) 1237 1238 # The oblate spheroid button. 1239 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Oblate spheroid")) 1240 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'oblate.png', wx.BITMAP_TYPE_ANY)) 1241 button.SetFont(font.normal) 1242 button.SetToolTipString("Optimise global model IV, the oblate spheroid diffusion model. Please click on the 'About' button for more information.") 1243 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1244 self.Bind(wx.EVT_BUTTON, self.select_oblate, button) 1245 1246 # The ellipsoid button. 1247 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Ellipsoid")) 1248 button.SetBitmapLabel(wx.Bitmap(paths.IMAGE_PATH+'ellipsoid.png', wx.BITMAP_TYPE_ANY)) 1249 button.SetFont(font.normal) 1250 button.SetToolTipString("Optimise global model V, the ellipsoid diffusion model. Please click on the 'About' button for more information.") 1251 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1252 self.Bind(wx.EVT_BUTTON, self.select_ellipsoid, button) 1253 1254 # The final button. 1255 button = wx.Button(self, -1, str_to_gui("Final")) 1256 button.SetToolTipString("The final run of the protocol. Please click on the 'About' button for more information.") 1257 button.SetFont(font.normal) 1258 sub_sizer.Add(button, 1, wx.EXPAND, 0) 1259 self.Bind(wx.EVT_BUTTON, self.select_final, button) 1260 1261 # Add the sub-sizer. 1262 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
1263 1264
1265 - def select_ellipsoid(self, event=None):
1266 """The ellipsoid global model has been selected. 1267 1268 @keyword event: The wx event. 1269 @type event: wx event 1270 """ 1271 1272 # Set the value. 1273 self.select = 'ellipsoid' 1274 1275 # Close the dialog. 1276 self.Close()
1277 1278
1279 - def select_final(self, event=None):
1280 """The final stage of the protocol has been selected. 1281 1282 @keyword event: The wx event. 1283 @type event: wx event 1284 """ 1285 1286 # Set the value. 1287 self.select = 'final' 1288 1289 # Close the dialog. 1290 self.Close()
1291 1292
1293 - def select_full_analysis(self, event=None):
1294 """The full analysis has been selected. 1295 1296 @keyword event: The wx event. 1297 @type event: wx event 1298 """ 1299 1300 # Set the value. 1301 self.select = 'Fully automated' 1302 1303 # Close the dialog. 1304 self.Close()
1305 1306
1307 - def select_local_tm(self, event=None):
1308 """The local_tm global model has been selected. 1309 1310 @keyword event: The wx event. 1311 @type event: wx event 1312 """ 1313 1314 # Set the value. 1315 self.select = 'local_tm' 1316 1317 # Close the dialog. 1318 self.Close()
1319 1320
1321 - def select_prolate(self, event=None):
1322 """The prolate global model has been selected. 1323 1324 @keyword event: The wx event. 1325 @type event: wx event 1326 """ 1327 1328 # Set the value. 1329 self.select = 'prolate' 1330 1331 # Close the dialog. 1332 self.Close()
1333 1334
1335 - def select_oblate(self, event=None):
1336 """The oblate global model has been selected. 1337 1338 @keyword event: The wx event. 1339 @type event: wx event 1340 """ 1341 1342 # Set the value. 1343 self.select = 'oblate' 1344 1345 # Close the dialog. 1346 self.Close()
1347 1348
1349 - def select_sphere(self, event=None):
1350 """The sphere global model has been selected. 1351 1352 @keyword event: The wx event. 1353 @type event: wx event 1354 """ 1355 1356 # Set the value. 1357 self.select = 'sphere' 1358 1359 # Close the dialog. 1360 self.Close()
1361