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, s2s, 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.setup import get_specific_fn
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.")
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 val = get_specific_fn('default_value')('csa')
796
797
798 uf_store['value.set'](val=val, param='csa', spin_id='@N*')
799
800
801
803 """The model-free analysis execution object."""
804
806 """Execute the calculation."""
807
808
809 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)
810
811
812
814 """The local model-free model list GUI element."""
815
816
817 desc = "Local %s models:" % tm
818 model_desc = [
819 "Model m0 with a local molecular correlation time (%s)." % tm,
820 "Model m1 with a local molecular correlation time (%s)." % tm,
821 "Model m2 with a local molecular correlation time (%s)." % tm,
822 "Model m3 with a local molecular correlation time (%s)." % tm,
823 "Model m4 with a local molecular correlation time (%s)." % tm,
824 "Model m5 with a local molecular correlation time (%s)." % tm,
825 "Model m6 with a local molecular correlation time (%s)." % tm,
826 "Model m7 with a local molecular correlation time (%s)." % tm,
827 "Model m8 with a local molecular correlation time (%s)." % tm,
828 "Model m9 with a local molecular correlation time (%s)." % tm
829 ]
830 models = [
831 "tm0",
832 "tm1",
833 "tm2",
834 "tm3",
835 "tm4",
836 "tm5",
837 "tm6",
838 "tm7",
839 "tm8",
840 "tm9"
841 ]
842 params = [
843 "{%s}" % local_tm,
844 "{%s, %s}" % (local_tm, s2),
845 "{%s, %s, %s}" % (local_tm, s2, te),
846 "{%s, %s, %s}" % (local_tm, s2, rex),
847 "{%s, %s, %s, %s}" % (local_tm, s2, te, rex),
848 "{%s, %s, %s, %s}" % (local_tm, s2, s2f, ts),
849 "{%s, %s, %s, %s, %s}" % (local_tm, s2, tf, s2f, ts),
850 "{%s, %s, %s, %s, %s}" % (local_tm, s2, s2f, ts, rex),
851 "{%s, %s, %s, %s, %s, %s}" % (local_tm, s2, tf, s2f, ts, rex),
852 "{%s, %s}" % (local_tm, rex)
853 ]
854 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?"
855 red_flag = True
856 size = wx.Size(680, 350)
857 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
858 tooltip_button = "Open the model list selector window."
859
860
861
863 """The model-free model list GUI element."""
864
865
866 desc = "Model-free models:"
867 model_desc = [
868 "No statistically significant internal motions.",
869 "The original model with a statistically insignificant %s." % te,
870 "The original Lipari and Szabo model.",
871 "The original model with chemical exchange relaxation but a statistically insignificant %s." % te,
872 "The original model with chemical exchange relaxation.",
873 "The extended model with a statistically insignificant %s." % tf,
874 "The Clore et al., 1991 extended model-free model.",
875 "The extended model with chemical exchange relaxation but a statistically insignificant %s." % tf,
876 "The extended model with chemical exchange relaxation.",
877 "No statistically significant internal motions but chemical exchange relaxation present."
878 ]
879 models = [
880 "m0",
881 "m1",
882 "m2",
883 "m3",
884 "m4",
885 "m5",
886 "m6",
887 "m7",
888 "m8",
889 "m9"
890 ]
891 params = [
892 "{}",
893 "{%s}" % s2,
894 "{%s, %s}" % (s2, te),
895 "{%s, %s}" % (s2, rex),
896 "{%s, %s, %s}" % (s2, te, rex),
897 "{%s, %s, %s}" % (s2, s2f, ts),
898 "{%s, %s, %s, %s}" % (s2, tf, s2f, ts),
899 "{%s, %s, %s, %s}" % (s2, s2f, ts, rex),
900 "{%s, %s, %s, %s, %s}" % (s2, tf, s2f, ts, rex),
901 "{%s}" % rex
902 ]
903 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?"
904 red_flag = True
905 size = wx.Size(850, 350)
906 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."
907 tooltip_button = "Open the model list selector window."
908
909
910
912 """The protocol mode selector window object."""
913
915 """Set up the window."""
916
917
918 wx.Dialog.__init__(self, None, id=-1, title="Protocol mode selection")
919
920
921 size_x = 600
922 size_y = 600
923 border = 10
924 self.select = 'Fully automated'
925
926
927 self.SetSize((size_x, size_y))
928 self.Centre()
929 self.SetFont(font.normal)
930
931
932 main_sizer = wx.BoxSizer(wx.VERTICAL)
933
934
935 self.SetSizer(main_sizer)
936
937
938 sizer = add_border(main_sizer, border=border, packing=wx.HORIZONTAL)
939
940
941 self.build_auto(sizer)
942
943
944 sizer.Add(wx.StaticLine(self, -1, style=wx.LI_VERTICAL), 0, wx.EXPAND|wx.ALL, border)
945
946
947 self.build_manual(sizer)
948
949
951 """Build the fully automated part of the window.
952
953 @param sizer: The sizer to pack the elements into.
954 @type sizer: wx.BoxSizer instance
955 """
956
957
958 sub_sizer = wx.BoxSizer(wx.VERTICAL)
959
960
961 title = wx.StaticText(self, -1, "Fully automated")
962 title.SetFont(font.subtitle)
963 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0)
964
965
966 sub_sizer.AddStretchSpacer()
967
968
969 button = wx.BitmapButton(self, -1, wx.Bitmap(fetch_icon('oxygen.actions.go-bottom', "48x48"), wx.BITMAP_TYPE_ANY))
970 button.SetMinSize((80, 80))
971 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.")
972 sub_sizer.Add(button, 3, wx.EXPAND, 0)
973 self.Bind(wx.EVT_BUTTON, self.select_full_analysis, button)
974
975
976 sub_sizer.AddStretchSpacer()
977
978
979 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
980
981
983 """Build the manual part of the window.
984
985 @param sizer: The sizer to pack the elements into.
986 @type sizer: wx.BoxSizer instance
987 """
988
989
990 sub_sizer = wx.BoxSizer(wx.VERTICAL)
991
992
993 title = wx.StaticText(self, -1, "Manual modes")
994 title.SetFont(font.subtitle)
995 sub_sizer.Add(title, 0, wx.ALIGN_CENTRE_HORIZONTAL, 0)
996
997
998 sub_sizer.AddSpacer(10)
999
1000
1001 button = wx.Button(self, -1, "Local %s" % tm)
1002 button.SetToolTipString("Optimise global model I, the %s models. Please click on the 'About' button for more information." % local_tm)
1003 button.SetFont(font.normal)
1004 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1005 self.Bind(wx.EVT_BUTTON, self.select_local_tm, button)
1006
1007
1008 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Sphere"))
1009 button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'sphere.png', wx.BITMAP_TYPE_ANY))
1010 button.SetFont(font.normal)
1011 button.SetToolTipString("Optimise global model II, the spherical diffusion model. Please click on the 'About' button for more information.")
1012 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1013 self.Bind(wx.EVT_BUTTON, self.select_sphere, button)
1014
1015
1016 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Prolate spheroid"))
1017 button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'prolate.png', wx.BITMAP_TYPE_ANY))
1018 button.SetFont(font.normal)
1019 button.SetToolTipString("Optimise global model III, the prolate spheroid diffusion model. Please click on the 'About' button for more information.")
1020 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1021 self.Bind(wx.EVT_BUTTON, self.select_prolate, button)
1022
1023
1024 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Oblate spheroid"))
1025 button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'oblate.png', wx.BITMAP_TYPE_ANY))
1026 button.SetFont(font.normal)
1027 button.SetToolTipString("Optimise global model IV, the oblate spheroid diffusion model. Please click on the 'About' button for more information.")
1028 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1029 self.Bind(wx.EVT_BUTTON, self.select_oblate, button)
1030
1031
1032 button = wx.lib.buttons.ThemedGenBitmapTextButton(self, -1, None, str_to_gui(" Ellipsoid"))
1033 button.SetBitmapLabel(wx.Bitmap(IMAGE_PATH+'ellipsoid.png', wx.BITMAP_TYPE_ANY))
1034 button.SetFont(font.normal)
1035 button.SetToolTipString("Optimise global model V, the ellipsoid diffusion model. Please click on the 'About' button for more information.")
1036 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1037 self.Bind(wx.EVT_BUTTON, self.select_ellipsoid, button)
1038
1039
1040 button = wx.Button(self, -1, str_to_gui("Final"))
1041 button.SetToolTipString("The final run of the protocol. Please click on the 'About' button for more information.")
1042 button.SetFont(font.normal)
1043 sub_sizer.Add(button, 1, wx.EXPAND, 0)
1044 self.Bind(wx.EVT_BUTTON, self.select_final, button)
1045
1046
1047 sizer.Add(sub_sizer, 1, wx.ALL|wx.EXPAND, 0)
1048
1049
1051 """The ellipsoid global model has been selected.
1052
1053 @keyword event: The wx event.
1054 @type event: wx event
1055 """
1056
1057
1058 self.select = 'ellipsoid'
1059
1060
1061 self.Close()
1062
1063
1065 """The final stage of the protocol has been selected.
1066
1067 @keyword event: The wx event.
1068 @type event: wx event
1069 """
1070
1071
1072 self.select = 'final'
1073
1074
1075 self.Close()
1076
1077
1079 """The full analysis has been selected.
1080
1081 @keyword event: The wx event.
1082 @type event: wx event
1083 """
1084
1085
1086 self.select = 'Fully automated'
1087
1088
1089 self.Close()
1090
1091
1093 """The local_tm global model has been selected.
1094
1095 @keyword event: The wx event.
1096 @type event: wx event
1097 """
1098
1099
1100 self.select = 'local_tm'
1101
1102
1103 self.Close()
1104
1105
1107 """The prolate global model has been selected.
1108
1109 @keyword event: The wx event.
1110 @type event: wx event
1111 """
1112
1113
1114 self.select = 'prolate'
1115
1116
1117 self.Close()
1118
1119
1121 """The oblate global model has been selected.
1122
1123 @keyword event: The wx event.
1124 @type event: wx event
1125 """
1126
1127
1128 self.select = 'oblate'
1129
1130
1131 self.Close()
1132
1133
1135 """The sphere global model has been selected.
1136
1137 @keyword event: The wx event.
1138 @type event: wx event
1139 """
1140
1141
1142 self.select = 'sphere'
1143
1144
1145 self.Close()
1146