/
fitting.py
110 lines (82 loc) · 3.02 KB
/
fitting.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import lmfit
import pandas as pd
import numpy as np
from .auxiliary import error_function
import multiprocess as multiprocessing
def get_minimizer(index, fitobj_df, data_df, params_df,
xname, yname, yerr):
"""Create an indexed series of minimizer functions.
Parameters
----------
index : Pandas index
A grouped index for the dataframe.
fitobj_df : dataframe
A dataframe of the fit objects.
data_df : dataframe
A dataframe of the input data.
params_df : dataframe
A dataframe of the input parameters.
xname : string
Name of the data_df column containing the xdata.
yname : string
Name of the data_df column contain the ydata.
yerr : string
Name of the data_df column containg the yerror
estimates (optional).
Returns
-------
minimizer : series
A pandas series containing all the indexed minimizer objects."""
# Creates the lmfit minimizer object
minimizer = list()
for i in index:
model_eq = fitobj_df.loc[i, 'model_eq']
xdata = data_df.loc[i, xname].values
ydata = data_df.loc[i, yname].values
if yerr is not None:
yerrors = data_df.loc[i, yerr].values
fcn_args = '(model_eq, xdata, ydata, yerrors)'
else:
fcn_args = '(model_eq, xdata, ydata)'
params = params_df.loc[i]
params = [ lmfit.Parameter(**params.loc[x].to_dict())
for x in params.index.levels[0]
]
minimizer.append(lmfit.Minimizer(error_function,
params,
fcn_args=eval(fcn_args))
)
return pd.Series(minimizer, index=index, name='minimizer')
def get_confidence_interval(fitobj_df, mask, sigma, threads=None):
"""Calculate the confidence intervals from the minimizer objects.
Parameters
----------
fitobj_df : dataframe
A dataframe of the fit objects.
mask : array/series
A boolean mask indicating if the confidence intervals
can't be calculated for any of the groups.
sigma : float or list
The confidence intervals to be calculated.
threads : int or None
The number of threads to use for multithreaded
calculation of confidence intervals.
Returns
-------
ci_obj : series
A series of confidence interval objects."""
def _calc_ci(arr):
ciobj = list()
for m,f in zip(arr[:,0], arr[:,1]):
try:
res = lmfit.conf_interval(m, f, sigmas=sigma)
except:
res = np.NaN
ciobj.append(res)
return np.array(ciobj)
if threads is None:
threads = multiprocessing.cpu_count()
fitobj_arr = np.array_split(fitobj_df[['minimizer','fitobj']].values, threads)
pool = multiprocessing.Pool()
ciobj = np.array(pool.map(_calc_ci, fitobj_arr)).flatten()
return pd.Series(ciobj, index=fitobj_df.index)