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