1   
   2   
   3   
   4   
   5   
   6   
   7   
   8   
   9   
  10   
  11   
  12   
  13   
  14   
  15   
  16   
  17   
  18   
  19   
  20   
  21   
  22   
  23   
  24   
  25  """Module for the automatic model-free protocol frame.""" 
  26   
  27   
  28  from math import ceil 
  29  from os import sep 
  30  import wx 
  31  import wx.lib.buttons 
  32  import wx.lib.mixins.listctrl 
  33   
  34   
  35  from auto_analyses import dauvergne_protocol 
  36  from data_store import Relax_data_store; ds = Relax_data_store() 
  37  from graphics import ANALYSIS_IMAGE_PATH, IMAGE_PATH, fetch_icon 
  38  from gui.about import About_base 
  39  from gui.analyses.base import Base_analysis 
  40  from gui.analyses.elements.spin_element import Spin_ctrl 
  41  from gui.analyses.elements.text_element import Text_ctrl 
  42  from gui.analyses.execute import Execute 
  43  from gui.analyses.elements.model_list import Model_list 
  44  from gui.base_classes import Container 
  45  from gui.components.relax_data import Relax_data_list 
  46  from gui.filedialog import RelaxDirDialog 
  47  from gui.fonts import font 
  48  from gui.message import error_message, Missing_data 
  49  from gui.misc import add_border, bitmap_setup 
  50  from gui.string_conv import gui_to_int, gui_to_str, str_to_gui 
  51  from gui.uf_objects import Uf_storage; uf_store = Uf_storage() 
  52  from gui.wizards.wiz_objects import Wiz_window 
  53  from lib.physical_constants import NH_BOND_LENGTH 
  54  from lib.errors import RelaxError 
  55  from lib.text.gui import local_tm, rex, s2, s2f, te, tf, tm, ts 
  56  from lib.text.string import LIST, PARAGRAPH, SECTION, SUBSECTION, TITLE 
  57  from pipe_control.interatomic import interatomic_loop 
  58  from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop 
  59  from pipe_control.pipes import has_bundle, has_pipe 
  60  from specific_analyses.api import return_api 
  61  from status import Status; status = Status() 
  62   
  63   
 148   
 149   
 150   
 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, uf_exec=[], 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 uf_exec:       The list of user function on_execute methods returned from the new analysis wizard. 
 178          @type uf_exec:          list of methods 
 179          @keyword data_index:    The index of the analysis in the relax data store (set to None if no data currently exists). 
 180          @type data_index:       None or int 
 181          """ 
 182   
 183           
 184          self.gui = gui 
 185   
 186           
 187          self.init_flag = True 
 188   
 189           
 190          if data_index == None: 
 191               
 192              if not has_pipe(pipe_name): 
 193                  self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='mf', bundle=pipe_bundle) 
 194   
 195               
 196              if not has_bundle(pipe_bundle): 
 197                  self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name) 
 198   
 199               
 200              data_index = ds.relax_gui.analyses.add('model-free') 
 201   
 202               
 203              ds.relax_gui.analyses[data_index].analysis_name = analysis_name 
 204              ds.relax_gui.analyses[data_index].pipe_name = pipe_name 
 205              ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle 
 206   
 207               
 208              ds.relax_gui.analyses[data_index].grid_inc = None 
 209              ds.relax_gui.analyses[data_index].diff_tensor_grid_inc = {'sphere': 11, 'prolate': 11, 'oblate': 11, 'ellipsoid': 6} 
 210              ds.relax_gui.analyses[data_index].mc_sim_num = None 
 211              ds.relax_gui.analyses[data_index].save_dir = self.gui.system_cwd_path 
 212              ds.relax_gui.analyses[data_index].local_tm_models = ['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9'] 
 213              ds.relax_gui.analyses[data_index].mf_models = ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9'] 
 214              ds.relax_gui.analyses[data_index].max_iter = 30 
 215   
 216           
 217          if ds.relax_gui.analyses[data_index].pipe_bundle == None: 
 218              raise RelaxError("The pipe bundle must be supplied.") 
 219   
 220           
 221          self.data = ds.relax_gui.analyses[data_index] 
 222          self.data_index = data_index 
 223   
 224           
 225          if not hasattr(self.data, 'local_tm_models'): 
 226              self.data.local_tm_models = ['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9'] 
 227          if not hasattr(self.data, 'mf_models'): 
 228              self.data.mf_models = ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9'] 
 229   
 230           
 231          self.mode_win = Protocol_mode_sel_window() 
 232   
 233           
 234          self.observer_register() 
 235   
 236           
 237          super(Auto_model_free, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name) 
  238   
 239   
 240 -    def _about(self, event=None): 
  241          """The about window. 
 242   
 243          @keyword event: The wx event. 
 244          @type event:    wx event 
 245          """ 
 246   
 247           
 248          self.about_dialog = About_window(self) 
 249   
 250           
 251          if status.show_gui: 
 252              self.about_dialog.Show() 
  253   
 254   
 256          """Activate or deactivate certain elements of the analysis in response to the execution lock.""" 
 257   
 258           
 259          enable = False 
 260          if not status.exec_lock.locked(): 
 261              enable = True 
 262   
 263           
 264          wx.CallAfter(self.field_results_dir.Enable, enable) 
 265          wx.CallAfter(self.spin_systems.Enable, enable) 
 266          wx.CallAfter(self.relax_data.Enable, enable) 
 267          wx.CallAfter(self.button_dipole_pair.Enable, enable) 
 268          wx.CallAfter(self.button_csa.Enable, enable) 
 269          wx.CallAfter(self.button_isotope_heteronuc.Enable, enable) 
 270          wx.CallAfter(self.button_isotope_proton.Enable, enable) 
 271          wx.CallAfter(self.local_tm_model_field.Enable, enable) 
 272          wx.CallAfter(self.mf_model_field.Enable, enable) 
 273          wx.CallAfter(self.grid_inc.Enable, enable) 
 274          wx.CallAfter(self.mc_sim_num.Enable, enable) 
 275          wx.CallAfter(self.max_iter.Enable, enable) 
 276          wx.CallAfter(self.mode.Enable, enable) 
 277          wx.CallAfter(self.button_exec_relax.Enable, enable) 
  278   
 279   
 281          """Create and add the value.set buttons for the model-free analysis. 
 282   
 283          @param box:     The box element to pack the GUI element into. 
 284          @type box:      wx.BoxSizer instance 
 285          """ 
 286   
 287           
 288          sizer = wx.BoxSizer(wx.HORIZONTAL) 
 289   
 290           
 291          self.button_dipole_pair = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " Dipolar relaxation") 
 292          self.button_dipole_pair.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.dipole_pair", "22x22"), wx.BITMAP_TYPE_ANY)) 
 293          self.button_dipole_pair.SetFont(font.normal) 
 294          self.button_dipole_pair.SetSize((-1, 25)) 
 295          self.button_dipole_pair.SetToolTipString("Define the magnetic dipole-dipole relaxation mechanism.") 
 296          self.gui.Bind(wx.EVT_BUTTON, self.setup_dipole_pair, self.button_dipole_pair) 
 297          sizer.Add(self.button_dipole_pair, 1, wx.ALL|wx.EXPAND, 0) 
 298   
 299           
 300          self.button_csa = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " CSA relaxation") 
 301          self.button_csa.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.align_tensor", "22x22"), wx.BITMAP_TYPE_ANY)) 
 302          self.button_csa.SetFont(font.normal) 
 303          self.button_csa.SetSize((-1, 25)) 
 304          self.button_csa.SetToolTipString("Define the Chemical Shift Anisotropy (CSA) relaxation mechanism via the value.set user function.") 
 305          self.gui.Bind(wx.EVT_BUTTON, self.value_set_csa, self.button_csa) 
 306          sizer.Add(self.button_csa, 1, wx.ALL|wx.EXPAND, 0) 
 307   
 308           
 309          self.button_isotope_heteronuc = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " X isotope") 
 310          self.button_isotope_heteronuc.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.nuclear_symbol", "22x22"), wx.BITMAP_TYPE_ANY)) 
 311          self.button_isotope_heteronuc.SetFont(font.normal) 
 312          self.button_isotope_heteronuc.SetSize((-1, 25)) 
 313          self.button_isotope_heteronuc.SetToolTipString("Set the nuclear isotope types of the heteronuclear spins via the spin.isotope user function.") 
 314          self.gui.Bind(wx.EVT_BUTTON, self.spin_isotope_heteronuc, self.button_isotope_heteronuc) 
 315          sizer.Add(self.button_isotope_heteronuc, 1, wx.ALL|wx.EXPAND, 0) 
 316   
 317           
 318          self.button_isotope_proton = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, " H isotope") 
 319          self.button_isotope_proton.SetBitmapLabel(wx.Bitmap(fetch_icon("relax.nuclear_symbol", "22x22"), wx.BITMAP_TYPE_ANY)) 
 320          self.button_isotope_proton.SetFont(font.normal) 
 321          self.button_isotope_proton.SetSize((-1, 25)) 
 322          self.button_isotope_proton.SetToolTipString("Set the nuclear isotope types of the proton spins via the spin.isotope user function.") 
 323          self.gui.Bind(wx.EVT_BUTTON, self.spin_isotope_proton, self.button_isotope_proton) 
 324          sizer.Add(self.button_isotope_proton, 1, wx.ALL|wx.EXPAND, 0) 
 325   
 326           
 327          box.Add(sizer, 0, wx.ALL|wx.EXPAND, 0) 
  328   
 329   
 331          """Assemble the data required for the auto-analysis. 
 332   
 333          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. 
 334   
 335          @return:    A container with all the data required for the auto-analysis. 
 336          @rtype:     class instance, list of str 
 337          """ 
 338   
 339           
 340          data = Container() 
 341          missing = [] 
 342   
 343           
 344          data.pipe_name = self.data.pipe_name 
 345          data.pipe_bundle = self.data.pipe_bundle 
 346   
 347           
 348          data.local_tm_models = self.local_tm_model_field.GetValue() 
 349          data.mf_models = self.mf_model_field.GetValue() 
 350   
 351           
 352          data.conv_loop = True 
 353   
 354           
 355          data.inc = gui_to_int(self.grid_inc.GetValue()) 
 356          if hasattr(self.data, 'diff_tensor_grid_inc'): 
 357              data.diff_tensor_grid_inc = self.data.diff_tensor_grid_inc 
 358          else: 
 359              data.diff_tensor_grid_inc = {'sphere': 11, 'prolate': 11, 'oblate': 11, 'ellipsoid': 6} 
 360   
 361           
 362          data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue()) 
 363   
 364           
 365          data.max_iter = self.data.max_iter 
 366   
 367           
 368          data.save_dir = self.data.save_dir 
 369   
 370           
 371          if not exists_mol_res_spin_data(): 
 372              missing.append("Sequence data") 
 373   
 374           
 375          if not hasattr(cdp, 'ri_ids') or len(cdp.ri_ids) == 0: 
 376              missing.append("Relaxation data") 
 377   
 378           
 379          if hasattr(cdp, 'ri_ids') and len(cdp.ri_ids) <= 3: 
 380              missing.append("Insufficient relaxation data, 4 or more data sets are essential for the execution of the dauvergne_protocol auto-analysis. Check that you have entered data for a least two spectrometer fields.") 
 381   
 382           
 383          if not hasattr(cdp, 'interatomic') or len(cdp.interatomic) == 0: 
 384              missing.append("Interatomic data (for the dipole-dipole interaction)") 
 385   
 386           
 387          mode = gui_to_str(self.mode.GetValue()) 
 388   
 389           
 390          if mode == 'Fully automated': 
 391               
 392              data.global_models = ['local_tm', 'sphere', 'prolate', 'oblate', 'ellipsoid', 'final'] 
 393   
 394           
 395          else: 
 396              data.global_models = [mode] 
 397   
 398           
 399          vector_check = False 
 400          if 'prolate' in data.global_models or 'oblate' in data.global_models or 'ellipsoid' in data.global_models: 
 401              vector_check = True 
 402   
 403           
 404          for spin, spin_id in spin_loop(return_id=True): 
 405               
 406              if not spin.select: 
 407                  continue 
 408   
 409               
 410              msg = "Spin '%s' - %s (try the %s user function)." % (spin_id, "%s", "%s") 
 411   
 412               
 413              if not hasattr(spin, 'isotope') or spin.isotope == None: 
 414                  missing.append(msg % ("nuclear isotope data", "spin.isotope")) 
 415   
 416               
 417              if (hasattr(spin, 'isotope') and spin.isotope in ['15N', '13C']) and (not hasattr(spin, 'csa') or spin.csa == None): 
 418                  missing.append(msg % ("CSA data", "value.set")) 
 419   
 420           
 421          for interatom in interatomic_loop(): 
 422               
 423              spin1 = return_spin(interatom.spin_id1) 
 424              spin2 = return_spin(interatom.spin_id2) 
 425   
 426               
 427              if not spin1.select: 
 428                  continue 
 429              if not spin2.select: 
 430                  continue 
 431   
 432               
 433              msg = "Spin pair '%s' and '%s' - %s (try the %s user function)." % (interatom.spin_id1, interatom.spin_id2, "%s", "%s") 
 434   
 435               
 436              if not hasattr(interatom, 'r') or interatom.r == None: 
 437                  missing.append(msg % ("bond length data", "value.set")) 
 438   
 439               
 440              if vector_check and (not hasattr(interatom, 'vector') or interatom.vector == None): 
 441                  missing.append(msg % ("unit vectors", "interatom.unit_vectors")) 
 442   
 443           
 444          return data, missing 
  445   
 446   
 448          """Construct the left hand box to pack into the main model-free box. 
 449   
 450          @return:    The left hand box element containing the bitmap and about button to pack into the main model-free box. 
 451          @rtype:     wx.BoxSizer instance 
 452          """ 
 453   
 454           
 455          left_box = wx.BoxSizer(wx.VERTICAL) 
 456   
 457           
 458          bitmaps = [ANALYSIS_IMAGE_PATH+"model_free"+sep+"model_free_200x200.png", 
 459                     IMAGE_PATH+'modelfree.png'] 
 460   
 461           
 462          for i in range(len(bitmaps)): 
 463               
 464              bitmap = wx.StaticBitmap(self, -1, bitmap_setup(bitmaps[i])) 
 465   
 466               
 467              left_box.Add(bitmap, 0, wx.ALL, 0) 
 468   
 469           
 470          left_box.AddStretchSpacer() 
 471   
 472           
 473          button_sizer = wx.BoxSizer(wx.HORIZONTAL) 
 474   
 475           
 476          button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, "About") 
 477          button.SetBitmapLabel(wx.Bitmap(fetch_icon('oxygen.actions.help-about', "22x22"), wx.BITMAP_TYPE_ANY)) 
 478          button.SetFont(font.normal) 
 479          button.SetToolTipString("Information about this automatic analysis") 
 480   
 481           
 482          self.Bind(wx.EVT_BUTTON, self._about, button) 
 483   
 484           
 485          cursor = wx.StockCursor(wx.CURSOR_QUESTION_ARROW) 
 486          button.SetCursor(cursor) 
 487   
 488           
 489          button_sizer.Add(button, 0, 0, 0) 
 490          left_box.Add(button_sizer, 0, wx.ALL, 0) 
 491   
 492           
 493          return left_box 
  494   
 495   
 497          """Construct the right hand box to pack into the main model-free box. 
 498   
 499          @return:    The right hand box element containing all model-free GUI elements (excluding the bitmap) to pack into the main model-free box. 
 500          @rtype:     wx.BoxSizer instance 
 501          """ 
 502   
 503           
 504          box = wx.BoxSizer(wx.VERTICAL) 
 505   
 506           
 507          self.add_title(box, "Model-free analysis") 
 508   
 509           
 510          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) 
 511   
 512           
 513          self.field_results_dir = Text_ctrl(box, self, text="Results directory:", icon=fetch_icon('oxygen.actions.document-open-folder', "16x16"), default=self.data.save_dir, tooltip="The directory in which all automatically created files will be saved.", tooltip_button="Select the results directory.", fn=self.results_directory, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 
 514   
 515           
 516          self.add_spin_systems(box, self) 
 517   
 518           
 519          box.AddSpacer(10) 
 520          self.relax_data = Relax_data_list(gui=self.gui, parent=self, box=box, id=str(self.data_index)) 
 521          box.AddSpacer(10) 
 522   
 523           
 524          self.add_values(box) 
 525          box.AddSpacer(10) 
 526   
 527           
 528          self.local_tm_model_field = Local_tm_list(self, box) 
 529          self.local_tm_model_field.set_value(self.data.local_tm_models) 
 530   
 531           
 532          self.mf_model_field = Mf_list(self, box) 
 533          self.mf_model_field.set_value(self.data.mf_models) 
 534   
 535           
 536          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) 
 537          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) 
 538   
 539           
 540          self.max_iter = Spin_ctrl(box, self, text="Maximum iterations:", default=self.data.max_iter, tooltip="The maximum number of iterations for the protocol.  This is the limit for the global looping over the optimisation of the model-free models, model elimination, model selection and then optimisation of the diffusion tensor.", min=25, max=100, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 
 541   
 542           
 543          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 separately.", tooltip_button="Open the protocol mode selection window.", icon=fetch_icon('oxygen.actions.system-run', "16x16"), fn=self.mode_dialog, editable=False, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal) 
 544   
 545           
 546          box.AddSpacer(30) 
 547          box.AddStretchSpacer() 
 548   
 549           
 550          self.button_exec_relax = self.add_execute_analysis(box, self.execute) 
 551   
 552           
 553          return box 
  554   
 555   
 557          """Unregister the spin count from the user functions.""" 
 558   
 559           
 560          self.observer_register(remove=True) 
 561   
 562           
 563          self.relax_data.delete() 
 564   
 565           
 566          if hasattr(self, 'dipole_wizard'): 
 567              self.dipole_wizard.Destroy() 
 568              del self.dipole_wizard 
 569   
 570           
 571          self.mode_win.Destroy() 
 572          del self.mode_win 
 573   
 574           
 575          self.local_tm_model_field.model_win.Destroy() 
 576          del self.local_tm_model_field 
 577          self.mf_model_field.model_win.Destroy() 
 578          del self.mf_model_field 
 579   
 580           
 581          if hasattr(self, 'missing_data'): 
 582              self.missing_data.Destroy() 
 583              del self.missing_data 
  584   
 585   
 626   
 627   
 629          """The calculation mode selection. 
 630   
 631          @keyword event: The wx event. 
 632          @type event:    wx event 
 633          """ 
 634   
 635           
 636          if status.show_gui: 
 637              self.mode_win.ShowModal() 
 638   
 639           
 640          self.mode.SetValue(str_to_gui(self.mode_win.select)) 
  641   
 642   
 663   
 664   
 666          """The results directory selection. 
 667   
 668          @keyword event: The wx event. 
 669          @type event:    wx event 
 670          """ 
 671   
 672           
 673          dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue()) 
 674   
 675           
 676          if status.show_gui and dialog.ShowModal() != wx.ID_OK: 
 677               
 678              return 
 679   
 680           
 681          path = gui_to_str(dialog.get_path()) 
 682          if not path: 
 683              return 
 684   
 685           
 686          self.data.save_dir = path 
 687   
 688           
 689          self.field_results_dir.SetValue(str_to_gui(path)) 
  690   
 691   
 693          """Create the wizard for the dipole-dipole interaction. 
 694   
 695          @keyword event: The wx event. 
 696          @type event:    wx event 
 697          """ 
 698   
 699           
 700          wx.BeginBusyCursor() 
 701   
 702           
 703          if hasattr(self, 'dipole_wizard'): 
 704              self.dipole_wizard.Destroy() 
 705   
 706           
 707          self.dipole_wizard = Wiz_window(parent=self.gui, size_x=1000, size_y=750, title="Dipole-dipole interaction setup") 
 708   
 709           
 710          if not hasattr(cdp, 'structure'): 
 711               
 712              page = uf_store['structure.read_pdb'].create_page(self.dipole_wizard, sync=True) 
 713              self.dipole_wizard.add_page(page, skip_button=True) 
 714   
 715               
 716              page = uf_store['structure.get_pos'].create_page(self.dipole_wizard, sync=True) 
 717              self.dipole_wizard.add_page(page, skip_button=True) 
 718   
 719           
 720          page = uf_store['interatom.define'].create_page(self.dipole_wizard, sync=True) 
 721          page.SetValue('spin_id1', '@N') 
 722          page.SetValue('spin_id2', '@H') 
 723          self.dipole_wizard.add_page(page) 
 724   
 725           
 726          page = uf_store['interatom.set_dist'].create_page(self.dipole_wizard, sync=True) 
 727          page.SetValue('spin_id1', '@N*') 
 728          page.SetValue('spin_id2', '@H*') 
 729          page.SetValue('ave_dist', NH_BOND_LENGTH) 
 730          self.dipole_wizard.add_page(page) 
 731   
 732           
 733          page = uf_store['interatom.unit_vectors'].create_page(self.dipole_wizard, sync=True) 
 734          self.dipole_wizard.add_page(page) 
 735   
 736           
 737          if wx.IsBusy(): 
 738              wx.EndBusyCursor() 
 739   
 740           
 741          self.dipole_wizard.run() 
  742   
 743   
 745          """Set the nuclear isotope types of the heteronuclear spins via the spin.isotope user function. 
 746   
 747          @keyword event: The wx event. 
 748          @type event:    wx event 
 749          """ 
 750   
 751           
 752          uf_store['spin.isotope'](isotope='15N', spin_id='@N*') 
  753   
 754   
 756          """Set the nuclear isotope types of the proton spins via the spin.isotope user function. 
 757   
 758          @keyword event: The wx event. 
 759          @type event:    wx event 
 760          """ 
 761   
 762           
 763          uf_store['spin.isotope'](isotope='1H', spin_id='@H*') 
  764   
 765   
 767          """Synchronise the analysis frame and the relax data store, both ways. 
 768   
 769          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. 
 770   
 771          @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. 
 772          @type upload:       bool 
 773          """ 
 774   
 775           
 776          if upload: 
 777              self.data.local_tm_models = self.local_tm_model_field.GetValue() 
 778          else: 
 779              self.local_tm_model_field.set_value(self.data.local_tm_models) 
 780   
 781           
 782          if upload: 
 783              self.data.mf_models = self.mf_model_field.GetValue() 
 784          else: 
 785              self.mf_model_field.set_value(self.data.mf_models) 
 786   
 787           
 788          if upload: 
 789              self.data.grid_inc = gui_to_int(self.grid_inc.GetValue()) 
 790          elif hasattr(self.data, 'grid_inc'): 
 791              self.grid_inc.SetValue(int(self.data.grid_inc)) 
 792   
 793           
 794          if upload: 
 795              self.data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue()) 
 796          elif hasattr(self.data, 'mc_sim_num'): 
 797              self.mc_sim_num.SetValue(int(self.data.mc_sim_num)) 
 798   
 799           
 800          if upload: 
 801              self.data.save_dir = str(self.field_results_dir.GetValue()) 
 802          else: 
 803              self.field_results_dir.SetValue(str_to_gui(self.data.save_dir)) 
 804   
 805           
 806          if upload: 
 807              self.data.max_iter = gui_to_int(self.max_iter.GetValue()) 
 808          else: 
 809              self.max_iter.SetValue(int(self.data.max_iter)) 
  810   
 811   
 813          """Set the CSA via the value.set uf. 
 814   
 815          @keyword event: The wx event. 
 816          @type event:    wx event 
 817          """ 
 818   
 819           
 820          api = return_api() 
 821          val = api.default_value('csa') 
 822   
 823           
 824          uf_store['value.set'](val=val, param='csa', spin_id='@N*') 
   825   
 826   
 827   
 829      """The model-free analysis execution object.""" 
 830   
 832          """Execute the calculation.""" 
 833   
 834           
 835          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) 
   836   
 837   
 838   
 840      """The local model-free model list GUI element.""" 
 841   
 842       
 843      desc = "Local %s models:" % tm 
 844      model_desc = [ 
 845          "Model m0 with a local molecular correlation time (%s)." % tm, 
 846          "Model m1 with a local molecular correlation time (%s)." % tm, 
 847          "Model m2 with a local molecular correlation time (%s)." % tm, 
 848          "Model m3 with a local molecular correlation time (%s)." % tm, 
 849          "Model m4 with a local molecular correlation time (%s)." % tm, 
 850          "Model m5 with a local molecular correlation time (%s)." % tm, 
 851          "Model m6 with a local molecular correlation time (%s)." % tm, 
 852          "Model m7 with a local molecular correlation time (%s)." % tm, 
 853          "Model m8 with a local molecular correlation time (%s)." % tm, 
 854          "Model m9 with a local molecular correlation time (%s)." % tm 
 855      ] 
 856      models = [ 
 857          "tm0", 
 858          "tm1", 
 859          "tm2", 
 860          "tm3", 
 861          "tm4", 
 862          "tm5", 
 863          "tm6", 
 864          "tm7", 
 865          "tm8", 
 866          "tm9" 
 867      ] 
 868      params = [ 
 869          "{%s}" % local_tm, 
 870          "{%s, %s}" % (local_tm, s2), 
 871          "{%s, %s, %s}" % (local_tm, s2, te), 
 872          "{%s, %s, %s}" % (local_tm, s2, rex), 
 873          "{%s, %s, %s, %s}" % (local_tm, s2, te, rex), 
 874          "{%s, %s, %s, %s}" % (local_tm, s2, s2f, ts), 
 875          "{%s, %s, %s, %s, %s}" % (local_tm, s2, tf, s2f, ts), 
 876          "{%s, %s, %s, %s, %s}" % (local_tm, s2, s2f, ts, rex), 
 877          "{%s, %s, %s, %s, %s, %s}" % (local_tm, s2, tf, s2f, ts, rex), 
 878          "{%s, %s}" % (local_tm, rex) 
 879      ] 
 880      warning = "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?" 
 881      red_flag = True 
 882      size = wx.Size(680, 350) 
 883      tooltip = "The list model-free models with the %s parameter to optimise as the first step of the protocol (see the about window for details).  This really should not be changed." % local_tm 
 884      tooltip_button = "Open the model list selector window." 
  885   
 886   
 887   
 889      """The model-free model list GUI element.""" 
 890   
 891       
 892      desc = "Model-free models:" 
 893      model_desc = [ 
 894          "No statistically significant internal motions.", 
 895          "The original model with a statistically insignificant %s." % te, 
 896          "The original Lipari and Szabo model.", 
 897          "The original model with chemical exchange relaxation but a statistically insignificant %s." % te, 
 898          "The original model with chemical exchange relaxation.", 
 899          "The extended model with a statistically insignificant %s." % tf, 
 900          "The Clore et al., 1991 extended model-free model.", 
 901          "The extended model with chemical exchange relaxation but a statistically insignificant %s." % tf, 
 902          "The extended model with chemical exchange relaxation.", 
 903          "No statistically significant internal motions but chemical exchange relaxation present." 
 904      ] 
 905      models = [ 
 906          "m0", 
 907          "m1", 
 908          "m2", 
 909          "m3", 
 910          "m4", 
 911          "m5", 
 912          "m6", 
 913          "m7", 
 914          "m8", 
 915          "m9" 
 916      ] 
 917      params = [ 
 918          "{}", 
 919          "{%s}" % s2, 
 920          "{%s, %s}" % (s2, te), 
 921          "{%s, %s}" % (s2, rex), 
 922          "{%s, %s, %s}" % (s2, te, rex), 
 923          "{%s, %s, %s}" % (s2, s2f, ts), 
 924          "{%s, %s, %s, %s}" % (s2, tf, s2f, ts), 
 925          "{%s, %s, %s, %s}" % (s2, s2f, ts, rex), 
 926          "{%s, %s, %s, %s, %s}" % (s2, tf, s2f, ts, rex), 
 927          "{%s}" % rex 
 928      ] 
 929      warning = "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?" 
 930      red_flag = True 
 931      size = wx.Size(850, 350) 
 932      tooltip = "The list model-free models to optimise as the iterative part of the protocol (see the about window for details).  This really should not be changed." 
 933      tooltip_button = "Open the model list selector window." 
  934   
 935   
 936   
 938      """The protocol mode selector window object.""" 
 939   
 941          """Set up the window.""" 
 942   
 943           
 944          wx.Dialog.__init__(self, None, id=-1, title="Protocol mode selection") 
 945   
 946           
 947          size_x = 600 
 948          size_y = 600 
 949          border = 10 
 950          self.select = 'Fully automated' 
 951   
 952           
 953          self.SetSize((size_x, size_y)) 
 954          self.Centre() 
 955          self.SetFont(font.normal) 
 956   
 957           
 958          main_sizer = wx.BoxSizer(wx.VERTICAL) 
 959   
 960           
 961          self.SetSizer(main_sizer) 
 962   
 963           
 964          sizer = add_border(main_sizer, border=border, packing=wx.HORIZONTAL) 
 965   
 966           
 967          self.build_auto(sizer) 
 968   
 969           
 970          sizer.Add(wx.StaticLine(self, -1, style=wx.LI_VERTICAL), 0, wx.EXPAND|wx.ALL, border) 
 971   
 972           
 973          self.build_manual(sizer) 
  974   
 975   
 977          """Build the fully automated part of the window. 
 978   
 979          @param sizer:   The sizer to pack the elements into. 
 980          @type sizer:    wx.BoxSizer instance 
 981          """ 
 982   
 983           
 984          sub_sizer = wx.BoxSizer(wx.VERTICAL) 
 985   
 986           
 987          title = wx.StaticText(self, -1, "Fully automated") 
 988          title.SetFont(font.subtitle) 
 989          sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 
 990   
 991           
 992          sub_sizer.AddStretchSpacer() 
 993   
 994           
 995          button = wx.BitmapButton(self, -1, wx.Bitmap(fetch_icon('oxygen.actions.go-bottom', "48x48"), wx.BITMAP_TYPE_ANY)) 
 996          button.SetMinSize((80, 80)) 
 997          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.") 
 998          sub_sizer.Add(button, 3, wx.EXPAND, 0) 
 999          self.Bind(wx.EVT_BUTTON, self.select_full_analysis, button) 
1000   
1001           
1002          sub_sizer.AddStretchSpacer() 
1003   
1004           
1005          sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0) 
 1006   
1007   
1009          """Build the manual part of the window. 
1010   
1011          @param sizer:   The sizer to pack the elements into. 
1012          @type sizer:    wx.BoxSizer instance 
1013          """ 
1014   
1015           
1016          sub_sizer = wx.BoxSizer(wx.VERTICAL) 
1017   
1018           
1019          title = wx.StaticText(self, -1, "Manual modes") 
1020          title.SetFont(font.subtitle) 
1021          sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0) 
1022   
1023           
1024          sub_sizer.AddSpacer(10) 
1025   
1026           
1027          button = wx.Button(self, -1, "Local %s" % tm) 
1028          button.SetToolTipString("Optimise global model I, the %s models.  Please click on the 'About' button for more information." % local_tm) 
1029          button.SetFont(font.normal) 
1030          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1031          self.Bind(wx.EVT_BUTTON, self.select_local_tm, button) 
1032   
1033           
1034          button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui("   Sphere")) 
1035          button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'sphere.png', wx.BITMAP_TYPE_ANY)) 
1036          button.SetFont(font.normal) 
1037          button.SetToolTipString("Optimise global model II, the spherical diffusion model.  Please click on the 'About' button for more information.") 
1038          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1039          self.Bind(wx.EVT_BUTTON, self.select_sphere, button) 
1040   
1041           
1042          button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui("   Prolate spheroid")) 
1043          button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'prolate.png', wx.BITMAP_TYPE_ANY)) 
1044          button.SetFont(font.normal) 
1045          button.SetToolTipString("Optimise global model III, the prolate spheroid diffusion model.  Please click on the 'About' button for more information.") 
1046          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1047          self.Bind(wx.EVT_BUTTON, self.select_prolate, button) 
1048   
1049           
1050          button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui("   Oblate spheroid")) 
1051          button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'oblate.png', wx.BITMAP_TYPE_ANY)) 
1052          button.SetFont(font.normal) 
1053          button.SetToolTipString("Optimise global model IV, the oblate spheroid diffusion model.  Please click on the 'About' button for more information.") 
1054          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1055          self.Bind(wx.EVT_BUTTON, self.select_oblate, button) 
1056   
1057           
1058          button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui("   Ellipsoid")) 
1059          button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'ellipsoid.png', wx.BITMAP_TYPE_ANY)) 
1060          button.SetFont(font.normal) 
1061          button.SetToolTipString("Optimise global model V, the ellipsoid diffusion model.  Please click on the 'About' button for more information.") 
1062          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1063          self.Bind(wx.EVT_BUTTON, self.select_ellipsoid, button) 
1064   
1065           
1066          button = wx.Button(self, -1, str_to_gui("Final")) 
1067          button.SetToolTipString("The final run of the protocol.  Please click on the 'About' button for more information.") 
1068          button.SetFont(font.normal) 
1069          sub_sizer.Add(button, 1, wx.EXPAND, 0) 
1070          self.Bind(wx.EVT_BUTTON, self.select_final, button) 
1071   
1072           
1073          sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0) 
 1074   
1075   
1077          """The ellipsoid global model has been selected. 
1078   
1079          @keyword event: The wx event. 
1080          @type event:    wx event 
1081          """ 
1082   
1083           
1084          self.select = 'ellipsoid' 
1085   
1086           
1087          self.Close() 
 1088   
1089   
1091          """The final stage of the protocol has been selected. 
1092   
1093          @keyword event: The wx event. 
1094          @type event:    wx event 
1095          """ 
1096   
1097           
1098          self.select = 'final' 
1099   
1100           
1101          self.Close() 
 1102   
1103   
1105          """The full analysis has been selected. 
1106   
1107          @keyword event: The wx event. 
1108          @type event:    wx event 
1109          """ 
1110   
1111           
1112          self.select = 'Fully automated' 
1113   
1114           
1115          self.Close() 
 1116   
1117   
1119          """The local_tm global model has been selected. 
1120   
1121          @keyword event: The wx event. 
1122          @type event:    wx event 
1123          """ 
1124   
1125           
1126          self.select = 'local_tm' 
1127   
1128           
1129          self.Close() 
 1130   
1131   
1133          """The prolate global model has been selected. 
1134   
1135          @keyword event: The wx event. 
1136          @type event:    wx event 
1137          """ 
1138   
1139           
1140          self.select = 'prolate' 
1141   
1142           
1143          self.Close() 
 1144   
1145   
1147          """The oblate global model has been selected. 
1148   
1149          @keyword event: The wx event. 
1150          @type event:    wx event 
1151          """ 
1152   
1153           
1154          self.select = 'oblate' 
1155   
1156           
1157          self.Close() 
 1158   
1159   
1161          """The sphere global model has been selected. 
1162   
1163          @keyword event: The wx event. 
1164          @type event:    wx event 
1165          """ 
1166   
1167           
1168          self.select = 'sphere' 
1169   
1170           
1171          self.Close() 
  1172