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