Source code for iocbio.kinetics.calc.explin_fit

import numpy as np
from scipy.optimize import least_squares
from .generic import AnalyzerGeneric, XYData, Stats


[docs]class AnalyzerExpLinFit(AnalyzerGeneric): """Analyser for exponential + linear fitting""" @staticmethod def fit_function(a, k, b, l, t): return a*np.exp(-k*t) + l*t + b @staticmethod def error_function(v, t, y): return y-AnalyzerExpLinFit.fit_function(*v, t) def __init__(self, x, y): AnalyzerGeneric.__init__(self, x, y) def fit(self): t = np.array(self.experiment.x) t0 = t[0] t = t - t0 y = np.array(self.experiment.y) # first estimate x0 = amp, rate, off, lin x0 = [0.2, 0.01, 0.1, -0.0001] bounds = ((0, 0, 0, -np.inf), (y.max(), 20, np.inf, 0)) r = least_squares(self.error_function, x0, args=(t, y), bounds=bounds, loss='soft_l1', f_scale=1, tr_solver='exact', ftol=1.e-10, xtol=1.e-10, max_nfev=100000) sol = r.x msg = r.message s = r.success self.exponential_amplitude, self.rate_constant, self.linear_offset, self.linear_slope = sol self.calc = XYData(t+t0, self.fit_function(*sol, t)) self.stats['exponential_amplitude'] = Stats("exponential amplitude", "Abs", self.exponential_amplitude) self.stats['rate_constant'] = Stats("rate constant", "1/min", self.rate_constant) self.stats['linear_offset'] = Stats("linear offset", "Abs", self.linear_offset) self.stats['linear_slope'] = Stats("linear slope", "Abs/min", self.linear_slope)