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