예제 #1
0
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)
예제 #2
0
    plt.plot(centers, th_axis_rad, label='full center')
    plt.plot(low_radius_centers, th_axis_rad, label='first center')
    plt.title('center position')
    plt_func.legend_wrapper()
    plt.subplot(122)
    plt.plot(radial_factors, th_axis_rad)
    plt.title('r factors')

    r = data.electrons.pos_r.value
    th = data.electrons.pos_t.value

    for i in range(len(th_axis_rad)):
        selection = (th_limits[i] < th) & (th < th_limits[i + 1])
        r[selection] *= radial_factors[i]

    r_th_img_corrected = epicea.center_histogram_2d(r, th, r_axis_mm,
                                                    th_axis_rad)

    r_proj_corrected = r_th_img_corrected.sum(axis=0)
    proj_corrected_params_initial = \
        epicea.electron_calibration_helper.start_params(
            r_axis_mm, r_proj_corrected, n_lines=2)
    proj_corrected_result = lmfit.minimize(line_model,
                                           proj_corrected_params_initial,
                                           args=(r_axis_mm, r_proj_corrected),
                                           kws={'line_type': line})

    ax = r_th_fig.add_subplot(222)
    plt.sca(ax)
    plt_func.imshow_wrapper(r_th_img_corrected,
                            r_axis_mm,
                            th_axis_rad,
예제 #3
0
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()
예제 #4
0
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)
예제 #5
0
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
예제 #6
0
    com_corr_max_line = com_corr_img[max_line_number]
    #    com_corr_max_line = com_corr_img.mean(axis=0)
    com_shift = com_corr_img - com_corr_max_line
    com_corrected = com_corr_max_line + com_shift

    plt.plot(com_corr_img, th_axis_rad, '.')
    r_factors = com_corrected.mean() / com_corrected

    r = data.electrons.pos_r.value
    th = data.electrons.pos_t.value

    for i_th in range(len(th_axis_rad)):
        mask_th = (th_limits[i_th] < th) & (th <= th_limits[i_th + 1])
        r[mask_th] *= r_factors[i_th]

    straigt_img = epicea.center_histogram_2d(r, th, r_axis_mm, th_axis_rad)
    plt_func.imshow_wrapper(straigt_img,
                            r_axis_mm,
                            th_axis_rad,
                            ax=ax_img_straight,
                            kw_args={'aspect': 'auto'})

    straight_proj = straigt_img.sum(axis=0)

    plt.figure('projections')
    plt.clf()
    plt.plot(r_axis_mm, r_proj / r_proj.sum())
    plt.plot(r_axis_mm, straight_proj / straight_proj.sum())
    random_slice = r_th_img[np.random.randint(len(th_axis_rad)), :]
    plt.plot(r_axis_mm, random_slice / random_slice.sum())