-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfits.py
173 lines (156 loc) · 5.11 KB
/
fits.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# -*- coding: utf-8 -*-
"""
"""
__author__ = "Alireza Panna"
__email__ = "[email protected]"
__status__ = "Development"
__date__ = "10/22/14"
__version__ = "0.2"
import numpy as np
def linear(x, intercept, slope):
"""
A linear fit function:
y-intercept : intercept
slope : slope
"""
return intercept+slope*x
def gaussian(x, offs, slope, peak, mu, sigma):
"""
A gaussian fit function:
Offset : offset
baseline : slope
Amplitude : peak
Mean : mu
Standard deviation : sigma
"""
return -offs-slope*x+\
peak*np.exp(-(x-mu)**2/(2*sigma**2))
def three_gaussian(x, offs, slope, peak_1, mu_1, sigma_1, peak_2, mu_2, sigma_2, peak_3, mu_3, sigma_3):
return -offs-slope*x+\
peak_1*np.exp(-(x-mu_1)**2/(2*sigma_1**2)) + \
peak_2*np.exp(-(x-mu_2)**2/(2*sigma_2**2)) + \
peak_3*np.exp(-(x-mu_3)**2/(2*sigma_3**2))
def log_gaussian(x, peak, mu, sigma):
"""
compute the a, b, c that parameterise the parabola
log(gauss(x, A, mu, sigma)) ~ a + bx**2 + cx.
"""
return np.log(peak) - (x-mu)**2/(2*sigma**2)
def lorentzian(x, offs, slope, peak, mu, fwhm):
"""
A lorentzian peak with:
Offset : p[0]
slope : p[1]
Amplitude : p[2]
Mean : p[3]
FWHM : p[4]
"""
return -offs-slope*x+\
(peak*fwhm**2/4)*(1/((x-mu)**2+(fwhm/2)**2))
def power(x, norm, offs, const):
"""
A power law fit with:
Normalization : p[0]
Offset : p[2]
Constant : p[3]
"""
return norm*(x-offs)**offs + const
def residuals(meas, fit):
res=[]
for i,j in zip(meas, fit):
res.append(i-j)
return res
def chi_squared(meas, fit, meas_sigma):
c2=0
for i, j, k in zip(meas, fit, meas_sigma):
c2+=((i-j)/k)**2
return c2
def r_squared(meas, fit, meas_mean):
ss_res=0
ss_tot=0
for i, j in zip(meas, fit):
ss_res+=(i-j)**2
ss_tot+=(i-meas_mean)**2
return 1-(ss_res/ss_tot)
def linear_baseline_correction(x, y, pts):
"""
Perform linear baseline correction on data to flatten the tails
"""
corrected = []
pts = int(pts)
slope = (np.mean(y[-pts:]) - np.mean(y[0:pts]))/(np.mean(x[-pts:]) - np.mean(x[0:pts]))
offset = (np.mean(y[0:pts]) * np.mean(x[-pts:]) - \
np.mean(y[-pts:]) * np.mean(x[0:pts]))/(np.mean(x[-pts:]) - np.mean(x[0:pts]));
for i, j in enumerate(y):
corrected.append(j-offset-slope*x[i])
return np.array(corrected)
def first_diff(x, y):
"""
Performs first order difference
Parameters
----------
Returns
-------
"""
fd = []
fd.append(0)
for y1, y2, x1, x2 in zip(y[0:-1], y[1:], x[0:-1], x[1:]):
if (x2 - x1) != 0:
fd.append((y2 - y1)/(x2 - x1))
return np.array(fd)
def find_peaks(x, y, **kwargs):
"""
Finds peaks in dataset.
"""
try:
peak_seperation = int(kwargs.get('dist'))
peak_threshold = kwargs.get('threshold')
except:
peak_seperation = 15
peak_threshold = 150
ct = 0
previous = 0
current = 0
local_maxima_x = []
maxima_y = []
max_y = []
maxima_x = []
local_maxima_y = []
# x_interp = np.linspace(min(x), max(x), num = 1000)
# y_interp = np.interp(x_interp, x, y)
# first order difference
diff = first_diff(x, y)
# diff2 = first_diff(x, diff)
# print diff2
for i, j in zip(diff[0:-1], diff[1:]):
# look for maxima.
previous = current
if ((i > 0 and j < 0) and y[ct] > peak_threshold):
current = ct;
if (current - previous > peak_seperation):
local_maxima_x.append(x[ct])
local_maxima_y.append(y[ct])
ct = ct + 1
local_maxima_y.sort()
# Get the highest peaks of the gaussians
if (len(local_maxima_y) >= 3):
maxima_y = [local_maxima_y[-1], local_maxima_y[-2], local_maxima_y[-3]]
elif (len(local_maxima_y) == 2):
maxima_y = [local_maxima_y[-1], local_maxima_y[-2]]
elif (len(local_maxima_y) == 1):
maxima_y = [local_maxima_y[-1]]
else:
maxima_y = [0]
# Get the peak position corresponding to the peaks
for i in maxima_y:
for k, j in zip(x, y):
if (i == j):
maxima_x.append(k)
# Resort according to peak position
maxima_x.sort(reverse=False)
for i in maxima_x:
max_y.append(y[i])
return maxima_x, max_y
if __name__=="__main__":
print "There is no place like main!"
6