Example #1
0
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
Example #2
0
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()
Example #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()
Example #4
0
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()
Example #5
0
def plot_ion_tof(data, verbose=False):
    """Plot some ions tof spectra."""
    if verbose:
        print('\nPlotting tof spectra')
    plt_func.figure_wrapper('Ion TOF {}'.format(data.name()))
    ax1 = plt.subplot(211)

    t_axis_us = np.arange(2., 6.5, 0.01)
    t_axis_ns = t_axis_us * 1e6
    if verbose:
        print('Get tof specturm for all ions.')
    i_tof_all = data.get_i_tof_spectrum(t_axis_ns)
    plt.plot(t_axis_us, i_tof_all, 'k', label='All ions')

    if verbose:
        print('Get tof specturm for e start ions.')
    i_tof_e_start = data.get_i_tof_spectrum(t_axis_ns,
                                            data.get_filter('e_start_ions'))
    if verbose:
        print('Get tof specturm for rand start ions.')
    i_tof_random_start = data.get_i_tof_spectrum(
        t_axis_ns, data.get_filter('rand_start_ions'))
    if verbose:
        print('Plot e start and rand start tof spectra.')
    plt.plot(t_axis_us, i_tof_e_start, 'b', label='electron start ions')
    plt.plot(t_axis_us, i_tof_random_start, 'g', label='random start ions')

    plt_func.xlabel_wrapper('flight time (us)')
    plt_func.ylabel_wrapper('number of ions per bin')
    plt_func.legend_wrapper()
    plt_func.tick_fontsize()

    plt.subplot(212, sharex=ax1)
    i_tof_NN_O = data.get_i_tof_spectrum(t_axis_ns,
                                         data.get_filter('NN_O_events_ions'))
    i_tof_NO_N = data.get_i_tof_spectrum(t_axis_ns,
                                         data.get_filter('NO_N_events_ions'))

    if verbose:
        print('Finding random start rescaling factor.')
    rescale_region = slice(t_axis_us.searchsorted(5.5),
                           t_axis_us.searchsorted(6.5))
    random_start_scaling = (i_tof_e_start[rescale_region].sum(dtype=float) /
                            i_tof_random_start[rescale_region].sum())

    plt.plot(t_axis_us, i_tof_e_start, 'b', label='electron start ions')
    plt.plot(t_axis_us,
             i_tof_random_start * random_start_scaling,
             'g',
             label='random start ions, rescaled')
    plt.plot(t_axis_us,
             i_tof_e_start - i_tof_random_start * random_start_scaling,
             'r',
             label='pure coincidence ions')
    plt.plot(t_axis_us, i_tof_NN_O * 5, 'y', label='NN+ O+ ions x 5')
    plt.plot(t_axis_us, i_tof_NO_N * 5, 'm', label='NO+ N+ ions x 5')

    plt_func.xlabel_wrapper('flight time (us)')
    plt_func.ylabel_wrapper('number of ions per bin')
    plt_func.legend_wrapper()
    plt_func.tick_fontsize()

    plt_func.savefig_wrapper()
Example #6
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)
Example #7
0
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)')
Example #8
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