def do_jackknife(T, prefix, x, y, y_err): fit_x = np.linspace(np.min(x), np.max(x), 100) y_dist = [] popt_dist = [] for i in range(len(x)): jack_x = np.delete(x, i) jack_y = np.delete(y, i) popt, pconv = op.curve_fit(linear, jack_x, jack_y) boot_fit_y = linear(fit_x, *popt) y_dist.append(boot_fit_y) popt_dist.append(popt) np.savetxt('_build/xy/bootstrap-{}-{:d}-resampled.tsv'.format(prefix, i), np.column_stack([jack_x, jack_y])) np.savetxt('_build/xy/bootstrap-{}-{:d}-fit.tsv'.format(prefix, i), np.column_stack([fit_x, boot_fit_y])) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(y_dist) np.savetxt('_build/xy/bootstrap-{}-band.tsv'.format(prefix), bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) np.savetxt('_build/xy/bootstrap-{}-final-fit.tsv'.format(prefix), np.column_stack([fit_x, fit_y_val])) popt_val, popt_err = bootstrap.average_and_std_arrays(popt_dist) popt_val, pconv = op.curve_fit(linear, x, y, sigma=y_err) T['bootstrap_{}_popt'.format(prefix)] = siunitx(popt_val, popt_err, error_digits=2) T['bootstrap_{}_err'.format(prefix)] = siunitx(popt_err)
def do_choice(T, prefix, x, y, y_err): fit_x = np.linspace(np.min(x), np.max(x), 100) y_dist = [] popt_dist = [] for i in range(len(x)): choice_x = bootstrap.generate_sample(x) choice_y = bootstrap.generate_sample(y) choice_y_err = bootstrap.generate_sample(y_err) popt, pconv = op.curve_fit(linear, choice_x, choice_y, sigma=choice_y_err) boot_fit_y = linear(fit_x, *popt) y_dist.append(boot_fit_y) popt_dist.append(popt) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(y_dist) np.savetxt('_build/xy/bootstrap-{}-band.tsv'.format(prefix), bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) np.savetxt('_build/xy/bootstrap-{}-final-fit.tsv'.format(prefix), np.column_stack([fit_x, fit_y_val])) popt_val, popt_err = bootstrap.average_and_std_arrays(popt_dist) popt_val, pconv = op.curve_fit(linear, x, y, sigma=y_err) T['bootstrap_{}_popt'.format(prefix)] = siunitx(popt_val, popt_err, error_digits=2) T['bootstrap_{}_err'.format(prefix)] = siunitx(popt_err)
def job_harmonic_power(T, extinction_dist, input_popt_dist): data = np.loadtxt('Data/harmonic_splitter.tsv') angle = data[:, 0] power_val = data[:, 1] * 1e-6 power_err = data[:, 2] * 1e-6 T['harmonic_splitter_table'] = list(zip( siunitx(angle), siunitx(power_val*1e6, power_err*1e6), )) power_dist = bootstrap.make_dist(power_val, power_err) fit_x = np.linspace(np.min(angle), np.max(angle), 200) fit_y_dist = [] angle_offset_dist = [] a_dist = [] b_dist = [] popt_dist = [] for power in power_dist: popt, pconv = op.curve_fit(cos_quartic, angle, power, p0=[1.5e-5, 0, 0]) fit_y_dist.append(cos_quartic(fit_x, *popt)) angle_offset_dist.append(popt[1]) a = popt[0] b = popt[2] a_dist.append(a) b_dist.append(b) popt_dist.append(popt) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) angle_offset_val, angle_offset_err = bootstrap.average_and_std_arrays(angle_offset_dist) a_val, a_err = bootstrap.average_and_std_arrays(a_dist) b_val, b_err = bootstrap.average_and_std_arrays(b_dist) np.savetxt('_build/xy/harmonic-splitter-data.tsv', np.column_stack([angle, power_val, power_err])) np.savetxt('_build/xy/harmonic-splitter-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('_build/xy/harmonic-splitter-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) T['splitter_angle_offset'] = siunitx(angle_offset_val, angle_offset_err) T['splitter_a'] = siunitx(a_val, a_err) T['splitter_b'] = siunitx(b_val, b_err) efficiency_dist = [] efficiency_sq_dist = [] for extinction, input_popt, popt in zip(extinction_dist, input_popt_dist, popt_dist): efficiency = popt[0] / (input_popt[0] * extinction) efficiency_dist.append(efficiency) efficiency_sq = popt[0] / (input_popt[0] * extinction)**2 efficiency_sq_dist.append(efficiency_sq) efficiency_val, efficiency_err = bootstrap.average_and_std_arrays(efficiency_dist) efficiency_sq_val, efficiency_sq_err = bootstrap.average_and_std_arrays(efficiency_sq_dist) T['efficiency'] = siunitx(efficiency_val, efficiency_err) T['efficiency_sq'] = siunitx(efficiency_sq_val, efficiency_sq_err)
def job_variable_attenuator(T, extinction_dist): data = np.loadtxt('Data/variable.tsv') angle = data[:, 0] power_val = data[:, 1] * 1e-6 power_err = np.ones(power_val.shape) * 1e-6 T['variable_attenuator_table'] = list(zip( siunitx(angle), siunitx(power_val*1e6, power_err*1e6), )) power_dist = bootstrap.make_dist(power_val, power_err, n=len(extinction_dist)) fit_x = np.linspace(np.min(angle), np.max(angle), 200) fit_y_dist = [] angle_offset_dist = [] a_dist = [] b_dist = [] popt_dist = [] extinction_ratio_dist = [] for power in power_dist: popt, pconv = op.curve_fit(cos_squared, angle, power, p0=[1.5, 0, 0]) fit_y_dist.append(cos_squared(fit_x, *popt)) angle_offset_dist.append(popt[1]) a = popt[0] b = popt[2] a_dist.append(a) b_dist.append(b) popt_dist.append(popt) extinction_ratio_dist.append((a + b) / b) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) angle_offset_val, angle_offset_err = bootstrap.average_and_std_arrays(angle_offset_dist) a_val, a_err = bootstrap.average_and_std_arrays(a_dist) b_val, b_err = bootstrap.average_and_std_arrays(b_dist) extinction_ratio_val, extinction_ratio_err = bootstrap.average_and_std_arrays(extinction_ratio_dist) np.savetxt('_build/xy/variable-data.tsv', np.column_stack([angle, power_val, power_err])) np.savetxt('_build/xy/variable-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('_build/xy/variable-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) T['variable_angle_offset'] = siunitx(angle_offset_val, angle_offset_err) T['variable_a'] = siunitx(a_val, a_err) T['variable_b'] = siunitx(b_val, b_err) T['extinction_ratio'] = siunitx(extinction_ratio_val, extinction_ratio_err) return popt_dist
def prepare_for_pgf(filename, error=False, show=False): data = np.loadtxt('Data/{}.txt'.format(filename)) channel = data[:,0] counts = data[:,1] lower = 0 upper = 8000 sieve_factor = 10 if error: np.savetxt('_build/xy/{}.txt'.format(filename), bootstrap.pgfplots_error_band(channel[lower:upper:sieve_factor], counts[lower:upper:sieve_factor], np.sqrt(counts[lower:upper:sieve_factor]))) else: np.savetxt('_build/xy/{}.txt'.format(filename), np.column_stack([channel[lower:upper:sieve_factor], counts[lower:upper:sieve_factor]])) if show: pl.plot(channel, counts, linestyle="none", marker="o") pl.show() pl.clf()
def job_input_polarization(T): data = np.loadtxt('Data/harmonic_bare.tsv') angle = data[:, 0] power_val = data[:, 1] * 1e-6 power_err = data[:, 2] * 1e-6 power_dist = bootstrap.make_dist(power_val, power_err) T['harmonic_bare_table'] = list(zip( siunitx(angle), siunitx(power_val*1e6, power_err*1e6), )) fit_x = np.linspace(np.min(angle), np.max(angle), 200) fit_y_dist = [] angle_offset_dist = [] a_dist = [] b_dist = [] popt_dist = [] for power in power_dist: popt, pconv = op.curve_fit(cos_quartic, angle, power, p0=[1.5e-5, 0, 0]) fit_y_dist.append(cos_quartic(fit_x, *popt)) angle_offset_dist.append(popt[1]) a = popt[0] b = popt[2] a_dist.append(a) b_dist.append(b) popt_dist.append(popt) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) angle_offset_val, angle_offset_err = bootstrap.average_and_std_arrays(angle_offset_dist) a_val, a_err = bootstrap.average_and_std_arrays(a_dist) b_val, b_err = bootstrap.average_and_std_arrays(b_dist) np.savetxt('_build/xy/harmonic-bare-data.tsv', np.column_stack([angle, power_val, power_err])) np.savetxt('_build/xy/harmonic-bare-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('_build/xy/harmonic-bare-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) T['bare_angle_offset'] = siunitx(angle_offset_val, angle_offset_err) T['bare_a'] = siunitx(a_val, a_err) T['bare_b'] = siunitx(b_val, b_err)
def job_temperature_dependence(T): data = np.loadtxt('Data/temperature.tsv') temp = data[:, 0] power_val = data[:, 1] * 1e-6 power_err = np.ones(power_val.shape) * 1e-6 power_dist = bootstrap.make_dist(power_val, power_err) T['temperature_table'] = list(zip( siunitx(temp), siunitx(power_val*1e6, power_err*1e6), )) p0 = [36.5, 1, 36-6, 2e-6] fit_x = np.linspace(np.min(temp), np.max(temp), 300) popt_dist = [] fit_y_dist = [] for power in power_dist: popt, pconv = op.curve_fit(sinc, temp, power, p0=p0) fit_y_dist.append(sinc(fit_x, *popt)) popt_dist.append(popt) center_dist, width_dist, amplitude_dist, offset_dist = zip(*popt_dist) center_val, center_err = bootstrap.average_and_std_arrays(center_dist) width_val, width_err = bootstrap.average_and_std_arrays(width_dist) amplitude_val, amplitude_err = bootstrap.average_and_std_arrays(amplitude_dist) offset_val, offset_err = bootstrap.average_and_std_arrays(offset_dist) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) np.savetxt('_build/xy/temperature-data.tsv', np.column_stack([temp, power_val, power_err])) np.savetxt('_build/xy/temperature-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('_build/xy/temperature-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) T['temp_center'] = siunitx(center_val, center_err) T['temp_width'] = siunitx(width_val, width_err) T['temp_amplitude'] = siunitx(amplitude_val, amplitude_err) T['temp_offset'] = siunitx(offset_val, offset_err)
def job_power(T): data = np.loadtxt('Data/diode.tsv') norm_current = data[:, 0] * 1e-3 norm_power_val = data[:, 1] * 1e-3 norm_power_err = np.ones(norm_power_val.shape) * 1e-6 norm_power_dist = bootstrap.make_dist(norm_power_val, norm_power_err) data = np.loadtxt('Data/diode_damped.tsv') damp_current = data[:, 0] * 1e-3 damp_power_val = data[:, 1] * 1e-3 damp_power_err = data[:, 2] * 1e-3 damp_power_dist = bootstrap.make_dist(damp_power_val, damp_power_err) np.savetxt('_build/xy/diode_normal-data.tsv', np.column_stack([norm_current, norm_power_val, norm_power_err])) np.savetxt('_build/xy/diode_damped-data.tsv', np.column_stack([damp_current, damp_power_val, damp_power_err])) T['diode_normal_table'] = list(zip( siunitx(norm_current*1e3), siunitx(norm_power_val*1e6, norm_power_err*1e6, allowed_hang=6), )) T['diode_damped_table'] = list(zip( siunitx(damp_current*1e3), siunitx(damp_power_val*1e6, damp_power_err*1e6), )) hbar_omega = 6.626e-34 * 3e8 / 987e-9 electron_charge = 1.609e-19 # Find the threshold current. sel = norm_power_val > 1e-3 slope_dist = [] quantum_efficiency_dist = [] threshold_dist = [] threshold_fit_x = np.linspace(0.05, 0.09, 100) threshold_fit_y_dist = [] # Jackknife fit to find root. for i in range(len(norm_power_val[sel])): x = np.delete(norm_current[sel], i) y_val = np.delete(norm_power_val[sel], i) y_err = np.delete(norm_power_err[sel], i) popt, pconv = op.curve_fit(linear, x, y_val, sigma=y_err) a, b = popt root = -b / a threshold_dist.append(root) threshold_fit_y_dist.append(linear(threshold_fit_x, *popt)) slope_dist.append(a) quantum_efficiency_dist.append(a * electron_charge / hbar_omega) threshold_val, threshold_err = bootstrap.average_and_std_arrays(threshold_dist) threshold_fit_y_val, threshold_fit_y_err = bootstrap.average_and_std_arrays(threshold_fit_y_dist) differential_efficiency_val, differential_efficiency_err = bootstrap.average_and_std_arrays(slope_dist) quantum_efficiency_val, quantum_efficiency_err = bootstrap.average_and_std_arrays(quantum_efficiency_dist) T['threshold'] = siunitx(threshold_val, threshold_err) T['differential_efficiency'] = siunitx(differential_efficiency_val, differential_efficiency_err) T['quantum_efficiency'] = siunitx(quantum_efficiency_val, quantum_efficiency_err) np.savetxt('_build/xy/diode_normal-band.tsv', bootstrap.pgfplots_error_band(threshold_fit_x, threshold_fit_y_val, threshold_fit_y_err)) # Compare ratios of damped and normal power in the overlap range. ratio_dist = [] x = np.linspace(70.1e-3, 86.9e-3, 20) for norm_power, damp_power in zip(norm_power_dist, damp_power_dist): norm_inter = scipy.interpolate.interp1d(norm_current, norm_power) damp_inter = scipy.interpolate.interp1d(damp_current, damp_power) a = norm_inter(x) b = damp_inter(x) ratio = a / b ratio_dist.append(ratio) ratio_val, ratio_err = bootstrap.average_and_std_arrays(ratio_dist) extinction_dist = np.array(ratio_dist).flatten() extinction_val, extinction_err = np.mean(ratio_dist), np.std(ratio_dist) T['extinction'] = siunitx(extinction_val, extinction_err) np.savetxt('_build/xy/diode-ratio-line.tsv', np.column_stack([x, ratio_val])) np.savetxt('_build/xy/diode-ratio-band.tsv', bootstrap.pgfplots_error_band(x, ratio_val, ratio_err)) return extinction_dist
def michelson_resolution(T): d_cm = np.sort(np.loadtxt('Data/lissajous_X.tsv')) order = np.arange(0,len(d_cm)) wavelength = 987e-9 # get theoretical values n_ground_theor = 1 + 1e-8 * (8342.13 + 2406030/(130-1/(wavelength*1e6)**2) + 15997/(38.9-1/(wavelength*1e6)**2)) T['n_ground_theor'] = siunitx(n_ground_theor - 1) n_harm_theor = 1 + 1e-8 * (8342.13 + 2406030/(130-1/(wavelength*.5e6)**2) + 15997/(38.9-1/(wavelength*.5e6)**2)) T['n_harm_theor'] = siunitx(n_harm_theor - 1) delta_n_theor = n_harm_theor - n_ground_theor T['delta_n_theor'] = siunitx(delta_n_theor) # prepare arrays slope_dist_cm = [] offset_dist_cm = [] delta_n_dist = [] dev_ratio_dist = [] res_michelson_dist = [] fit_y_dist = [] # perform Jackknife for i in range(len(d_cm)): x = np.delete(order, i) y = np.delete(d_cm, i) popt, pconv = op.curve_fit(linear, x, y) slope_dist_cm.append(popt[0]) offset_dist_cm.append(popt[1]) fit_y_dist.append(linear(order, *popt)) # experimental value for difference in refractive index delta_n = wavelength/(8*popt[0]*1e-2) delta_n_dist.append(delta_n) # deviation from optimal 1/2 ratio dev_ratio_dist.append(.5*delta_n/n_harm_theor) # resolution of michelson interferometer delta_wavelength = wavelength * (delta_n/n_ground_theor**2) res_michelson_dist.append(wavelength/delta_wavelength) # get averages and std slope_val_cm, slope_err_cm = bootstrap.average_and_std_arrays(slope_dist_cm) offset_val_cm, offset_err_cm = bootstrap.average_and_std_arrays(offset_dist_cm) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) delta_n_val, delta_n_err = bootstrap.average_and_std_arrays(delta_n_dist) dev_ratio_val, dev_ratio_err = bootstrap.average_and_std_arrays(dev_ratio_dist) dev_ratio_theor = .5*(delta_n_theor/n_harm_theor) res_michelson_val, res_michelson_err = bootstrap.average_and_std_arrays(res_michelson_dist) # write into T T['distance_lissajous_X'] = siunitx(slope_val_cm, slope_err_cm) T['delta_n'] = siunitx(delta_n_val, delta_n_err) T['dev_ratio'] = siunitx(dev_ratio_val, dev_ratio_err) T['dev_ratio_theor'] = siunitx(dev_ratio_theor) T['res_michelson'] = siunitx(res_michelson_val, res_michelson_err) # write data for plot np.savetxt('_build/xy/michelson-line.tsv', np.column_stack([order, d_cm])) np.savetxt('_build/xy/michelson-band.tsv', bootstrap.pgfplots_error_band(order, fit_y_val, fit_y_err)) T['mirror_position_table'] = list(zip( siunitx(d_cm) )) print(siunitx(dev_ratio_val, dev_ratio_err)) print(siunitx(dev_ratio_theor)) print(siunitx(res_michelson_val, res_michelson_err))
def get_acryl_data(T, slope_val, width): data = np.loadtxt('Data/longlong.txt') channel = data[:, 0] time = slope_val * channel counts = data[:, 1] x = np.linspace(np.min(time), np.max(time), 500) fit_func = lambda t, mean, A_0, A_t, tau_0, tau_t, BG: \ np.log(models.lifetime_spectrum(t, mean, width, A_0, A_t, tau_0, tau_t, BG)) results = [] sel1 = (10.92 < time) & (time < 11.58) sel2 = (13.11 < time) & (time < 22) sels = [sel1, sel2] x1 = np.linspace(np.min(time[sel1]), np.max(time[sel1]), 10) x2 = np.linspace(np.min(time[sel2]), np.max(time[sel2]), 10) for sample_id in range(BOOTSTRAP_SAMPLES): print('Bootstrap sample', sample_id, 'running …') boot_counts = bootstrap.redraw_count(counts) lin_lifetimes = [] lin_results = [] for sel_lin, x_lin in zip(sels, [x1, x2]): popt_lin, pconv_lin = op.curve_fit(exp_decay, time[sel_lin], boot_counts[sel_lin], p0=[1e5, 0.3]) y_lin = exp_decay(x_lin, *popt_lin) lin_results.append(y_lin) lin_results.append(popt_lin) lin_results.append(1/popt_lin[1]) lin_lifetimes.append(1/popt_lin[1]) sel = (10 < time) & (time < 50) & (boot_counts > 0) p0 = [10.5, 13e3, 34e2] + lin_lifetimes + [2] popt, pconv = op.curve_fit(fit_func, time[sel], np.log(boot_counts[sel]), p0=p0) mean, A_0, A_t, tau_0, tau_t, BG = popt intens_0 = A_0 / (A_0 + A_t) intens_t = A_t / (A_0 + A_t) tau_bar = intens_0 * tau_0 + intens_t * tau_t y = np.exp(fit_func(x, *popt)) tau_f = 1 / (intens_0 / tau_0 - intens_t / tau_t) sigma_c = 1 / tau_0 - 1 / tau_f results.append([ tau_0, tau_bar, tau_f, tau_t, intens_0, intens_t, y, popt, sigma_c, ] + lin_results) tau_0_dist, tau_bar_dist, tau_f_dist, tau_t_dist, intens_0_dist, \ intens_t_dist, lifetime_y_dist, lifetime_popt_dist, sigma_c_dist, \ y_lin1_dist, popt_lin1_dist, tau_lin1_dist, \ y_lin2_dist, popt_lin2_dist, tau_lin2_dist, \ = zip(*results) tau_0_val, tau_0_err = bootstrap.average_and_std_arrays(tau_0_dist) tau_t_val, tau_t_err = bootstrap.average_and_std_arrays(tau_t_dist) tau_f_val, tau_f_err = bootstrap.average_and_std_arrays(tau_f_dist) tau_bar_val, tau_bar_err = bootstrap.average_and_std_arrays(tau_bar_dist) popt_val, popt_err = bootstrap.average_and_std_arrays(lifetime_popt_dist) y_val, y_err = bootstrap.average_and_std_arrays(lifetime_y_dist) popt_lin1_val, popt_lin1_err = bootstrap.average_and_std_arrays(popt_lin1_dist) y_lin1_val, y_lin1_err = bootstrap.average_and_std_arrays(y_lin1_dist) tau_lin1_val, tau_lin1_err = bootstrap.average_and_std_arrays(tau_lin1_dist) popt_lin2_val, popt_lin2_err = bootstrap.average_and_std_arrays(popt_lin2_dist) y_lin2_val, y_lin2_err = bootstrap.average_and_std_arrays(y_lin2_dist) tau_lin2_val, tau_lin2_err = bootstrap.average_and_std_arrays(tau_lin2_dist) print('tau_0', siunitx(tau_0_val, tau_0_err)) print('tau_t', siunitx(tau_t_val, tau_t_err)) print('tau_f', siunitx(tau_f_val, tau_f_err)) print('tau_bar', siunitx(tau_bar_val, tau_bar_err)) T['acryl_tau_0'] = siunitx(tau_0_val, tau_0_err) T['acryl_tau_t'] = siunitx(tau_t_val, tau_t_err) T['acryl_tau_f'] = siunitx(tau_f_val, tau_f_err) T['acryl_tau_bar'] = siunitx(tau_bar_val, tau_bar_err) print('popt', siunitx(popt_val, popt_err)) print('popt_lin1', siunitx(popt_lin1_val, popt_lin1_err)) print('popt_lin2', siunitx(popt_lin2_val, popt_lin2_err)) print('tau_lin1', siunitx(tau_lin1_val, tau_lin1_err)) print('tau_lin2', siunitx(tau_lin2_val, tau_lin2_err)) T['acryl_tau_0_lin'] = siunitx(tau_lin1_val, tau_lin1_err) T['acryl_tau_t_lin'] = siunitx(tau_lin2_val, tau_lin2_err) print(x.shape) print(y_lin1_val.shape) pl.plot(time, counts, color='black', alpha=0.3) counts_smooth = scipy.ndimage.filters.gaussian_filter1d(counts, 8) pl.plot(time, counts_smooth, color='green') pl.fill_between(x, y_val - y_err, y_val + y_err, alpha=0.5, color='red') pl.plot(x, y_val, color='red') pl.xlabel('Time / ns') pl.ylabel('Counts') dandify_plot() #pl.xlim((8, 20)) pl.ylim((0.1, np.max(counts)*1.1)) pl.savefig('_build/mpl-lifetime-acryl.pdf') pl.savefig('_build/mpl-lifetime-acryl.png') pl.yscale('log') pl.fill_between(x1, y_lin1_val - y_lin1_err, y_lin1_val + y_lin1_err, alpha=0.5, color='blue') pl.fill_between(x2, y_lin2_val - y_lin2_err, y_lin2_val + y_lin2_err, alpha=0.5, color='blue') pl.plot(x1, y_lin1_val, color='blue', alpha=0.5) pl.plot(x2, y_lin2_val, color='blue', alpha=0.5) dandify_plot() pl.savefig('_build/mpl-lifetime-acryl-log.pdf') pl.savefig('_build/mpl-lifetime-acryl-log.png') #pl.show() pl.clf() np.savetxt('_build/xy/acryl-lifetime-data.tsv', np.column_stack([time, counts])) np.savetxt('_build/xy/acryl-lifetime-smoothed.tsv', np.column_stack([time, counts_smooth])) np.savetxt('_build/xy/acryl-lifetime-fit.tsv', np.column_stack([x, y_val])) np.savetxt('_build/xy/acryl-lifetime-band.tsv', bootstrap.pgfplots_error_band(x, y_val, y_err)) np.savetxt('_build/xy/acryl-lifetime-fit-lin1.tsv', np.column_stack([x1, y_lin1_val])) np.savetxt('_build/xy/acryl-lifetime-band-lin1.tsv', bootstrap.pgfplots_error_band(x1, y_lin1_val, y_lin1_err)) np.savetxt('_build/xy/acryl-lifetime-fit-lin2.tsv', np.column_stack([x2, y_lin2_val])) np.savetxt('_build/xy/acryl-lifetime-band-lin2.tsv', bootstrap.pgfplots_error_band(x2, y_lin2_val, y_lin2_err))
def time_gauge(T, show_gauss=False, show_lin=False): time = [] channel_val = [] channel_err = [] # go through all six prompt-files for i in range(1, 7): time_raw = np.loadtxt('Data/prompt-{}.txt'.format(i)) channel = time_raw[:, 0] counts = time_raw[:, 1] if i == 1: counts_tot = counts elif i < 6: counts_tot += counts # bootstrap: # - draw new counts from gaussian distribution with width of 'sqrt(N)' # - fit gaussian distribution to drawn data # - add mean to array mean = [] width = [] amplitude = [] for a in range(BOOTSTRAP_SAMPLES): boot_counts = redraw_count(counts) popt, pconv = op.curve_fit(gauss, channel, boot_counts, p0=[400 + i * 600, 200, 100]) mean.append(popt[0]) width.append(popt[1]) amplitude.append(popt[2]) # find average and standard deviation in arrays mean_val, mean_err = bootstrap.average_and_std_arrays(mean) width_val, width_err = bootstrap.average_and_std_arrays(width) amplitude_val, amplitude_err = bootstrap.average_and_std_arrays( amplitude) # create files for prompt curve fits x = np.linspace(mean_val - 200, mean_val + 200, 100) y = gauss(x, mean_val, width_val, amplitude_val) np.savetxt('_build/xy/prompt-{}-fit.txt'.format(i), np.column_stack([x, y])) # write result into new channel arrays channel_val.append(mean_val) channel_err.append(mean_err) # write real time for gauging time.append((i - 1) * 4) # write files for prompt curve plotting np.savetxt( '_build/xy/prompts-short.txt', bootstrap.pgfplots_error_band(channel[500:3500], counts_tot[500:3500], np.sqrt(counts_tot[500:3500]))) np.savetxt( '_build/xy/prompts-long.txt', bootstrap.pgfplots_error_band(channel[3600:4200], counts[3600:4200], np.sqrt(counts[3600:4200]))) # convert lists to arrays channel_val = np.array(channel_val) channel_err = np.array(channel_err) time = np.array(time) T['time_gauge_param'] = list( zip(map(str, time), siunitx(channel_val, channel_err))) # linear fit with delete-1-jackknife slope = [] intercept = [] y_dist = [] x = np.linspace(750, 4000, 100) for i in range(len(channel_val)): channel_jackknife = np.delete(channel_val, i) time_jackknife = np.delete(time, i) popt, pconv = op.curve_fit(linear, channel_jackknife, time_jackknife) slope.append(popt[0]) intercept.append(popt[1]) y = linear(x, *popt) y_dist.append(y) if show_lin: x = np.linspace(0, 4000, 1000) y = linear(x, *popt) pl.plot(channel_val, time, linestyle="none", marker="o") pl.plot(x, y) pl.show() pl.clf() slope_val, slope_err = bootstrap.average_and_std_arrays(slope) intercept_val, intercept_err = bootstrap.average_and_std_arrays(intercept) y_val, y_err = bootstrap.average_and_std_arrays(y_dist) # files for fit and plot of time gauge np.savetxt('_build/xy/time_gauge_plot.txt', np.column_stack([channel_val, time, channel_err])) np.savetxt('_build/xy/time_gauge_fit.txt', np.column_stack([x, y_val])) np.savetxt('_build/xy/time_gauge_band.txt', bootstrap.pgfplots_error_band(x, y_val, y_err)) T['time_gauge_slope'] = siunitx(slope_val * 1e3, slope_err * 1e3) T['time_gauge_intercept'] = siunitx(intercept_val, intercept_err) # time resolution T['width_6'] = siunitx(width_val, width_err) FWHM_val = 2 * np.sqrt(2 * np.log(2)) * width_val FWHM_err = 2 * np.sqrt(2 * np.log(2)) * width_err T['FWHM_6'] = siunitx(FWHM_val, FWHM_err) time_res = FWHM_val * slope_val time_res_err = np.sqrt((FWHM_val * slope_err)**2 + (FWHM_err * slope_val)**2) T['time_resolution'] = siunitx(time_res, time_res_err) return slope_val, width_val * slope_val
def michelson_resolution(T): d_cm = np.sort(np.loadtxt('Data/lissajous_X.tsv')) order = np.arange(0, len(d_cm)) wavelength = 987e-9 # get theoretical values n_ground_theor = 1 + 1e-8 * (8342.13 + 2406030 / (130 - 1 / (wavelength * 1e6)**2) + 15997 / (38.9 - 1 / (wavelength * 1e6)**2)) T['n_ground_theor'] = siunitx(n_ground_theor - 1) n_harm_theor = 1 + 1e-8 * (8342.13 + 2406030 / (130 - 1 / (wavelength * .5e6)**2) + 15997 / (38.9 - 1 / (wavelength * .5e6)**2)) T['n_harm_theor'] = siunitx(n_harm_theor - 1) delta_n_theor = n_harm_theor - n_ground_theor T['delta_n_theor'] = siunitx(delta_n_theor) # prepare arrays slope_dist_cm = [] offset_dist_cm = [] delta_n_dist = [] dev_ratio_dist = [] res_michelson_dist = [] fit_y_dist = [] # perform Jackknife for i in range(len(d_cm)): x = np.delete(order, i) y = np.delete(d_cm, i) popt, pconv = op.curve_fit(linear, x, y) slope_dist_cm.append(popt[0]) offset_dist_cm.append(popt[1]) fit_y_dist.append(linear(order, *popt)) # experimental value for difference in refractive index delta_n = wavelength / (8 * popt[0] * 1e-2) delta_n_dist.append(delta_n) # deviation from optimal 1/2 ratio dev_ratio_dist.append(.5 * delta_n / n_harm_theor) # resolution of michelson interferometer delta_wavelength = wavelength * (delta_n / n_ground_theor**2) res_michelson_dist.append(wavelength / delta_wavelength) # get averages and std slope_val_cm, slope_err_cm = bootstrap.average_and_std_arrays( slope_dist_cm) offset_val_cm, offset_err_cm = bootstrap.average_and_std_arrays( offset_dist_cm) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) delta_n_val, delta_n_err = bootstrap.average_and_std_arrays(delta_n_dist) dev_ratio_val, dev_ratio_err = bootstrap.average_and_std_arrays( dev_ratio_dist) dev_ratio_theor = .5 * (delta_n_theor / n_harm_theor) res_michelson_val, res_michelson_err = bootstrap.average_and_std_arrays( res_michelson_dist) # write into T T['distance_lissajous_X'] = siunitx(slope_val_cm, slope_err_cm) T['delta_n'] = siunitx(delta_n_val, delta_n_err) T['dev_ratio'] = siunitx(dev_ratio_val, dev_ratio_err) T['dev_ratio_theor'] = siunitx(dev_ratio_theor) T['res_michelson'] = siunitx(res_michelson_val, res_michelson_err) # write data for plot np.savetxt('_build/xy/michelson-line.tsv', np.column_stack([order, d_cm])) np.savetxt('_build/xy/michelson-band.tsv', bootstrap.pgfplots_error_band(order, fit_y_val, fit_y_err)) T['mirror_position_table'] = list(zip(siunitx(d_cm))) print(siunitx(dev_ratio_val, dev_ratio_err)) print(siunitx(dev_ratio_theor)) print(siunitx(res_michelson_val, res_michelson_err))
def job_harmonic_power(T, extinction_dist, input_popt_dist): data = np.loadtxt('Data/harmonic_splitter.tsv') angle = data[:, 0] power_val = data[:, 1] * 1e-6 power_err = data[:, 2] * 1e-6 T['harmonic_splitter_table'] = list( zip( siunitx(angle), siunitx(power_val * 1e6, power_err * 1e6), )) power_dist = bootstrap.make_dist(power_val, power_err) fit_x = np.linspace(np.min(angle), np.max(angle), 200) fit_y_dist = [] angle_offset_dist = [] a_dist = [] b_dist = [] popt_dist = [] for power in power_dist: popt, pconv = op.curve_fit(cos_quartic, angle, power, p0=[1.5e-5, 0, 0]) fit_y_dist.append(cos_quartic(fit_x, *popt)) angle_offset_dist.append(popt[1]) a = popt[0] b = popt[2] a_dist.append(a) b_dist.append(b) popt_dist.append(popt) fit_y_val, fit_y_err = bootstrap.average_and_std_arrays(fit_y_dist) angle_offset_val, angle_offset_err = bootstrap.average_and_std_arrays( angle_offset_dist) a_val, a_err = bootstrap.average_and_std_arrays(a_dist) b_val, b_err = bootstrap.average_and_std_arrays(b_dist) np.savetxt('_build/xy/harmonic-splitter-data.tsv', np.column_stack([angle, power_val, power_err])) np.savetxt('_build/xy/harmonic-splitter-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('_build/xy/harmonic-splitter-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) T['splitter_angle_offset'] = siunitx(angle_offset_val, angle_offset_err) T['splitter_a'] = siunitx(a_val, a_err) T['splitter_b'] = siunitx(b_val, b_err) efficiency_dist = [] efficiency_sq_dist = [] for extinction, input_popt, popt in zip(extinction_dist, input_popt_dist, popt_dist): efficiency = popt[0] / (input_popt[0] * extinction) efficiency_dist.append(efficiency) efficiency_sq = popt[0] / (input_popt[0] * extinction)**2 efficiency_sq_dist.append(efficiency_sq) efficiency_val, efficiency_err = bootstrap.average_and_std_arrays( efficiency_dist) efficiency_sq_val, efficiency_sq_err = bootstrap.average_and_std_arrays( efficiency_sq_dist) T['efficiency'] = siunitx(efficiency_val, efficiency_err) T['efficiency_sq'] = siunitx(efficiency_sq_val, efficiency_sq_err)
def get_indium_data(T, slope_val, width): files = glob.glob('Data/in-*.txt') temps_val = [] temps_err = [] all_counts = [] all_tau_0_dist = [] all_tau_bar_dist = [] all_tau_f_dist = [] all_tau_t_dist = [] all_intens_0_dist = [] all_intens_t_dist = [] all_lifetime_y_dist = [] all_lifetime_popt_dist = [] all_sigma_c_dist = [] # Process lifetime curves with bootstrap. for sample_id in range(BOOTSTRAP_SAMPLES): print('Bootstrap sample', sample_id, 'running …') results = [] for file_ in sorted(files): print('Working on lifetime spectrum', file_) if sample_id == 0: temp_lower, temp_upper = get_temp(file_) temp_mean = (temp_lower + temp_upper)/2 temp_err = temp_upper - temp_mean temps_val.append(temp_mean) temps_err.append(temp_err) print('Mean temperature:', temp_mean) data = np.loadtxt(file_) channel = data[:, 0] time = slope_val * channel counts = data[:, 1] boot_counts = bootstrap.redraw_count(counts) if sample_id == 0: all_counts.append(counts) x = np.linspace(np.min(time), np.max(time), 2000) sel = (9 < time) & (time < 15) fit_func = lambda t, mean, A_0, A_t, tau_0, tau_t, BG: \ models.lifetime_spectrum(t, mean, width, A_0, A_t, tau_0, tau_t, BG) p0 = [10.5, 210, 190, 0.07, 0.8, 0] popt, pconv = op.curve_fit(fit_func, time[sel], boot_counts[sel], p0=p0) mean, A_0, A_t, tau_0, tau_t, BG = popt intens_0 = A_0 / (A_0 + A_t) intens_t = A_t / (A_0 + A_t) tau_bar = intens_0 * tau_0 + intens_t * tau_t y = fit_func(x, *popt) tau_f = 1 / (intens_0 / tau_0 - intens_t / tau_t) sigma_c = 1 / tau_0 - 1 / tau_f results.append([ tau_0, tau_bar, tau_f, tau_t, intens_0, intens_t, y, popt, sigma_c, ]) tau_0_list, tau_bar_list, tau_f_list, tau_t_list, intens_0_list, \ intens_t_list, lifetime_y_list, lifetime_popt_list, sigma_c_list \ = zip(*results) all_tau_0_dist.append(tau_0_list) all_tau_bar_dist.append(tau_bar_list) all_tau_f_dist.append(tau_f_list) all_tau_t_dist.append(tau_t_list) all_intens_0_dist.append(intens_0_list) all_intens_t_dist.append(intens_t_list) all_lifetime_y_dist.append(lifetime_y_list) all_lifetime_popt_dist.append(lifetime_popt_list) all_sigma_c_dist.append(sigma_c_list) T['temps_int'] = [] # Generate plots with lifetime curves and fits. for temp, counts, lifetime_y_dist in zip(temps_val, all_counts, zip(*all_lifetime_y_dist)): print('Creating lifetime plot with temp', temp) y_val, y_err = bootstrap.average_and_std_arrays(lifetime_y_dist) np.savetxt('_build/xy/lifetime-{}K-data.tsv'.format(int(temp)), bootstrap.pgfplots_error_band(time[0:4000], counts[0:4000], np.sqrt(counts[0:4000]))) np.savetxt('_build/xy/lifetime-{}K-fit.tsv'.format(int(temp)), np.column_stack([x, y_val])) np.savetxt('_build/xy/lifetime-{}K-band.tsv'.format(int(temp)), bootstrap.pgfplots_error_band(x, y_val, y_err)) T['temps_int'].append(int(temp)) if False: pl.fill_between(x, y_val - y_err, y_val + y_err, alpha=0.5, color='red') pl.plot(time, counts, color='black') counts_smooth = scipy.ndimage.filters.gaussian_filter1d(counts, 8) pl.plot(time, counts_smooth, color='green') pl.plot(x, y_val, color='red') pl.xlabel('Time / ns') pl.ylabel('Counts') dandify_plot() pl.xlim((8, 20)) pl.savefig('_build/mpl-lifetime-{:04d}K.pdf'.format(int(temp))) pl.savefig('_build/mpl-lifetime-{:04d}K.png'.format(int(temp))) pl.yscale('log') pl.savefig('_build/mpl-lifetime-{:04d}K-log.pdf'.format(int(temp))) pl.savefig('_build/mpl-lifetime-{:04d}K-log.png'.format(int(temp))) pl.clf() T['temps_int'].sort() # Plot the lifetimes. taus_0_val, taus_0_err = bootstrap.average_and_std_arrays(all_tau_0_dist) taus_t_val, taus_t_err = bootstrap.average_and_std_arrays(all_tau_t_dist) taus_f_val, taus_f_err = bootstrap.average_and_std_arrays(all_tau_f_dist) taus_bar_val, taus_bar_err = bootstrap.average_and_std_arrays(all_tau_bar_dist) pl.errorbar(temps_val, taus_0_val, xerr=temps_err, yerr=taus_0_err, label=r'$\tau_0$', linestyle='none', marker='+') pl.errorbar(temps_val, taus_bar_val, xerr=temps_err, yerr=taus_bar_err, label=r'$\bar\tau$', linestyle='none', marker='+') pl.errorbar(temps_val, taus_t_val, xerr=temps_err, yerr=taus_t_err, label=r'$\tau_\mathrm{t}$', linestyle='none', marker='+') pl.errorbar(temps_val, taus_f_val, xerr=temps_err, yerr=taus_f_err, label=r'$\tau_\mathrm{f}$', linestyle='none', marker='+') pl.xlabel('T / K') pl.ylabel(r'$\tau$ / ns') dandify_plot() pl.savefig('_build/mpl-tau_0-tau_t.pdf') pl.savefig('_build/mpl-tau_0-tau_t.png') pl.clf() np.savetxt('_build/xy/tau_0.tsv', np.column_stack([temps_val, taus_0_val, taus_0_err])) np.savetxt('_build/xy/tau_t.tsv', np.column_stack([temps_val, taus_t_val, taus_t_err])) np.savetxt('_build/xy/tau_f.tsv', np.column_stack([temps_val, taus_f_val, taus_f_err])) np.savetxt('_build/xy/tau_bar.tsv', np.column_stack([temps_val, taus_bar_val, taus_bar_err])) T['taus_table'] = list(zip( siunitx(temps_val, temps_err), siunitx(taus_0_val, taus_0_err), siunitx(taus_t_val, taus_t_err), siunitx(taus_f_val, taus_f_err), siunitx(taus_bar_val, taus_bar_err), )) # Plot relative intensities. all_intens_0_val, all_intens_0_err = bootstrap.average_and_std_arrays(all_intens_0_dist) all_intens_t_val, all_intens_t_err = bootstrap.average_and_std_arrays(all_intens_t_dist) pl.errorbar(temps_val, all_intens_0_val, xerr=temps_err, yerr=all_intens_0_err, label=r'$A_0$', linestyle='none', marker='+') pl.errorbar(temps_val, all_intens_t_val, xerr=temps_err, yerr=all_intens_t_err, label=r'$A_\mathrm{t}$', linestyle='none', marker='+') pl.xlabel('T / K') pl.ylabel(r'Relative Intensity') dandify_plot() pl.savefig('_build/mpl-intensities.pdf') pl.savefig('_build/mpl-intensities.png') pl.clf() np.savetxt('_build/xy/intensities-0.tsv', np.column_stack([temps_val, all_intens_0_val, all_intens_0_err])) np.savetxt('_build/xy/intensities-t.tsv', np.column_stack([temps_val, all_intens_t_val, all_intens_t_err])) T['intensities_table'] = list(zip( siunitx(temps_val, temps_err), siunitx(all_intens_0_val, all_intens_0_err), siunitx(all_intens_t_val, all_intens_t_err), )) inv_temps = 1 / np.array(temps_val) results = [] x = np.linspace(np.min(inv_temps), np.max(inv_temps), 1000) kelvin_to_eV = 8.621738e-5 for all_sigma_c in all_sigma_c_dist: p0 = [11, 240] print('inv_temps:', inv_temps) print('all_sigma_c:', all_sigma_c) for leave_out in range(len(all_sigma_c)): inv_temps_jack = np.delete(inv_temps, leave_out) all_sigma_c_jack = np.delete(all_sigma_c, leave_out) popt, pconv = op.curve_fit(exp_decay, inv_temps_jack, all_sigma_c_jack, p0=p0) y = exp_decay(x, *popt) results.append([ popt, popt[1] * kelvin_to_eV, y, ]) popt_dist, Ht_eV_dist, arr_y_dist = zip(*results) popt_val, popt_err = bootstrap.average_and_std_arrays(popt_dist) print('popt:', siunitx(popt_val, popt_err)) Ht_eV_val, Ht_eV_err = bootstrap.average_and_std_arrays(Ht_eV_dist) arr_y_val, arr_y_err = bootstrap.average_and_std_arrays(arr_y_dist) sigma_c_val, sigma_c_err = bootstrap.average_and_std_arrays(all_sigma_c_dist) pl.fill_between(x, arr_y_val - arr_y_err, arr_y_val + arr_y_err, alpha=0.5, color='red') pl.plot(x, arr_y_val, color='red') pl.errorbar(inv_temps, sigma_c_val, yerr=sigma_c_err, marker='+', linestyle='none', color='black') pl.xlabel(r'$1 / T$') pl.ylabel(r'$\sigma C_t(T)$') pl.savefig('_build/mpl-arrhenius.pdf') pl.savefig('_build/mpl-arrhenius.png') pl.clf() np.savetxt('_build/xy/arrhenius-data.tsv', np.column_stack([inv_temps, sigma_c_val, sigma_c_err])) np.savetxt('_build/xy/arrhenius-fit.tsv', np.column_stack([x, arr_y_val])) np.savetxt('_build/xy/arrhenius-band.tsv', bootstrap.pgfplots_error_band(x, arr_y_val, arr_y_err)) T['arrhenius_table'] = list(zip( siunitx(inv_temps), siunitx(sigma_c_val, sigma_c_err), )) print('Ht_eV:', siunitx(Ht_eV_val, Ht_eV_err)) T['Ht_eV'] = siunitx(Ht_eV_val, Ht_eV_err) pl.errorbar(temps_val, taus_bar_val, xerr=temps_err, yerr=taus_bar_err, label=r'$\bar\tau$', linestyle='none', marker='+') dandify_plot() pl.xlabel('T / K') pl.ylabel(r'$\bar\tau$ / ns') pl.savefig('_build/mpl-s_curve.pdf') pl.savefig('_build/mpl-s_curve.png') pl.clf() np.savetxt('_build/xy/s_curve.tsv', np.column_stack([temps_val, taus_bar_val, taus_bar_err]))
def time_gauge(T, show_gauss=False, show_lin=False): time = [] channel_val = [] channel_err = [] # go through all six prompt-files for i in range(1,7): time_raw = np.loadtxt('Data/prompt-{}.txt'.format(i)) channel = time_raw[:,0] counts = time_raw[:,1] if i==1: counts_tot = counts elif i<6: counts_tot += counts # bootstrap: # - draw new counts from gaussian distribution with width of 'sqrt(N)' # - fit gaussian distribution to drawn data # - add mean to array mean = [] width = [] amplitude = [] for a in range(BOOTSTRAP_SAMPLES): boot_counts = redraw_count(counts) popt, pconv = op.curve_fit(gauss, channel, boot_counts, p0=[400+i*600, 200, 100]) mean.append(popt[0]) width.append(popt[1]) amplitude.append(popt[2]) # find average and standard deviation in arrays mean_val, mean_err = bootstrap.average_and_std_arrays(mean) width_val, width_err = bootstrap.average_and_std_arrays(width) amplitude_val, amplitude_err = bootstrap.average_and_std_arrays(amplitude) # create files for prompt curve fits x = np.linspace(mean_val-200, mean_val+200, 100) y = gauss(x, mean_val, width_val, amplitude_val) np.savetxt('_build/xy/prompt-{}-fit.txt'.format(i), np.column_stack([x, y])) # write result into new channel arrays channel_val.append(mean_val) channel_err.append(mean_err) # write real time for gauging time.append((i-1)*4) # write files for prompt curve plotting np.savetxt('_build/xy/prompts-short.txt', bootstrap.pgfplots_error_band(channel[500:3500], counts_tot[500:3500], np.sqrt(counts_tot[500:3500]))) np.savetxt('_build/xy/prompts-long.txt', bootstrap.pgfplots_error_band(channel[3600:4200], counts[3600:4200], np.sqrt(counts[3600:4200]))) # convert lists to arrays channel_val = np.array(channel_val) channel_err = np.array(channel_err) time = np.array(time) T['time_gauge_param'] = list(zip( map(str, time), siunitx(channel_val, channel_err) )) # linear fit with delete-1-jackknife slope = [] intercept = [] y_dist = [] x = np.linspace(750, 4000, 100) for i in range(len(channel_val)): channel_jackknife = np.delete(channel_val, i) time_jackknife = np.delete(time, i) popt, pconv = op.curve_fit(linear, channel_jackknife, time_jackknife) slope.append(popt[0]) intercept.append(popt[1]) y = linear(x, *popt) y_dist.append(y) if show_lin: x = np.linspace(0, 4000, 1000) y = linear(x, *popt) pl.plot(channel_val, time, linestyle="none", marker="o") pl.plot(x, y) pl.show() pl.clf() slope_val, slope_err = bootstrap.average_and_std_arrays(slope) intercept_val, intercept_err = bootstrap.average_and_std_arrays(intercept) y_val, y_err = bootstrap.average_and_std_arrays(y_dist) # files for fit and plot of time gauge np.savetxt('_build/xy/time_gauge_plot.txt', np.column_stack([channel_val,time, channel_err])) np.savetxt('_build/xy/time_gauge_fit.txt', np.column_stack([x, y_val])) np.savetxt('_build/xy/time_gauge_band.txt', bootstrap.pgfplots_error_band(x, y_val, y_err)) T['time_gauge_slope'] = siunitx(slope_val*1e3, slope_err*1e3) T['time_gauge_intercept'] = siunitx(intercept_val, intercept_err) # time resolution T['width_6'] = siunitx(width_val , width_err) FWHM_val = 2*np.sqrt(2*np.log(2)) * width_val FWHM_err = 2*np.sqrt(2*np.log(2)) * width_err T['FWHM_6'] = siunitx(FWHM_val , FWHM_err) time_res = FWHM_val * slope_val time_res_err = np.sqrt((FWHM_val * slope_err)**2 + (FWHM_err * slope_val)**2) T['time_resolution'] = siunitx(time_res , time_res_err) return slope_val, width_val*slope_val
def main(): options = _parse_args() R = 300 # Read in the data from the paper. a_inv_val = 1616 a_inv_err = 20 a_inv_dist = bootstrap.make_dist(a_inv_val, a_inv_err, n=R) aml, ams, l, t, trajectories, ampi_val, ampi_err, amk_val, amk_err, f_k_f_pi_val, f_k_f_pi_err = util.load_columns( 'physical_point/gmor.txt') ampi_dist = bootstrap.make_dist(ampi_val, ampi_err, n=R) amk_dist = bootstrap.make_dist(amk_val, amk_err, n=R) mpi_dist = [ampi * a_inv for ampi, a_inv in zip(ampi_dist, a_inv_dist)] mk_dist = [amk * a_inv for amk, a_inv in zip(amk_dist, a_inv_dist)] # Convert the data in lattice units into physical units. mpi_dist = [a_inv * ampi for ampi, a_inv in zip(ampi_dist, a_inv_dist)] mpi_val, mpi_avg, mpi_err = bootstrap.average_and_std_arrays(mpi_dist) mpi_sq_dist = [mpi**2 for mpi in mpi_dist] mpi_sq_val, mpi_sq_avg, mpi_sq_err = bootstrap.average_and_std_arrays( mpi_sq_dist) ampi_sq_dist = [ampi**2 for ampi in ampi_dist] ampi_sq_val, ampi_sq_avg, ampi_sq_err = bootstrap.average_and_std_arrays( ampi_sq_dist) # Do a GMOR fit in order to extract `a B` and `a m_cr`. popt_dist = [ op.curve_fit(gmor_pion, aml, ampi_sq)[0] for ampi_sq in ampi_sq_dist ] aB_dist = [popt[0] for popt in popt_dist] amcr_dist = [popt[1] for popt in popt_dist] aB_val, aB_avg, aB_err = bootstrap.average_and_std_arrays(aB_dist) amcr_val, amcr_avg, amcr_err = bootstrap.average_and_std_arrays(amcr_dist) print('aB =', siunitx(aB_val, aB_err)) print('am_cr =', siunitx(amcr_val, amcr_err)) ams_paper = -0.057 ams_phys = ams_paper - amcr_val ams_red = 0.9 * ams_phys ams_bare_red = ams_red + amcr_val print(ams_paper, ams_phys, ams_red, ams_bare_red) print() print('Mass preconditioning masses:') amlq = aml - amcr_val for i in range(3): amprec = amlq * 10**i + amcr_val kappa = 1 / (amprec * 2 + 8) print('a m_prec:', amprec) print('κ', kappa) exit() diff_dist = [ np.sqrt(2) * np.sqrt(mk**2 - 0.5 * mpi**2) for mpi, mk in zip(mpi_dist, mk_dist) ] diff_val, diff_avg, diff_err = bootstrap.average_and_std_arrays(diff_dist) popt_dist = [ op.curve_fit(linear, mpi, diff)[0] for mpi, diff in zip(mpi_dist, diff_dist) ] fit_x = np.linspace(np.min(mpi_dist), np.max(mpi_dist), 100) fit_y_dist = [linear(fit_x, *popt) for popt in popt_dist] fit_y_val, fit_y_avg, fit_y_err = bootstrap.average_and_std_arrays( fit_y_dist) # Physical meson masses from FLAG paper. mpi_phys_dist = bootstrap.make_dist(134.8, 0.3, R) mk_phys_dist = bootstrap.make_dist(494.2, 0.3, R) mpi_phys_val, mpi_phys_avg, mpi_phys_err = bootstrap.average_and_std_arrays( mpi_phys_dist) ampi_phys_dist = [ mpi_phys / a_inv for a_inv, mpi_phys in zip(a_inv_dist, mpi_phys_dist) ] amk_phys_dist = [ mk_phys / a_inv for a_inv, mk_phys in zip(a_inv_dist, mk_phys_dist) ] ampi_phys_val, ampi_phys_avg, ampi_phys_err = bootstrap.average_and_std_arrays( ampi_phys_dist) amk_phys_val, amk_phys_avg, amk_phys_err = bootstrap.average_and_std_arrays( amk_phys_dist) print('aM_pi phys =', siunitx(ampi_phys_val, ampi_phys_err)) print('aM_k phys =', siunitx(amk_phys_val, amk_phys_err)) new_b_dist = [ np.sqrt(mk_phys**2 - 0.5 * mpi_phys**2) - popt[0] * mpi_phys for mpi_phys, mk_phys, popt in zip(mpi_phys_dist, mk_phys_dist, popt_dist) ] diff_sqrt_phys_dist = [ np.sqrt(mk_phys**2 - 0.5 * mpi_phys**2) for mpi_phys, mk_phys in zip(mpi_phys_dist, mk_phys_dist) ] diff_sqrt_phys_val, diff_sqrt_phys_avg, diff_sqrt_phys_err = bootstrap.average_and_std_arrays( diff_sqrt_phys_dist) ex_x = np.linspace(120, 700, 100) ex_y_dist = [ linear(ex_x, popt[0], b) for popt, b in zip(popt_dist, new_b_dist) ] ex_y_val, ex_y_avg, ex_y_err = bootstrap.average_and_std_arrays(ex_y_dist) ams_art_dist = [ linear(mpi, popt[0], b)**2 / a_inv**2 / aB - amcr for mpi, popt, b, a_inv, aB, amcr in zip( mpi_dist, popt_dist, new_b_dist, a_inv_dist, aB_dist, amcr_dist) ] ams_art_val, ams_art_avg, ams_art_err = bootstrap.average_and_std_arrays( ams_art_dist) print('a m_s with artifacts', siunitx(ams_art_val, ams_art_err)) fig, ax = util.make_figure() ax.fill_between(fit_x, fit_y_val + fit_y_err, fit_y_val - fit_y_err, color='red', alpha=0.2) ax.plot(fit_x, fit_y_val, label='Fit', color='red') ax.fill_between(ex_x, ex_y_val + ex_y_err, ex_y_val - ex_y_err, color='orange', alpha=0.2) ax.plot(ex_x, ex_y_val, label='Extrapolation', color='orange') ax.errorbar(mpi_val, diff_val, xerr=mpi_err, yerr=diff_err, linestyle='none', label='Data (Dürr 2010)') ax.errorbar([mpi_phys_val], [diff_sqrt_phys_val], xerr=[mpi_phys_err], yerr=[diff_sqrt_phys_err], label='Physical Point (Aoki)') util.save_figure(fig, 'test') np.savetxt('artifact-bmw-data.tsv', np.column_stack([mpi_val, diff_val, mpi_err, diff_err])) np.savetxt('artifact-bmw-fit.tsv', np.column_stack([fit_x, fit_y_val])) np.savetxt('artifact-bmw-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_val, fit_y_err)) np.savetxt( 'artifact-phys-data.tsv', np.column_stack([[mpi_phys_val], [diff_sqrt_phys_val], [mpi_phys_err], [diff_sqrt_phys_err]])) np.savetxt('artifact-phys-fit.tsv', np.column_stack([ex_x, ex_y_val])) np.savetxt('artifact-phys-band.tsv', bootstrap.pgfplots_error_band(ex_x, ex_y_val, ex_y_err)) np.savetxt('artifact-ms.tsv', np.column_stack([mpi_val, ams_art_val, mpi_err, ams_art_err])) # Compute the strange quark mass that is needed to obtain a physical meson # mass difference, ignoring lattice artifacts. ams_phys_dist = [(amk_phys**2 - 0.5 * ampi_phys**2) / aB - amcr for ampi_phys, amk_phys, aB, amcr in zip( ampi_phys_dist, amk_phys_dist, aB_dist, amcr_dist)] ams_phys_cen, ams_phys_val, ams_phys_err = bootstrap.average_and_std_arrays( ams_phys_dist) print('M_K = {} MeV <== am_s ='.format(siunitx(494.2, 0.3)), siunitx(ams_phys_cen, ams_phys_err)) aml_phys_dist = [ op.newton(lambda aml: gmor_pion(aml, *popt) - ampi_phys**2, np.min(aml)) for popt, ampi_phys in zip(popt_dist, ampi_phys_dist) ] fit_x = np.linspace(np.min(aml_phys_dist), np.max(aml), 100) fit_y_dist = [ np.sqrt(gmor_pion(fit_x, *popt)) * a_inv for popt, a_inv in zip(popt_dist, a_inv_dist) ] fit_y_cen, fit_y_val, fit_y_err = bootstrap.average_and_std_arrays( fit_y_dist) np.savetxt('physical_point/mpi-vs-aml-data.tsv', np.column_stack([aml, mpi_val, mpi_err])) np.savetxt('physical_point/mpi-vs-aml-fit.tsv', np.column_stack([fit_x, fit_y_cen])) np.savetxt('physical_point/mpi-vs-aml-band.tsv', bootstrap.pgfplots_error_band(fit_x, fit_y_cen, fit_y_err)) aml_phys_val, aml_phys_avg, aml_phys_err = bootstrap.average_and_std_arrays( aml_phys_dist) mpi_cen, mpi_val, mpi_err = bootstrap.average_and_std_arrays(mpi_dist) #aml_240_val, aml_240_avg, aml_240_err = bootstrap.average_and_std_arrays(aml_240_dist) print('M_pi = {} MeV <== am_l ='.format(siunitx(134.8, 0.3)), siunitx(aml_phys_val, aml_phys_err)) #print('M_pi = 240 MeV <== am_l =', siunitx(aml_240_val, aml_240_err)) fig = pl.figure() ax = fig.add_subplot(2, 1, 1) ax.fill_between(fit_x, fit_y_val - fit_y_err, fit_y_val + fit_y_err, color='0.8') ax.plot(fit_x, fit_y_val, color='black', label='GMOR Fit') ax.errorbar(aml, mpi_val, yerr=mpi_err, color='blue', marker='+', linestyle='none', label='Data') ax.errorbar([aml_phys_val], [135], xerr=[aml_phys_err], marker='+', color='red', label='Extrapolation') #ax.errorbar([aml_240_val], [240], xerr=[aml_240_err], marker='+', color='red') ax.set_title('Extrapolation to the Physical Point') ax.set_xlabel(r'$a m_\mathrm{ud}$') ax.set_ylabel(r'$M_\pi / \mathrm{MeV}$') util.dandify_axes(ax) ax = fig.add_subplot(2, 1, 2) ax.hist(aml_phys_dist - aml_phys_val, bins=50) ax.locator_params(nbins=6) ax.set_title('Bootstrap Bias') ax.set_xlabel( r'$(a m_\mathrm{ud}^\mathrm{phys})^* - a m_\mathrm{ud}^\mathrm{phys}$') util.dandify_axes(ax) util.dandify_figure(fig) fig.savefig('physical_point/GMOR.pdf') np.savetxt('physical_point/ampi-sq-vs-aml.tsv', np.column_stack([aml, ampi_sq_val, ampi_sq_err])) np.savetxt('physical_point/mpi-sq-vs-aml.tsv', np.column_stack([aml, mpi_sq_val, mpi_sq_err]))
def get_acryl_data(T, slope_val, width): data = np.loadtxt('Data/longlong.txt') channel = data[:, 0] time = slope_val * channel counts = data[:, 1] x = np.linspace(np.min(time), np.max(time), 500) fit_func = lambda t, mean, A_0, A_t, tau_0, tau_t, BG: \ np.log(models.lifetime_spectrum(t, mean, width, A_0, A_t, tau_0, tau_t, BG)) results = [] sel1 = (10.92 < time) & (time < 11.58) sel2 = (13.11 < time) & (time < 22) sels = [sel1, sel2] x1 = np.linspace(np.min(time[sel1]), np.max(time[sel1]), 10) x2 = np.linspace(np.min(time[sel2]), np.max(time[sel2]), 10) for sample_id in range(BOOTSTRAP_SAMPLES): print('Bootstrap sample', sample_id, 'running …') boot_counts = bootstrap.redraw_count(counts) lin_lifetimes = [] lin_results = [] for sel_lin, x_lin in zip(sels, [x1, x2]): popt_lin, pconv_lin = op.curve_fit(exp_decay, time[sel_lin], boot_counts[sel_lin], p0=[1e5, 0.3]) y_lin = exp_decay(x_lin, *popt_lin) lin_results.append(y_lin) lin_results.append(popt_lin) lin_results.append(1 / popt_lin[1]) lin_lifetimes.append(1 / popt_lin[1]) sel = (10 < time) & (time < 50) & (boot_counts > 0) p0 = [10.5, 13e3, 34e2] + lin_lifetimes + [2] popt, pconv = op.curve_fit(fit_func, time[sel], np.log(boot_counts[sel]), p0=p0) mean, A_0, A_t, tau_0, tau_t, BG = popt intens_0 = A_0 / (A_0 + A_t) intens_t = A_t / (A_0 + A_t) tau_bar = intens_0 * tau_0 + intens_t * tau_t y = np.exp(fit_func(x, *popt)) tau_f = 1 / (intens_0 / tau_0 - intens_t / tau_t) sigma_c = 1 / tau_0 - 1 / tau_f results.append([ tau_0, tau_bar, tau_f, tau_t, intens_0, intens_t, y, popt, sigma_c, ] + lin_results) tau_0_dist, tau_bar_dist, tau_f_dist, tau_t_dist, intens_0_dist, \ intens_t_dist, lifetime_y_dist, lifetime_popt_dist, sigma_c_dist, \ y_lin1_dist, popt_lin1_dist, tau_lin1_dist, \ y_lin2_dist, popt_lin2_dist, tau_lin2_dist, \ = zip(*results) tau_0_val, tau_0_err = bootstrap.average_and_std_arrays(tau_0_dist) tau_t_val, tau_t_err = bootstrap.average_and_std_arrays(tau_t_dist) tau_f_val, tau_f_err = bootstrap.average_and_std_arrays(tau_f_dist) tau_bar_val, tau_bar_err = bootstrap.average_and_std_arrays(tau_bar_dist) popt_val, popt_err = bootstrap.average_and_std_arrays(lifetime_popt_dist) y_val, y_err = bootstrap.average_and_std_arrays(lifetime_y_dist) popt_lin1_val, popt_lin1_err = bootstrap.average_and_std_arrays( popt_lin1_dist) y_lin1_val, y_lin1_err = bootstrap.average_and_std_arrays(y_lin1_dist) tau_lin1_val, tau_lin1_err = bootstrap.average_and_std_arrays( tau_lin1_dist) popt_lin2_val, popt_lin2_err = bootstrap.average_and_std_arrays( popt_lin2_dist) y_lin2_val, y_lin2_err = bootstrap.average_and_std_arrays(y_lin2_dist) tau_lin2_val, tau_lin2_err = bootstrap.average_and_std_arrays( tau_lin2_dist) print('tau_0', siunitx(tau_0_val, tau_0_err)) print('tau_t', siunitx(tau_t_val, tau_t_err)) print('tau_f', siunitx(tau_f_val, tau_f_err)) print('tau_bar', siunitx(tau_bar_val, tau_bar_err)) T['acryl_tau_0'] = siunitx(tau_0_val, tau_0_err) T['acryl_tau_t'] = siunitx(tau_t_val, tau_t_err) T['acryl_tau_f'] = siunitx(tau_f_val, tau_f_err) T['acryl_tau_bar'] = siunitx(tau_bar_val, tau_bar_err) print('popt', siunitx(popt_val, popt_err)) print('popt_lin1', siunitx(popt_lin1_val, popt_lin1_err)) print('popt_lin2', siunitx(popt_lin2_val, popt_lin2_err)) print('tau_lin1', siunitx(tau_lin1_val, tau_lin1_err)) print('tau_lin2', siunitx(tau_lin2_val, tau_lin2_err)) T['acryl_tau_0_lin'] = siunitx(tau_lin1_val, tau_lin1_err) T['acryl_tau_t_lin'] = siunitx(tau_lin2_val, tau_lin2_err) print(x.shape) print(y_lin1_val.shape) pl.plot(time, counts, color='black', alpha=0.3) counts_smooth = scipy.ndimage.filters.gaussian_filter1d(counts, 8) pl.plot(time, counts_smooth, color='green') pl.fill_between(x, y_val - y_err, y_val + y_err, alpha=0.5, color='red') pl.plot(x, y_val, color='red') pl.xlabel('Time / ns') pl.ylabel('Counts') dandify_plot() #pl.xlim((8, 20)) pl.ylim((0.1, np.max(counts) * 1.1)) pl.savefig('_build/mpl-lifetime-acryl.pdf') pl.savefig('_build/mpl-lifetime-acryl.png') pl.yscale('log') pl.fill_between(x1, y_lin1_val - y_lin1_err, y_lin1_val + y_lin1_err, alpha=0.5, color='blue') pl.fill_between(x2, y_lin2_val - y_lin2_err, y_lin2_val + y_lin2_err, alpha=0.5, color='blue') pl.plot(x1, y_lin1_val, color='blue', alpha=0.5) pl.plot(x2, y_lin2_val, color='blue', alpha=0.5) dandify_plot() pl.savefig('_build/mpl-lifetime-acryl-log.pdf') pl.savefig('_build/mpl-lifetime-acryl-log.png') #pl.show() pl.clf() np.savetxt('_build/xy/acryl-lifetime-data.tsv', np.column_stack([time, counts])) np.savetxt('_build/xy/acryl-lifetime-smoothed.tsv', np.column_stack([time, counts_smooth])) np.savetxt('_build/xy/acryl-lifetime-fit.tsv', np.column_stack([x, y_val])) np.savetxt('_build/xy/acryl-lifetime-band.tsv', bootstrap.pgfplots_error_band(x, y_val, y_err)) np.savetxt('_build/xy/acryl-lifetime-fit-lin1.tsv', np.column_stack([x1, y_lin1_val])) np.savetxt('_build/xy/acryl-lifetime-band-lin1.tsv', bootstrap.pgfplots_error_band(x1, y_lin1_val, y_lin1_err)) np.savetxt('_build/xy/acryl-lifetime-fit-lin2.tsv', np.column_stack([x2, y_lin2_val])) np.savetxt('_build/xy/acryl-lifetime-band-lin2.tsv', bootstrap.pgfplots_error_band(x2, y_lin2_val, y_lin2_err))
def job_power(T): data = np.loadtxt('Data/diode.tsv') norm_current = data[:, 0] * 1e-3 norm_power_val = data[:, 1] * 1e-3 norm_power_err = np.ones(norm_power_val.shape) * 1e-6 norm_power_dist = bootstrap.make_dist(norm_power_val, norm_power_err) data = np.loadtxt('Data/diode_damped.tsv') damp_current = data[:, 0] * 1e-3 damp_power_val = data[:, 1] * 1e-3 damp_power_err = data[:, 2] * 1e-3 damp_power_dist = bootstrap.make_dist(damp_power_val, damp_power_err) np.savetxt('_build/xy/diode_normal-data.tsv', np.column_stack([norm_current, norm_power_val, norm_power_err])) np.savetxt('_build/xy/diode_damped-data.tsv', np.column_stack([damp_current, damp_power_val, damp_power_err])) T['diode_normal_table'] = list( zip( siunitx(norm_current * 1e3), siunitx(norm_power_val * 1e6, norm_power_err * 1e6, allowed_hang=6), )) T['diode_damped_table'] = list( zip( siunitx(damp_current * 1e3), siunitx(damp_power_val * 1e6, damp_power_err * 1e6), )) hbar_omega = 6.626e-34 * 3e8 / 987e-9 electron_charge = 1.609e-19 # Find the threshold current. sel = norm_power_val > 1e-3 slope_dist = [] quantum_efficiency_dist = [] threshold_dist = [] threshold_fit_x = np.linspace(0.05, 0.09, 100) threshold_fit_y_dist = [] # Jackknife fit to find root. for i in range(len(norm_power_val[sel])): x = np.delete(norm_current[sel], i) y_val = np.delete(norm_power_val[sel], i) y_err = np.delete(norm_power_err[sel], i) popt, pconv = op.curve_fit(linear, x, y_val, sigma=y_err) a, b = popt root = -b / a threshold_dist.append(root) threshold_fit_y_dist.append(linear(threshold_fit_x, *popt)) slope_dist.append(a) quantum_efficiency_dist.append(a * electron_charge / hbar_omega) threshold_val, threshold_err = bootstrap.average_and_std_arrays( threshold_dist) threshold_fit_y_val, threshold_fit_y_err = bootstrap.average_and_std_arrays( threshold_fit_y_dist) differential_efficiency_val, differential_efficiency_err = bootstrap.average_and_std_arrays( slope_dist) quantum_efficiency_val, quantum_efficiency_err = bootstrap.average_and_std_arrays( quantum_efficiency_dist) T['threshold'] = siunitx(threshold_val, threshold_err) T['differential_efficiency'] = siunitx(differential_efficiency_val, differential_efficiency_err) T['quantum_efficiency'] = siunitx(quantum_efficiency_val, quantum_efficiency_err) np.savetxt( '_build/xy/diode_normal-band.tsv', bootstrap.pgfplots_error_band(threshold_fit_x, threshold_fit_y_val, threshold_fit_y_err)) # Compare ratios of damped and normal power in the overlap range. ratio_dist = [] x = np.linspace(70.1e-3, 86.9e-3, 20) for norm_power, damp_power in zip(norm_power_dist, damp_power_dist): norm_inter = scipy.interpolate.interp1d(norm_current, norm_power) damp_inter = scipy.interpolate.interp1d(damp_current, damp_power) a = norm_inter(x) b = damp_inter(x) ratio = a / b ratio_dist.append(ratio) ratio_val, ratio_err = bootstrap.average_and_std_arrays(ratio_dist) extinction_dist = np.array(ratio_dist).flatten() extinction_val, extinction_err = np.mean(ratio_dist), np.std(ratio_dist) T['extinction'] = siunitx(extinction_val, extinction_err) np.savetxt('_build/xy/diode-ratio-line.tsv', np.column_stack([x, ratio_val])) np.savetxt('_build/xy/diode-ratio-band.tsv', bootstrap.pgfplots_error_band(x, ratio_val, ratio_err)) return extinction_dist
def bootstrap_driver(T): # Load all the input data from the files. lum_data = np.loadtxt('Data/luminosity.txt') lum_val = lum_data[:, 0] lum_err = lum_data[:, 3] radiative_hadrons = np.loadtxt('Data/radiative-hadrons.tsv') radiative_leptons = np.loadtxt('Data/radiative-leptons.tsv') raw_matrix = np.loadtxt('Data/matrix.txt').T mc_sizes = np.loadtxt('Data/monte-carlo-sizes.txt') filtered = np.loadtxt('Data/filtered.txt') # Some output into the template. T['luminosities_table'] = list(zip(siunitx(energies), siunitx(lum_val, lum_err))) T['radiative_cs_table'] = list(zip( siunitx(energies), siunitx(radiative_hadrons), siunitx(radiative_leptons), )) # Container for the results of each bootstrap run. results = [] for r in range(SAMPLES): # Draw new numbers for the matrix. boot_matrix = bootstrap.redraw_count(raw_matrix) # Draw new luminosities. boot_lum_val = np.array([ random.gauss(val, err) for val, err in zip(lum_val, lum_err)]) # Draw new filtered readings. boot_readings = bootstrap.redraw_count(filtered) # Run the analysis on the resampled data and save the results. results.append(bootstrap_kernel(mc_sizes, boot_matrix, boot_readings, boot_lum_val, radiative_hadrons, radiative_leptons)) # The `results` is a list which contains one entry per bootstrap run. This # is not particularly helpful as the different interesting quantities are # only on the second index on the list. The first index of the `results` # list is the bootstrap run index. Therefore we use the `zip(*x)` trick to # exchange the two indices. The result will be a list of quantities which # are themselves lists of the bootstrap samples. Then using Python tuple # assignments, we can split that (now) outer list into different # quantities. Each of the new variables created here is a list of R # bootstrap samples. x_dist, masses_dist, widths_dist, cross_sections_dist, y_dist, corr_dist, \ matrix_dist, inverted_dist, readings_dist, peaks_dist, brs_dist, \ width_electron_dist, width_flavors_dist, missing_width_dist, \ width_lepton_dist, neutrino_families_dist, popts_dist, \ mean_mass_dist, mean_width_dist \ = zip(*results) # We only need one of the lists of the x-values as they are all the same. # So take the first and throw the others out. x = x_dist[0] # The masses and the widths that are given back from the `bootstrap_kernel` # are a list of four elements (electrons, muons, tauons, hadrons) each. The # variable `masses_dist` contains R copies of this four-list, one copy for # each bootstrap sample. We now average along the bootstrap dimension, that # is the outermost dimension. For each of the four masses, we take the # average along the R copies. This will give us four masses and four # masses-errors. masses_val, masses_err = bootstrap.average_and_std_arrays(masses_dist) widths_val, widths_err = bootstrap.average_and_std_arrays(widths_dist) peaks_val, peaks_err = bootstrap.average_and_std_arrays(peaks_dist) brs_val, brs_err = bootstrap.average_and_std_arrays(brs_dist) T['brs'] = siunitx(brs_val[0:3], brs_err[0:3]) # Format masses and widths for the template. T['lorentz_fits_table'] = list(zip( display_names, siunitx(masses_val, masses_err), siunitx(widths_val, widths_err), siunitx(peaks_val, peaks_err), )) width_electron_val, width_electron_err = bootstrap.average_and_std_arrays(width_electron_dist) width_flavors_val, width_flavors_err = bootstrap.average_and_std_arrays(width_flavors_dist) T['width_electron_mev'] = siunitx(width_electron_val*1000, width_electron_err*1000) T['width_flavors_mev'] = siunitx(width_flavors_val*1000, width_flavors_err*1000) missing_width_val, missing_width_err = bootstrap.average_and_std_arrays(missing_width_dist) width_lepton_val, width_lepton_err = bootstrap.average_and_std_arrays(width_lepton_dist) neutrino_families_val, neutrino_families_err = bootstrap.average_and_std_arrays(neutrino_families_dist) T['missing_width_mev'] = siunitx(missing_width_val*1000, missing_width_err*1000) T['width_lepton_mev'] = siunitx(width_lepton_val*1000, width_lepton_err*1000) T['neutrino_families'] = siunitx(neutrino_families_val, neutrino_families_err) # Format original counts for the template. val, err = bootstrap.average_and_std_arrays(readings_dist) T['counts_table'] = [] for i in range(7): T['counts_table'].append([siunitx(energies[i])] + siunitx(val[i, :], err[i, :], allowed_hang=10)) # Format corrected counts for the template. val, err = bootstrap.average_and_std_arrays(corr_dist) T['corrected_counts_table'] = [] for i in range(7): T['corrected_counts_table'].append([siunitx(energies[i])] + siunitx(val[i, :], err[i, :], allowed_hang=10)) # Format matrix for the template. matrix_val, matrix_err = bootstrap.average_and_std_arrays(matrix_dist) T['matrix'] = [] for i in range(4): T['matrix'].append([display_names[i]] + siunitx(matrix_val[i, :]*100, matrix_err[i, :]*100, allowed_hang=10)) # Format inverted matrix for the template. inverted_val, inverted_err = bootstrap.average_and_std_arrays(inverted_dist) T['inverted'] = [] for i in range(4): T['inverted'].append([display_names[i]] + list(map(number_padding, siunitx(inverted_val[i, :], inverted_err[i, :], allowed_hang=10)))) # Format cross sections for the template. cs_val, cs_err = bootstrap.average_and_std_arrays(cross_sections_dist) T['cross_sections_table'] = [] for i in range(7): T['cross_sections_table'].append([siunitx(energies[i])] + siunitx(cs_val[:, i], cs_err[:, i])) # Build error band for pgfplots. y_list_val, y_list_err = bootstrap.average_and_std_arrays(y_dist) for i, name in zip(itertools.count(), names): # Extract the y-values for the given decay type. y_val = y_list_val[i, :] y_err = y_list_err[i, :] # Store the data for pgfplots. np.savetxt('_build/xy/cross_section-{}s.tsv'.format(name), np.column_stack([energies, cs_val[i, :], cs_err[i, :]])) np.savetxt('_build/xy/cross_section-{}s-band.tsv'.format(name), bootstrap.pgfplots_error_band(x, y_val, y_err)) np.savetxt('_build/xy/cross_section-{}s-fit.tsv'.format(name), np.column_stack((x, y_val))) popts_val, popts_err = bootstrap.average_and_std_arrays(popts_dist) T['chi_sq'] = [] T['chi_sq_red'] = [] T['p'] = [] for i in range(4): residuals = cs_val[i, :] - propagator(energies, *popts_val[i, :]) chi_sq = np.sum((residuals / cs_err[i, :])**2) dof = len(residuals) - 1 - len(popts_val[i, :]) p = 1 - scipy.stats.chi2.cdf(chi_sq, dof) print('chi_sq', chi_sq, chi_sq/dof, p) T['chi_sq'].append(siunitx(chi_sq)) T['chi_sq_red'].append(siunitx(chi_sq/dof)) T['p'].append(siunitx(p)) T['confidence_table'] = list(zip( display_names, T['chi_sq'], T['chi_sq_red'], T['p'], )) mean_mass_val, mean_mass_err = bootstrap.average_and_std_arrays(mean_mass_dist) mean_width_val, mean_width_err = bootstrap.average_and_std_arrays(mean_width_dist) T['mean_mass'] = siunitx(mean_mass_val, mean_mass_err) T['mean_width'] = siunitx(mean_width_val, mean_width_err)
def bootstrap_driver(T): # Load all the input data from the files. lum_data = np.loadtxt('Data/luminosity.txt') lum_val = lum_data[:, 0] lum_err = lum_data[:, 3] radiative_hadrons = np.loadtxt('Data/radiative-hadrons.tsv') radiative_leptons = np.loadtxt('Data/radiative-leptons.tsv') raw_matrix = np.loadtxt('Data/matrix.txt').T mc_sizes = np.loadtxt('Data/monte-carlo-sizes.txt') filtered = np.loadtxt('Data/filtered.txt') # Some output into the template. T['luminosities_table'] = list( zip(siunitx(energies), siunitx(lum_val, lum_err))) T['radiative_cs_table'] = list( zip( siunitx(energies), siunitx(radiative_hadrons), siunitx(radiative_leptons), )) # Container for the results of each bootstrap run. results = [] for r in range(SAMPLES): # Draw new numbers for the matrix. boot_matrix = bootstrap.redraw_count(raw_matrix) # Draw new luminosities. boot_lum_val = np.array( [random.gauss(val, err) for val, err in zip(lum_val, lum_err)]) # Draw new filtered readings. boot_readings = bootstrap.redraw_count(filtered) # Run the analysis on the resampled data and save the results. results.append( bootstrap_kernel(mc_sizes, boot_matrix, boot_readings, boot_lum_val, radiative_hadrons, radiative_leptons)) # The `results` is a list which contains one entry per bootstrap run. This # is not particularly helpful as the different interesting quantities are # only on the second index on the list. The first index of the `results` # list is the bootstrap run index. Therefore we use the `zip(*x)` trick to # exchange the two indices. The result will be a list of quantities which # are themselves lists of the bootstrap samples. Then using Python tuple # assignments, we can split that (now) outer list into different # quantities. Each of the new variables created here is a list of R # bootstrap samples. x_dist, masses_dist, widths_dist, cross_sections_dist, y_dist, corr_dist, \ matrix_dist, inverted_dist, readings_dist, peaks_dist, brs_dist, \ width_electron_dist, width_flavors_dist, missing_width_dist, \ width_lepton_dist, neutrino_families_dist, popts_dist, \ mean_mass_dist, mean_width_dist \ = zip(*results) # We only need one of the lists of the x-values as they are all the same. # So take the first and throw the others out. x = x_dist[0] # The masses and the widths that are given back from the `bootstrap_kernel` # are a list of four elements (electrons, muons, tauons, hadrons) each. The # variable `masses_dist` contains R copies of this four-list, one copy for # each bootstrap sample. We now average along the bootstrap dimension, that # is the outermost dimension. For each of the four masses, we take the # average along the R copies. This will give us four masses and four # masses-errors. masses_val, masses_err = bootstrap.average_and_std_arrays(masses_dist) widths_val, widths_err = bootstrap.average_and_std_arrays(widths_dist) peaks_val, peaks_err = bootstrap.average_and_std_arrays(peaks_dist) brs_val, brs_err = bootstrap.average_and_std_arrays(brs_dist) T['brs'] = siunitx(brs_val[0:3], brs_err[0:3]) # Format masses and widths for the template. T['lorentz_fits_table'] = list( zip( display_names, siunitx(masses_val, masses_err), siunitx(widths_val, widths_err), siunitx(peaks_val, peaks_err), )) width_electron_val, width_electron_err = bootstrap.average_and_std_arrays( width_electron_dist) width_flavors_val, width_flavors_err = bootstrap.average_and_std_arrays( width_flavors_dist) T['width_electron_mev'] = siunitx(width_electron_val * 1000, width_electron_err * 1000) T['width_flavors_mev'] = siunitx(width_flavors_val * 1000, width_flavors_err * 1000) missing_width_val, missing_width_err = bootstrap.average_and_std_arrays( missing_width_dist) width_lepton_val, width_lepton_err = bootstrap.average_and_std_arrays( width_lepton_dist) neutrino_families_val, neutrino_families_err = bootstrap.average_and_std_arrays( neutrino_families_dist) T['missing_width_mev'] = siunitx(missing_width_val * 1000, missing_width_err * 1000) T['width_lepton_mev'] = siunitx(width_lepton_val * 1000, width_lepton_err * 1000) T['neutrino_families'] = siunitx(neutrino_families_val, neutrino_families_err) # Format original counts for the template. val, err = bootstrap.average_and_std_arrays(readings_dist) T['counts_table'] = [] for i in range(7): T['counts_table'].append( [siunitx(energies[i])] + siunitx(val[i, :], err[i, :], allowed_hang=10)) # Format corrected counts for the template. val, err = bootstrap.average_and_std_arrays(corr_dist) T['corrected_counts_table'] = [] for i in range(7): T['corrected_counts_table'].append( [siunitx(energies[i])] + siunitx(val[i, :], err[i, :], allowed_hang=10)) # Format matrix for the template. matrix_val, matrix_err = bootstrap.average_and_std_arrays(matrix_dist) T['matrix'] = [] for i in range(4): T['matrix'].append([display_names[i]] + siunitx( matrix_val[i, :] * 100, matrix_err[i, :] * 100, allowed_hang=10)) # Format inverted matrix for the template. inverted_val, inverted_err = bootstrap.average_and_std_arrays( inverted_dist) T['inverted'] = [] for i in range(4): T['inverted'].append([display_names[i]] + list( map( number_padding, siunitx( inverted_val[i, :], inverted_err[i, :], allowed_hang=10)))) # Format cross sections for the template. cs_val, cs_err = bootstrap.average_and_std_arrays(cross_sections_dist) T['cross_sections_table'] = [] for i in range(7): T['cross_sections_table'].append([siunitx(energies[i])] + siunitx(cs_val[:, i], cs_err[:, i])) # Build error band for pgfplots. y_list_val, y_list_err = bootstrap.average_and_std_arrays(y_dist) for i, name in zip(itertools.count(), names): # Extract the y-values for the given decay type. y_val = y_list_val[i, :] y_err = y_list_err[i, :] # Store the data for pgfplots. np.savetxt('_build/xy/cross_section-{}s.tsv'.format(name), np.column_stack([energies, cs_val[i, :], cs_err[i, :]])) np.savetxt('_build/xy/cross_section-{}s-band.tsv'.format(name), bootstrap.pgfplots_error_band(x, y_val, y_err)) np.savetxt('_build/xy/cross_section-{}s-fit.tsv'.format(name), np.column_stack((x, y_val))) popts_val, popts_err = bootstrap.average_and_std_arrays(popts_dist) T['chi_sq'] = [] T['chi_sq_red'] = [] T['p'] = [] for i in range(4): residuals = cs_val[i, :] - propagator(energies, *popts_val[i, :]) chi_sq = np.sum((residuals / cs_err[i, :])**2) dof = len(residuals) - 1 - len(popts_val[i, :]) p = 1 - scipy.stats.chi2.cdf(chi_sq, dof) print('chi_sq', chi_sq, chi_sq / dof, p) T['chi_sq'].append(siunitx(chi_sq)) T['chi_sq_red'].append(siunitx(chi_sq / dof)) T['p'].append(siunitx(p)) T['confidence_table'] = list( zip( display_names, T['chi_sq'], T['chi_sq_red'], T['p'], )) mean_mass_val, mean_mass_err = bootstrap.average_and_std_arrays( mean_mass_dist) mean_width_val, mean_width_err = bootstrap.average_and_std_arrays( mean_width_dist) T['mean_mass'] = siunitx(mean_mass_val, mean_mass_err) T['mean_width'] = siunitx(mean_width_val, mean_width_err)