def calibrate_new(f="a*x+b", p="a,b"): """ Automates calibration of the apparatus; returns function which converts bin numbers to energies """ spectrum_sum = add_spectra(spectra_Tr[78:223], chronological=True) # true peak locations x0 = [5.607, 5.769, 6.051, 6.090, 8.794] x0_init = [1188, 1224, 1285, 1294, 1882] n0_init = [450, 450, 12000, 300, 20000] s0_init = [3, 3, 4.5, 1, 5] fit_func = "" parameters = "" for i in range(len(x0_init)): fit_func += "n" + str(i) + "*G(x-x" + str(i) + ",s" + str(i) + ")+" parameters += "n" + str(i) + "=" + str(n0_init[i]) + \ ",x" + str(i) + "=" + str(x0_init[i]) + \ ",s" + str(i) + "=" + str(s0_init[i]) + "," fit_func += "bg" parameters += "bg=1" e_fit_init = sm.data.fitter(f=fit_func, p=parameters, g={'G' : _gaussian}) e_fit_init.set_data(xdata=bins, ydata=spectrum_sum.counts(), eydata=get_yerr_counts(spectrum_sum)) e_fit_init.set(xmin=1170, xmax=1900) e_fit_init.fit() peak_inds = np.arange(1, 3*len(x0_init), 3) x0_found = e_fit_init.results[0][peak_inds] calib_fit = sm.data.fitter(f="a*x+b", p="a,b") calib_fit.set_data(xdata=x0_found, ydata=x0, eydata=0.01) calib_fit.fit() slope = calib_fit.results[0][0] intercept = calib_fit.results[0][1] slope_err = np.sqrt(calib_fit.results[1][0][0]) intercept_err = np.sqrt(calib_fit.results[1][1][1]) def bin_to_energy(bin): energy = slope * bin + intercept energy_err = np.sqrt(bin**2 * slope_err**2 + intercept_err**2) return (energy, energy_err) return bin_to_energy
def _analyze_energy_and_branching(spectra, bin_to_energy): """ Automates analysis of alpha energy and branching ratio data """ spectrum_sum = add_spectra(spectra, chronological=True) x0 = [5.607, 5.769, 6.051, 6.090, 8.794] n0 = [0.4, 0.7, 12, 1.5, 30] s0 = [0.005, 0.005, 0.01, 0.008, 0.01] c0 = [0.01, 0.01, 1, 0.001, 1] t0 = [10, 10, 10, 10, 10] fit_func = "" parameters = "" for i in range(len(x0)): fit_func += "n" + str(i) + "*G(x-x" + str(i) + ",s" + str(i) + ")*(1+" + \ "c" + str(i) + "*exp(abs(t" + str(i) + ")*(x" + str(i) + "-x)))+" parameters += "n" + str(i) + "=" + str(n0[i]) + \ ",x" + str(i) + "=" + str(x0[i]) + \ ",s" + str(i) + "=" + str(s0[i]) + \ ",c" + str(i) + "=" + str(c0[i]) + \ ",t" + str(i) + "=" + str(t0[i]) + "," fit_func += "bg" parameters += "bg=6" # save having to run calibrate() each time if bin_to_energy is None: bin_to_energy = calibrate_new() energy_bins = np.asarray([bin_to_energy(bin) for bin in bins]) xmin = bin_to_energy(1170)[0] xmax = bin_to_energy(1900)[0] e_fit = sm.data.fitter(f=fit_func, p=parameters, g={'G' : _gaussian}) e_fit.set_data( xdata=energy_bins[:,0], ydata=spectrum_sum.counts(), exdata=energy_bins[:,1], eydata=get_yerr_counts(spectrum_sum)) e_fit.set(xmin=xmin, xmax=xmax) e_fit.fit() ndof_per_peak = 5 n0_inds = ndof_per_peak * np.arange(len(x0)) x0_inds = n0_inds + 1 s0_inds = n0_inds + 2 result_vals = e_fit.results[0] result_errs = np.sqrt(np.diagonal(e_fit.results[1])) # for finding the peak locations x0_vals = result_vals[x0_inds] x0_errs = result_errs[x0_inds] peak_locs = (x0_vals, x0_errs) # for finding the peak areas n0_vals = result_vals[n0_inds] n0_errs = result_errs[n0_inds] peak_areas = (n0_vals, n0_errs) # might want peak widths for something s0_vals = result_vals[s0_inds] s0_errs = result_errs[s0_inds] return (peak_locs, peak_areas)