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 relaxation dispersion analysis."""
25
26
27 import wx
28
29
30 from auto_analyses.relax_disp import Relax_disp
31 from data_store import Relax_data_store; ds = Relax_data_store()
32 from graphics import ANALYSIS_IMAGE_PATH, fetch_icon
33 from gui.analyses.base import Base_analysis
34 from gui.analyses.elements.bool_element import Boolean_ctrl
35 from gui.analyses.elements.float_element import Float_ctrl
36 from gui.analyses.elements.spin_element import Spin_ctrl
37 from gui.analyses.elements.text_element import Text_ctrl
38 from gui.analyses.elements.model_list import Model_list
39 from gui.analyses.execute import Execute
40 from gui.base_classes import Container
41 from gui.components.spectrum import Spectra_list
42 from gui.filedialog import RelaxDirDialog
43 from gui.fonts import font
44 from gui.message import error_message, Missing_data
45 from gui.string_conv import float_to_gui, gui_to_float, gui_to_int, gui_to_str, str_to_gui
46 from gui.uf_objects import Uf_storage; uf_store = Uf_storage()
47 from gui.wizards.peak_intensity import Peak_intensity_wizard
48 from lib.dispersion.variables import MODEL_B14, MODEL_B14_FULL, MODEL_CR72, MODEL_CR72_FULL, MODEL_DPL94, MODEL_IT99, MODEL_LIST_CPMG, MODEL_LIST_R1RHO, MODEL_LM63, MODEL_LM63_3SITE, MODEL_M61, MODEL_M61B, MODEL_MMQ_CR72, MODEL_MP05, MODEL_NOREX, MODEL_NS_CPMG_2SITE_3D, MODEL_NS_CPMG_2SITE_3D_FULL, MODEL_NS_CPMG_2SITE_EXPANDED, MODEL_NS_CPMG_2SITE_STAR, MODEL_NS_CPMG_2SITE_STAR_FULL, MODEL_NS_MMQ_2SITE, MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR, MODEL_NS_R1RHO_2SITE, MODEL_NS_R1RHO_3SITE, MODEL_NS_R1RHO_3SITE_LINEAR, MODEL_R2EFF, MODEL_TAP03, MODEL_TP02, MODEL_TSMFK01
49 from lib.text.gui import dw, dw_AB, dw_BC, dwH, dwH_AB, dwH_BC, i0, kex, kAB, kBC, kAC, padw2, phi_ex, phi_exB, phi_exC, r1, r1rho, r1rho_prime, r1, r2, r2a, r2b, r2eff
50 from pipe_control.mol_res_spin import exists_mol_res_spin_data, spin_loop
51 from pipe_control.pipes import has_bundle, has_pipe
52 from specific_analyses.relax_disp.data import has_cpmg_exp_type, has_r1rho_exp_type
53 from status import Status; status = Status()
54
55
57 """The relaxation dispersion auto-analysis GUI element."""
58
59
60 analysis_type = None
61 bitmap = ANALYSIS_IMAGE_PATH+"relax_disp_200x200.png"
62 label = 'Relax-disp'
63
64 - 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):
65 """Build the automatic R1 and R2 analysis GUI frame elements.
66
67 @param parent: The parent wx element.
68 @type parent: wx object
69 @keyword id: The unique ID number.
70 @type id: int
71 @keyword pos: The position.
72 @type pos: wx.Size object
73 @keyword size: The size.
74 @type size: wx.Size object
75 @keyword style: The style.
76 @type style: int
77 @keyword name: The name for the panel.
78 @type name: unicode
79 @keyword gui: The main GUI class.
80 @type gui: gui.relax_gui.Main instance
81 @keyword analysis_name: The name of the analysis (the name in the tab part of the notebook).
82 @type analysis_name: str
83 @keyword pipe_name: The name of the data pipe associated with this analysis.
84 @type pipe_name: str
85 @keyword pipe_bundle: The name of the data pipe bundle associated with this analysis.
86 @type pipe_bundle: str
87 @keyword uf_exec: The list of user function on_execute methods returned from the new analysis wizard.
88 @type uf_exec: list of methods
89 @keyword data_index: The index of the analysis in the relax data store (set to None if no data currently exists).
90 @type data_index: None or int
91 """
92
93
94 self.gui = gui
95
96
97 self.init_flag = True
98
99
100 if data_index == None:
101
102 if not has_pipe(pipe_name):
103 self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='relax_disp', bundle=pipe_bundle)
104
105
106 if not has_bundle(pipe_bundle):
107 self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name)
108
109
110 data_index = ds.relax_gui.analyses.add(self.label)
111
112
113 ds.relax_gui.analyses[data_index].analysis_name = analysis_name
114 ds.relax_gui.analyses[data_index].pipe_name = pipe_name
115 ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle
116
117
118 ds.relax_gui.analyses[data_index].r1_fit = False
119 ds.relax_gui.analyses[data_index].numeric_only = False
120 ds.relax_gui.analyses[data_index].grid_inc = None
121 ds.relax_gui.analyses[data_index].mc_sim_num = None
122 ds.relax_gui.analyses[data_index].exp_mc_sim_num = None
123 ds.relax_gui.analyses[data_index].pre_run_dir = None
124 ds.relax_gui.analyses[data_index].mc_sim_all_models = False
125 ds.relax_gui.analyses[data_index].insignificance = 1.0
126 ds.relax_gui.analyses[data_index].save_dir = self.gui.launch_dir
127
128
129 ds.relax_gui.analyses[data_index].disp_models = [
130 MODEL_R2EFF,
131 MODEL_NOREX,
132 MODEL_CR72,
133 MODEL_NS_CPMG_2SITE_EXPANDED,
134 MODEL_MP05,
135 MODEL_NS_R1RHO_2SITE
136 ]
137
138
139 if ds.relax_gui.analyses[data_index].pipe_bundle == None:
140 raise RelaxError("The pipe bundle must be supplied.")
141
142
143 self.data = ds.relax_gui.analyses[data_index]
144 self.data_index = data_index
145
146
147 self.observer_register()
148
149
150 super(Auto_relax_disp, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
151
152
153 self.opt_func_tol = 1e-25
154 self.opt_max_iterations = int(1e7)
155
156
157 self.update_clusters()
158
159
161 """Activate or deactivate certain elements of the analysis in response to the execution lock."""
162
163
164 enable = False
165 if not status.exec_lock.locked():
166 enable = True
167
168
169 wx.CallAfter(self.field_results_dir.Enable, enable)
170 wx.CallAfter(self.field_pre_run_dir.Enable, enable)
171 wx.CallAfter(self.spin_systems.Enable, enable)
172 wx.CallAfter(self.field_cluster.Enable, enable)
173 wx.CallAfter(self.button_isotope.Enable, enable)
174 wx.CallAfter(self.button_r1.Enable, enable)
175 wx.CallAfter(self.button_chemical_shift.Enable, enable)
176 wx.CallAfter(self.button_interatom_define.Enable, enable)
177 wx.CallAfter(self.peak_intensity.Enable, enable)
178 wx.CallAfter(self.model_field.Enable, enable)
179 wx.CallAfter(self.button_exec_relax.Enable, enable)
180
181
240
241
243 """Assemble the data required for the Auto_noe class.
244
245 @return: A container with all the data required for the auto-analysis, the missing list, and a list of models that don't match the experiment types.
246 @rtype: class instance, list of str, list of str
247 """
248
249
250 data = Container()
251 missing = []
252 model_mismatch = []
253
254
255 data.pipe_name = self.data.pipe_name
256 data.pipe_bundle = self.data.pipe_bundle
257
258
259 data.save_dir = self.data.save_dir
260 data.pre_run_dir = gui_to_str(self.field_pre_run_dir.GetValue())
261
262
263 if not exists_mol_res_spin_data():
264 missing.append("Sequence data")
265
266
267 for spin, spin_id in spin_loop(return_id=True, skip_desel=True):
268
269 msg = "Spin '%s' - %s (try the %s user function)." % (spin_id, "%s", "%s")
270
271
272 if not hasattr(spin, 'isotope') or spin.isotope == None:
273 missing.append(msg % ("nuclear isotope data", "spin.isotope"))
274
275
276 if not hasattr(cdp, 'spectrum_ids') or len(cdp.spectrum_ids) < 2:
277 missing.append("Spectral data")
278
279
280 data.models = self.model_field.GetValue()
281
282
283 for model in data.models:
284
285 if model != MODEL_NOREX and model in MODEL_LIST_CPMG and not has_cpmg_exp_type():
286 model_mismatch.append([model, 'CPMG'])
287
288
289 if model != MODEL_NOREX and model in MODEL_LIST_R1RHO and not has_r1rho_exp_type():
290 model_mismatch.append([model, 'R1rho'])
291
292
293 data.r1_fit = self.r1_fit.GetValue()
294
295
296 data.numeric_only = self.numeric_only.GetValue()
297
298
299 data.inc = gui_to_int(self.grid_inc.GetValue())
300
301
302 data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
303 data.exp_mc_sim_num = gui_to_int(self.exp_mc_sim_num.GetValue())
304 data.mc_sim_all_models = self.mc_sim_all_models.GetValue()
305
306
307 data.insignificance = self.insignificance.GetValue()
308 try:
309 data.insignificance = gui_to_float(data.insignificance)
310 except:
311 missing.append("The insignificance level must be a number.")
312
313
314 data.opt_func_tol = self.opt_func_tol
315 data.opt_max_iterations = self.opt_max_iterations
316
317
318 return data, missing, model_mismatch
319
320
322 """Construct the right hand box to pack into the main relax_disp box.
323
324 @return: The right hand box element containing all relaxation dispersion GUI elements (excluding the bitmap) to pack into the main box.
325 @rtype: wx.BoxSizer instance
326 """
327
328
329 box = wx.BoxSizer(wx.VERTICAL)
330
331
332 self.add_title(box, "Relaxation dispersion analysis")
333
334
335 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)
336
337
338 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)
339
340
341 tooltip = "The optional directory containing the dispersion auto-analysis results from a previous run. The optimised parameters from these previous results will be used as the starting point for optimisation rather than performing a grid search. This is essential for when large spin clusters are specified, as a grid search becomes prohibitively expensive with clusters of three or more spins. At some point a RelaxError will occur because the grid search is impossibly large. For the cluster specific parameters, i.e. the populations of the states and the exchange parameters, an average value will be used as the starting point. For all other parameters, the R20 values for each spin and magnetic field, as well as the parameters related to the chemical shift difference dw, the optimised values of the previous run will be directly copied."
342 self.field_pre_run_dir = Text_ctrl(box, self, text="Previous run directory:", icon=fetch_icon('oxygen.actions.document-open-folder', "16x16"), tooltip=tooltip, tooltip_button="Select the results directory of the previous run.", fn=self.pre_run_directory, button=True, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
343
344
345 self.add_spin_systems(box, self)
346
347
348 self.field_cluster = Text_ctrl(box, self, text="Spin cluster IDs:", button_text=" Cluster", icon=fetch_icon("relax.cluster", "16x16"), tooltip="The list of currently defined spin clusters. A spin cluster will share the same the dispersion parameters during the optimisation of the dispersion model. The special 'free spins' cluster ID refers to all non-clustered spins.", tooltip_button="Define clusters of spins using the relax_disp.cluster user function.", fn=self.relax_disp_cluster, button=True, editable=False, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
349
350
351 box.AddSpacer(20)
352 self.add_buttons(box=box)
353
354
355 box.AddSpacer(20)
356 self.peak_intensity = Spectra_list(gui=self.gui, parent=self, box=box, id=str(self.data_index), fn_add=self.peak_wizard_launch, relax_disp_flag=True)
357 box.AddSpacer(10)
358
359
360 self.model_field = Disp_model_list(self, box)
361 self.model_field.set_value(self.data.disp_models)
362
363
364 tooltip = "Toggle the optimisation of the off-resonance R1 parameter.\n\nThis allows the optimisation of R1 values to be turned on an off for the relaxation dispersion dispersion models. If turned off, the current values of R1 will be fixed. Otherwise the R1 values will be added to the model parameter set. For models which do not support the R1 parameter for off-resonance effects, this setting will have no effect."
365 self.r1_fit = Boolean_ctrl(box, self, text="R1 parameter optimisation:", default=False, tooltip=tooltip, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
366
367
368 tooltip = "The class of models to use in the final model selection.\n\nThe default of False allows all dispersion models to be compared for statistical significance in the analysis (no exchange, the analytic models and the numeric models). The value of True will activate a pure numeric solution - the analytic models will be optimised, as they are very useful for replacing the grid search for the numeric models, but the final model selection will not include them."
369 self.numeric_only = Boolean_ctrl(box, self, text="Pure numeric solutions:", default=False, tooltip=tooltip, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
370
371
372 self.grid_inc = Spin_ctrl(box, self, text="Grid search increments:", default=21, 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)
373
374
375 self.exp_mc_sim_num = Spin_ctrl(box, self, text="Exponential curve error analysis:", default=500, min=-1, max=100000, tooltip="This is the number of Monte Carlo simulations performed for error propagation and analysis when estimating R2eff errors from exponential curve fitting. Setting to '-1' estimates error from the Covariance matrix.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
376 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. For best results, at least 500 is recommended.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
377 self.mc_sim_all_models = Boolean_ctrl(box, self, text="Per model error analysis:", default=False, tooltip="A flag which if True will cause Monte Carlo simulations to be performed for each individual model. Otherwise Monte Carlo simulations will be reserved for the final model.", width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
378
379
380 tooltip = "Experimental option, be careful. True will set the grid %s values from the minimum %s values. This will speed up the grid search with a factor GRID_INC^(Nr_spec_freq). For a CPMG experiment with two fields and standard GRID_INC=21, the speed-up is a factor 441." % (r2, r2eff)
381 self.set_grid_r20 = Boolean_ctrl(box, self, text="Set R20 to the minimum R2eff:", default=False, tooltip=tooltip, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
382
383
384 tooltip = "The %s/%s value in rad/s by which to judge insignificance. If the maximum difference between two points on all dispersion curves for a spin is less than this value, that spin will be deselected. This does not affect the '%s' model. Set this value to 0.0 to use all data." % (r2eff, r1rho, MODEL_NOREX)
385 self.insignificance = Float_ctrl(box, self, text="Insignificance level:", default=1.0, tooltip=tooltip, width_text=self.width_text, width_button=self.width_button, spacer=self.spacer_horizontal)
386
387
388 box.AddSpacer(30)
389 box.AddStretchSpacer()
390
391
392 self.button_exec_relax = self.add_execute_analysis(box, self.execute)
393
394
395 return box
396
397
399 """Unregister the spin count from the user functions."""
400
401
402 self.observer_register(remove=True)
403
404
405 self.peak_intensity.delete()
406
407
408 if hasattr(self, 'peak_wizard'):
409 self.peak_wizard.Destroy()
410 del self.peak_wizard
411
412
413 self.model_field.model_win.Destroy()
414 del self.model_field
415
416
417 if hasattr(self, 'missing_data'):
418 self.missing_data.Destroy()
419 del self.missing_data
420
421
423 """Set up, execute, and process the automatic Rx analysis.
424
425 @param event: The wx event.
426 @type event: wx event
427 """
428
429
430 self.gui.interpreter.flush()
431
432
433 if status.exec_lock.locked():
434 error_message("relax is currently executing.", "relax execution lock")
435 event.Skip()
436 return
437
438
439 self.gui.close_windows()
440
441
442 self.sync_ds(upload=True)
443
444
445 data, missing, model_mismatch = self.assemble_data()
446
447
448 if len(missing):
449 self.missing_data = Missing_data(missing)
450 return
451
452
453 if len(model_mismatch):
454
455 text = ''
456 for model, exp in model_mismatch:
457 text += "The '%s' %s model cannot be used as no %s experiment types have been set up.\n" % (model, exp, exp)
458
459
460 error_message(text, caption='Model mismatch')
461 return
462
463
464 self.gui.show_controller(None)
465 self.gui.controller.log_panel.on_goto_end(None)
466
467
468 self.thread = Execute_relax_disp(self.gui, data, self.data_index)
469 self.thread.start()
470
471
472 event.Skip()
473
474
476 """Define the interatomic interactions of the spins via the interatom.define user function.
477
478 @keyword event: The wx event.
479 @type event: wx event
480 """
481
482
483 uf_store['interatom.define'](wx_wizard_modal=True, spin_id1='@N', spin_id2='@H')
484
485
487 """Read chemical shift data from a peak list via the chemical_shift.read user function.
488
489 @keyword event: The wx event.
490 @type event: wx event
491 """
492
493
494 uf_store['chemical_shift.read'](wx_wizard_modal=True)
495
496
498 """Load R1 relaxation data via the relax_data.read user function.
499
500 @keyword event: The wx event.
501 @type event: wx event
502 """
503
504
505 uf_store['relax_data.read'](wx_wizard_modal=True, ri_type='R1')
506
507
531
532
534 """Launch the peak loading wizard.
535
536 @param event: The wx event.
537 @type event: wx event
538 """
539
540
541 if hasattr(self, 'peak_wizard'):
542 self.peak_wizard.Destroy()
543
544
545 self.peak_wizard = Peak_intensity_wizard(relax_disp=True)
546
547
549 """The pre-run directory selection.
550
551 @param event: The wx event.
552 @type event: wx event
553 """
554
555
556 dialog = RelaxDirDialog(parent=self, message='Select the directory of the previous run', defaultPath=self.field_pre_run_dir.GetValue())
557
558
559 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
560
561 return
562
563
564 path = gui_to_str(dialog.get_path())
565 if not path:
566 return
567
568
569 self.field_pre_run_dir.SetValue(str_to_gui(path))
570
571
573 """Set up spin clustering via the relax_disp.cluster user function.
574
575 @keyword event: The wx event.
576 @type event: wx event
577 """
578
579
580 uf_store['relax_disp.cluster'](wx_wizard_modal=True)
581
582
584 """The results directory selection.
585
586 @param event: The wx event.
587 @type event: wx event
588 """
589
590
591 dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue())
592
593
594 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
595
596 return
597
598
599 path = gui_to_str(dialog.get_path())
600 if not path:
601 return
602
603
604 self.data.save_dir = path
605
606
607 self.field_results_dir.SetValue(str_to_gui(path))
608
609
611 """Set the nuclear isotope types of the spins via the spin.isotope user function.
612
613 @keyword event: The wx event.
614 @type event: wx event
615 """
616
617
618 uf_store['spin.isotope'](wx_wizard_modal=True, isotope='15N', spin_id='@N*')
619
620
622 """Synchronise the analysis frame and the relax data store, both ways.
623
624 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.
625
626 @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.
627 @type upload: bool
628 """
629
630
631 if upload:
632 self.data.r1_fit = self.r1_fit.GetValue()
633 elif hasattr(self.data, 'r1_fit'):
634 self.r1_fit.SetValue(bool(self.data.r1_fit))
635
636
637 if upload:
638 self.data.numeric_only = self.numeric_only.GetValue()
639 elif hasattr(self.data, 'numeric_only'):
640 self.numeric_only.SetValue(bool(self.data.numeric_only))
641
642
643 if upload:
644 self.data.grid_inc = gui_to_int(self.grid_inc.GetValue())
645 elif hasattr(self.data, 'grid_inc'):
646 self.grid_inc.SetValue(int(self.data.grid_inc))
647
648
649 if upload:
650 self.data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
651 elif hasattr(self.data, 'mc_sim_num'):
652 self.mc_sim_num.SetValue(int(self.data.mc_sim_num))
653
654
655 if upload:
656 self.data.exp_mc_sim_num = gui_to_int(self.exp_mc_sim_num.GetValue())
657 elif hasattr(self.data, 'exp_mc_sim_num'):
658 self.exp_mc_sim_num.SetValue(int(self.data.exp_mc_sim_num))
659
660
661 if upload:
662 self.data.mc_sim_all_models = self.mc_sim_all_models.GetValue()
663 elif hasattr(self.data, 'mc_sim_all_models'):
664 self.mc_sim_all_models.SetValue(bool(self.data.mc_sim_all_models))
665
666
667 if upload:
668 self.data.insignificance = self.insignificance.GetValue()
669 try:
670 self.data.insignificance = gui_to_float(self.data.insignificance)
671 except:
672 pass
673 elif hasattr(self.data, 'insignificance'):
674 self.insignificance.SetValue(float_to_gui(self.data.insignificance))
675
676
677 if upload:
678 self.data.save_dir = gui_to_str(self.field_results_dir.GetValue())
679 else:
680 self.field_results_dir.SetValue(str_to_gui(self.data.save_dir))
681
682
683 if upload:
684 self.data.pre_run_dir = gui_to_str(self.field_pre_run_dir.GetValue())
685 elif hasattr(self.data, 'pre_run_dir'):
686 self.field_pre_run_dir.SetValue(str_to_gui(self.data.pre_run_dir))
687
688
689 if upload:
690 self.data.disp_models = self.model_field.GetValue()
691 else:
692 self.model_field.set_value(self.data.disp_models)
693
694
696 """Update the cluster field."""
697
698
699 cluster_keys = []
700 if hasattr(cdp, 'clustering'):
701 cluster_keys = sorted(cdp.clustering.keys())
702
703
704 if not len(cluster_keys):
705 wx.CallAfter(self.field_cluster.SetValue, "free spins")
706
707
708 else:
709
710 text = ""
711 if "free spins" in cluster_keys:
712 text += "free spins"
713 for i in range(len(cluster_keys)):
714 if cluster_keys[i] != "free spins":
715 text += ", %s" % cluster_keys[i]
716
717
718 wx.CallAfter(self.field_cluster.SetValue, text)
719
720
722 """Launch the value.set user function.
723
724 @keyword event: The wx event.
725 @type event: wx event
726 """
727
728
729 uf_store['value.set'](wx_wizard_modal=True)
730
731
732
734 """The relaxation dispersion analysis execution object."""
735
737 """Execute the calculation."""
738
739
740 Relax_disp.opt_func_tol = self.data.opt_func_tol
741 Relax_disp.opt_max_iterations = self.data.opt_max_iterations
742
743
744 Relax_disp(pipe_name=self.data.pipe_name, pipe_bundle=self.data.pipe_bundle, results_dir=self.data.save_dir, models=self.data.models, grid_inc=self.data.inc, mc_sim_num=self.data.mc_sim_num, exp_mc_sim_num=self.data.exp_mc_sim_num, pre_run_dir=self.data.pre_run_dir, mc_sim_all_models=self.data.mc_sim_all_models, insignificance=self.data.insignificance, numeric_only=self.data.numeric_only, r1_fit=self.data.r1_fit)
745
746
747 data = ds.relax_gui.analyses[self.data_index]
748
749
750
752 """The diffusion model list GUI element."""
753
754
755 desc = "Relaxation dispersion models:"
756 models = [
757 MODEL_R2EFF,
758 None,
759 MODEL_NOREX,
760 None,
761 MODEL_LM63,
762 MODEL_LM63_3SITE,
763 MODEL_CR72,
764 MODEL_CR72_FULL,
765 MODEL_IT99,
766 MODEL_TSMFK01,
767 MODEL_B14,
768 MODEL_B14_FULL,
769 MODEL_NS_CPMG_2SITE_EXPANDED,
770 MODEL_NS_CPMG_2SITE_3D,
771 MODEL_NS_CPMG_2SITE_3D_FULL,
772 MODEL_NS_CPMG_2SITE_STAR,
773 MODEL_NS_CPMG_2SITE_STAR_FULL,
774 None,
775 MODEL_M61,
776 MODEL_M61B,
777 MODEL_DPL94,
778 MODEL_TP02,
779 MODEL_TAP03,
780 MODEL_MP05,
781 MODEL_NS_R1RHO_2SITE,
782 MODEL_NS_R1RHO_3SITE_LINEAR,
783 MODEL_NS_R1RHO_3SITE,
784 None,
785 MODEL_MMQ_CR72,
786 MODEL_NS_MMQ_2SITE,
787 MODEL_NS_MMQ_3SITE_LINEAR,
788 MODEL_NS_MMQ_3SITE
789 ]
790 params = [
791 "{%s/%s, %s}" % (r2eff, r1rho, i0),
792 None,
793 "{%s, ...}" % (r2),
794 None,
795 "{%s, ..., %s, %s}" % (r2, phi_ex, kex),
796 "{%s, ..., %s, kB, %s, kC}" % (r2, phi_exB, phi_exC),
797 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
798 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
799 "{%s, ..., %s, %s, %s}" % (r2, phi_ex, padw2, kex),
800 "{%s, ..., %s, k_AB}" % (r2a, dw),
801 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
802 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
803 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
804 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
805 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
806 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
807 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
808 None,
809 "{%s, ..., %s, %s}" % (r1rho_prime, phi_ex, kex),
810 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
811 "{%s, ..., %s, %s}" % (r1rho_prime, phi_ex, kex),
812 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
813 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
814 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
815 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
816 "{%s, ..., pA, %s, %s, pB, %s, %s}" % (r1rho_prime, dw_AB, kAB, dw_BC, kBC),
817 "{%s, ..., pA, %s, %s, pB, %s, %s, %s}" % (r1rho_prime, dw_AB, kAB, dw_BC, kBC, kAC),
818 None,
819 "{%s, ..., pA, %s, %s, %s}" % (r2, dw, dwH, kex),
820 "{%s, ..., pA, %s, %s, %s}" % (r2, dw, dwH, kex),
821 "{%s, ..., pA, %s, %s, %s, pB, %s, %s, %s}" % (r2, dw_AB, dwH_AB, kAB, dw_BC, dwH_BC, kBC),
822 "{%s, ..., pA, %s, %s, %s, pB, %s, %s, %s, %s}" % (r2, dw_AB, dwH_AB, kAB, dw_BC, dwH_BC, kBC, kAC)
823 ]
824 model_desc = [
825 "The base model for determining the %s/%s values and errors for all other models." % (r2eff, r1rho),
826 None,
827 "The model for no chemical exchange relaxation.",
828 None,
829 "The original Luz and Meiboom (1963) 2-site fast exchange equation.",
830 "The original Luz and Meiboom (1963) 3-site fast exchange equation.",
831 "The Carver and Richards (1972) 2-site equation for all time scales (with %s = %s)." % (r2a, r2b),
832 "The Carver and Richards (1972) 2-site equation for all time scales.",
833 "The Ishima and Torchia (1999) 2-site model for all time scales with pA >> pB.",
834 "The Tollinger et al. (2001) 2-site very-slow exchange model.",
835 "The Baldwin (2014) 2-site exact solution model for all time scales (with %s = %s)." % (r2a, r2b),
836 "The Baldwin (2014) 2-site exact solution model for all time scales.",
837 "The 2-site numerical solution expanded using Maple by Nikolai Skrynnikov.",
838 "The 2-site numerical solution using 3D magnetisation vectors (with %s = %s)." % (r2a, r2b),
839 "The 2-site numerical solution using 3D magnetisation vectors.",
840 "The 2-site numerical solution using complex conjugate matrices (with %s = %s)." % (r2a, r2b),
841 "The 2-site numerical solution using complex conjugate matrices.",
842 None,
843 "The Meiboom (1961) 2-site fast exchange equation.",
844 "The Meiboom (1961) 2-site equation for all time scales with pA >> pB.",
845 "The Davis, Perlman and London (1994) 2-site fast exchange equation.",
846 "The Trott and Palmer (2002) 2-site equation for all time scales.",
847 "The Trott, Abergel and Palmer (2003) off-resonance 2-site equation for all time scales.",
848 "The Miloushev and Palmer (2005) off-resonance 2-site equation for all time scales.",
849 "The 2-site numerical solution using 3D magnetisation vectors.",
850 "The 3-site linearised numerical solution using 3D magnetisation vectors.",
851 "The 3-site numerical solution using 3D magnetisation vectors.",
852 None,
853 "The CR72 2-site model extended to MMQ CPMG data by Korzhnev et al., 2004.",
854 "The 2-site numerical solution of Korzhnev et al. (2004) from multi-quantum CPMG data.",
855 "The 3-site linearised numerical solution of Korzhnev et al. (2005) for MMQ CPMG data.",
856 "The 3-site numerical solution of Korzhnev et al. (2005) for MMQ CPMG data."
857 ]
858 size = wx.Size(1024, 750)
859 tooltip = "The list of all relaxation dispersion models to be optimised as part of the protocol."
860 tooltip_button = "Open the model list selector window."
861