1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24  """Target functions for relaxation exponential curve fitting with both minfx and scipy.optimize.leastsq.""" 
 25   
 26   
 27  from copy import deepcopy 
 28  from numpy import array, asarray, diag, exp, log, ones, sqrt, sum, transpose, zeros 
 29  from minfx.generic import generic_minimise 
 30  import sys 
 31  from warnings import warn 
 32   
 33   
 34  from dep_check import C_module_exp_fn, scipy_module 
 35  from lib.dispersion.variables import MODEL_R2EFF 
 36  from lib.errors import RelaxError 
 37  from lib.statistics import multifit_covar 
 38  from lib.text.sectioning import subsection 
 39  from lib.warnings import RelaxWarning 
 40  from pipe_control.mol_res_spin import generate_spin_string, spin_loop 
 41  from specific_analyses.relax_disp.checks import check_model_type 
 42  from specific_analyses.relax_disp.data import average_intensity, loop_exp_frq_offset_point, loop_time, return_param_key_from_data 
 43  from specific_analyses.relax_disp.parameters import disassemble_param_vector 
 44  from target_functions.chi2 import chi2_rankN, dchi2 
 45  from target_functions.relax_fit_wrapper import Relax_fit_opt 
 46   
 47   
 48  if scipy_module: 
 49       
 50      from scipy.optimize import leastsq 
 51   
 52   
 54      """This will estimate the R2eff and i0 errors from the covariance matrix Qxx.  Qxx is calculated from the Jacobian matrix and the optimised parameters. 
 55   
 56      @keyword spin_id:       The spin identification string. 
 57      @type spin_id:          str 
 58      @param epsrel:          Any columns of R which satisfy |R_{kk}| <= epsrel |R_{11}| are considered linearly-dependent and are excluded from the covariance matrix, where the corresponding rows and columns of the covariance matrix are set to zero. 
 59      @type epsrel:           float 
 60      @keyword verbosity:     The amount of information to print.  The higher the value, the greater the verbosity. 
 61      @type verbosity:        int 
 62      """ 
 63   
 64       
 65      if not C_module_exp_fn: 
 66          raise RelaxError("Relaxation curve fitting is not available.  Try compiling the C modules on your platform.") 
 67   
 68       
 69      check_model_type(model=MODEL_R2EFF) 
 70   
 71       
 72      for cur_spin, mol_name, resi, resn, cur_spin_id in spin_loop(selection=spin_id, full_info=True, return_id=True, skip_desel=True): 
 73           
 74          spin_string = generate_spin_string(spin=cur_spin, mol_name=mol_name, res_num=resi, res_name=resn) 
 75   
 76           
 77          if not (hasattr(cur_spin, 'r2eff') and hasattr(cur_spin, 'i0')): 
 78              raise RelaxError("Spin %s does not contain optimised 'r2eff' and 'i0' values.  Try execute: minimise.execute(min_algor='Newton', constraints=False)"%(spin_string)) 
 79   
 80           
 81          if hasattr(cur_spin, 'g_count'): 
 82              if getattr(cur_spin, 'g_count') == 0.0: 
 83                  text = "Spin %s contains a gradient count of 0.0.  Is the R2eff parameter optimised?  Try execute: minimise.execute(min_algor='Newton', constraints=False)" %(spin_string) 
 84                  warn(RelaxWarning("%s." % text)) 
 85   
 86           
 87          if verbosity >= 1: 
 88               
 89              top = 2 
 90              if verbosity >= 2: 
 91                  top += 2 
 92              subsection(file=sys.stdout, text="Estimating R2eff error for spin: %s"%spin_string, prespace=top) 
 93   
 94           
 95          for exp_type, frq, offset, point, ei, mi, oi, di in loop_exp_frq_offset_point(return_indices=True): 
 96               
 97              param_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 
 98   
 99               
100              r2eff = getattr(cur_spin, 'r2eff')[param_key] 
101              i0 = getattr(cur_spin, 'i0')[param_key] 
102   
103               
104              param_vector = [r2eff, i0] 
105   
106               
107              values = [] 
108              errors = [] 
109              times = [] 
110              for time in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point): 
111                  values.append(average_intensity(spin=cur_spin, exp_type=exp_type, frq=frq, offset=offset, point=point, time=time)) 
112                  errors.append(average_intensity(spin=cur_spin, exp_type=exp_type, frq=frq, offset=offset, point=point, time=time, error=True)) 
113                  times.append(time) 
114   
115               
116              values = asarray(values) 
117              errors = asarray(errors) 
118              times = asarray(times) 
119   
120               
121              scaling_list = [1.0, 1.0] 
122              model = Relax_fit_opt(model='exp', num_params=len(param_vector), values=values, errors=errors, relax_times=times, scaling_matrix=scaling_list) 
123   
124               
125              jacobian_matrix_exp = transpose(asarray( model.jacobian(param_vector) ) ) 
126              weights = 1. / errors**2 
127   
128               
129              pcov = multifit_covar(J=jacobian_matrix_exp, weights=weights) 
130   
131               
132              param_vector_error = sqrt(diag(pcov)) 
133   
134               
135              r2eff_err, i0_err = param_vector_error 
136   
137               
138              if not hasattr(cur_spin, 'r2eff_err'): 
139                  setattr(cur_spin, 'r2eff_err', deepcopy(getattr(cur_spin, 'r2eff'))) 
140              if not hasattr(cur_spin, 'i0_err'): 
141                  setattr(cur_spin, 'i0_err', deepcopy(getattr(cur_spin, 'i0'))) 
142   
143               
144              cur_spin.r2eff_err[param_key] = r2eff_err 
145              cur_spin.i0_err[param_key] = i0_err 
146   
147               
148              chi2 = getattr(cur_spin, 'chi2') 
149   
150               
151              print_strings = [] 
152              if verbosity >= 1: 
153                   
154                  point_info = "%s at %3.1f MHz, for offset=%3.3f ppm and dispersion point %-5.1f, with %i time points." % (exp_type, frq/1E6, offset, point, len(times)) 
155                  print_strings.append(point_info) 
156   
157                  par_info = "r2eff=%3.3f r2eff_err=%3.4f, i0=%6.1f, i0_err=%3.4f, chi2=%3.3f.\n" % ( r2eff, r2eff_err, i0, i0_err, chi2) 
158                  print_strings.append(par_info) 
159   
160                  if verbosity >= 2: 
161                      time_info = ', '.join(map(str, times)) 
162                      print_strings.append('For time array: '+time_info+'.\n\n') 
163   
164               
165              if len(print_strings) > 0: 
166                  for print_string in print_strings: 
167                      print(print_string), 
 168   
169   
170   
171   
174          """Class for to set settings for minimisation and dispersion target functions for minimisation. 
175   
176          This class contains minimisation functions for both minfx and scipy.optimize.leastsq. 
177   
178          @keyword verbosity:         The amount of information to print.  The higher the value, the greater the verbosity. 
179          @type verbosity:            int 
180          """ 
181   
182           
183          self.verbosity = verbosity 
184   
185           
186          self.set_settings_leastsq() 
187          self.set_settings_minfx() 
 188   
189   
190 -    def setup_data(self, times=None, values=None, errors=None): 
 191          """Setup for minimisation with minfx. 
192   
193          @keyword times:             The time points. 
194          @type times:                numpy array 
195          @keyword values:            The measured intensity values per time point. 
196          @type values:               numpy array 
197          @keyword errors:            The standard deviation of the measured intensity values per time point. 
198          @type errors:               numpy array 
199          """ 
200   
201           
202          self.times = times 
203          self.values = values 
204          self.errors = errors 
 205   
206   
208          """Setup options to scipy.optimize.leastsq. 
209   
210          @keyword ftol:              The function tolerance for the relative error desired in the sum of squares, parsed to leastsq. 
211          @type ftol:                 float 
212          @keyword xtol:              The error tolerance for the relative error desired in the approximate solution, parsed to leastsq. 
213          @type xtol:                 float 
214          @keyword maxfev:            The maximum number of function evaluations, parsed to leastsq.  If zero, then 100*(N+1) is the maximum function calls.  N is the number of elements in x0=[r2eff, i0]. 
215          @type maxfev:               int 
216          @keyword factor:            The initial step bound, parsed to leastsq.  It determines the initial step bound (''factor * || diag * x||'').  Should be in the interval (0.1, 100). 
217          @type factor:               float 
218          """ 
219   
220           
221          self.ftol = ftol 
222          self.xtol = xtol 
223          self.maxfev = maxfev 
224          self.factor = factor 
 225   
226   
227 -    def set_settings_minfx(self, scaling_matrix=None, min_algor='simplex', c_code=True, constraints=False, chi2_jacobian=False, func_tol=1e-25, grad_tol=None, max_iterations=10000000): 
 228          """Setup options to minfx. 
229   
230          @keyword scaling_matrix:    The square and diagonal scaling matrix. 
231          @type scaling_matrix:       numpy rank-2 float array 
232          @keyword min_algor:         The minimisation algorithm 
233          @type min_algor:            string 
234          @keyword c_code:            If optimise with C code. 
235          @type c_code:               bool 
236          @keyword constraints:       If constraints should be used. 
237          @type constraints:          bool 
238          @keyword chi2_jacobian:     If the chi2 Jacobian should be used. 
239          @type chi2_jacobian:        bool 
240          @keyword func_tol:          The function tolerance which, when reached, terminates optimisation.  Setting this to None turns of the check. 
241          @type func_tol:             None or float 
242          @keyword grad_tol:          The gradient tolerance which, when reached, terminates optimisation.  Setting this to None turns of the check. 
243          @type grad_tol:             None or float 
244          @keyword max_iterations:    The maximum number of iterations for the algorithm. 
245          @type max_iterations:       int 
246          """ 
247   
248           
249          self.scaling_matrix = scaling_matrix 
250          self.c_code = c_code 
251          self.chi2_jacobian = chi2_jacobian 
252   
253           
254          self.scaling_flag = False 
255          if self.scaling_matrix != None: 
256              self.scaling_flag = True 
257   
258           
259          self.min_algor = min_algor 
260   
261           
262          self.constraints = constraints 
263   
264           
265          self.func_tol = func_tol 
266          self.grad_tol = grad_tol 
267          self.max_iterations = max_iterations 
268   
269           
270          if self.constraints: 
271              self.min_options = ('%s'%(self.min_algor),) 
272              self.min_algor = 'Log barrier' 
273              self.A = array([ [ 1.,  0.], 
274                          [-1.,  0.], 
275                          [ 0.,  1.]] ) 
276              self.b = array([   0., -200.,    0.]) 
277   
278          else: 
279              self.min_options = () 
280              self.A = None 
281              self.b = None 
 282   
283   
285          """Estimate starting parameter x0 = [r2eff_est, i0_est], by converting the exponential curve to a linear problem.  Then solving by linear least squares of: ln(Intensity[j]) = ln(i0) - time[j]* r2eff. 
286   
287          @keyword times:         The time points. 
288          @type times:            numpy array 
289          @keyword values:        The measured intensity values per time point. 
290          @type values:           numpy array 
291          @return:                The list with estimated r2eff and i0 parameter for optimisation, [r2eff_est, i0_est] 
292          @rtype:                 list 
293          """ 
294   
295           
296          w = log(values) 
297          x = - 1. * times 
298          n = len(times) 
299   
300           
301          b = (sum(x*w) - 1./n * sum(x) * sum(w) ) / ( sum(x**2) - 1./n * (sum(x))**2 ) 
302          a = 1./n * sum(w) - b * 1./n * sum(x) 
303   
304           
305          r2eff_est = b 
306          i0_est = exp(a) 
307   
308           
309          return [r2eff_est, i0_est] 
 310   
311   
312 -    def func_exp(self, params=None, times=None): 
 313          """Calculate the function values of exponential function. 
314   
315          @param params:  The vector of parameter values. 
316          @type params:   numpy rank-1 float array 
317          @keyword times: The time points. 
318          @type times:    numpy array 
319          @return:        The function values. 
320          @rtype:         numpy array 
321          """ 
322   
323           
324          r2eff, i0 = params 
325   
326           
327          return i0 * exp( -times * r2eff) 
 328   
329   
331          """Calculate the residual vector betwen measured values and the function values. 
332   
333          @param params:  The vector of parameter values. 
334          @type params:   numpy rank-1 float array 
335          @keyword times: The time points. 
336          @type times:    numpy array 
337          @param values:  The measured values. 
338          @type values:   numpy array 
339          @return:        The residuals. 
340          @rtype:         numpy array 
341          """ 
342   
343           
344          K = values - self.func_exp(params=params, times=times) 
345   
346           
347          return K 
 348   
349   
351          """Calculate the weighted residual vector betwen measured values and the function values. 
352   
353          @param params:  The vector of parameter values. 
354          @type params:   numpy rank-1 float array 
355          @keyword times: The time points. 
356          @type times:    numpy array 
357          @param values:  The measured values. 
358          @type values:   numpy array 
359          @param errors:  The standard deviation of the measured intensity values per time point. 
360          @type errors:   numpy array 
361          @return:        The weighted residuals. 
362          @rtype:         numpy array 
363          """ 
364   
365           
366          Kw = 1. / errors * self.func_exp_residual(params=params, times=times, values=values) 
367   
368           
369          return Kw 
 370   
371   
373          """The gradient (Jacobian matrix) of func_exp for Co-variance calculation. 
374   
375          @param params:  The vector of parameter values. 
376          @type params:   numpy rank-1 float array 
377          @keyword times: The time points. 
378          @type times:    numpy array 
379          @return:        The Jacobian matrix with 'm' rows of function derivatives per 'n' columns of parameters. 
380          @rtype:         numpy array 
381          """ 
382   
383           
384          r2eff = params[0] 
385          i0 = params[1] 
386   
387           
388          d_exp_d_r2eff = -i0 * times * exp(-r2eff * times) 
389   
390           
391          d_exp_d_i0 = exp(-r2eff * times) 
392   
393           
394          jacobian_matrix_exp = transpose(array( [d_exp_d_r2eff, d_exp_d_i0] ) ) 
395   
396           
397          return jacobian_matrix_exp 
 398   
399   
400 -    def func_exp_chi2(self, params=None, times=None, values=None, errors=None): 
 401          """Target function for minimising chi2 in minfx, for exponential fit. 
402   
403          @param params:  The vector of parameter values. 
404          @type params:   numpy rank-1 float array 
405          @keyword times: The time points. 
406          @type times:    numpy array 
407          @param values:  The measured values. 
408          @type values:   numpy array 
409          @param errors:  The standard deviation of the measured intensity values per time point. 
410          @type errors:   numpy array 
411          @return:        The chi2 value. 
412          @rtype:         float 
413          """ 
414   
415           
416          back_calc = self.func_exp(params=params, times=times) 
417   
418           
419          chi2 = chi2_rankN(data=values, back_calc_vals=back_calc, errors=errors) 
420   
421           
422          return chi2 
 423   
424   
426          """Target function for the gradient (Jacobian matrix) to minfx, for exponential fit . 
427   
428          @param params:  The vector of parameter values. 
429          @type params:   numpy rank-1 float array 
430          @keyword times: The time points. 
431          @type times:    numpy array 
432          @param values:  The measured values. 
433          @type values:   numpy array 
434          @param errors:  The standard deviation of the measured intensity values per time point. 
435          @type errors:   numpy array 
436          @return:        The Jacobian matrix with 'm' rows of function derivatives per 'n' columns of parameters, which have been summed together. 
437          @rtype:         numpy array 
438          """ 
439   
440           
441          back_calc = self.func_exp(params=params, times=times) 
442   
443           
444          exp_grad = self.func_exp_grad(params=params, times=times) 
445   
446           
447          exp_grad_t = transpose(exp_grad) 
448   
449           
450          n = len(params) 
451   
452           
453          jacobian_chi2_minfx = zeros([n]) 
454   
455           
456          dchi2(dchi2=jacobian_chi2_minfx, M=n, data=values, back_calc_vals=back_calc, back_calc_grad=exp_grad_t, errors=errors) 
457   
458           
459          return jacobian_chi2_minfx 
 460   
461   
463          """Return the gradient (Jacobian matrix) of func_exp_chi2() for parameter co-variance error estimation.  This needs return as array. 
464   
465          @param params:      The vector of parameter values. 
466          @type params:       numpy rank-1 float array 
467          @keyword times:     The time points. 
468          @type times:        numpy array 
469          @keyword values:    The measured intensity values per time point. 
470          @type values:       numpy array 
471          @keyword errors:    The standard deviation of the measured intensity values per time point. 
472          @type errors:       numpy array 
473          @return:            The Jacobian matrix with 'm' rows of function derivatives per 'n' columns of parameters. 
474          @rtype:             numpy array 
475          """ 
476   
477           
478          r2eff = params[0] 
479          i0 = params[1] 
480   
481           
482          d_chi2_d_r2eff = 2.0 * i0 * times * ( -i0 * exp( -r2eff * times) + values) * exp( -r2eff * times ) / errors**2 
483   
484           
485          d_chi2_d_i0 = - 2.0 * ( -i0 * exp( -r2eff * times) + values) * exp( -r2eff * times) / errors**2 
486   
487           
488          jacobian_matrix_exp_chi2 = transpose(array( [d_chi2_d_r2eff, d_chi2_d_i0] ) ) 
489   
490          return jacobian_matrix_exp_chi2 
 493 -def estimate_r2eff(method='minfx', min_algor='simplex', c_code=True, constraints=False, chi2_jacobian=False, spin_id=None, ftol=1e-15, xtol=1e-15, maxfev=10000000, factor=100.0, verbosity=1): 
 494      """Estimate r2eff and errors by exponential curve fitting with scipy.optimize.leastsq or minfx. 
495   
496      THIS IS ONLY FOR TESTING. 
497   
498      scipy.optimize.leastsq is a wrapper around MINPACK's lmdif and lmder algorithms. 
499   
500      MINPACK is a FORTRAN90 library which solves systems of nonlinear equations, or carries out the least squares minimization of the residual of a set of linear or nonlinear equations. 
501   
502      Errors are calculated by taking the square root of the reported co-variance. 
503   
504      This can be an huge time saving step, when performing model fitting in R1rho. 
505      Errors of R2eff values, are normally estimated by time-consuming Monte-Carlo simulations. 
506   
507      Initial guess for the starting parameter x0 = [r2eff_est, i0_est], is by converting the exponential curve to a linear problem. 
508      Then solving initial guess by linear least squares of: ln(Intensity[j]) = ln(i0) - time[j]* r2eff. 
509   
510   
511      @keyword method:            The method to minimise and estimate errors.  Options are: 'minfx' or 'scipy.optimize.leastsq'. 
512      @type method:               string 
513      @keyword min_algor:         The minimisation algorithm 
514      @type min_algor:            string 
515      @keyword c_code:            If optimise with C code. 
516      @type c_code:               bool 
517      @keyword constraints:       If constraints should be used. 
518      @type constraints:          bool 
519      @keyword chi2_jacobian:     If the chi2 Jacobian should be used. 
520      @type chi2_jacobian:        bool 
521      @keyword spin_id:           The spin identification string. 
522      @type spin_id:              str 
523      @keyword ftol:              The function tolerance for the relative error desired in the sum of squares, parsed to leastsq. 
524      @type ftol:                 float 
525      @keyword xtol:              The error tolerance for the relative error desired in the approximate solution, parsed to leastsq. 
526      @type xtol:                 float 
527      @keyword maxfev:            The maximum number of function evaluations, parsed to leastsq.  If zero, then 100*(N+1) is the maximum function calls.  N is the number of elements in x0=[r2eff, i0]. 
528      @type maxfev:               int 
529      @keyword factor:            The initial step bound, parsed to leastsq.  It determines the initial step bound (''factor * || diag * x||'').  Should be in the interval (0.1, 100). 
530      @type factor:               float 
531      @keyword verbosity:         The amount of information to print.  The higher the value, the greater the verbosity. 
532      @type verbosity:            int 
533      """ 
534   
535       
536      check_model_type(model=MODEL_R2EFF) 
537   
538       
539      if not C_module_exp_fn and method == 'minfx': 
540          raise RelaxError("Relaxation curve fitting is not available.  Try compiling the C modules on your platform.") 
541   
542       
543      E = Exp(verbosity=verbosity) 
544      E.set_settings_leastsq(ftol=ftol, xtol=xtol, maxfev=maxfev, factor=factor) 
545   
546       
547      precalc = True 
548      for cur_spin, mol_name, resi, resn, cur_spin_id in spin_loop(selection=spin_id, full_info=True, return_id=True, skip_desel=True): 
549           
550          if not hasattr(cur_spin, 'peak_intensity_err'): 
551              precalc = False 
552              break 
553   
554           
555          for id in cdp.spectrum_ids: 
556              if id not in cur_spin.peak_intensity_err: 
557                  precalc = False 
558                  break 
559   
560       
561      for cur_spin, mol_name, resi, resn, cur_spin_id in spin_loop(selection=spin_id, full_info=True, return_id=True, skip_desel=True): 
562           
563          spin_string = generate_spin_string(spin=cur_spin, mol_name=mol_name, res_num=resi, res_name=resn) 
564   
565           
566          if E.verbosity >= 1: 
567               
568              top = 2 
569              if E.verbosity >= 2: 
570                  top += 2 
571              subsection(file=sys.stdout, text="Fitting with %s to: %s"%(method, spin_string), prespace=top) 
572              if method == 'minfx': 
573                  subsection(file=sys.stdout, text="min_algor='%s', c_code=%s, constraints=%s, chi2_jacobian?=%s"%(min_algor, c_code, constraints, chi2_jacobian), prespace=0) 
574   
575           
576          for exp_type, frq, offset, point, ei, mi, oi, di in loop_exp_frq_offset_point(return_indices=True): 
577               
578              param_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 
579   
580               
581              values = [] 
582              errors = [] 
583              times = [] 
584              for time in loop_time(exp_type=exp_type, frq=frq, offset=offset, point=point): 
585                  values.append(average_intensity(spin=cur_spin, exp_type=exp_type, frq=frq, offset=offset, point=point, time=time)) 
586                  errors.append(average_intensity(spin=cur_spin, exp_type=exp_type, frq=frq, offset=offset, point=point, time=time, error=True)) 
587                  times.append(time) 
588   
589               
590              values = asarray(values) 
591              errors = asarray(errors) 
592              times = asarray(times) 
593   
594               
595              E.setup_data(values=values, errors=errors, times=times) 
596   
597               
598              if method == 'scipy.optimize.leastsq': 
599                   
600                  results = minimise_leastsq(E=E) 
601   
602              elif method == 'minfx': 
603                   
604                  E.set_settings_minfx(min_algor=min_algor, c_code=c_code, chi2_jacobian=chi2_jacobian, constraints=constraints) 
605   
606                   
607                  results = minimise_minfx(E=E) 
608              else: 
609                  raise RelaxError("Method for minimisation not known. Try setting: method='scipy.optimize.leastsq'.") 
610   
611               
612              param_vector, param_vector_error, chi2, iter_count, f_count, g_count, h_count, warning = results 
613   
614               
615              r2eff = param_vector[0] 
616              i0 = param_vector[1] 
617              r2eff_err = param_vector_error[0] 
618              i0_err = param_vector_error[1] 
619   
620               
621              disassemble_param_vector(param_vector=param_vector, spins=[cur_spin], key=param_key) 
622   
623               
624              if not hasattr(cur_spin, 'r2eff_err'): 
625                  setattr(cur_spin, 'r2eff_err', deepcopy(getattr(cur_spin, 'r2eff'))) 
626              if not hasattr(cur_spin, 'i0_err'): 
627                  setattr(cur_spin, 'i0_err', deepcopy(getattr(cur_spin, 'i0'))) 
628   
629               
630              cur_spin.r2eff_err[param_key] = r2eff_err 
631              cur_spin.i0_err[param_key] = i0_err 
632   
633               
634              cur_spin.chi2 = chi2 
635   
636               
637              cur_spin.f_count = f_count 
638   
639               
640              cur_spin.warning = warning 
641   
642               
643              print_strings = [] 
644              if E.verbosity >= 1: 
645                   
646                  point_info = "%s at %3.1f MHz, for offset=%3.3f ppm and dispersion point %-5.1f, with %i time points." % (exp_type, frq/1E6, offset, point, len(times)) 
647                  print_strings.append(point_info) 
648   
649                  par_info = "r2eff=%3.3f r2eff_err=%3.4f, i0=%6.1f, i0_err=%3.4f, chi2=%3.3f.\n" % ( r2eff, r2eff_err, i0, i0_err, chi2) 
650                  print_strings.append(par_info) 
651   
652                  if E.verbosity >= 2: 
653                      time_info = ', '.join(map(str, times)) 
654                      print_strings.append('For time array: '+time_info+'.\n\n') 
655   
656               
657              if len(print_strings) > 0: 
658                  for print_string in print_strings: 
659                      print(print_string), 
 660   
661   
663      """Estimate r2eff and errors by exponential curve fitting with scipy.optimize.leastsq. 
664   
665      @keyword E:     The Exponential function class, which contain data and functions. 
666      @type E:        class 
667      @return:        Packed list with optimised parameter, estimated parameter error, chi2, iter_count, f_count, g_count, h_count, warning 
668      @rtype:         list 
669      """ 
670   
671       
672      if not scipy_module: 
673          raise RelaxError("scipy module is not available.") 
674   
675       
676      x0 = E.estimate_x0_exp(times=E.times, values=E.values) 
677   
678       
679      use_weights = True 
680   
681      if use_weights: 
682          func = E.func_exp_weighted_residual 
683           
684          absolute_sigma = True 
685      else: 
686          func = E.func_exp_residual 
687          absolute_sigma = False 
688   
689       
690      args=(E.times, E.values, E.errors) 
691   
692       
693      popt, pcov, infodict, errmsg, ier = leastsq(func=func, x0=x0, args=args, full_output=True, ftol=E.ftol, xtol=E.xtol, maxfev=E.maxfev, factor=E.factor) 
694   
695       
696      if ier in [1, 2, 3, 4]: 
697          warning = None 
698      elif ier in [9]: 
699          warn(RelaxWarning("%s." % errmsg)) 
700          warning = errmsg 
701      elif ier in [0, 5, 6, 7, 8]: 
702          raise RelaxError("scipy.optimize.leastsq raises following error: '%s'." % errmsg) 
703   
704       
705      f_count = infodict['nfev'] 
706   
707       
708      fvec = infodict['fvec'] 
709       
710   
711       
712       
713   
714       
715       
716   
717       
718       
719   
720       
721       
722   
723       
724       
725      chi2 = sum( fvec**2 ) 
726   
727       
728      N = len(E.values) 
729       
730      p = len(x0) 
731       
732       
733      n = N - p 
734   
735       
736      chi2_red = chi2 / n 
737   
738       
739       
740       
741       
742   
743      if pcov is None: 
744           
745          pcov = zeros((len(popt), len(popt)), dtype=float) 
746          pcov.fill(inf) 
747      elif not absolute_sigma: 
748          if N > p: 
749              pcov = pcov * chi2_red 
750          else: 
751              pcov.fill(inf) 
752   
753       
754      perr = sqrt(diag(pcov)) 
755   
756       
757      param_vector = popt 
758      param_vector_error = perr 
759   
760      iter_count = 0 
761      g_count = 0 
762      h_count = 0 
763   
764       
765      results = [param_vector, param_vector_error, chi2, iter_count, f_count, g_count, h_count, warning] 
766   
767       
768      return results 
 769   
770   
772      """Estimate r2eff and errors by minimising with minfx. 
773   
774      @keyword E:     The Exponential function class, which contain data and functions. 
775      @type E:        class 
776      @return:        Packed list with optimised parameter, parameter error set to 'inf', chi2, iter_count, f_count, g_count, h_count, warning 
777      @rtype:         list 
778      """ 
779   
780       
781      if not C_module_exp_fn: 
782          raise RelaxError("Relaxation curve fitting is not available.  Try compiling the C modules on your platform.") 
783   
784       
785      x0 = asarray( E.estimate_x0_exp(times=E.times, values=E.values) ) 
786   
787      if E.c_code: 
788           
789   
790           
791          scaling_list = [1.0, 1.0] 
792          model = Relax_fit_opt(model='exp', num_params=len(x0), values=E.values, errors=E.errors, relax_times=E.times, scaling_matrix=scaling_list) 
793   
794           
795          t_func = model.func 
796          t_dfunc = model.dfunc 
797          t_d2func = model.d2func 
798          args=() 
799   
800      else: 
801           
802           
803          t_func = E.func_exp_chi2 
804          t_dfunc = E.func_exp_chi2_grad 
805          t_d2func = None 
806           
807          args=(E.times, E.values, E.errors) 
808   
809       
810      results_minfx = generic_minimise(func=t_func, dfunc=t_dfunc, d2func=t_d2func, args=args, x0=x0, min_algor=E.min_algor, min_options=E.min_options, func_tol=E.func_tol, grad_tol=E.grad_tol, maxiter=E.max_iterations, A=E.A, b=E.b, full_output=True, print_flag=0) 
811   
812       
813      param_vector, chi2, iter_count, f_count, g_count, h_count, warning = results_minfx 
814   
815       
816      r2eff, i0 = param_vector 
817   
818       
819      if E.c_code == True: 
820          if E.chi2_jacobian: 
821               
822              jacobian_matrix_exp = transpose(asarray( model.jacobian_chi2(param_vector) ) ) 
823              weights = ones(E.errors.shape) 
824   
825          else: 
826               
827              jacobian_matrix_exp = transpose(asarray( model.jacobian(param_vector) ) ) 
828              weights = 1. / E.errors**2 
829   
830      elif E.c_code == False: 
831          if E.chi2_jacobian: 
832               
833              jacobian_matrix_exp = E.func_exp_chi2_grad_array(params=param_vector, times=E.times, values=E.values, errors=E.errors) 
834              weights = ones(E.errors.shape) 
835   
836          else: 
837               
838              jacobian_matrix_exp = E.func_exp_grad(params=param_vector, times=E.times) 
839              weights = 1. / E.errors**2 
840   
841      pcov = multifit_covar(J=jacobian_matrix_exp, weights=weights) 
842   
843       
844      param_vector_error = sqrt(diag(pcov)) 
845   
846       
847      results = [param_vector, param_vector_error, chi2, iter_count, f_count, g_count, h_count, warning] 
848   
849       
850      return results 
 851