From 9fab4d39ebb88813aaf5d04f209aee1b7daae47f Mon Sep 17 00:00:00 2001 From: Andrey Aristov <aaristov@pasteur.fr> Date: Fri, 8 Oct 2021 16:26:44 +0200 Subject: [PATCH] add sigmoid, hill --- droplet_growth/fit.py | 48 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/droplet_growth/fit.py b/droplet_growth/fit.py index 6f39c4e..309e9f6 100644 --- a/droplet_growth/fit.py +++ b/droplet_growth/fit.py @@ -228,15 +228,20 @@ def lin_exp_fit(curve:list, plot=False, fun=lin_exp_fun, **kwargs): return popt -def fit_exp_on_baseline(data, x=None, p0=(1,1,0), **kwargs): +def fit_exp_on_baseline(data, x=None, p0=(1,1,0), plot=False, **kwargs): """fits a + b * exp(c * x) - kwargs: same as in fit.fit_exponent + kwargs: same as in fit.fit_exponent and fit.plot_fit returns: (a, b, c) """ try: - return fit_exponent(data, bins=x, fun=exp_on_baseline, - p0=p0, **kwargs) + popt, bins = fit_exponent(data, bins=x, fun=exp_on_baseline, + p0=p0, plot=False, return_bins=True) + if plot: + curve = data - popt[0] + fit = exp_on_baseline(bins, 0, popt[1], popt[2]) + plot_fit(curve, fit, bins, plot=plot, **kwargs) + return (popt) except RuntimeError: print('No fit') return (None, None, None) @@ -247,15 +252,36 @@ def lag_exponent(x, lag, c): return np.exp((x - lag) / c) -def sigmoid(t, a, b, c): +def gompertz(t, a, b, c): ''' https://en.wikipedia.org/wiki/Gompertz_function ''' return a * np.exp(- b * np.exp(- c * t)) +def sigmoid(x, a, b): + return 1 / (1 + np.exp(a * x + b)) + + +def hill(x, n, K): + return x ** n/(x ** n + K) + + +def fit_sigmoid(probs, ax, fun=sigmoid, fit_name='sigmoid', p0=(2., -2.)): + probs = probs.copy() + vector = probs.index +# print(vector) +# probs.loc[:, 'negative'] = 1 - probs.positive + popt, pcov = curve_fit(fun, vector, probs.q, p0=p0) + a, b = popt + da, db = np.sqrt(np.diag(pcov)) + ax.plot(vector, probs.q, '.', label='data') + ax.plot((x := sorted(vector)), fun(x, *popt), lw=10, alpha=.5, label=f'{fit_name} fit') + plt.legend() + return popt, (da, db) + def fit_exponent(curve, bins=None, fun=exponent, p0=(1., .5,), bounds=(-np.inf, np.inf), - plot=False, plot_init=False, **kwargs): + plot=False, plot_init=False, return_bins=False, **kwargs): ''' Fits exponent to 1D curve plot: ['linear', 'log', None] @@ -263,14 +289,18 @@ def fit_exponent(curve, bins=None, fun=exponent, p0=(1., .5,), bounds=(-np.inf, if bins is None: bins = np.arange(len(curve)) popt, _ = curve_fit(f=fun, xdata=bins, ydata=curve, p0=p0, bounds=bounds) + fit_result = fun(bins, *popt) plot_fit(curve, fit_result, bins, plot=plot, **kwargs) if plot_init: plot_fit(curve, fun(bins, *p0), bins, plot=plot, labels=['init', 'data'], **kwargs) + if return_bins: + return popt, bins return popt -def plot_fit(curve=None, fit=None, vector=None, plot='linear', labels=['data', 'fit'], markers=['.', 'o'], legend=True, **kwargs): +def plot_fit(curve=None, fit=None, vector=None, plot='linear', + labels=['data', 'fit'], markers=['.', '-'], legend=True, **kwargs): ''' plot: ['linear', 'log', None] ''' @@ -296,11 +326,11 @@ def add_doubling_time( rate_column:str='c', frame_rate:float=1., new_column='Doubling time, min', - fun = lambda c, rate_value: 1 / c * rate_value + convert_rate_time = lambda c, frame_rate: np.log(2) / c * frame_rate ): ''' adds a column with doubling time using rate 'c' ''' table = df.copy() - table[new_column] = fun(table[rate_column].values, frame_rate) + table[new_column] = convert_rate_time(table[rate_column].values, frame_rate) return table \ No newline at end of file -- GitLab