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
56 default_grid_inc = 21
57 default_exp_mc_sim_num = 500
58 default_mc_sim_num = 500
59
60
62 """The relaxation dispersion auto-analysis GUI element."""
63
64
65 analysis_type = None
66 bitmap = ANALYSIS_IMAGE_PATH+"relax_disp_200x200.png"
67 label = 'Relax-disp'
68
69 - 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):
70 """Build the automatic R1 and R2 analysis GUI frame elements.
71
72 @param parent: The parent wx element.
73 @type parent: wx object
74 @keyword id: The unique ID number.
75 @type id: int
76 @keyword pos: The position.
77 @type pos: wx.Size object
78 @keyword size: The size.
79 @type size: wx.Size object
80 @keyword style: The style.
81 @type style: int
82 @keyword name: The name for the panel.
83 @type name: unicode
84 @keyword gui: The main GUI class.
85 @type gui: gui.relax_gui.Main instance
86 @keyword analysis_name: The name of the analysis (the name in the tab part of the notebook).
87 @type analysis_name: str
88 @keyword pipe_name: The name of the data pipe associated with this analysis.
89 @type pipe_name: str
90 @keyword pipe_bundle: The name of the data pipe bundle associated with this analysis.
91 @type pipe_bundle: str
92 @keyword uf_exec: The list of user function on_execute methods returned from the new analysis wizard.
93 @type uf_exec: list of methods
94 @keyword data_index: The index of the analysis in the relax data store (set to None if no data currently exists).
95 @type data_index: None or int
96 """
97
98
99 self.gui = gui
100
101
102 self.init_flag = True
103
104
105 if data_index == None:
106
107 if not has_pipe(pipe_name):
108 self.gui.interpreter.apply('pipe.create', pipe_name=pipe_name, pipe_type='relax_disp', bundle=pipe_bundle)
109
110
111 if not has_bundle(pipe_bundle):
112 self.gui.interpreter.apply('pipe.bundle', bundle=pipe_bundle, pipe=pipe_name)
113
114
115 data_index = ds.relax_gui.analyses.add(self.label)
116
117
118 ds.relax_gui.analyses[data_index].analysis_name = analysis_name
119 ds.relax_gui.analyses[data_index].pipe_name = pipe_name
120 ds.relax_gui.analyses[data_index].pipe_bundle = pipe_bundle
121
122
123 ds.relax_gui.analyses[data_index].r1_fit = False
124 ds.relax_gui.analyses[data_index].numeric_only = False
125 ds.relax_gui.analyses[data_index].grid_inc = None
126 ds.relax_gui.analyses[data_index].mc_sim_num = None
127 ds.relax_gui.analyses[data_index].exp_mc_sim_num = None
128 ds.relax_gui.analyses[data_index].pre_run_dir = None
129 ds.relax_gui.analyses[data_index].mc_sim_all_models = False
130 ds.relax_gui.analyses[data_index].insignificance = 1.0
131 ds.relax_gui.analyses[data_index].save_dir = self.gui.system_cwd_path
132
133
134 ds.relax_gui.analyses[data_index].disp_models = [
135 MODEL_R2EFF,
136 MODEL_NOREX,
137 MODEL_CR72,
138 MODEL_NS_CPMG_2SITE_EXPANDED,
139 MODEL_MP05,
140 MODEL_NS_R1RHO_2SITE
141 ]
142
143
144 if ds.relax_gui.analyses[data_index].pipe_bundle == None:
145 raise RelaxError("The pipe bundle must be supplied.")
146
147
148 self.data = ds.relax_gui.analyses[data_index]
149 self.data_index = data_index
150
151
152 self.observer_register()
153
154
155 super(Auto_relax_disp, self).__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
156
157
158 self.opt_func_tol = 1e-25
159 self.opt_max_iterations = int(1e7)
160
161
162 self.update_clusters()
163
164
166 """Activate or deactivate certain elements of the analysis in response to the execution lock."""
167
168
169 enable = False
170 if not status.exec_lock.locked():
171 enable = True
172
173
174 wx.CallAfter(self.field_results_dir.Enable, enable)
175 wx.CallAfter(self.field_pre_run_dir.Enable, enable)
176 wx.CallAfter(self.spin_systems.Enable, enable)
177 wx.CallAfter(self.field_cluster.Enable, enable)
178 wx.CallAfter(self.button_isotope.Enable, enable)
179 wx.CallAfter(self.button_r1.Enable, enable)
180 wx.CallAfter(self.button_chemical_shift.Enable, enable)
181 wx.CallAfter(self.button_interatom_define.Enable, enable)
182 wx.CallAfter(self.peak_intensity.Enable, enable)
183 wx.CallAfter(self.model_field.Enable, enable)
184 wx.CallAfter(self.button_exec_relax.Enable, enable)
185
186
245
246
248 """Assemble the data required for the Auto_noe class.
249
250 @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.
251 @rtype: class instance, list of str, list of str
252 """
253
254
255 data = Container()
256 missing = []
257 model_mismatch = []
258
259
260 data.pipe_name = self.data.pipe_name
261 data.pipe_bundle = self.data.pipe_bundle
262
263
264 data.save_dir = self.data.save_dir
265 data.pre_run_dir = gui_to_str(self.field_pre_run_dir.GetValue())
266
267
268 if not exists_mol_res_spin_data():
269 missing.append("Sequence data")
270
271
272 for spin, spin_id in spin_loop(return_id=True, skip_desel=True):
273
274 msg = "Spin '%s' - %s (try the %s user function)." % (spin_id, "%s", "%s")
275
276
277 if not hasattr(spin, 'isotope') or spin.isotope == None:
278 missing.append(msg % ("nuclear isotope data", "spin.isotope"))
279
280
281 if not hasattr(cdp, 'spectrum_ids') or len(cdp.spectrum_ids) < 2:
282 missing.append("Spectral data")
283
284
285 data.models = self.model_field.GetValue()
286
287
288 for model in data.models:
289
290 if model != MODEL_NOREX and model in MODEL_LIST_CPMG and not has_cpmg_exp_type():
291 model_mismatch.append([model, 'CPMG'])
292
293
294 if model != MODEL_NOREX and model in MODEL_LIST_R1RHO and not has_r1rho_exp_type():
295 model_mismatch.append([model, 'R1rho'])
296
297
298 data.r1_fit = self.r1_fit.GetValue()
299
300
301 data.numeric_only = self.numeric_only.GetValue()
302
303
304 data.inc = gui_to_int(self.grid_inc.GetValue())
305
306
307 data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
308 data.exp_mc_sim_num = gui_to_int(self.exp_mc_sim_num.GetValue())
309 data.mc_sim_all_models = self.mc_sim_all_models.GetValue()
310
311
312 data.insignificance = self.insignificance.GetValue()
313 try:
314 data.insignificance = gui_to_float(data.insignificance)
315 except:
316 missing.append("The insignificance level must be a number.")
317
318
319 data.opt_func_tol = self.opt_func_tol
320 data.opt_max_iterations = self.opt_max_iterations
321
322
323 return data, missing, model_mismatch
324
325
327 """Construct the right hand box to pack into the main relax_disp box.
328
329 @return: The right hand box element containing all relaxation dispersion GUI elements (excluding the bitmap) to pack into the main box.
330 @rtype: wx.BoxSizer instance
331 """
332
333
334 box = wx.BoxSizer(wx.VERTICAL)
335
336
337 self.add_title(box, "Relaxation dispersion analysis")
338
339
340 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)
341
342
343 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)
344
345
346 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."
347 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)
348
349
350 self.add_spin_systems(box, self)
351
352
353 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)
354
355
356 box.AddSpacer(20)
357 self.add_buttons(box=box)
358
359
360 box.AddSpacer(20)
361 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)
362 box.AddSpacer(10)
363
364
365 self.model_field = Disp_model_list(self, box)
366 self.model_field.set_value(self.data.disp_models)
367
368
369 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."
370 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)
371
372
373 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."
374 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)
375
376
377 self.grid_inc = Spin_ctrl(box, self, text="Grid search increments:", default=default_grid_inc, 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)
378
379
380 self.exp_mc_sim_num = Spin_ctrl(box, self, text="Exponential curve error analysis:", default=default_exp_mc_sim_num, 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)
381 self.mc_sim_num = Spin_ctrl(box, self, text="Monte Carlo simulation number:", default=default_mc_sim_num, 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)
382 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)
383
384
385 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)
386 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)
387
388
389 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)
390 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)
391
392
393 box.AddSpacer(30)
394 box.AddStretchSpacer()
395
396
397 self.button_exec_relax = self.add_execute_analysis(box, self.execute)
398
399
400 return box
401
402
404 """Unregister the spin count from the user functions."""
405
406
407 self.observer_register(remove=True)
408
409
410 self.peak_intensity.delete()
411
412
413 if hasattr(self, 'peak_wizard'):
414 self.peak_wizard.Destroy()
415 del self.peak_wizard
416
417
418 self.model_field.model_win.Destroy()
419 del self.model_field
420
421
422 if hasattr(self, 'missing_data'):
423 self.missing_data.Destroy()
424 del self.missing_data
425
426
428 """Set up, execute, and process the automatic Rx analysis.
429
430 @param event: The wx event.
431 @type event: wx event
432 """
433
434
435 self.gui.interpreter.flush()
436
437
438 if status.exec_lock.locked():
439 error_message("relax is currently executing.", "relax execution lock")
440 event.Skip()
441 return
442
443
444 self.gui.close_windows()
445
446
447 self.sync_ds(upload=True)
448
449
450 data, missing, model_mismatch = self.assemble_data()
451
452
453 if len(missing):
454 self.missing_data = Missing_data(missing)
455 return
456
457
458 if len(model_mismatch):
459
460 text = ''
461 for model, exp in model_mismatch:
462 text += "The '%s' %s model cannot be used as no %s experiment types have been set up.\n" % (model, exp, exp)
463
464
465 error_message(text, caption='Model mismatch')
466 return
467
468
469 self.gui.show_controller(None)
470 self.gui.controller.log_panel.on_goto_end(None)
471
472
473 self.thread = Execute_relax_disp(self.gui, data, self.data_index)
474 self.thread.start()
475
476
477 event.Skip()
478
479
481 """Define the interatomic interactions of the spins via the interatom.define user function.
482
483 @keyword event: The wx event.
484 @type event: wx event
485 """
486
487
488 uf_store['interatom.define'](wx_wizard_modal=True, spin_id1='@N', spin_id2='@H')
489
490
492 """Read chemical shift data from a peak list via the chemical_shift.read user function.
493
494 @keyword event: The wx event.
495 @type event: wx event
496 """
497
498
499 uf_store['chemical_shift.read'](wx_wizard_modal=True)
500
501
503 """Load R1 relaxation data via the relax_data.read user function.
504
505 @keyword event: The wx event.
506 @type event: wx event
507 """
508
509
510 uf_store['relax_data.read'](wx_wizard_modal=True, ri_type='R1')
511
512
536
537
539 """Launch the peak loading wizard.
540
541 @param event: The wx event.
542 @type event: wx event
543 """
544
545
546 if hasattr(self, 'peak_wizard'):
547 self.peak_wizard.Destroy()
548
549
550 self.peak_wizard = Peak_intensity_wizard(relax_disp=True)
551
552
554 """The pre-run directory selection.
555
556 @param event: The wx event.
557 @type event: wx event
558 """
559
560
561 dialog = RelaxDirDialog(parent=self, message='Select the directory of the previous run', defaultPath=self.field_pre_run_dir.GetValue())
562
563
564 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
565
566 return
567
568
569 path = gui_to_str(dialog.get_path())
570 if not path:
571 return
572
573
574 self.field_pre_run_dir.SetValue(str_to_gui(path))
575
576
578 """Set up spin clustering via the relax_disp.cluster user function.
579
580 @keyword event: The wx event.
581 @type event: wx event
582 """
583
584
585 uf_store['relax_disp.cluster'](wx_wizard_modal=True)
586
587
589 """The results directory selection.
590
591 @param event: The wx event.
592 @type event: wx event
593 """
594
595
596 dialog = RelaxDirDialog(parent=self, message='Select the results directory', defaultPath=self.field_results_dir.GetValue())
597
598
599 if status.show_gui and dialog.ShowModal() != wx.ID_OK:
600
601 return
602
603
604 path = gui_to_str(dialog.get_path())
605 if not path:
606 return
607
608
609 self.data.save_dir = path
610
611
612 self.field_results_dir.SetValue(str_to_gui(path))
613
614
616 """Set the nuclear isotope types of the spins via the spin.isotope user function.
617
618 @keyword event: The wx event.
619 @type event: wx event
620 """
621
622
623 uf_store['spin.isotope'](wx_wizard_modal=True, isotope='15N', spin_id='@N*')
624
625
627 """Synchronise the analysis frame and the relax data store, both ways.
628
629 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.
630
631 @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.
632 @type upload: bool
633 """
634
635
636 if upload:
637 self.data.r1_fit = self.r1_fit.GetValue()
638 elif hasattr(self.data, 'r1_fit'):
639 self.r1_fit.SetValue(bool(self.data.r1_fit))
640
641
642 if upload:
643 self.data.numeric_only = self.numeric_only.GetValue()
644 elif hasattr(self.data, 'numeric_only'):
645 self.numeric_only.SetValue(bool(self.data.numeric_only))
646
647
648 if upload:
649 self.data.grid_inc = gui_to_int(self.grid_inc.GetValue())
650 elif hasattr(self.data, 'grid_inc'):
651 if self.data.grid_inc == None:
652 self.data.grid_inc = default_grid_inc
653 self.grid_inc.SetValue(int(self.data.grid_inc))
654
655
656 if upload:
657 self.data.mc_sim_num = gui_to_int(self.mc_sim_num.GetValue())
658 elif hasattr(self.data, 'mc_sim_num'):
659 if self.data.mc_sim_num == None:
660 self.data.mc_sim_num = default_mc_sim_num
661 self.mc_sim_num.SetValue(int(self.data.mc_sim_num))
662
663
664 if upload:
665 self.data.exp_mc_sim_num = gui_to_int(self.exp_mc_sim_num.GetValue())
666 elif hasattr(self.data, 'exp_mc_sim_num'):
667 if self.data.exp_mc_sim_num == None:
668 self.data.exp_mc_sim_num = default_exp_mc_sim_num
669 self.exp_mc_sim_num.SetValue(int(self.data.exp_mc_sim_num))
670
671
672 if upload:
673 self.data.mc_sim_all_models = self.mc_sim_all_models.GetValue()
674 elif hasattr(self.data, 'mc_sim_all_models'):
675 self.mc_sim_all_models.SetValue(bool(self.data.mc_sim_all_models))
676
677
678 if upload:
679 self.data.insignificance = self.insignificance.GetValue()
680 try:
681 self.data.insignificance = gui_to_float(self.data.insignificance)
682 except:
683 pass
684 elif hasattr(self.data, 'insignificance'):
685 self.insignificance.SetValue(float_to_gui(self.data.insignificance))
686
687
688 if upload:
689 self.data.save_dir = gui_to_str(self.field_results_dir.GetValue())
690 else:
691 self.field_results_dir.SetValue(str_to_gui(self.data.save_dir))
692
693
694 if upload:
695 self.data.pre_run_dir = gui_to_str(self.field_pre_run_dir.GetValue())
696 elif hasattr(self.data, 'pre_run_dir'):
697 self.field_pre_run_dir.SetValue(str_to_gui(self.data.pre_run_dir))
698
699
700 if upload:
701 self.data.disp_models = self.model_field.GetValue()
702 else:
703 self.model_field.set_value(self.data.disp_models)
704
705
707 """Update the cluster field."""
708
709
710 cluster_keys = []
711 if hasattr(cdp, 'clustering'):
712 cluster_keys = sorted(cdp.clustering.keys())
713
714
715 if not len(cluster_keys):
716 wx.CallAfter(self.field_cluster.SetValue, "free spins")
717
718
719 else:
720
721 text = ""
722 if "free spins" in cluster_keys:
723 text += "free spins"
724 for i in range(len(cluster_keys)):
725 if cluster_keys[i] != "free spins":
726 text += ", %s" % cluster_keys[i]
727
728
729 wx.CallAfter(self.field_cluster.SetValue, text)
730
731
733 """Launch the value.set user function.
734
735 @keyword event: The wx event.
736 @type event: wx event
737 """
738
739
740 uf_store['value.set'](wx_wizard_modal=True)
741
742
743
745 """The relaxation dispersion analysis execution object."""
746
748 """Execute the calculation."""
749
750
751 Relax_disp.opt_func_tol = self.data.opt_func_tol
752 Relax_disp.opt_max_iterations = self.data.opt_max_iterations
753
754
755 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)
756
757
758 data = ds.relax_gui.analyses[self.data_index]
759
760
761
763 """The diffusion model list GUI element."""
764
765
766 desc = "Relaxation dispersion models:"
767 models = [
768 MODEL_R2EFF,
769 None,
770 MODEL_NOREX,
771 None,
772 MODEL_LM63,
773 MODEL_LM63_3SITE,
774 MODEL_CR72,
775 MODEL_CR72_FULL,
776 MODEL_IT99,
777 MODEL_TSMFK01,
778 MODEL_B14,
779 MODEL_B14_FULL,
780 MODEL_NS_CPMG_2SITE_EXPANDED,
781 MODEL_NS_CPMG_2SITE_3D,
782 MODEL_NS_CPMG_2SITE_3D_FULL,
783 MODEL_NS_CPMG_2SITE_STAR,
784 MODEL_NS_CPMG_2SITE_STAR_FULL,
785 None,
786 MODEL_M61,
787 MODEL_M61B,
788 MODEL_DPL94,
789 MODEL_TP02,
790 MODEL_TAP03,
791 MODEL_MP05,
792 MODEL_NS_R1RHO_2SITE,
793 MODEL_NS_R1RHO_3SITE_LINEAR,
794 MODEL_NS_R1RHO_3SITE,
795 None,
796 MODEL_MMQ_CR72,
797 MODEL_NS_MMQ_2SITE,
798 MODEL_NS_MMQ_3SITE_LINEAR,
799 MODEL_NS_MMQ_3SITE
800 ]
801 params = [
802 "{%s/%s, %s}" % (r2eff, r1rho, i0),
803 None,
804 "{%s, ...}" % (r2),
805 None,
806 "{%s, ..., %s, %s}" % (r2, phi_ex, kex),
807 "{%s, ..., %s, kB, %s, kC}" % (r2, phi_exB, phi_exC),
808 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
809 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
810 "{%s, ..., %s, %s, %s}" % (r2, phi_ex, padw2, kex),
811 "{%s, ..., %s, k_AB}" % (r2a, dw),
812 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
813 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
814 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
815 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
816 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
817 "{%s, ..., pA, %s, %s}" % (r2, dw, kex),
818 "{%s, %s, ..., pA, %s, %s}" % (r2a, r2b, dw, kex),
819 None,
820 "{%s, ..., %s, %s}" % (r1rho_prime, phi_ex, kex),
821 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
822 "{%s, ..., %s, %s}" % (r1rho_prime, phi_ex, kex),
823 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
824 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
825 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
826 "{%s, ..., pA, %s, %s}" % (r1rho_prime, dw, kex),
827 "{%s, ..., pA, %s, %s, pB, %s, %s}" % (r1rho_prime, dw_AB, kAB, dw_BC, kBC),
828 "{%s, ..., pA, %s, %s, pB, %s, %s, %s}" % (r1rho_prime, dw_AB, kAB, dw_BC, kBC, kAC),
829 None,
830 "{%s, ..., pA, %s, %s, %s}" % (r2, dw, dwH, kex),
831 "{%s, ..., pA, %s, %s, %s}" % (r2, dw, dwH, kex),
832 "{%s, ..., pA, %s, %s, %s, pB, %s, %s, %s}" % (r2, dw_AB, dwH_AB, kAB, dw_BC, dwH_BC, kBC),
833 "{%s, ..., pA, %s, %s, %s, pB, %s, %s, %s, %s}" % (r2, dw_AB, dwH_AB, kAB, dw_BC, dwH_BC, kBC, kAC)
834 ]
835 model_desc = [
836 "The base model for determining the %s/%s values and errors for all other models." % (r2eff, r1rho),
837 None,
838 "The model for no chemical exchange relaxation.",
839 None,
840 "The original Luz and Meiboom (1963) 2-site fast exchange equation.",
841 "The original Luz and Meiboom (1963) 3-site fast exchange equation.",
842 "The Carver and Richards (1972) 2-site equation for all time scales (with %s = %s)." % (r2a, r2b),
843 "The Carver and Richards (1972) 2-site equation for all time scales.",
844 "The Ishima and Torchia (1999) 2-site model for all time scales with pA >> pB.",
845 "The Tollinger et al. (2001) 2-site very-slow exchange model.",
846 "The Baldwin (2014) 2-site exact solution model for all time scales (with %s = %s)." % (r2a, r2b),
847 "The Baldwin (2014) 2-site exact solution model for all time scales.",
848 "The 2-site numerical solution expanded using Maple by Nikolai Skrynnikov.",
849 "The 2-site numerical solution using 3D magnetisation vectors (with %s = %s)." % (r2a, r2b),
850 "The 2-site numerical solution using 3D magnetisation vectors.",
851 "The 2-site numerical solution using complex conjugate matrices (with %s = %s)." % (r2a, r2b),
852 "The 2-site numerical solution using complex conjugate matrices.",
853 None,
854 "The Meiboom (1961) 2-site fast exchange equation.",
855 "The Meiboom (1961) 2-site equation for all time scales with pA >> pB.",
856 "The Davis, Perlman and London (1994) 2-site fast exchange equation.",
857 "The Trott and Palmer (2002) 2-site equation for all time scales.",
858 "The Trott, Abergel and Palmer (2003) off-resonance 2-site equation for all time scales.",
859 "The Miloushev and Palmer (2005) off-resonance 2-site equation for all time scales.",
860 "The 2-site numerical solution using 3D magnetisation vectors.",
861 "The 3-site linearised numerical solution using 3D magnetisation vectors.",
862 "The 3-site numerical solution using 3D magnetisation vectors.",
863 None,
864 "The CR72 2-site model extended to MMQ CPMG data by Korzhnev et al., 2004.",
865 "The 2-site numerical solution of Korzhnev et al. (2004) from multi-quantum CPMG data.",
866 "The 3-site linearised numerical solution of Korzhnev et al. (2005) for MMQ CPMG data.",
867 "The 3-site numerical solution of Korzhnev et al. (2005) for MMQ CPMG data."
868 ]
869 size = wx.Size(1024, 750)
870 tooltip = "The list of all relaxation dispersion models to be optimised as part of the protocol."
871 tooltip_button = "Open the model list selector window."
872