1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """The automatic relaxation dispersion protocol."""
25
26
27 from copy import deepcopy
28 from os import F_OK, access, getcwd, sep
29 from numpy import version
30 import sys
31 from warnings import warn
32
33
34 from lib.dispersion.variables import EQ_ANALYTIC, EQ_NUMERIC, EQ_SILICO, MODEL_LIST_ANALYTIC, MODEL_LIST_NEST, MODEL_LIST_NUMERIC, MODEL_LIST_R1RHO, MODEL_LIST_R1RHO_FULL, MODEL_NOREX, MODEL_PARAMS, MODEL_R2EFF, PARAMS_R20
35 from lib.errors import RelaxError, RelaxFileError, RelaxNoPipeError
36 from lib.io import determine_compression, get_file_path
37 from lib.text.sectioning import section, subsection, subtitle, title
38 from lib.warnings import RelaxWarning
39 from pipe_control.mol_res_spin import return_spin, spin_loop
40 from pipe_control.pipes import has_pipe
41 from prompt.interpreter import Interpreter
42 from specific_analyses.relax_disp.data import has_exponential_exp_type, has_cpmg_exp_type, has_fixed_time_exp_type, has_r1rho_exp_type, is_r1_optimised
43 from specific_analyses.relax_disp.data import INTERPOLATE_DISP, INTERPOLATE_OFFSET, X_AXIS_DISP, X_AXIS_W_EFF, X_AXIS_THETA, Y_AXIS_R2_R1RHO, Y_AXIS_R2_EFF
44 from specific_analyses.relax_disp.model import nesting_model, nesting_param
45 from status import Status; status = Status()
46
47
49 """The relaxation dispersion auto-analysis."""
50
51
52 opt_func_tol = 1e-25
53 opt_max_iterations = int(1e7)
54
55 - def __init__(self, pipe_name=None, pipe_bundle=None, results_dir=None, models=[MODEL_R2EFF], grid_inc=11, mc_sim_num=500, exp_mc_sim_num=None, modsel='AIC', pre_run_dir=None, optimise_r2eff=False, insignificance=0.0, numeric_only=False, mc_sim_all_models=False, eliminate=True, set_grid_r20=False, r1_fit=False):
56 """Perform a full relaxation dispersion analysis for the given list of models.
57
58 @keyword pipe_name: The name of the data pipe containing all of the data for the analysis.
59 @type pipe_name: str
60 @keyword pipe_bundle: The data pipe bundle to associate all spawned data pipes with.
61 @type pipe_bundle: str
62 @keyword results_dir: The directory where results files are saved.
63 @type results_dir: str
64 @keyword models: The list of relaxation dispersion models to optimise.
65 @type models: list of str
66 @keyword grid_inc: Number of grid search increments. If set to None, then the grid search will be turned off and the default parameter values will be used instead.
67 @type grid_inc: int or None
68 @keyword mc_sim_num: The number of Monte Carlo simulations to be used for error analysis at the end of the analysis.
69 @type mc_sim_num: int
70 @keyword exp_mc_sim_num: The number of Monte Carlo simulations for the error analysis in the 'R2eff' model when exponential curves are fitted. This defaults to the value of the mc_sim_num argument when not given. When set to '-1', the R2eff errors are estimated from the Covariance matrix. For the 2-point fixed-time calculation for the 'R2eff' model, this argument is ignored.
71 @type exp_mc_sim_num: int or None
72 @keyword modsel: The model selection technique to use in the analysis to determine which model is the best for each spin cluster. This can currently be one of 'AIC', 'AICc', and 'BIC'.
73 @type modsel: str
74 @keyword pre_run_dir: 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.
75 @type pre_run_dir: None or str
76 @keyword optimise_r2eff: Flag to specify if the read previous R2eff results should be optimised. For R1rho models where the error of R2eff values are determined by Monte-Carlo simulations, it can be valuable to make an initial R2eff run with a high number of Monte-Carlo simulations. Any subsequent model analysis can then be based on these R2eff values, without optimising the R2eff values.
77 @type optimise_r2eff: bool
78 @keyword insignificance: The R2eff/R1rho 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 'No Rex' model. Set this value to 0.0 to use all data. The value will be passed on to the relax_disp.insignificance user function.
79 @type insignificance: float
80 @keyword numeric_only: The class of models to use in the model selection. The default of False allows all dispersion models to be used 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.
81 @type numeric_only: bool
82 @keyword mc_sim_all_models: 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.
83 @type mc_sim_all_models: bool
84 @keyword eliminate: A flag which if True will enable the elimination of failed models and failed Monte Carlo simulations through the eliminate user function.
85 @type eliminate: bool
86 @keyword set_grid_r20: A flag which if True will set the grid R20 values from the minimum R2eff values through the r20_from_min_r2eff user function. 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.
87 @type set_grid_r20: bool
88 @keyword r1_fit: A flag which if True will activate R1 parameter fitting via relax_disp.r1_fit for the models that support it. If False, then the relax_disp.r1_fit user function will not be called.
89 """
90
91
92 title(file=sys.stdout, text="Relaxation dispersion auto-analysis", prespace=4)
93
94
95 status.exec_lock.acquire(pipe_bundle, mode='auto-analysis')
96
97
98 status.init_auto_analysis(pipe_bundle, type='relax_disp')
99 status.current_analysis = pipe_bundle
100
101
102 self.pipe_name = pipe_name
103 self.pipe_bundle = pipe_bundle
104 self.results_dir = results_dir
105 self.grid_inc = grid_inc
106 self.mc_sim_num = mc_sim_num
107 self.exp_mc_sim_num = exp_mc_sim_num
108 self.models = models
109 self.modsel = modsel
110 self.pre_run_dir = pre_run_dir
111 self.optimise_r2eff = optimise_r2eff
112 self.insignificance = insignificance
113 self.set_grid_r20 = set_grid_r20
114 self.numeric_only = numeric_only
115 self.mc_sim_all_models = mc_sim_all_models
116 self.eliminate = eliminate
117 self.r1_fit = r1_fit
118
119
120 if not self.results_dir:
121 self.results_dir = getcwd()
122
123
124 self.check_vars()
125
126
127
128 self.check_numpy_less_1_8_and_numerical_model()
129
130
131 self.interpreter = Interpreter(show_script=False, raise_relax_error=True)
132 self.interpreter.populate_self()
133 self.interpreter.on(verbose=False)
134
135
136 try:
137 self.run()
138
139
140 finally:
141 status.auto_analysis[self.pipe_bundle].fin = True
142 status.current_analysis = None
143 status.exec_lock.release()
144
145
147 """Determine if the model should be used for model selection.
148
149 @keyword model: The model to check.
150 @type model: str
151 @return: True if the model should be included in the model selection list, False if not.
152 @rtype: bool
153 """
154
155
156 if model == MODEL_R2EFF:
157 return False
158
159
160 if self.numeric_only and model in MODEL_LIST_ANALYTIC:
161 return False
162
163
164 return True
165
166
168 """Check that the user has set the variables correctly."""
169
170
171 section(file=sys.stdout, text="Variable checking", prespace=2)
172
173
174 if not has_pipe(self.pipe_name):
175 raise RelaxNoPipeError(self.pipe_name)
176
177
178 allowed = ['AIC', 'AICc', 'BIC']
179 if self.modsel not in allowed:
180 raise RelaxError("The model selection technique '%s' is not in the allowed list of %s." % (self.modsel, allowed))
181
182
183 if self.numeric_only:
184
185 for model in self.models:
186
187 if model in MODEL_LIST_NEST:
188 continue
189
190
191 if model in MODEL_LIST_ANALYTIC:
192 warn(RelaxWarning("The analytic model '%s' will be optimised but will not be used in any way in this numeric model only auto-analysis." % model))
193
194
195 print("The dispersion auto-analysis variables are OK.")
196
197
199 """Check for numerical model using numpy version under 1.8. This will result in slow "for loop" calculation through data, making the analysis 5-6 times slower."""
200
201
202 if float(version.version[:3]) < 1.8:
203
204 models = []
205
206
207 for model in self.models:
208 if model in MODEL_LIST_NUMERIC:
209 models.append(model)
210
211
212 if len(models) > 0:
213
214 section(file=sys.stdout, text="Numpy version checking for numerical models.", prespace=2)
215 warn(RelaxWarning("Your version of numpy is %s, and below the recommended version of 1.8 for numerical models." % (version.version)))
216 warn(RelaxWarning("Please consider upgrading your numpy version to 1.8."))
217
218
219 for model in models:
220 warn(RelaxWarning("This could make the numerical analysis with model '%s', 5 to 6 times slower." % (model)))
221
222
224 """Perform an error analysis of the peak intensities for each field strength separately."""
225
226
227 section(file=sys.stdout, text="Error analysis", prespace=2)
228
229
230 precalc = True
231 for spin in spin_loop(skip_desel=True):
232
233 if not hasattr(spin, 'peak_intensity_err'):
234 precalc = False
235 break
236
237
238 for id in cdp.spectrum_ids:
239 if id not in spin.peak_intensity_err:
240 precalc = False
241 break
242
243
244 if precalc:
245 print("Skipping the error analysis as it has already been performed.")
246 return
247
248
249 self.interpreter.spectrum.error_analysis_per_field()
250
251
253 """Generate a unique name for the data pipe.
254
255 @param prefix: The prefix of the data pipe name.
256 @type prefix: str
257 """
258
259
260 name = "%s - %s" % (prefix, self.pipe_bundle)
261
262
263 return name
264
265
267 """Support for model nesting.
268
269 If model nesting is detected, the optimised parameters from the simpler model will be used for the more complex model. The method will then signal if the nesting condition is met for the model, allowing the grid search to be skipped.
270
271
272 @keyword model: The model to be optimised.
273 @type model: str
274 @return: True if the model parameters is equivalent to the nested model, and all parameters are copied. False if none or some of the parameters have been translated from the nested model. Here the Grid search should still be performed.
275 @rtype: bool
276 """
277
278
279 subsection(file=sys.stdout, text="Nesting and model equivalence checks", prespace=1)
280
281
282 model_info, comparable_model_info = nesting_model(self_models=self.models, model=model)
283 if comparable_model_info != None:
284 nested_pipe = self.name_pipe(comparable_model_info.model)
285 else:
286 nested_pipe = None
287
288
289 if not nested_pipe:
290 print("No model nesting or model equivalence detected.")
291 return False
292
293
294 if model_info.eq in [EQ_NUMERIC, EQ_SILICO] and comparable_model_info.eq == EQ_ANALYTIC:
295 analytic = True
296 else:
297 analytic = False
298
299
300 if model_info.params == comparable_model_info.params:
301 equivalent = True
302 else:
303 equivalent = False
304
305
306 if equivalent:
307 print("Model equivalence detected, copying the optimised parameters from the '%s' model rather than performing a grid search." % comparable_model_info.model)
308 else:
309 print("Model nesting detected, translating the optimised parameters %s from the '%s' model to the parameters %s of model '%s'. A grid search is issued for the remaining parameters." % (comparable_model_info.params, comparable_model_info.model, model_info.params, model))
310 if analytic:
311 print("The parameters are copied from a %s model to a %s model." % (comparable_model_info.eq, model_info.eq))
312
313
314 par_dic = nesting_param(model_params=model_info.params, nested_model_params=comparable_model_info.params)
315
316
317 for param in model_info.params:
318
319 param_conv = par_dic[param]
320
321
322 if param_conv == None:
323 continue
324
325 print("Copying from parameter '%s' to '%s'." % (param_conv, param))
326
327
328 for spin, spin_id in spin_loop(return_id=True, skip_desel=True):
329
330 nested_spin = return_spin(spin_id=spin_id, pipe=nested_pipe)
331
332
333
334 if param_conv == '1 - pA':
335 val = 1.0 - getattr(nested_spin, 'pA')
336
337 elif param_conv == '0.0':
338 val = 0.0
339
340 else:
341 val = deepcopy(getattr(nested_spin, param_conv))
342
343
344 setattr(spin, param, val)
345
346
347 return equivalent
348
349
350 - def optimise(self, model=None, model_path=None):
351 """Optimise the model, taking model nesting into account.
352
353 @keyword model: The model to be optimised.
354 @type model: str
355 @keyword model_path: The folder name for the model, where possible spaces has been replaced with underscore.
356 @type model_path: str
357 """
358
359
360 section(file=sys.stdout, text="Optimisation", prespace=2)
361
362
363 if model not in [MODEL_R2EFF, MODEL_NOREX]:
364 self.interpreter.relax_disp.insignificance(level=self.insignificance)
365
366
367 if self.set_grid_r20 and model != MODEL_R2EFF:
368 self.interpreter.relax_disp.r20_from_min_r2eff(force=True)
369
370
371
372 if self.pre_run_dir:
373 path = self.pre_run_dir + sep + model_path
374
375 file_path = get_file_path('results', path)
376
377
378 try:
379 compress_type, file_path = determine_compression(file_path)
380 res_file_exists = True
381
382 except RelaxFileError:
383 res_file_exists = False
384
385 if self.pre_run_dir and res_file_exists:
386 self.pre_run_parameters(model=model, model_path=model_path)
387
388
389 else:
390
391 nested = self.nesting(model=model)
392
393
394 if not nested:
395
396 if self.grid_inc:
397 self.interpreter.minimise.grid_search(inc=self.grid_inc)
398
399
400 else:
401
402 for param in MODEL_PARAMS[model]:
403 self.interpreter.value.set(param=param, index=None)
404
405
406 if is_r1_optimised(model=model):
407 self.interpreter.value.set(param='r1', index=None)
408
409
410 do_minimise = False
411 if model == MODEL_R2EFF:
412
413 constraints = False
414
415
416
417 min_algor = 'Newton'
418
419
420 has_r2eff = False
421
422
423 for cur_spin, spin_id in spin_loop(return_id=True, skip_desel=True):
424
425 if hasattr(cur_spin, 'r2eff') and hasattr(cur_spin, 'r2eff_err'):
426 has_r2eff = True
427 else:
428 has_r2eff = False
429 break
430
431
432 if has_r2eff and not self.optimise_r2eff:
433 pass
434
435
436 elif has_r2eff and self.optimise_r2eff:
437 do_minimise = True
438
439
440 elif not has_r2eff:
441 do_minimise = True
442
443
444 else:
445 do_minimise = True
446 constraints = True
447
448 min_algor = 'simplex'
449
450
451 if do_minimise:
452 self.interpreter.minimise.execute(min_algor=min_algor, func_tol=self.opt_func_tol, max_iter=self.opt_max_iterations, constraints=constraints)
453
454
455 if self.eliminate:
456 self.interpreter.eliminate()
457
458
459 do_monte_carlo = False
460 if model == MODEL_R2EFF:
461
462 constraints = False
463
464
465 min_algor = 'Newton'
466
467
468 if has_r2eff and not self.optimise_r2eff:
469 pass
470
471
472 elif has_r2eff and self.optimise_r2eff:
473 do_monte_carlo = True
474
475
476 elif not has_r2eff:
477 do_monte_carlo = True
478
479 elif self.mc_sim_all_models or len(self.models) < 2:
480 do_monte_carlo = True
481
482 constraints = True
483
484 min_algor = 'simplex'
485
486
487 if do_monte_carlo:
488
489 monte_carlo_sim = self.mc_sim_num
490
491
492 if model == MODEL_R2EFF and self.exp_mc_sim_num != None:
493 monte_carlo_sim = self.exp_mc_sim_num
494
495
496
497 if model == MODEL_R2EFF and self.exp_mc_sim_num == -1:
498
499 subsection(file=sys.stdout, text="Estimating errors from Covariance matrix", prespace=1)
500
501
502 text = 'Estimating errors from the Covariance matrix is highly likely to be "quite" wrong. Use only with extreme care, and for initial rapid testing of your data.'
503 warn(RelaxWarning(text))
504
505
506 self.interpreter.relax_disp.r2eff_err_estimate()
507 else:
508 self.interpreter.monte_carlo.setup(number=monte_carlo_sim)
509 self.interpreter.monte_carlo.create_data()
510 self.interpreter.monte_carlo.initial_values()
511 self.interpreter.minimise.execute(min_algor=min_algor, func_tol=self.opt_func_tol, max_iter=self.opt_max_iterations, constraints=constraints)
512 if self.eliminate:
513 self.interpreter.eliminate()
514 self.interpreter.monte_carlo.error_analysis()
515
516
549
550
552 """Execute the auto-analysis."""
553
554
555 if MODEL_R2EFF in self.models:
556 self.error_analysis()
557
558
559 if self.r1_fit:
560 subtitle(file=sys.stdout, text="R1 parameter optimisation activation", prespace=3)
561 self.interpreter.relax_disp.r1_fit(fit=self.r1_fit)
562 else:
563
564 self.interpreter.relax_disp.r1_fit(fit=self.r1_fit)
565
566
567 self.model_pipes = []
568 for model in self.models:
569
570 subtitle(file=sys.stdout, text="The '%s' model" % model, prespace=3)
571
572
573 model_path = model.replace(" ", "_")
574 path = self.results_dir+sep+model_path
575
576
577 model_pipe = self.name_pipe(model)
578 if self.is_model_for_selection(model):
579 self.model_pipes.append(model_pipe)
580
581
582 path1 = path + sep + 'results'
583 path2 = path1 + '.bz2'
584 path3 = path1 + '.gz'
585 if access(path1, F_OK) or access(path2, F_OK) or access(path2, F_OK):
586
587 print("Detected the presence of results files for the '%s' model - loading these instead of performing optimisation for a second time." % model)
588
589
590 self.interpreter.pipe.create(pipe_name=model_pipe, pipe_type='relax_disp', bundle=self.pipe_bundle)
591 self.interpreter.pipe.switch(model_pipe)
592
593
594 self.interpreter.results.read(file='results', dir=path)
595
596
597 continue
598
599
600 self.interpreter.pipe.copy(pipe_from=self.pipe_name, pipe_to=model_pipe, bundle_to=self.pipe_bundle)
601 self.interpreter.pipe.switch(model_pipe)
602
603
604 self.interpreter.relax_disp.select_model(model)
605
606
607 if model != MODEL_R2EFF and MODEL_R2EFF in self.models:
608 self.interpreter.value.copy(pipe_from=self.name_pipe(MODEL_R2EFF), pipe_to=model_pipe, param='r2eff')
609
610
611 if model == MODEL_R2EFF and not has_exponential_exp_type():
612 self.interpreter.minimise.calculate()
613
614
615 else:
616 self.optimise(model=model, model_path=model_path)
617
618
619 self.write_results(path=path, model=model)
620
621
622 if len(self.models) >= 2:
623
624 section(file=sys.stdout, text="Final results", prespace=2)
625
626
627 self.interpreter.model_selection(method=self.modsel, modsel_pipe=self.name_pipe('final'), bundle=self.pipe_bundle, pipes=self.model_pipes)
628
629
630 if not self.mc_sim_all_models:
631 self.interpreter.monte_carlo.setup(number=self.mc_sim_num)
632 self.interpreter.monte_carlo.create_data()
633 self.interpreter.monte_carlo.initial_values()
634 self.interpreter.minimise.execute('simplex', func_tol=self.opt_func_tol, max_iter=self.opt_max_iterations, constraints=True)
635 if self.eliminate:
636 self.interpreter.eliminate()
637 self.interpreter.monte_carlo.error_analysis()
638
639
640 self.write_results(path=self.results_dir+sep+'final')
641
642
643 else:
644 warn(RelaxWarning("Model selection in the dispersion auto-analysis has been skipped as only %s models have been optimised." % len(self.model_pipes)))
645
646
647 self.interpreter.state.save(state='final_state', dir=self.results_dir, force=True)
648
649
651 """Create a set of results, text and Grace files for the current data pipe.
652
653 @keyword path: The directory to place the files into.
654 @type path: str
655 """
656
657
658 section(file=sys.stdout, text="Results writing", prespace=2)
659
660
661 if model == None:
662 models_tested = []
663 for spin, spin_id in spin_loop(return_id=True, skip_desel=True):
664 spin_model = spin.model
665
666
667 if spin_model not in models_tested:
668 models_tested.append(spin_model)
669 else:
670 models_tested = None
671
672
673 if model == MODEL_R2EFF:
674
675 self.interpreter.value.write(param='r2eff', file='r2eff.out', dir=path, force=True)
676 self.interpreter.grace.write(x_data_type='res_num', y_data_type='r2eff', file='r2eff.agr', dir=path, force=True)
677
678
679 if has_exponential_exp_type():
680 self.interpreter.relax_disp.plot_exp_curves(file='intensities.agr', dir=path, force=True)
681 self.interpreter.relax_disp.plot_exp_curves(file='intensities_norm.agr', dir=path, force=True, norm=True)
682
683
684 self.interpreter.value.write(param='i0', file='i0.out', dir=path, force=True)
685 self.interpreter.grace.write(x_data_type='res_num', y_data_type='i0', file='i0.agr', dir=path, force=True)
686
687
688 self.interpreter.relax_disp.plot_disp_curves(dir=path, force=True)
689 self.interpreter.relax_disp.write_disp_curves(dir=path, force=True)
690
691
692 if model == None:
693 self.interpreter.value.write(param='model', file='model.out', dir=path, force=True)
694
695
696 if has_cpmg_exp_type():
697
698 self.write_results_test(path=path, model=model, models_tested=models_tested, param='r2', file_name_ini='r20')
699
700
701 self.write_results_test(path=path, model=model, models_tested=models_tested, param='r2a', file_name_ini='r20a')
702 self.write_results_test(path=path, model=model, models_tested=models_tested, param='r2b', file_name_ini='r20b')
703
704
705 if has_r1rho_exp_type():
706
707 self.write_results_test(path=path, model=model, models_tested=models_tested, param='r1')
708
709
710 self.write_results_test(path=path, model=model, models_tested=models_tested, param='r2', file_name_ini='r1rho_prime')
711
712
713 if model in [None] + MODEL_LIST_R1RHO:
714 self.interpreter.relax_disp.plot_disp_curves(dir=path, x_axis=X_AXIS_THETA, force=True)
715 self.interpreter.relax_disp.plot_disp_curves(dir=path, y_axis=Y_AXIS_R2_R1RHO, x_axis=X_AXIS_W_EFF, force=True)
716 self.interpreter.relax_disp.plot_disp_curves(dir=path, y_axis=Y_AXIS_R2_EFF, x_axis=X_AXIS_THETA, interpolate=INTERPOLATE_OFFSET, force=True)
717
718
719 if model in MODEL_LIST_R1RHO_FULL:
720 self.interpreter.value.write(param='theta', file='theta.out', dir=path, force=True)
721 self.interpreter.value.write(param='w_eff', file='w_eff.out', dir=path, force=True)
722
723
724 self.write_results_test(path=path, model=model, models_tested=models_tested, param='pA')
725 self.write_results_test(path=path, model=model, models_tested=models_tested, param='pB')
726
727
728 self.write_results_test(path=path, model=model, models_tested=models_tested, param='pC')
729
730
731 self.write_results_test(path=path, model=model, models_tested=models_tested, param='phi_ex')
732
733
734 self.write_results_test(path=path, model=model, models_tested=models_tested, param='phi_ex_B')
735 self.write_results_test(path=path, model=model, models_tested=models_tested, param='phi_ex_C')
736
737
738 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dw')
739
740
741 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dw_AB')
742 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dw_BC')
743 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dw_AC')
744
745
746 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dwH')
747
748
749 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dwH_AB')
750 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dwH_BC')
751 self.write_results_test(path=path, model=model, models_tested=models_tested, param='dwH_AC')
752
753
754 self.write_results_test(path=path, model=model, models_tested=models_tested, param='k_AB')
755 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kex')
756 self.write_results_test(path=path, model=model, models_tested=models_tested, param='tex')
757
758
759 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kex_AB')
760 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kex_BC')
761 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kex_AC')
762
763
764 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kB')
765 self.write_results_test(path=path, model=model, models_tested=models_tested, param='kC')
766
767
768 if not (model == MODEL_R2EFF and has_fixed_time_exp_type()):
769 self.interpreter.value.write(param='chi2', file='chi2.out', dir=path, force=True)
770 self.interpreter.grace.write(y_data_type='chi2', file='chi2.agr', dir=path, force=True)
771
772
773 self.interpreter.results.write(file='results', dir=path, force=True)
774
775
776 - def write_results_test(self, path=None, model=None, models_tested=None, param=None, file_name_ini=None):
777 """Create a set of results, text and Grace files for the current data pipe.
778
779 @keyword path: The directory to place the files into.
780 @type path: str
781 @keyword model: The model tested.
782 @type model: None or str
783 @keyword model_tested: List of models tested, if the pipe is final.
784 @type model_tested: None or list of str.
785 @keyword param: The param to write out.
786 @type param: None or list of str.
787 @keyword file_name_ini: The initial part of the file name for the grace and text files.
788 @type file_name_ini: None or str.
789 """
790
791
792 if file_name_ini == None:
793 file_name_ini = param
794
795
796 write_result = False
797 if model != None:
798
799 model_params = MODEL_PARAMS[model]
800
801 if param in model_params:
802 write_result = True
803
804
805 elif model == None:
806
807 for model_tested in models_tested:
808
809 model_params = MODEL_PARAMS[model_tested]
810
811 if param in model_params:
812 write_result = True
813 break
814
815
816 if write_result:
817 self.interpreter.value.write(param=param, file='%s.out'%file_name_ini, dir=path, force=True)
818 self.interpreter.grace.write(x_data_type='res_num', y_data_type=param, file='%s.agr'%file_name_ini, dir=path, force=True)
819