In [1]:
%pylab inline
In [300]:
range_data = np.array([0.8516, 1.542, 2.866, 5.70, 9.15, 26.76, 36.96, 58.79, 93.32,
152.4, 211.5, 441.8, 553.4, 771.2, 1088, 1599, 2095, 3998,
4920, 6724, 9360, 13620, 17760, 33430, 40840, 54950, 74590,
104000, 130200, 212900,
2.453e5,
2.990e5,
3.616e5,
4.384e5,
4.957e5,
6.400e5,
6.877e5,
7.603e5,
8.379e5,
9.264e5,
9.894e5,
1.141e6,
1.189e6])
momentum_data = np.array([47.04, 56.16, 68.02, 85.1, 100, 152.7, 176.4, 221.8,
286.8, 391.7, 494.5, 899.5, 1101, 1502, 2103, 3104, 4104,
8105, 10110, 14110, 20110, 30110, 40110, 80110, 100100,
140100, 200100, 300100, 400100, 800100,
1e6,
1.4e6,
2e6,
3e6,
4e6,
8e6,
1e7,
1.4e7,
2e7,
3e7,
4e7,
8e7,
1e8])
In [305]:
plot(np.log(range_data), np.log(momentum_data), 'k.')
xlim((-2, 15))
xlabel("log range")
ylabel("log momentum")
Out[305]:
In [222]:
# find the slope and intercept for the low range data
In [345]:
slope = (log(momentum_data[3]) - log(momentum_data[0])) / (log(range_data[3]) - log(range_data[0]))
slope
Out[345]:
In [346]:
rint = log(momentum_data[0]) - slope * log(range_data[0])
rint
Out[346]:
In [308]:
log(momentum_data[1])
Out[308]:
In [338]:
rng = np.linspace(np.log(range_data[0]), np.log(range_data[-1]), 2000)
In [323]:
#def fn(x, a):
# return np.sqrt(a * (x - 3.8509983035903717)) - 0.16063834596281262
def fn(x, a, b, c):
res = a * (x + b) ** 2 + c
#res = sqrt(a * abs(x - b)) + c
return res
In [327]:
plot(np.log(range_data), np.log(momentum_data), 'k.')
ylim((-2, 15))
from scipy.optimize import curve_fit
popt, _ = curve_fit(fn, np.log(range_data), np.log(momentum_data))
plot(rng, fn(rng, *popt))
Out[327]:
In [325]:
lres = fn(np.log(range_data), *popt) - np.log(momentum_data)
plot(np.log(momentum_data), lres, 'k.')
Out[325]:
In [333]:
range_data[3]
Out[333]:
In [348]:
a, b, c = popt
a, b, c
Out[348]:
In [335]:
def newfit(x):
a, b, c = popt
res = a * (x + b) ** 2 + c
low_idx = x < log(range_data[3])
res[low_idx] = slope * x[low_idx] + rint
return res
In [339]:
loglog(range_data, momentum_data, 'k.')
#ylim((-2, 4))
#xlim((3,6))
plot(np.exp(rng), np.exp(newfit(rng)))
xlabel("Range (g/cm^2)")
ylabel("Momentum (MeV/c)")
title("Fit to Groom 2001 Muon Range data")
Out[339]:
In [ ]: