def center_check(data_list): x_axis_mm = np.linspace(-23, 23, 2**9) r_axis_mm = np.linspace(0, 23, 2**9 + 1)[1::2] th_axis_rad = np.linspace(0, np.pi * 2, 2**9 + 1)[1::2] xy_center_slice = slice(x_axis_mm.searchsorted(-1), x_axis_mm.searchsorted(1, side='right')) x = [] y = [] r = [] th = [] for data in data_list: x.extend(data.electrons.pos_x.value) y.extend(data.electrons.pos_y.value) if np.any(data.electrons.pos_t.value > np.pi * 2): data.electrons.recalculate_polar_coordinates() r.extend(data.electrons.pos_r.value) th.extend(data.electrons.pos_t.value) image_xy = epicea.center_histogram_2d(x, y, x_axis_mm) x_slice = image_xy[xy_center_slice, :].sum(axis=0) y_slice = image_xy[:, xy_center_slice].sum(axis=1) image_rt = epicea.center_histogram_2d(r, th, r_axis_mm, th_axis_rad) plt_func.figure_wrapper('Electron data {} eV pass'.format( data_list[0].electron_center_energy())) plt.subplot(231) plt_func.imshow_wrapper(image_xy, x_axis_mm) plt.subplot(234) plt_func.imshow_wrapper(image_rt, r_axis_mm, th_axis_rad, kw_args={'aspect': 'auto'}) plt.subplot(132) plt.plot(x_axis_mm, x_slice, label='normal') plt.plot(x_axis_mm[::-1], x_slice, label='flipped') plt_func.title_wrapper('x slice') plt_func.legend_wrapper() plt.xlim(xmin=7) plt.subplot(133) plt.plot(x_axis_mm, y_slice, label='normal') plt.plot(x_axis_mm[::-1], y_slice, label='flipped') plt_func.title_wrapper('y slice') plt_func.legend_wrapper() plt.xlim(xmin=7)
def get_r_theta_image(dataset, r_axis_mm, th_axis_rad, gas, *, plot=False, verbose=False, fig=None): data_name = dataset.name() if verbose: print('Get the theta-r spectrum for {}.'.format(data_name), flush=True) # Get the image fron the data in polar coordinates e_rth_image, e_rth_image_time_stamp = \ dataset.get_e_rth_image(r_axis_mm, th_axis_rad, verbose=False) if plot: if verbose: print('Plot the raw theta r image of', data_name) if fig is None: # Make the figure rth_fig = plt_func.figure_wrapper( 'e spectra theta-r {}'.format(data_name)) else: rth_fig = fig ax1 = rth_fig.add_subplot(131) # Show the image plt_func.imshow_wrapper(e_rth_image, r_axis_mm, th_axis_rad, kw_args={'aspect': 'auto'}) # Make the image look nice plt_func.tick_fontsize() plt_func.title_wrapper('original ' + dataset.name()) plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Angle (rad)') # plt_func.colorbar_wrapper() rth_fig.add_subplot(132, sharex=ax1, sharey=ax1) ax3 = rth_fig.add_subplot(133, sharex=ax1) ax3.plot(r_axis_mm, e_rth_image.sum(axis=0)) else: rth_fig = None return e_rth_image, e_rth_image_time_stamp, rth_fig
def plot_combined_e_spec(data_list, verbose=False): full_fig = plt_func.figure_wrapper('all electrons') full_412_ax = full_fig.add_subplot(211) full_430_ax = full_fig.add_subplot(212, sharex=full_412_ax) nn_o_fig = plt_func.figure_wrapper('NN + O') nn_o_412_ax = nn_o_fig.add_subplot(211, sharex=full_412_ax) nn_o_430_ax = nn_o_fig.add_subplot(212, sharex=full_412_ax) no_n_fig = plt_func.figure_wrapper('NO + N') no_n_412_ax = no_n_fig.add_subplot(211, sharex=full_412_ax) no_n_430_ax = no_n_fig.add_subplot(212, sharex=full_412_ax) with_fig = plt_func.figure_wrapper('energy uncertainty') with_ax = None with_ax_list = [] e_axis_ev = np.linspace(343, 376, 2**9 + 1)[1::2] w_axis_ev = np.linspace(0, 0.5, 2**10 + 1)[1::2] for i_data, data in enumerate(data_list): with_ax = with_fig.add_subplot(2, 3, i_data + 1, sharex=with_ax) with_ax_list.append(with_ax) hist = epicea.center_histogram(data.electrons.energy_uncertainty, w_axis_ev) with_ax.semilogy(w_axis_ev, hist) plt_func.title_wrapper(data.name()) detector_angle_filter = data.get_filter( 'detector_angle', filter_function=epicea.ff.electron_angle_range, filter_kw_params={'angle_range_list': [0, 7]}, verbose=verbose, update=True) uncertainty_filter_electrons = data.get_filter( 'energy_uncertainty_inf', filter_function=epicea.ff.electron_energy_uncertainty, filter_kw_params={'max_uncertainty': np.inf}, verbose=verbose, update=True) uncertainty_filter_electrons *= detector_angle_filter NN_O_events_electrons = data.get_filter('NN_O_events_electrons', verbose=verbose) NN_O_events_electrons *= detector_angle_filter NO_N_events_electrons = data.get_filter('NO_N_events_electrons', verbose=verbose) NO_N_events_electrons *= detector_angle_filter e_energy_dist, _ = data.get_e_spectrum( e_axis_ev, electrons_filter=uncertainty_filter_electrons, verbose=verbose) e_NN_O_energy_dist, _ = data.get_e_spectrum( e_axis_ev, electrons_filter=NN_O_events_electrons, verbose=verbose) e_NO_N_energy_dist, _ = data.get_e_spectrum( e_axis_ev, electrons_filter=NO_N_events_electrons, verbose=verbose) ax_nn_o, ax_no_n, ax_full = ((nn_o_412_ax, no_n_412_ax, full_412_ax) if data.photon_energy() == 412 else (nn_o_430_ax, no_n_430_ax, full_430_ax)) ax_full.plot(e_axis_ev, e_energy_dist, '.-', label='full {}'.format(data.name())) ax_nn_o.plot(e_axis_ev, e_NN_O_energy_dist, '.-', label=r'N$_2$$^+$ + O$^+$ {}'.format(data.name())) ax_no_n.plot(e_axis_ev, e_NO_N_energy_dist, '.-', label=r'NO$^+$ + N$^+$ {}'.format(data.name())) grifith_img = imread('Grif2.jpg') for ax in [ nn_o_412_ax, nn_o_430_ax, no_n_412_ax, no_n_430_ax, full_412_ax, full_430_ax ]: y_extent = ax.get_ylim()[1] * 1.05 ax.imshow(grifith_img, aspect='auto', extent=(335, 379.65, -0.044 * y_extent, y_extent)) plt.sca(ax) plt.legend(loc='best') plt.xlabel('auger energu (eV)') plt.ylabel('signal (arb. u)') # plt_func.legend_wrapper(ax) full_fig.savefig('first_look_figures/full_spectra.pdf') nn_o_fig.savefig('first_look_figures/nn_o_spectra.pdf') no_n_fig.savefig('first_look_figures/no_n_spectra.pdf')
def plot_e_spec(data, verbose=False): """First view of the electron spectra.""" if verbose: print('Plotting electron spectra for {}.'.format(data.name())) plt_func.figure_wrapper('Electron data {}'.format(data.name())) valid_pos = data.get_filter('has_position_electrons', verbose=verbose) NN_O_events_electrons = data.get_filter('NN_O_events_electrons', verbose=verbose) NO_N_events_electrons = data.get_filter('NO_N_events_electrons', verbose=verbose) if verbose: print('Valid positions for {} electrons.'.format(valid_pos.sum())) x_axis_mm = np.linspace(-23, 23, 512) r_axis_mm = np.linspace(0, 23, 513)[1::2] th_axis_rad = np.linspace(0, 2 * np.pi, 513)[1::2] xy_center_slice = slice(x_axis_mm.searchsorted(-3), x_axis_mm.searchsorted(3, side='right')) e_axis_ev = np.linspace(320, 380, 2**8 + 1)[1::2] # e_all_image_xy = data.get_e_xy_image(x_axis_mm, verbose=verbose) e_all_image_xy, _ = data.get_e_xy_image( x_axis_mm, verbose=verbose, electrons_filter=data.electrons.event_id.value > 0.9 * data.events.len()) e_all_x_slice = e_all_image_xy[xy_center_slice, :].sum(axis=0) e_all_y_slice = e_all_image_xy[:, xy_center_slice].sum(axis=1) # e_all_image_rth = data.get_e_rth_image(r_axis_mm, th_axis_rad, # verbose=verbose) e_all_image_rth, _ = data.get_e_rth_image( r_axis_mm, th_axis_rad, verbose=verbose, electrons_filter=data.electrons.event_id.value > 0.9 * data.events.len()) e_all_radial_dist = e_all_image_rth.sum(axis=0) # e_NN_O_image_xy = data.get_e_xy_image( # x_axis_mm, electrons_filter=NN_O_events_electrons) # e_NO_N_image_xy = data.get_e_xy_image( # x_axis_mm, electrons_filter=NO_N_events_electrons) e_NN_O_image_rth, _ = data.get_e_rth_image( r_axis_mm, th_axis_rad, electrons_filter=NN_O_events_electrons, verbose=verbose) e_NN_O_radial_dist = e_NN_O_image_rth.sum(axis=0) e_NO_N_image_rth, _ = data.get_e_rth_image( r_axis_mm, th_axis_rad, electrons_filter=NO_N_events_electrons, verbose=verbose) e_NO_N_radial_dist = e_NO_N_image_rth.sum(axis=0) e_NN_O_energy_dist, _ = data.get_e_spectrum( e_axis_ev, electrons_filter=NN_O_events_electrons, verbose=verbose) e_NO_N_energy_dist, _ = data.get_e_spectrum( e_axis_ev, electrons_filter=NO_N_events_electrons, verbose=verbose) plt.subplot(231) plt_func.imshow_wrapper(e_all_image_xy, x_axis_mm) plt_func.title_wrapper('2D image') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Position (mm)') plt_func.tick_fontsize() plt.subplot(437) plt.plot(x_axis_mm, e_all_x_slice, label='normal') plt.plot(x_axis_mm[::-1], e_all_x_slice, label='flipped') plt_func.title_wrapper('x slice') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Number of ions') plt_func.tick_fontsize() plt_func.legend_wrapper() plt.subplot(4, 3, 10) plt.plot(x_axis_mm, e_all_y_slice, label='normal') plt.plot(x_axis_mm[::-1], e_all_y_slice, label='flipped') plt_func.title_wrapper('y slice') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Number of ions') plt_func.tick_fontsize() plt_func.legend_wrapper() plt.subplot(232) plt_func.imshow_wrapper(e_all_image_rth, r_axis_mm, th_axis_rad, kw_args={'aspect': 'auto'}) plt_func.title_wrapper('2D image') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Angle (rad)') plt_func.tick_fontsize() plt.subplot(235) plt.plot(r_axis_mm, e_all_radial_dist) plt_func.title_wrapper('Radial distribution') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Number of electrons') plt_func.tick_fontsize() # plt.subplot(233) # plt_func.imshow_wrapper(e_NN_O_image_xy, x_axis_mm) # plt_func.title_wrapper('NN+ O+ events') # plt_func.xlabel_wrapper('Position (mm)') # plt_func.ylabel_wrapper('Position (mm)') # plt_func.tick_fontsize() # # plt.subplot(236) # plt_func.imshow_wrapper(e_NO_N_image_xy, x_axis_mm) # plt_func.title_wrapper('NO+ N+ events') # plt_func.xlabel_wrapper('Position (mm)') # plt_func.ylabel_wrapper('Position (mm)') # plt_func.tick_fontsize() # # plt.subplot(233) # plt_func.imshow_wrapper(e_NN_O_image_rth, r_axis_mm, th_axis_rad) # plt_func.title_wrapper('NN+ O+ events') # plt_func.xlabel_wrapper('Position (mm)') # plt_func.ylabel_wrapper('Angle (rad)') # plt_func.tick_fontsize() # # plt.subplot(236) # plt_func.imshow_wrapper(e_NO_N_image_rth, r_axis_mm, th_axis_rad) # plt_func.title_wrapper('NO+ N+ events') # plt_func.xlabel_wrapper('Position (mm)') # plt_func.ylabel_wrapper('Angle (rad)') # plt_func.tick_fontsize() plt.subplot(233) plt.plot(r_axis_mm, e_NN_O_radial_dist, 'y', label=r'N$_2$$^+$ + O$^+$') plt.plot(r_axis_mm, e_NO_N_radial_dist, 'm', label=r'NO$^+$ + N$^+$') plt_func.title_wrapper('on radial grid') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Number of electrons') plt_func.tick_fontsize() plt_func.legend_wrapper() plt.subplot(236) plt.plot(e_axis_ev, e_NN_O_energy_dist, 'y', label=r'N$_2$$^+$ + O$^+$') plt.plot(e_axis_ev, e_NO_N_energy_dist, 'm', label=r'NO$^+$ + N$^+$') plt_func.title_wrapper('On an energy grid') plt_func.xlabel_wrapper('Energy (eV)') plt_func.ylabel_wrapper('Number of electrons') plt_func.tick_fontsize() plt_func.legend_wrapper() plt.tight_layout() plt_func.savefig_wrapper()
def plot_two_ion_corelations(data, verbose=False): if verbose: print('In plot_two_ion_corelations.') # Get some ions filters data.get_filter('two_ions_events_ions') double_ions_e_start = data.get_filter('two_ion_e_start_events_ions') data.get_filter('two_ion_rand_start_events_ions') NN_O_events_ions = data.get_filter('NN_O_events_ions', verbose=verbose) NO_N_events_ions = data.get_filter('NO_N_events_ions', verbose=verbose) # Plot distribution of nomber of ions num_ions = data.events.num_i.value num_ions_axis = np.arange(5) hist_ions_all = epicea.center_histogram(num_ions, num_ions_axis) hist_ions_e_start = epicea.center_histogram( num_ions[data.get_filter('e_start_events')], num_ions_axis) hist_ions_rand_start = epicea.center_histogram( num_ions[data.get_filter('rand_start_events')], num_ions_axis) plt_func.figure_wrapper('Two-ion correlations {}'.format(data.name())) plt.subplot(221) plt.plot(num_ions_axis, hist_ions_all, 'o-', label='All events') plt.plot(num_ions_axis, hist_ions_rand_start, 'o-', label='random start') plt.plot(num_ions_axis, hist_ions_e_start, 'o-', label='e start') plt_func.legend_wrapper() plt_func.title_wrapper('Ion number distributions.') plt_func.xlabel_wrapper('Number of ions per event') plt_func.ylabel_wrapper('Number of events') plt_func.tick_fontsize() # Look at some two ions, e start event correlations # Angle information # plt_func.figure_wrapper('two ion angles {}'.format(data.name())) plt.subplot(222) if verbose: print('Get angles.') th_e_start = data.ions.pos_t[double_ions_e_start] th_NN_O = data.ions.pos_t[NN_O_events_ions] th_NO_N = data.ions.pos_t[NO_N_events_ions] th_axis_rad = np.linspace(0, np.pi, 513)[1::2] th_hist_e_start, th_diff_e_start = calc_angle_diffs_hist( th_e_start, th_axis_rad) th_hist_NN_O, _ = calc_angle_diffs_hist(th_NN_O, th_axis_rad) th_hist_NO_N, _ = calc_angle_diffs_hist(th_NO_N, th_axis_rad) plt_func.bar_wrapper(th_axis_rad, th_hist_e_start, label='e start ion pairs') sl = slice(th_axis_rad.searchsorted(ANGLE_CUT), None) plt_func.bar_wrapper(th_axis_rad[sl], th_hist_e_start[sl], 'r', label='selection') plt_func.bar_wrapper(th_axis_rad, th_hist_NN_O, 'y', label='NN+ O+ ion pairs') plt_func.bar_wrapper(th_axis_rad, th_hist_NO_N, 'm', label='NO+ N+ ion pairs') # plt.hist(angle_diff[np.isfinite(angle_diff)], # bins=np.linspace(-0.1, np.pi, 256)) plt_func.xlabel_wrapper('Angle difference between tow ions (rad)') plt_func.ylabel_wrapper('Number of ion pairs') plt_func.title_wrapper('Two ion angles.') plt_func.legend_wrapper() plt_func.tick_fontsize() if verbose: print('{} events with two ions and electron start identified.'.format( data.get_filter('two_ion_e_start_events').sum())) print('{} valid angle diffs found.'.format(th_hist_e_start.sum())) # Radial information # plt_func.figure_wrapper('radii {}'.format(data.name())) plt.subplot(223) if verbose: print('Get radii.') r_frac_axis = np.linspace(1., 3.5, 257)[1::2] r_e_start = data.ions.pos_r[double_ions_e_start] r_NN_O = data.ions.pos_r[NN_O_events_ions] r_NO_N = data.ions.pos_r[NO_N_events_ions] r_frac_e_start_hist = calc_radius_fraction_hist(r_e_start, r_frac_axis) r_frac_selection_hist = calc_radius_fraction_hist( r_e_start.reshape(-1, 2)[th_diff_e_start > ANGLE_CUT, :], r_frac_axis) r_frac_NN_O_hist = calc_radius_fraction_hist(r_NN_O, r_frac_axis) r_frac_NO_N_hist = calc_radius_fraction_hist(r_NO_N, r_frac_axis) plt_func.bar_wrapper(r_frac_axis, r_frac_e_start_hist, label='e start') plt_func.bar_wrapper(r_frac_axis, r_frac_selection_hist, 'r', label='selection') plt_func.bar_wrapper(r_frac_axis, r_frac_NN_O_hist, 'y', label='NN+ O+ ions') plt_func.bar_wrapper(r_frac_axis, r_frac_NO_N_hist, 'm', label='NO+ N+ ions') # plt.hist(r_frac, bins=np.linspace(0.9, 3., 256)) plt_func.xlabel_wrapper('Radial quotient for two ions r1/r2') plt_func.ylabel_wrapper('Number of ion pairs') plt_func.title_wrapper('Radius quotient') plt_func.legend_wrapper() plt_func.tick_fontsize() plt_func.savefig_wrapper() ########################### # TOF-TOF correlation plot plt_func.figure_wrapper('tof-tof hist {}'.format(data.name())) t_axis_us = np.linspace(3.3, 5.3, 512) t_axis = t_axis_us * 1e6 # names = ['e start', 'all', 'random start'] # for i, ions_filter in enumerate([double_ions_e_start, # double_ions, # double_ions_rand_start]): # plt.subplot(2, 2, i+1) names = ['electrons'] for i, ions_filter in enumerate([double_ions_e_start]): i_tof = data.ions.tof_falling_edge[ions_filter] i_tof = i_tof.reshape(-1, 2) i_tof.sort(axis=1) i_tof = i_tof[np.isfinite(i_tof).sum(1) == 2, :] tof_tof_hist = epicea.center_histogram_2d(i_tof[:, 0], i_tof[:, 1], t_axis) tof_tof_sym_hist = tof_tof_hist + tof_tof_hist.T # plt_func.imshow_wrapper(tof_tof_sym_hist, t_axis_us) plt_func.imshow_wrapper(np.log(tof_tof_sym_hist + 1), t_axis_us) # plt.plot(t_axis_us, # glob.NN_O_TIME_SUM_RANGE_US[data.name()][0] - t_axis_us, # 'y', label='NN+ O+ selection') # plt.plot(t_axis_us, # glob.NN_O_TIME_SUM_RANGE_US[data.name()][1] - t_axis_us, # 'y') # plt.plot(t_axis_us, # glob.NN_O_TIME_DIFF_RANGE_US[data.name()][0] + t_axis_us, # 'y') # plt.plot(t_axis_us, # glob.NN_O_TIME_DIFF_RANGE_US[data.name()][1] + t_axis_us, # 'y') for sum_range, diff_range, label, c in zip([ glob.NO_N_TIME_SUM_RANGE_US[data.name()], glob.NN_O_TIME_SUM_RANGE_US[data.name()] ], [ glob.NO_N_TIME_DIFF_RANGE_US[data.name()], glob.NN_O_TIME_DIFF_RANGE_US[data.name()] ], ['NO+ N+ selection', 'NN+ O+ selection'], ['m', 'y']): s = sum_range[[0, 1, 1, 0, 0]] d = diff_range[[1, 1, 0, 0, 1]] x = (s - d) / 2 y = (s + d) / 2 plt.plot(x, y, c, label=label) plt_func.title_wrapper(names[i]) plt.axis([ t_axis_us.min(), t_axis_us.max(), t_axis_us.min(), t_axis_us.max() ]) plt_func.ylabel_wrapper('Time of flight (us)') plt_func.xlabel_wrapper('Time of flight (us)') plt_func.legend_wrapper(loc='center right') plt_func.colorbar_wrapper('log(counts + 1)') plt_func.tick_fontsize() # if i == 0: # tof_tof_hist_e_start = tof_tof_sym_hist.copy() # if i == 2: # tof_tof_hist_random = tof_tof_sym_hist.copy() # # sl = slice(t_axis.searchsorted(5.5e6)) # factor = (tof_tof_hist_e_start[sl, :].sum() / # tof_tof_hist_random[sl, :].sum()) # pure = tof_tof_hist_e_start - tof_tof_hist_random * factor # # plt.subplot(224) # plt_func.imshow_wrapper(pure, t_axis_us) # plt_func.tick_fontsize() plt_func.savefig_wrapper()
def plot_ion_image(data, verbose=False): """Plot some ion images.""" if verbose: print('\nPlot some ion image data.') x_axis_mm = np.arange(-40, 40, 0.1) if verbose: print('Get full image.') i_image = data.get_i_xy_image(x_axis_mm) if verbose: print('Get e start image.') i_image_e_start = data.get_i_xy_image( x_axis_mm, ions_filter=data.get_filter('e_start_ions')) if verbose: print('Get rand start iage.') i_image_random_start = data.get_i_xy_image( x_axis_mm, ions_filter=~data.get_filter('e_start_ions')) plt_func.figure_wrapper('Ion image {}'.format(data.name())) plt.subplot(331) plt_func.imshow_wrapper(i_image, x_axis_mm) plt_func.title_wrapper('all ions') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Position (mm)') plt_func.colorbar_wrapper() plt_func.tick_fontsize() plt.subplot(332) plt_func.imshow_wrapper(i_image_e_start, x_axis_mm) plt_func.title_wrapper('electron start') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Position (mm)') plt_func.colorbar_wrapper() plt_func.tick_fontsize() plt.subplot(334) plt_func.imshow_wrapper(i_image_random_start, x_axis_mm) plt_func.title_wrapper('random start') plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Position (mm)') plt_func.colorbar_wrapper() plt_func.tick_fontsize() # Make a slice selection around the center of the image selection = slice(x_axis_mm.searchsorted(-5), x_axis_mm.searchsorted(5)) # Project along x and y x_projection = i_image_e_start[selection, :].sum(axis=0) y_projection = i_image_e_start[:, selection].sum(axis=1) plt.subplot(638) plt.plot(x_axis_mm, x_projection, label='normal') plt.plot(x_axis_mm[::-1], x_projection, label='reverse') plt_func.title_wrapper('x slice') plt_func.xlabel_wrapper('Position (mm)') plt_func.legend_wrapper() plt_func.tick_fontsize() plt.subplot(6, 3, 11) plt.plot(x_axis_mm, y_projection, label='nomral') plt.plot(x_axis_mm[::-1], y_projection, label='reversed') plt_func.title_wrapper('y slice') plt_func.xlabel_wrapper('Position (mm)') plt_func.legend_wrapper() plt_func.tick_fontsize() r_axis_mm = np.linspace(0, 40, 201)[1::2] th_axis_rad = np.linspace(0, 2 * np.pi, 513)[1::2] rt_image = data.get_i_rth_image(r_axis_mm=r_axis_mm, th_axis_rad=th_axis_rad) NN_O_ions = data.get_filter('NN_O_events_ions') NO_N_ions = data.get_filter('NO_N_events_ions') NN_O_rth_image = data.get_i_rth_image(r_axis_mm, th_axis_rad, ions_filter=NN_O_ions) NO_N_rth_image = data.get_i_rth_image(r_axis_mm, th_axis_rad, ions_filter=NO_N_ions) NN_O_r_proj = NN_O_rth_image.sum(axis=0) NO_N_r_proj = NO_N_rth_image.sum(axis=0) plt.subplot(333) plt_func.imshow_wrapper(rt_image, r_axis_mm, th_axis_rad, kw_args={'aspect': 'auto'}) plt_func.tick_fontsize() plt_func.title_wrapper('electron start polar') plt_func.xlabel_wrapper('Radius (mm)') plt_func.ylabel_wrapper('Angle (rad)') plt.subplot(336) r_projection = rt_image.sum(axis=0) plt.plot(r_axis_mm, r_projection, label='e start') plt_func.xlabel_wrapper('Radius (mm)') plt_func.ylabel_wrapper('Number of counts') plt_func.legend_wrapper() plt_func.tick_fontsize() plt.subplot(337) plt.plot(r_axis_mm, NN_O_r_proj, 'y', label='NN+ O+ ions') plt_func.xlabel_wrapper('Radius (mm)') plt_func.ylabel_wrapper('Number of counts') plt_func.legend_wrapper() plt_func.tick_fontsize() plt.subplot(338) r_projection = rt_image.sum(axis=0) plt.plot(r_axis_mm, NO_N_r_proj, 'm', label='NO+ N+ ions') plt_func.xlabel_wrapper('Radius (mm)') plt_func.ylabel_wrapper('Number of counts') plt_func.legend_wrapper() plt_func.tick_fontsize() plt_func.savefig_wrapper()
def make_calibration(setting, plot=True, verbose=False): """Make the electron calibration for a given center energy setting.""" # The Kr binding energies are needed for Kr based calibrations calibration_file_name = 'h5_data/calib_{}.h5'.format(setting) # Get the list of data sets calib_data_list = load_data_for_calibration(setting, verbose=verbose) if 'Kr' in calib_data_list[0].name(): gas = 'Kr' n_lines = 2 elif 'N2' in calib_data_list[0].name(): gas = 'N2' n_lines = 1 else: print('Unknown gas.', 'Dataset names must specify the used gas (N2 or Kr).') # Create an empty calibration object calibration = epicea.ElectronEnergyCalibration() # # Make an x axis # x_axis_mm = np.linspace(-23, 23, 2**8) # # Define polar coordinate axis vectors # r_axis_mm = np.linspace(0, 25, 2**7+1)[1::2] # th_axis_rad = np.linspace(0, 2*np.pi, 2**9+1)[1::2] if plot: # Create a plot of all the spectra in the data list if verbose: print('Plot all the raw spectra.') # Create the figure plt_func.figure_wrapper('Calibration spectra {} eV'.format(setting)) # One subplot for each data set... n_subplots = calib_data_list.len() # ... nicely set in collumns and rows n_rows = np.floor(np.sqrt(n_subplots)) n_cols = np.ceil(float(n_subplots) / n_rows) # Iterate over the datasets for i, c_data in enumerate(calib_data_list): plt.subplot(n_rows, n_cols, i + 1) # Make the subplot # Show the electron figure plt_func.imshow_wrapper( c_data.get_e_xy_image(x_axis_mm)[0], x_axis_mm) # Adjust the figure for good looks plt_func.tick_fontsize() plt_func.title_wrapper(c_data.name()) plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Position (mm)') # plt.tight_layout() # Keep track of the latest time stamp of the lines latest_lines = 0 rth_fig = {} straight_img = {} straight_img_time_stamp = {} radial_factors = {} # Iterate over the datasets and make images for each set. # Also find the lines in each of the spectra for i, c_data in enumerate(calib_data_list): d_name = c_data.name() ####################################### # Raw theta vs. r spectrum e_rth_image, e_rth_image_time_stamp, rth_fig[d_name] = \ get_r_theta_image(c_data, r_axis_mm, th_axis_rad, gas, plot=True, verbose=verbose, fig=None) ####################################### # radial factors radial_factors[d_name], radial_factors_time_stamp, _ = \ get_radial_factors(c_data, r_axis_mm, th_axis_rad, e_rth_image_time_stamp, gas, e_rth_image=e_rth_image, verbose=verbose) ####################################### # Straight image straight_img[d_name], straight_img_time_stamp[d_name], _= \ get_straight_image(c_data, r_axis_mm, th_axis_rad, radial_factors_time_stamp, gas, radial_factors=radial_factors[d_name], verbose=verbose, plot=plot, fig=rth_fig[d_name]) # Make sure the straight image is avaliable for all the calibration data # sets before making the background. # This is achieved by exiting the loop and starting a neew one. for i, c_data in enumerate(calib_data_list): d_name = c_data.name() ####################################### # N_2 background if gas == 'N2': if not background.check_bg_valid( setting, len(r_axis_mm), verbose=verbose): if verbose: print('Make new N2 background.', flush=True) background.make_new_bg(setting=setting, plot=plot, verbose=verbose) elif verbose: print('Use old N2 background.') n2_bg = (background.load_background(setting, len(r_axis_mm)) * c_data.data_scaling) kws = {'bg': n2_bg} else: n2_bg = None kws = {} ######## # do some plotting of the straight image projection and a fit to it if plot: plot_projections(rth_fig[d_name], c_data, straight_img[d_name], r_axis_mm, th_axis_rad, gas, n_lines, setting, verbose=verbose, **kws) ####################################### # Find lines r, w, a, red_chi2, lines_time_stamp = get_lines( c_data, r_axis_mm, th_axis_rad, n_lines, setting, max(straight_img_time_stamp.values()), gas, verbose=verbose, plot=plot, fig=rth_fig[d_name], straight_img=straight_img[d_name], radial_factors=radial_factors[d_name], n2_bg=n2_bg, calibration=calibration) # Keep the latest time stamp latest_lines = max(lines_time_stamp, latest_lines) print('Create calibration', flush=True) # calibration.create_conversion(poly_order=2) calibration.create_or_load_conversion(calibration_file_name, compare_time_stmp=max( latest_lines, 1444746720), poly_order=2, verbose=verbose) print('Check the calibration', flush=True) plt_func.figure_wrapper('Calib data check') theta_list, data_list = calibration.get_data_copy() r_min = data_list[:, :, 0].min() r_max = data_list[:, :, 0].max() r_axis_for_calib_check_mm = np.linspace(r_min + (r_min - r_max) * 0.0, r_max + (r_max - r_min) * 0.0, 256) for idx in range(0, len(theta_list), int(np.ceil(float(len(theta_list)) / 20))): plt.subplot(121) plt.plot(data_list[:, idx, 0], data_list[:, idx, 1], '.:') # plt.plot(r_axis_for_calib_check_mm, # epicea.poly_line(calibration._energy_params_list[idx], # r_axis_for_calib_check_mm), 'r') plt.plot( r_axis_for_calib_check_mm, epicea.electron_calibration_helper.r_to_e_conversion( calibration._energy_params_list[idx], r_axis_for_calib_check_mm), 'r') plt.subplot(122) shift = 0.1 * idx plt.plot(data_list[:, idx, 0], 1. / data_list[:, idx, 3] + shift, '.:') # plt.plot(r_axis_for_calib_check_mm, # epicea.poly_line(calibration._weights_params_list[idx], # r_axis_for_calib_check_mm) + shift, 'r') plt.plot(data_list[..., 0].mean(1), 1. / data_list[..., 3].mean(1), 'k', lw=2) a, b = ((338, 368) if setting == 357 else (359, 368) if setting == 366 else (366, 376) if setting == 373 else (480, 508)) E_axis_eV = np.linspace(a, b, 2**9 + 1)[1::2] E_all = [] err_all = [] theta_all = [] weight_all = [] for c_data in calib_data_list: print('Get the calibrated energies, {} eV.'.format( c_data.photon_energy()), flush=True) c_data.calculate_electron_energy(calibration, verbose=verbose) # E, err, weigths = calibration.get_energies(c_data.electrons.pos_r, # c_data.electrons.pos_t) E_all.extend(c_data.electrons.energy.value) err_all.extend(c_data.electrons.energy_uncertainty.value) theta_all.extend(c_data.electrons.pos_t.value) weight_all.extend(c_data.electrons.spectral_weight.value) plt_func.figure_wrapper('Energy domain all calibration data') ax = plt.subplot(211) E_image = epicea.center_histogram_2d(E_all, theta_all, E_axis_eV, th_axis_rad, weights=weight_all) plt_func.imshow_wrapper(E_image, E_axis_eV, th_axis_rad, kw_args={'aspect': 'auto'}) plt.subplot(212, sharex=ax) plt.plot(E_axis_eV, E_image.sum(0)) plt.grid(True) calibration.save_to_file(calibration_file_name)
def plot_projections(fig, data, straight_img, r_axis_mm, th_axis_rad, gas, n_lines, setting, *, verbose=False, **kws): # Get the projection r_projection = straight_img.sum(axis=0) params, fit_funk, kws, method = \ epicea.electron_calibration_helper.get_params_and_funktion( setting, gas, r_axis_mm, r_projection, bg=(kws['bg'] if 'bg' in kws else None)) # parameters for the two line fit # line_type = {'line_type': 'voigt'} # if gas == 'Kr': # params_r_proj = \ # epicea.electron_calibration_helper.start_params( # x=r_axis_mm, y=r_projection, # n_lines=n_lines, # **line_type) # fit_funk = epicea.electron_calibration_helper.n_line_fit_model # elif gas == 'N2': # # get start parameters # if setting == 500: # params_r_proj = skewed_gauss_for_500_eV_start_params( # r_axis_mm, r_projection, bg=True) ## params_r_proj['bg_factor'].value = 1 # fit_funk = skewed_gauss_for_500_eV # else: # params_r_proj = n_voigt_with_bg_start_params( # r_axis_mm, r_projection, # n_lines=1, bg=True) # if 'bg_factor' in params_r_proj: # params_r_proj['bg_factor'].vary = False # fit_funk = n_voigt_with_bg_model # do the fit leastsq_kws = {} res = lmfit.minimize(fit_funk, params, args=(r_axis_mm, r_projection), kws=kws, method=method, **leastsq_kws) # ci = lmfit.conf_interval(res) if verbose: print('\nProjection fit report for {}.'.format(data.name())) # Not sure what is in the MinimizerResult, wrap stuff in try statements try: print(res.message) except: pass try: print(res.ier) except: pass try: print(res.lmdif_message) except: pass lmfit.report_fit(res) # lmfit.ci_report(ci) # lmfit.report_errors(params_r_proj) ax = fig.axes[2] ax.plot(r_axis_mm, r_projection) # if gas == 'Kr': # ax.plot( # r_axis_mm, # epicea.electron_calibration_helper.n_line_fit_model( # params_r_proj, r_axis_mm, **line_type), # 'r--') # elif setting == 500: # proj_fit = skewed_gauss_for_500_eV(params_r_proj, r_axis_mm, **kws) # ax.plot( # r_axis_mm, n_voigt_with_bg_model(params_r_proj, # r_axis_mm, # **kws), # 'm--') ax.plot(r_axis_mm, fit_funk(res.params, r_axis_mm, **kws), '--r') plt.sca(ax) plt_func.tick_fontsize() plt_func.title_wrapper('straight ' + data.name()) plt_func.xlabel_wrapper('Position (mm)')
def get_straight_image(data, r_axis_mm, th_axis_rad, compare_time_stamp, gas, *, verbose=False, plot=False, fig=None, radial_factors=None): d_name = data.name() if radial_factors is None: radial_factors, r_f_time_stamp, fig = get_radial_factors( data, r_axis_mm, th_axis_rad, 0, gas, verbose=verbose, plot=plot) compare_time_stamp = max(compare_time_stamp, r_f_time_stamp) compare_time_stamp = max(compare_time_stamp, 144178446) th_limits = epicea.limits_from_centers(th_axis_rad) # Get the corrected image with some defined properties straight_img_name = 'e_rth_image_straight' filter_sum_string = 'no_filter' match_data_dict = {'r_axis_mm': r_axis_mm, 'th_axis_rad': th_axis_rad} # With the radial factors done, now look for the corrected image match_data_dict['radial_factors'] = radial_factors straight_img, straight_img_time_stamp = \ data.load_derived_data( straight_img_name, filter_sum_string, compare_time_stamp=compare_time_stamp, verbose=verbose, match_data_dict=match_data_dict) # If there is no data it needs to be made if straight_img.size > 0: if verbose: print('Use old straight image.', flush=True) else: if verbose: print('Make new straight image.', flush=True) # Get and adjust the coordinates th = data.electrons.pos_t.value r = data.electrons.pos_r.value for i_th in range(len(th_axis_rad)): try: I = (th_limits[i_th] <= th) & (th < th_limits[i_th + 1]) except RuntimeWarning as W: print(W.args) print(W.with_traceback) print('I.sum() =', I.sum(), 'i_th =', i_th, th_limits[i_th]) r[I] *= radial_factors[i_th] straight_img = epicea.center_histogram_2d(r, th, r_axis_mm, th_axis_rad) # Save the straight image straight_img_time_stamp = data.store_derived_data( straight_img, straight_img_name, filter_sum_string, match_data_dict=match_data_dict, verbose=verbose) if (fig is not None) & (plot == True): if verbose: print('Plot the straight image of', d_name, flush=True) plt.sca(fig.axes[1]) img_axis = plt_func.imshow_wrapper(straight_img, r_axis_mm, th_axis_rad, kw_args={'aspect': 'auto'}) plt_func.tick_fontsize() plt_func.title_wrapper('straight ' + d_name) plt_func.xlabel_wrapper('Position (mm)') plt_func.ylabel_wrapper('Angle (rad)') plt_func.colorbar_wrapper(mappable=img_axis) return straight_img, straight_img_time_stamp, fig