Esempio n. 1
0
def test_rebin():
    # 1D
    a = np.array([1, 1, 1, 1])
    aR = utils.rebin(a, 2)
    assert np.allclose(aR, np.array([1, 1]))

    # 2D
    b = np.array([[1,1,1,1], [2,2,2,2]])
    bR = utils.rebin(b, 1, 2)
    assert np.allclose(bR, [[1,1], [2,2]])
    bR = utils.rebin(b, None, 2)
    assert np.allclose(bR, [[1,1], [2,2]])
    bR = utils.rebin(b, 2, 1)
    assert np.allclose(bR, [1.5, 1.5, 1.5, 1.5])
    bR = utils.rebin(b, 2, None)
    assert np.allclose(bR, [1.5, 1.5, 1.5, 1.5])

    c = np.zeros([10, 10, 10])
    cR = utils.rebin(c, n_z=2)
    assert cR.shape == (10, 10, 5)
    cR = utils.rebin(c, n_y=2)
    assert cR.shape == (10, 5, 10)
    cR = utils.rebin(c, n_x=2)
    assert cR.shape == (5, 10, 10)

    c = np.zeros([10, 10, 10, 10])
    with pytest.raises(RuntimeError):
        utils.rebin(c, 2, 2)
Esempio n. 2
0
def plot_waterfall(fil,
                   f_start=None,
                   f_stop=None,
                   if_id=0,
                   logged=True,
                   cb=False,
                   freq_label=False,
                   MJD_time=False,
                   **kwargs):
    """ Plot waterfall of data

    Args:
        f_start (float): start frequency, in MHz
        f_stop (float): stop frequency, in MHz
        logged (bool): Plot in linear (False) or dB units (True),
        cb (bool): for plotting the colorbar
        kwargs: keyword args to be passed to matplotlib imshow()
    """

    matplotlib.rc('font', **font)

    plot_f, plot_data = fil.grab_data(f_start, f_stop, if_id)

    # Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]

    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = plot_data.shape[1] / MAX_IMSHOW_POINTS[1]

    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    if MJD_time:
        extent = (plot_f[0], plot_f[-1], fil.timestamps[-1], fil.timestamps[0])
    else:
        extent = (plot_f[0], plot_f[-1],
                  (fil.timestamps[-1] - fil.timestamps[0]) * 24. * 60. * 60,
                  0.0)

    this_plot = plt.imshow(plot_data,
                           aspect='auto',
                           rasterized=True,
                           interpolation='nearest',
                           extent=extent,
                           cmap='viridis_r',
                           **kwargs)
    if cb:
        plt.colorbar()

    if freq_label:
        plt.xlabel("Frequency [Hz]", fontdict=font)
    if MJD_time:
        plt.ylabel("Time [MJD]", fontdict=font)
    else:
        plt.ylabel("Time [s]", fontdict=font)

    return this_plot
Esempio n. 3
0
def __write_to_hdf5_light(wf, filename_out, f_scrunch=None, *args, **kwargs):
    """ Write data to HDF5 file in one go.

    Args:
        filename_out (str): Name of output file
        f_scrunch (int or None): Average (scrunch) N channels together
    """

    block_size = 0

    with h5py.File(filename_out, 'w') as h5:

        h5.attrs['CLASS']   = 'FILTERBANK'
        h5.attrs['VERSION'] = '1.0'

        bs_compression = hdf5plugin.Bitshuffle(nelems=0, lz4=True)['compression']
        bs_compression_opts = hdf5plugin.Bitshuffle(nelems=0, lz4=True)['compression_opts']

        if f_scrunch is None:
            data_out = wf.data
        else:
            wf.logger.info('Frequency scrunching by %i' % f_scrunch)
            data_out = utils.rebin(wf.data, n_z=f_scrunch)
            wf.header['foff'] *= f_scrunch

        dset = h5.create_dataset('data',
                                 data=data_out,
                                 compression=bs_compression,
                                 compression_opts=bs_compression_opts)

        dset_mask = h5.create_dataset('mask',
                                      shape=data_out.shape,
                                      compression=bs_compression,
                                      compression_opts=bs_compression_opts,
                                      dtype='uint8')

        dset.dims[2].label = b"frequency"
        dset.dims[1].label = b"feed_id"
        dset.dims[0].label = b"time"

        dset_mask.dims[2].label = b"frequency"
        dset_mask.dims[1].label = b"feed_id"
        dset_mask.dims[0].label = b"time"

        # Copy over header information as attributes
        for key, value in wf.header.items():
            dset.attrs[key] = value
Esempio n. 4
0
def test_rebin():
    # 1D
    a = np.array([1, 1, 1, 1])
    aR = utils.rebin(a, 2)
    assert np.allclose(aR, np.array([1, 1]))

    # 2D
    b = np.array([[1,1,1,1], [2,2,2,2]])
    bR = utils.rebin(b, 1, 2)
    assert np.allclose(bR, [[1,1], [2,2]])
    bR = utils.rebin(b, None, 2)
    assert np.allclose(bR, [[1,1], [2,2]])
    bR = utils.rebin(b, 2, 1)
    assert np.allclose(bR, [1.5, 1.5, 1.5, 1.5])
    bR = utils.rebin(b, 2, None)
    assert np.allclose(bR, [1.5, 1.5, 1.5, 1.5])

    c = np.zeros([10, 10, 10])
    with pytest.raises(RuntimeError):
        utils.rebin(c, 2, 2)
Esempio n. 5
0
def plot_waterfall(fil, source_name, f_start=None, f_stop=None, **kwargs):
    r"""
    Plot waterfall of data in a .fil or .h5 file.

    Parameters
    ----------
    fil : str
        Filterbank file containing the dynamic spectrum data.
    source_name : str
        Name of the target.
    f_start : float
        Start frequency, in MHz.
    f_stop : float
        Stop frequency, in MHz.
    kwargs : dict
        Keyword args to be passed to matplotlib imshow().

    Notes
    -----
    Plot a single-panel waterfall plot (frequency vs. time vs. intensity)
    for one of the on or off observations in the cadence of interest, at the
    frequency of the expected event. Calls :func:`~overlay_drift`

    """
    # prepare font
    matplotlib.rc('font', **font)

    # Load in the data from fil
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)

    # Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1

    # rebinning data to plot correctly with fewer points
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    # Rolled back PR #82

    # determine extent of the plotting panel for imshow
    extent = (plot_f[0], plot_f[-1],
              (fil.timestamps[-1] - fil.timestamps[0]) * 24. * 60. * 60, 0.0)

    # plot and scale intensity (log vs. linear)
    kwargs['cmap'] = kwargs.get('cmap', 'viridis')
    plot_data = 10.0 * np.log10(plot_data)

    # get normalization parameters
    vmin = plot_data.min()
    vmax = plot_data.max()
    normalized_plot_data = (plot_data - vmin) / (vmax - vmin)

    # display the waterfall plot
    this_plot = plt.imshow(normalized_plot_data,
                           aspect='auto',
                           rasterized=True,
                           interpolation='nearest',
                           extent=extent,
                           **kwargs)

    # add plot labels
    plt.xlabel("Frequency [Hz]", fontdict=font)
    plt.ylabel("Time [s]", fontdict=font)

    # add source name
    ax = plt.gca()
    plt.text(0.03,
             0.8,
             source_name,
             transform=ax.transAxes,
             bbox=dict(facecolor='white'))
    # if plot_snr != False:
    #     plt.text(0.03, 0.6, plot_snr, transform=ax.transAxes, bbox=dict(facecolor='white'))
    # return plot
    return this_plot
Esempio n. 6
0
def make_waterfall_plots(fil_file_list,
                         on_source_name,
                         f_start,
                         f_stop,
                         drift_rate,
                         f_mid,
                         filter_level,
                         source_name_list,
                         offset=0,
                         **kwargs):
    r'''
    Makes waterfall plots of an event for an entire on-off cadence.

    Parameters
    ----------
    fil_file_list : str
        List of filterbank files in the cadence.
    on_source_name : str
        Name of the on_source target.
    f_start : float
        Start frequency, in MHz.
    f_stop : float
        Stop frequency, in MHz.
    drift_rate : float
        Drift rate in Hz/s.
    f_mid : float
        <iddle frequency of the event, in MHz.
    filter_level : int
        Filter level (1, 2, or 3) that produced the event.
    source_name_list : list
        List of source names in the cadence, in order.
    bandwidth : int
        Width of the plot, incorporating drift info.
    kwargs : dict
        Keyword args to be passed to matplotlib imshow().

    Notes
    -----
    Makes a series of waterfall plots, to be read from top to bottom, displaying a full cadence
    at the frequency of a recorded event from find_event. Calls :func:`~plot_waterfall`

    '''
    global logger_plot_event

    # prepare for plotting
    matplotlib.rc('font', **font)

    # set up the sub-plots
    n_plots = len(fil_file_list)
    fig = plt.subplots(n_plots,
                       sharex=True,
                       sharey=True,
                       figsize=(10, 2 * n_plots))

    # get directory path for storing PNG files
    dirpath = dirname(fil_file_list[0]) + '/'

    # read in data for the first panel
    fil1 = bl.Waterfall(fil_file_list[0], f_start=f_start, f_stop=f_stop)
    t0 = fil1.header['tstart']
    dummy, plot_data1 = fil1.grab_data()

    # rebin data to plot correctly with fewer points
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data1.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data1.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data1.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data1.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data1 = rebin(plot_data1, dec_fac_x, dec_fac_y)

    # define more plot parameters
    # never used: delta_f = 0.000250
    mid_f = np.abs(f_start + f_stop) / 2.

    subplots = []

    # Fill in each subplot for the full plot
    for i, filename in enumerate(fil_file_list):
        logger_plot_event.debug(
            'make_waterfall_plots: file {} in list: {}'.format(i, filename))
        # identify panel
        subplot = plt.subplot(n_plots, 1, i + 1)
        subplots.append(subplot)

        # read in data
        fil = bl.Waterfall(filename, f_start=f_start, f_stop=f_stop)
        # make plot with plot_waterfall
        source_name = source_name_list[i]
        this_plot = plot_waterfall(fil,
                                   source_name,
                                   f_start=f_start,
                                   f_stop=f_stop,
                                   **kwargs)

        # calculate parameters for estimated drift line
        t_elapsed = Time(fil.header['tstart'], format='mjd').unix - Time(
            t0, format='mjd').unix
        t_duration = (fil.n_ints_in_file - 1) * fil.header['tsamp']
        f_event = f_mid + drift_rate / 1e6 * t_elapsed

        # plot estimated drift line
        overlay_drift(f_event, f_start, f_stop, drift_rate, t_duration, offset)

        # Title the full plot
        if i == 0:
            plot_title = "%s \n $\dot{\\nu}$ = %2.3f Hz/s , MJD:%5.5f" % (
                on_source_name, drift_rate, t0)

            plt.title(plot_title)
        # Format full plot
        if i < len(fil_file_list) - 1:
            plt.xticks(np.linspace(f_start, f_stop, num=4), ['', '', '', ''])

    # More overall plot formatting, axis labelling
    factor = 1e6
    units = 'Hz'

    ax = plt.gca()
    ax.get_xaxis().get_major_formatter().set_useOffset(False)
    xloc = np.linspace(f_start, f_stop, 5)
    xticks = [round(loc_freq) for loc_freq in (xloc - mid_f) * factor]
    if np.max(xticks) > 1000:
        xticks = [xt / 1000 for xt in xticks]
        units = 'kHz'
    plt.xticks(xloc, xticks)
    plt.xlabel("Relative Frequency [%s] from %f MHz" % (units, mid_f),
               fontdict=font)

    # Add colorbar
    cax = fig[0].add_axes([0.94, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot,
                    cax=cax,
                    label='Normalized Power (Arbitrary Units)')

    # Adjust plots
    plt.subplots_adjust(hspace=0, wspace=0)

    # save the figures
    path_png = dirpath + filter_level + '_' + on_source_name + '_dr_' + "{:0.2f}".format(
        drift_rate) + '_freq_' "{:0.6f}".format(f_start) + ".png"
    plt.savefig(path_png, bbox_inches='tight')
    logger_plot_event.debug(
        'make_waterfall_plots: Saved file {}'.format(path_png))

    # show figure before closing if this is an interactive context
    mplbe = matplotlib.get_backend()
    logger_plot_event.debug('make_waterfall_plots: backend = {}'.format(mplbe))
    if mplbe in matplotlib.rcsetup.interactive_bk:
        plt.show()

    # close all figure windows
    plt.close('all')

    return subplots
Esempio n. 7
0
def make_waterfall_plots(filenames_list,
                         f_start,
                         f_stop,
                         plot_range=True,
                         target='',
                         ion=False,
                         epoch=None,
                         local_host='',
                         plot_name='',
                         save_pdf_plot=False,
                         saving_fig=False,
                         **kwargs):
    ''' Makes waterfall plots per group of ON-OFF pairs (up to 6 plots.)

        plot_range:  selecting vmin vmax from first On observation, or not.

    '''

    matplotlib.rc('font', **font)

    if ion:
        plt.ion()

    min_val = 0
    max_val = 5.
    factor = 1e6
    units = 'Hz'

    n_plots = len(filenames_list)
    fig = plt.subplots(n_plots,
                       sharex=True,
                       sharey=True,
                       figsize=(10, 2 * n_plots))

    #finding plotting values range
    fil = Waterfall(filenames_list[0], f_start=f_start, f_stop=f_stop)
    plot_f, plot_data = fil.grab_data(f_start, f_stop, 0)
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = plot_data.shape[1] / MAX_IMSHOW_POINTS[1]
    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    A1_avg = np.median(plot_data)
    A1_max = plot_data.max()
    A1_std = np.std(plot_data)

    if not epoch:
        epoch = fil.header[u'tstart']

    if not target:
        target = fil.header[u'source_name']

    labeling = ['A', 'B', 'A', 'C', 'A', 'D']

    #    delta_f = ('%f0.6'%np.abs(f_start-f_stop))
    delta_f = f_start - f_stop
    mid_f = np.abs(f_start + f_stop) / 2.

    for i, filename in enumerate(filenames_list):
        print(filename)
        plt.subplot(n_plots, 1, i + 1)

        fil = Waterfall(filename, f_start=f_start, f_stop=f_stop)
        if plot_range:
            this_plot = plot_waterfall(fil,
                                       f_start=f_start,
                                       f_stop=f_stop,
                                       vmin=A1_avg - A1_std * min_val,
                                       vmax=A1_avg + max_val * A1_std,
                                       **kwargs)
        else:
            this_plot = plot_waterfall(fil,
                                       f_start=f_start,
                                       f_stop=f_stop,
                                       **kwargs)

        if i == 0:
            plt.title(target.replace('HIP', 'HIP '))

        if i < len(filenames_list) - 1:
            plt.xticks(np.arange(f_start, f_stop, delta_f / 4.),
                       ['', '', '', ''])

    #Some plot formatting.
    ax = plt.gca()
    ax.get_xaxis().get_major_formatter().set_useOffset(False)
    print('delta_f', delta_f)
    plt.xticks(np.arange(f_start, f_stop, delta_f / 4.), [
        round(loc_freq) for loc_freq in np.arange(
            (f_start - mid_f), (f_stop - mid_f), delta_f / 4.) * factor
    ])
    plt.xlabel("Relative Frequency [%s] from %f MHz" % (units, mid_f),
               fontdict=font)

    #to plot color bar. for now.
    cax = fig[0].add_axes([0.9, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot, cax=cax, label='Power [Arbitrary Units]')

    # Fine-tune figure; make subplots close to each other and hide x ticks for
    # all but bottom plot.
    plt.subplots_adjust(hspace=0, wspace=0)

    if saving_fig:
        if not plot_name:
            plot_name = 'Candidate_waterfall_plots.%s.t%.0f.%s.f%.0f.png' % (
                target, epoch, local_host, mid_f * 1e6)

        print('Saving png figure.')
        plt.savefig(plot_name, bbox_inches='tight')
        if save_pdf_plot:
            print('Saving pdf figure.')
            plt.savefig(plot_name.replace('.png', '') + '.pdf',
                        format='pdf',
                        dpi=300,
                        bbox_inches='tight')
Esempio n. 8
0
def make_waterfall_plots(fil_file_list,
                         on_source_name,
                         f_start,
                         f_stop,
                         drift_rate,
                         f_mid,
                         filter_level,
                         source_name_list,
                         bandwidth,
                         offset=0,
                         **kwargs):
    ''' Makes waterfall plots of an event for an entire on-off cadence
    Args:
        fil_file_list (str): list of filterbank files in the cadence
        on_source_name (str): name of the on_source target
        f_start (float): start frequency, in MHz
        f_stop (float): stop frequency, in MHz
        drift_rate (float) = drift rate in Hz/s
        f_mid = middle frequency of the event, in MHz
        filter_level = filter level (1,2,or 3) that produced the event
        source_name_list = list of source names in the cadence, in order
        bandwidth = width of the plot, incorporating drift info
        kwargs: keyword args to be passed to matplotlib imshow()
    '''

    #prepare for plotting
    matplotlib.rc('font', **font)

    #set up the sub-plots
    n_plots = len(fil_file_list)
    fig = plt.subplots(n_plots,
                       sharex=True,
                       sharey=True,
                       figsize=(10, 2 * n_plots))

    #read in data for the first panel
    fil1 = bl.Waterfall(fil_file_list[0], f_start=f_start, f_stop=f_stop)
    t0 = fil1.header['tstart']
    plot_f1, plot_data1 = fil1.grab_data()

    #rebin data to plot correctly with fewer points
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data1.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data1.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data1.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data1.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data1 = rebin(plot_data1, dec_fac_x, dec_fac_y)

    #define more plot parameters
    delta_f = 0.000250
    mid_f = np.abs(f_start + f_stop) / 2.

    subplots = []

    #Fill in each subplot for the full plot
    for i, filename in enumerate(fil_file_list):
        #identify panel
        subplot = plt.subplot(n_plots, 1, i + 1)
        subplots.append(subplot)

        #read in data
        fil = bl.Waterfall(filename, f_start=f_start, f_stop=f_stop)
        try:
            #make plot with plot_waterfall
            source_name = source_name_list[i]
            this_plot = plot_waterfall(fil,
                                       source_name,
                                       f_start=f_start,
                                       f_stop=f_stop,
                                       drift_rate=drift_rate,
                                       **kwargs)

            #calculate parameters for estimated drift line
            t_elapsed = Time(fil.header['tstart'], format='mjd').unix - Time(
                t0, format='mjd').unix
            t_duration = (fil.n_ints_in_file - 1) * fil.header['tsamp']
            f_event = f_mid + drift_rate / 1e6 * t_elapsed

            #plot estimated drift line
            overlay_drift(f_event, f_start, f_stop, drift_rate, t_duration,
                          offset)
        except:
            raise

        #Title the full plot
        if i == 0:
            plot_title = "%s \n $\dot{\\nu}$ = %2.3f Hz/s" % (on_source_name,
                                                              drift_rate)
            plt.title(plot_title)
        #Format full plot
        if i < len(fil_file_list) - 1:
            plt.xticks(np.arange(f_start, f_stop, delta_f / 4.),
                       ['', '', '', ''])

    #More overall plot formatting, axis labelling
    factor = 1e6
    units = 'Hz'

    ax = plt.gca()
    ax.get_xaxis().get_major_formatter().set_useOffset(False)
    xloc = np.linspace(f_start, f_stop, 5)
    xticks = [round(loc_freq) for loc_freq in (xloc - mid_f) * factor]
    if np.max(xticks) > 1000:
        xticks = [xt / 1000 for xt in xticks]
        units = 'kHz'
    plt.xticks(xloc, xticks)
    plt.xlabel("Relative Frequency [%s] from %f MHz" % (units, mid_f),
               fontdict=font)

    #Add colorbar
    cax = fig[0].add_axes([0.94, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot, cax=cax, label='Normalized Power')

    #Adjust plots
    plt.subplots_adjust(hspace=0, wspace=0)

    #save the figures
    plt.savefig(filter_level + '_' + on_source_name + '_dr_' +
                "{:0.2f}".format(drift_rate) + '_freq_'
                "{:0.6f}".format(f_start) + ".png",
                bbox_inches='tight')

    return subplots
Esempio n. 9
0
def plot_waterfall(fil,
                   source_name,
                   f_start=None,
                   f_stop=None,
                   drift_rate=None,
                   logged=True,
                   **kwargs):
    """ Plot waterfall of data in a .fil or .h5 file
    Args:
        fil (str): filterbank file containing the dynamic spectrum data
        source_name (str): name of the target
        f_start (float): start frequency, in MHz
        f_stop (float): stop frequency, in MHz
        drift_rate (float) = drift rate in Hz/s
        logged (bool): Plot in linear (False) or dB units (True),
        kwargs: keyword args to be passed to matplotlib imshow()
    """

    #prepare font
    matplotlib.rc('font', **font)

    #Load in the data from fil
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)

    #Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1

    #rebinning data to plot correctly with fewer points
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    #determine extent of the plotting panel for imshow
    extent = (plot_f[0], plot_f[-1],
              (fil.timestamps[-1] - fil.timestamps[0]) * 24. * 60. * 60, 0.0)

    #plot and scale intensity (log vs. linear)
    kwargs['cmap'] = kwargs.get('cmap', 'viridis')
    kwargs['logged'] = True
    if kwargs['logged'] == True:
        plot_data = 10 * np.log10(plot_data)
        kwargs.pop('logged')

    #get normalization parameters
    vmin = plot_data.min()
    vmax = plot_data.max()
    normalized_plot_data = (plot_data - vmin) / (vmax - vmin)

    #display the waterfall plot
    this_plot = plt.imshow(normalized_plot_data,
                           aspect='auto',
                           rasterized=True,
                           interpolation='nearest',
                           extent=extent,
                           **kwargs)

    #add plot labels
    plt.xlabel("Frequency [Hz]", fontdict=font)
    plt.ylabel("Time [s]", fontdict=font)

    #add source name
    ax = plt.gca()
    plt.text(0.03,
             0.8,
             source_name,
             transform=ax.transAxes,
             bbox=dict(facecolor='white'))

    #return plot
    return this_plot
Esempio n. 10
0
def make_waterfall_plots(filenames_list, target, drates, fvals, f_start,f_stop, node_string, filter_level, ion=False,
                         epoch=None,bw=250.0, local_host='',plot_name='',save_pdf_plot=False,saving_fig=False,offset=0,
                         dedoppler=False,**kwargs):
    """Makes waterfall plots per group of ON-OFF pairs (up to 6 plots.)

    Args:
      filenames_list: 
      target: 
      drates: 
      fvals: 
      f_start: 
      f_stop: 
      node_string: 
      filter_level: 
      ion:  (Default value = False)
      epoch:  (Default value = None)
      bw:  (Default value = 250.0)
      local_host:  (Default value = '')
      plot_name:  (Default value = '')
      save_pdf_plot:  (Default value = False)
      saving_fig:  (Default value = False)
      offset:  (Default value = 0)
      dedoppler:  (Default value = False)
      **kwargs: 

    Returns:

    """
    
    #prepares for plotting
    print('Preparing to plot: ', target)
    matplotlib.rc('font', **font)
    if ion:
        plt.ion()

    #defines a minimum and maximum of... something
    min_val = 0
    max_val = 5.
    factor = 1e6
    units = 'Hz'


    #finding plotting values range for the first panel (A1)
    fil = bl.Waterfall(filenames_list[0], f_start=f_start, f_stop=f_stop)

    t0 = fil.header['tstart']
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)
    dec_fac_x, dec_fac_y = 1, 1
    
    #rebinning data to plot correctly with fewer points
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] // MAX_IMSHOW_POINTS[0] 
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y =  plot_data.shape[1] /  MAX_IMSHOW_POINTS[1]
        print ('dec_fac_y', dec_fac_y)
    #insert rebin definition code from utils.py in blimpy and edit it because this is the problem
    d=plot_data
    n_x=dec_fac_x
    n_y=dec_fac_y

    d = rebin(d, n_x, n_y)
    plot_data=d
    #print('d', d)

    #plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    #investigate intensity values for A1 (first panel)
    plot_data = 10*np.log10(plot_data)
    A1_avg = np.median(plot_data)
    A1_max = plot_data.max()
    A1_std = np.std(plot_data)
    
    #defining more plot parameters
    delta_f = 0.000250
    epoch = fil.header['tstart']
    mid_f = np.abs(f_start+f_stop)/2.
    drate_max = np.max(np.abs(drates))
    
    subplots = []
    
    #working out intensity scale
    if kwargs.get('clim', None) is None:
        vmin=A1_avg-A1_std*min_val-2
        vmax=A1_avg+max_val*A1_std
    else:
        vmin, vmax = kwargs['clim']
        
    #Filling in each subplot for the full plot
    for i,filename in enumerate(filenames_list):
        subplot = plt.subplot(n_plots,1,i+1)
        subplots.append(subplot)
        
        #read in data
        fil = bl.Waterfall(filename, f_start=f_start, f_stop=f_stop)


        try:
            #make plot with plot_waterfall
            source_name = source_name_list[i]
            this_plot = plot_waterfall(fil,
                                       source_name,
                                       f_start=f_start, 
                                       f_stop=f_stop, 
                                       drift_rate=drift_rate,
                                       **kwargs)
            
            #calculate parameters for estimated drift line
            t_elapsed = Time(fil.header['tstart'], format='mjd').unix - Time(t0, format='mjd').unix
            t_duration = (fil.n_ints_in_file - 1) * fil.header['tsamp']
            f_event = f_mid + drift_rate / 1e6 * t_elapsed
            
            #plot estimated drift line
            overlay_drift(f_event, f_start, f_stop, drift_rate, t_duration, offset)
        except:
            raise
            
        #Title the full plot
        if i == 0:
            plot_title = "%s \n $\dot{\\nu}$ = %2.3f Hz/s" % (on_source_name, drift_rate)
            plt.title(plot_title)
        #Format full plot
        if i < len(fil_file_list)-1:
            plt.xticks(np.arange(f_start, f_stop, delta_f/4.), ['','','',''])

    #More overall plot formatting, axis labelling
    factor = 1e6
    units = 'Hz'
            
    ax = plt.gca()
    ax.get_xaxis().get_major_formatter().set_useOffset(False)
    xloc = np.linspace(f_start, f_stop, 5)
    xticks = [round(loc_freq) for loc_freq in (xloc - mid_f)*factor]
    if np.max(xticks) > 1000:
        xticks = [xt/1000 for xt in xticks]
        units = 'kHz'
    plt.xticks(xloc, xticks)
    plt.xlabel("Relative Frequency [%s] from %f MHz"%(units,mid_f),fontdict=font)
    
    #Add colorbar
    cax = fig[0].add_axes([0.94, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot,cax=cax,label='Normalized Power')
    
    #Adjust plots
    plt.subplots_adjust(hspace=0,wspace=0)
    
    #save the figures
    plt.savefig(filter_level + '_' + on_source_name + '_dr_' + "{:0.2f}".format(drift_rate) + '_freq_' "{:0.6f}".format(f_start) + ".png",
               bbox_inches='tight')

    return subplots
def plot_waterfall(fil,
                   source_name,
                   f_start=None,
                   f_stop=None,
                   drift_rate=None,
                   logged=True,
                   plot_snr=False,
                   **kwargs):
    """ Plot waterfall of data in a .fil or .h5 file
    Args:
        fil (str): filterbank file containing the dynamic spectrum data
        source_name (str): name of the target
        f_start (float): start frequency, in MHz
        f_stop (float): stop frequency, in MHz
        drift_rate (float) = drift rate in Hz/s
        logged (bool): Plot in linear (False) or dB units (True),
        kwargs: keyword args to be passed to matplotlib imshow()
    """

    #prepare font
    matplotlib.rc('font', **font)

    #Load in the data from fil
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)

    #Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1

    #rebinning data to plot correctly with fewer points
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    #determine extent of the plotting panel for imshow
    if plot_f[-1] < plot_f[0]:
        plot_f = plot_f[::-1]
    extent = (plot_f[0], plot_f[-1],
              (fil.timestamps[-1] - fil.timestamps[0]) * 24. * 60. * 60, 0.0)

    #plot and scale intensity (log vs. linear)
    kwargs['cmap'] = kwargs.get('cmap', 'viridis')
    kwargs['logged'] = True
    if kwargs['logged'] == True:
        plot_data = 10 * np.log10(plot_data)
        kwargs.pop('logged')

#     data = np.copy(plot_data)
#     tsamp = fil.header['tsamp']
#     chan_bw = fil.header['foff']
#     drift_rate = -0.15
#     n_roll = (drift_rate * 1e-6 * tsamp) / chan_bw

#     for ii in range(data.shape[0]):
#         plot_data[ii] = np.roll(data[ii], int(n_roll*ii), axis = 0)

#get normalization parameters
    vmin = plot_data.min()
    vmax = plot_data.max()
    normalized_plot_data = (plot_data - vmin) / (vmax - vmin)

    #display the waterfall plot
    this_plot = plt.imshow(normalized_plot_data,
                           aspect='auto',
                           rasterized=True,
                           interpolation='nearest',
                           extent=extent,
                           **kwargs)

    #add plot labels
    plt.xlabel("Frequency [Hz]", fontdict=font)
    plt.ylabel("Time [s]", fontdict=font)
    plt.locator_params(axis='x', nbins=3)
    #add source name
    ax = plt.gca()

    #     if extent[2] > 300:
    #         ax.figure.set_size_inches(5,2)
    if source_name == 'ProxCen':
        if drift_rate > 0:
            plt.text(0.03,
                     0.9,
                     source_name,
                     transform=ax.transAxes,
                     bbox=dict(facecolor='white', edgecolor='none',
                               alpha=0.75))
        else:
            plt.text(0.97,
                     0.9,
                     source_name,
                     transform=ax.transAxes,
                     ha='right',
                     bbox=dict(facecolor='white', edgecolor='none',
                               alpha=0.75))
        plt.yticks(np.arange(0, extent[2], (extent[2]) // 5)[:-1])
    else:
        if drift_rate > 0:
            plt.text(0.03,
                     0.35,
                     source_name,
                     transform=ax.transAxes,
                     bbox=dict(facecolor='white', edgecolor='none',
                               alpha=0.75))
        else:
            plt.text(0.97,
                     0.35,
                     source_name,
                     transform=ax.transAxes,
                     ha='right',
                     bbox=dict(facecolor='white', edgecolor='none',
                               alpha=0.75))
        plt.yticks(np.arange(0, extent[2], (extent[2]) // 2)[:-1])


#     if plot_snr != False:
#         plt.text(0.03, 0.6, plot_snr, transform=ax.transAxes, bbox=dict(facecolor='white'))
#return plot
    return this_plot
Esempio n. 12
0
def __write_to_hdf5_heavy(wf, filename_out, f_scrunch=None, *args, **kwargs):
    """ Write data to HDF5 file.

    Args:
        filename_out (str): Name of output file
        f_scrunch (int or None): Average (scrunch) N channels together
    """

    block_size = 0

    # Note that a chunk is not a blob!!
    # chunk_dim = wf._get_chunk_dimensions() <-- seems intended for raw to fil
    # And, chunk dimensions should not exceed the Waterfall selection shape dimensions.
    chunk_list = list(wf._get_chunk_dimensions())
    for ix in range(0, len(chunk_list)):
        if chunk_list[ix] > wf.selection_shape[ix]:
            chunk_list[ix] = wf.selection_shape[ix]
    chunk_dim = tuple(chunk_list)
    blob_dim  = wf._get_blob_dimensions(chunk_dim)
    n_blobs   = wf.container.calc_n_blobs(blob_dim)

    with h5py.File(filename_out, 'w') as h5:

        h5.attrs['CLASS'] = 'FILTERBANK'
        h5.attrs['VERSION'] = '1.0'

        bs_compression = hdf5plugin.Bitshuffle(nelems=0, lz4=True)['compression']
        bs_compression_opts = hdf5plugin.Bitshuffle(nelems=0, lz4=True)['compression_opts']

        dout_shape     = list(wf.selection_shape)    # Make sure not a tuple
        dout_chunk_dim = list(chunk_dim)

        if f_scrunch is not None:
            dout_shape[-1] //= f_scrunch
            dout_chunk_dim[-1] //= f_scrunch
            wf.header['foff'] *= f_scrunch

        dset = h5.create_dataset('data',
                                 shape=tuple(dout_shape),
                                 chunks=tuple(dout_chunk_dim),
                                 compression=bs_compression,
                                 compression_opts=bs_compression_opts,
                                 dtype=wf.data.dtype)

        dset_mask = h5.create_dataset('mask',
                                      shape=tuple(dout_shape),
                                      chunks=tuple(dout_chunk_dim),
                                      compression=bs_compression,
                                      compression_opts=bs_compression_opts,
                                      dtype='uint8')

        dset.dims[2].label = b"frequency"
        dset.dims[1].label = b"feed_id"
        dset.dims[0].label = b"time"

        dset_mask.dims[2].label = b"frequency"
        dset_mask.dims[1].label = b"feed_id"
        dset_mask.dims[0].label = b"time"

        # Copy over header information as attributes
        for key, value in wf.header.items():
            dset.attrs[key] = value

        if blob_dim[wf.freq_axis] < wf.selection_shape[wf.freq_axis]:

            wf.logger.info('Using %i n_blobs to write the data.'% n_blobs)
            for ii in range(0, n_blobs):
                wf.logger.info('Reading %i of %i' % (ii + 1, n_blobs))

                bob = wf.container.read_blob(blob_dim, n_blob=ii)

                #-----
                #Using channels instead of frequency.
                c_start = wf.container.chan_start_idx + ii * blob_dim[wf.freq_axis]
                t_start = wf.container.t_start + (c_start / wf.selection_shape[wf.freq_axis]) * blob_dim[wf.time_axis]
                t_stop = t_start + blob_dim[wf.time_axis]

                # Reverse array if frequency axis is flipped
#                     if self.header['foff'] < 0:
#                         c_stop = self.selection_shape[self.freq_axis] - (c_start)%self.selection_shape[self.freq_axis]
#                         c_start = c_stop - blob_dim[self.freq_axis]
#                     else:
                c_start = (c_start) % wf.selection_shape[wf.freq_axis]
                c_stop = c_start + blob_dim[wf.freq_axis]
                #-----

                if f_scrunch is not None:
                    c_start //= f_scrunch
                    c_stop  //= f_scrunch
                    bob = utils.rebin(bob, n_z=f_scrunch)

                wf.logger.debug(t_start,t_stop,c_start,c_stop)
                dset[t_start:t_stop,0,c_start:c_stop] = bob[:]

        else:

            wf.logger.info('Using %i n_blobs to write the data.'% n_blobs)
            for ii in range(0, n_blobs):
                wf.logger.info('Reading %i of %i' % (ii + 1, n_blobs))

                bob = wf.container.read_blob(blob_dim, n_blob=ii)
                t_start = wf.container.t_start + ii * blob_dim[wf.time_axis]

                #This prevents issues when the last blob is smaller than the others in time
                if (ii+1)*blob_dim[wf.time_axis] > wf.n_ints_in_file:
                    t_stop = wf.n_ints_in_file
                else:
                    t_stop = (ii+1)*blob_dim[wf.time_axis]

                if f_scrunch is not None:
                    bob = utils.rebin(bob, n_z=f_scrunch)

                dset[t_start:t_stop] = bob[:]
Esempio n. 13
0
def plot_hit_candidate(dat_file_list,
                       fil_file_list,
                       source_name_list,
                       all_hits_frame,
                       candidate=None,
                       check_zero_drift=False,
                       outdir=None,
                       alpha=1,
                       color='black',
                       window=None):
    """ 
    Parameters
    ----------
    dat_file_list : list
        A Python list that contains a series of 
        strings corresponding to the filenames of .dat
        files, each on a new line, that corresponds to 
        the .dat files created when running turboSETI 
        candidate search on the .h5 or .fil files below
    fil_file_list : list
        A Python list that contains a series of 
        strings corresponding to the filenames of .dat
        files, each on a new line, that corresponds to 
        the cadence used to create the .csv file used 
        for event_csv_string.
    source_name_list : list
        A Python list that contains a series of strings
        corresponding to the source names of the 
        cadence in chronological (descending through 
        the plot pannels) cadence.
    all_hits_frame : dict
        A pandas dataframe contining information about 
        all the hits detected. The necessary data 
        includes the start and stop frequencies, the drift
        rate, and the source name. This dataframe is 
        generated in plot_all_hit_and_candidates above. 
    candidate : dict, optional
        A single row from a pandas dataframe containing
        information about one of the candidate signals
        detected. Contains information about the candidate 
        signal to be plotted. The necessary data includes 
        the start and stop frequencies, the drift rate, 
        and the source name. The dataframe the candiate
        comes from is generated in plot_all_hit_and_candidates
        above as `candidate_event_dataframe`. The default is None.
    check_zero_drift : bool, optional
         A True/False flag that tells the program whether to
        include hits that have a drift rate of 0 Hz/s. Earth-
        based RFI tends to have no drift rate, while signals
        from the sky are expected to have non-zero drift rates.
        The default is False.
    outdir : str, optional
        Path to the directory where the plots will be saved to. 
        The default is None, which will result in the plots being 
        saved to the directory the .dat file are located.
    alpha : float, optional
        The opacity of the overlayed hit plot. This should 
        be between 0 and 1, with 0 being invisible, and 1
        being the default opacity. This is passed into 
        matplotlib.pyplot function. 
    color : str, optional
        Allows for the specification of the color of the overlayed
        hits. The default is 'black'.
    window : tuple, optional
        Sets the start and stop frequencies of the plot, in MHz.
        The input takes the form of a tuple: (start, stop). And 
        assumes that the start is less than the stop. The 
        resulting plot will range exactly between the start/stop
        frequencies. The default is None, which will result in 
        a plot of the entire range of hits detected.
    """
    #set plot boundaries based on the contents of the file
    freq_range = np.max(all_hits_frame["Freq"]) - np.min(
        all_hits_frame["Freq"])
    filter_level = "f0"

    # total range all hits fall between
    f_min = np.min(all_hits_frame["Freq"])
    f_max = np.max(all_hits_frame["Freq"])

    fil1 = bl.Waterfall(fil_file_list[0], load_data=False)
    t0 = fil1.header["tstart"]
    t_elapsed = Time(fil1.header['tstart'], format='mjd').unix - Time(
        t0, format='mjd').unix
    bandwidth = 2.4 * abs(freq_range) / 1e6 * t_elapsed
    bandwidth = np.max((bandwidth, 500. / 1e6))

    # Get start and stop frequencies based on midpoint and bandwidth
    f_start, f_stop = np.sort(
        (f_min - (bandwidth / 2), f_max + (bandwidth / 2)))
    mid_f = 0.5 * (f_start + f_stop)

    #if given a window to plot in, set boundaries accordingly
    if window is not None:
        f_start = min(window)
        f_stop = max(window)
        mid_f = 0.5 * (f_start + f_stop)

    # plugging some code from make_waterfall_plots
    global logger_plot_event

    # prepare for plotting
    matplotlib.rc('font', **font)

    # set up the sub-plots
    n_plots = len(fil_file_list)
    fig = plt.subplots(n_plots,
                       sharex=True,
                       sharey=True,
                       figsize=(10, 2 * n_plots))

    # get directory path for storing PNG files
    dirpath = dirname(fil_file_list[0]) + '/'

    # read in data for the first panel
    max_load = bl.calcload.calc_max_load(fil_file_list[0])
    print('plot_dat plot_hit_candidate: max_load={} is required for {}'.format(
        max_load, fil_file_list[0]))
    fil1 = bl.Waterfall(fil_file_list[0],
                        f_start=f_start,
                        f_stop=f_stop,
                        max_load=max_load)
    t0 = fil1.header['tstart']
    dummy, plot_data1 = fil1.grab_data()

    # rebin data to plot correctly with fewer points
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data1.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data1.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data1.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data1.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data1 = rebin(plot_data1, dec_fac_x, dec_fac_y)

    subplots = []
    del fil1, dummy, plot_data1
    gc.collect()

    on_source_name = source_name_list[0]
    f_candidate = mid_f

    if candidate is not None:
        on_source_name = candidate["Source"]
        f_candidate = candidate["Freq"]

    for i, filename in enumerate(fil_file_list):
        subplot = plt.subplot(n_plots, 1, i + 1)
        subplots.append(subplot)

        #read in the data
        max_load = bl.calcload.calc_max_load(filename)
        print(
            'plot_event make_waterfall_plots: max_load={} is required for {}'.
            format(max_load, filename))
        wf = bl.Waterfall(filename,
                          f_start=f_start,
                          f_stop=f_stop,
                          max_load=max_load)

        this_plot = plot_event.plot_waterfall(wf, source_name_list[i], f_start,
                                              f_stop)

        make_plot(dat_file_list[i],
                  fil_file_list[i],
                  f_start,
                  f_stop,
                  t0,
                  candidate,
                  check_zero_drift=check_zero_drift,
                  alpha=alpha,
                  color=color)

        #more code from make_waterfall_plots
        # Title the full plot
        if i == 0:
            plot_title = "%s \n MJD:%5.5f" % (on_source_name, t0)

            plt.title(plot_title)
        # Format full plot
        if i < len(fil_file_list) - 1:
            plt.xticks(np.linspace(f_start, f_stop, num=4), ['', '', '', ''])

        del wf
        gc.collect()

    # More overall plot formatting, axis labelling
    factor = 1e6
    units = 'Hz'

    #ax = plt.gca()
    #ax.get_xaxis().get_major_formatter().set_useOffset(False)
    xloc = np.linspace(f_start, f_stop, 5)
    xticks = [round(loc_freq) for loc_freq in (xloc - mid_f) * factor]
    if np.max(xticks) > 1000:
        xticks = [xt / 1000 for xt in xticks]
        units = 'kHz'
    plt.xticks(xloc, xticks)
    plt.xlabel("Relative Frequency [%s] from %f MHz" % (units, mid_f),
               fontdict=font)

    # Add colorbar
    cax = fig[0].add_axes([0.94, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot,
                    cax=cax,
                    label='Normalized Power (Arbitrary Units)')

    # Adjust plots
    plt.subplots_adjust(hspace=0, wspace=0)

    # save the figures
    if outdir is not None:
        dirpath = outdir

    # make note if the plot contains a candidate
    cand = ""
    if candidate is not None:
        cand = "_candidate"
    path_png = dirpath + filter_level + '_' + on_source_name + cand + '_freq_' "{:0.6f}".format(
        f_candidate) + ".png"
    plt.savefig(path_png, bbox_inches='tight', transparent=False)
    logger_plot_event.debug(
        'make_waterfall_plots: Saved file {}'.format(path_png))

    # close all figure windows
    plt.close('all')
Esempio n. 14
0
def plot_waterfall(fil,
                   source_name,
                   f_start=None,
                   f_stop=None,
                   f_scrunch=1,
                   **kwargs):
    """ Plot waterfall of data in a .fil or .h5 file
    Args:
        fil (str): filterbank file containing the dynamic spectrum data
        source_name (str): name of the target
        f_start (float): start frequency, in MHz
        f_stop (float): stop frequency, in MHz
        f_scrunch (int): Average across frequency channels
        kwargs: keyword args to be passed to matplotlib imshow()
    """
    file1 = os.getcwd() + '/' + fil
    #prepare font
    #matplotlib.rc('font', **font)
    fil = bl.Waterfall(file1, f_start=f_start, f_stop=f_stop)
    #Load in the data from fil
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)

    #Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1

    if dec_fac_y == 1 and f_scrunch > 1:
        dec_fac_y = f_scrunch

    #rebinning data to plot correctly with fewer points
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    #fix case where frequencies are reversed by fil.grab_data() # Shane Smith PR #82
    if plot_f[-1] < plot_f[0]:
        plot_f = plot_f[::-1]
        plot_data = plot_data[:, ::-1]

    #determine extent of the plotting panel for imshow
    extent = (plot_f[0], plot_f[-1],
              (fil.timestamps[-1] - fil.timestamps[0]) * 24. * 60. * 60, 0.0)

    #plot and scale intensity (log vs. linear)
    kwargs['cmap'] = kwargs.get('cmap', 'viridis')
    kwargs['logged'] = True
    if kwargs['logged'] == True:
        plot_data = 10 * np.log10(plot_data)
        kwargs.pop('logged')

    #get normalization parameters
    vmin = plot_data.min()
    vmax = plot_data.max()
    normalized_plot_data = (plot_data - vmin) / (vmax - vmin)

    #display the waterfall plot
    this_plot = plt.imshow(normalized_plot_data,
                           aspect='auto',
                           rasterized=True,
                           interpolation='nearest',
                           extent=extent,
                           **kwargs)

    #add plot labels
    plt.xlabel("Frequency [Hz]", fontdict=font)
    plt.ylabel("Time [s]", fontdict=font)

    #add source name
    ax = plt.gca()
    #plt.text(0.03, 0.8, source_name, transform=ax.transAxes, bbox=dict(facecolor='white'))
    #if plot_snr != False:
    #    plt.text(0.03, 0.6, plot_snr, transform=ax.transAxes, bbox=dict(facecolor='white'))
    #return plot
    return this_plot
Esempio n. 15
0
def plot_waterfall(fil, f_start=None, f_stop=None, drate=None, if_id=0, logged=True, cb=False,freq_label=False,MJD_time=False, **kwargs):
    """Plot waterfall of data

    Args:
      f_start(float, optional): start frequency, in MHz (Default value = None)
      f_stop(float, optional): stop frequency, in MHz (Default value = None)
      logged(bool, optional): Plot in linear (False) or dB units (True), (Default value = True)
      cb(bool, optional): for plotting the colorbar (Default value = False)
      kwargs: keyword args to be passed to matplotlib imshow()
      fil: 
      drate:  (Default value = None)
      if_id:  (Default value = 0)
      freq_label:  (Default value = False)
      MJD_time:  (Default value = False)
      **kwargs: 

    Returns:

    """

    #prepare font
    matplotlib.rc('font', **font)

    #Get the data
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)

    # Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y =  plot_data.shape[1] /  MAX_IMSHOW_POINTS[1]
    #insert rebin definition code from utils.py in blimpy and edit it because this is the problem
    d=plot_data
    n_x=dec_fac_x
    n_y=dec_fac_y

    d = rebin(d, n_x, n_y)
    plot_data=d
    #print('d', d)

    #plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)

    if MJD_time:
        extent=(plot_f[0], plot_f[-1], fil.timestamps[-1], fil.timestamps[0])
    else:
        extent=(plot_f[0], plot_f[-1], (fil.timestamps[-1]-fil.timestamps[0])*24.*60.*60, 0.0)

    #plots and scales intensity
    kwargs['cmap'] = kwargs.get('cmap', 'viridis')
    kwargs['logged'] = True
    if kwargs['logged'] == True:
        plot_data = 10*np.log10(plot_data)
        kwargs.pop('logged')

    #shows the waterfall plot
    this_plot = plt.imshow(plot_data,
        aspect='auto',
        rasterized=True,
        interpolation='nearest',
        extent=extent,
        **kwargs
    )
    #add colorbar
    if cb:
        plt.colorbar()

    #add plot labels
    if freq_label:
        plt.xlabel("Frequency [Hz]",fontdict=font)
    if MJD_time:
        plt.ylabel("Time [MJD]",fontdict=font)
    else:
        plt.ylabel("Time [s]",fontdict=font)

    return this_plot 
Esempio n. 16
0
def make_waterfall_plots(file_list,
                         plot_dir,
                         f_start=None,
                         f_stop=None,
                         **kwargs):
    r"""
    Make waterfall plots of a file set, view from top to bottom.

    Parameters
    ----------
    file_list : str
        List of filterbank files to plot in a stacked mode.
    f_start : float
        Start frequency, in MHz.
    f_stop : float
        Stop frequency, in MHz.
    source_name_list : list
        List of source names in the set, in order.
    kwargs : dict
        Keyword args to be passed to matplotlib imshow().
    """

    # prepare for plotting
    matplotlib.rc("font", **font)

    # set up the sub-plots
    n_plots = len(file_list)
    fig = plt.subplots(n_plots,
                       sharex=True,
                       sharey=True,
                       figsize=(10, 2 * n_plots))

    # get directory path for storing PNG files
    if plot_dir is None:
        dirpath = dirname(abspath(file_list[0])) + "/"
    else:
        if not isdir(plot_dir):
            os.mkdir(plot_dir)
        dirpath = plot_dir

    # read in data for the first panel
    max_load = bl.calcload.calc_max_load(file_list[0])
    #print("plot_event make_waterfall_plots: max_load={} is required for {}".format(max_load, file_list[0]))
    wf1 = bl.Waterfall(file_list[0], max_load=max_load)
    t0 = wf1.header["tstart"]
    source_name = wf1.header["source_name"]

    # Fix frequency boundaries if required.
    freqs = wf1.container.populate_freqs()
    if f_start is None:
        f_start = freqs[0]
    if f_stop is None:
        f_stop = freqs[-1]
    the_lowest, the_highest = sort2(f_start, f_stop)

    # rebin data to plot correctly with fewer points
    plot_f1, plot_data1 = wf1.grab_data(f_start=the_lowest, f_stop=the_highest)
    dec_fac_x, dec_fac_y = 1, 1
    if plot_data1.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data1.shape[0] / MAX_IMSHOW_POINTS[0]
    if plot_data1.shape[1] > MAX_IMSHOW_POINTS[1]:
        dec_fac_y = int(np.ceil(plot_data1.shape[1] / MAX_IMSHOW_POINTS[1]))
    plot_data1 = rebin(plot_data1, dec_fac_x, dec_fac_y)

    # Compute the midpoint.
    the_midpoint = np.abs(the_lowest + the_highest) / 2.

    # Protect RAM utilisation.
    del wf1, freqs, plot_f1, plot_data1
    gc.collect()

    # Fill in each subplot for the full plot
    subplots = []
    for ii, filename in enumerate(file_list):
        logger.debug("make_waterfall_plots: file {} in list: {}".format(
            ii, filename))
        # identify panel
        subplot = plt.subplot(n_plots, 1, ii + 1)
        subplots.append(subplot)

        # read in data
        max_load = bl.calcload.calc_max_load(filename)
        wf = bl.Waterfall(filename, max_load=max_load)

        # Validate frequency range.
        freqs = wf.container.populate_freqs()
        ii_lowest, ii_highest = sort2(freqs[0], freqs[-1])
        logger.info("Processing: {}, freq lowest={}, highest={}".format(
            filename, ii_lowest, ii_highest))
        if the_lowest < ii_lowest or the_highest > ii_highest:
            logger.warning(
                "Frequency range not compatible!  Ignoring this file.")
            # Protect RAM utilisation.
            del wf, freqs
            gc.collect()
            continue  # Skip this file.

        # make plot with plot_waterfall
        source_name = wf.header["source_name"]
        this_plot = plot_waterfall(wf,
                                   f_start=the_lowest,
                                   f_stop=the_highest,
                                   **kwargs)

        # Title the full plot if processing the first file.
        if ii == 0:
            plot_title = "%s \n MJD:%5.5f (first file)" % (source_name, t0)
            plt.title(plot_title)

        # Format full plot.
        if ii < len(file_list) - 1:
            plt.xticks(np.linspace(the_lowest, the_highest, num=4),
                       ["", "", "", ""])

        # Protect RAM utilisation.
        del wf, freqs
        gc.collect()

    # More overall plot formatting, axis labelling.
    factor = 1e6
    units = "Hz"
    xloc = np.linspace(the_lowest, the_highest, 5)
    xticks = [round(loc_freq) for loc_freq in (xloc - the_midpoint) * factor]
    if np.max(xticks) > 1000:
        xticks = [xt / 1000 for xt in xticks]
        units = "kHz"
    plt.xticks(xloc, xticks)
    plt.xlabel("Relative Frequency [%s] from %f MHz" % (units, the_midpoint),
               fontdict=font)

    # Add colorbar.
    cax = fig[0].add_axes([0.94, 0.11, 0.03, 0.77])
    fig[0].colorbar(this_plot,
                    cax=cax,
                    label="Normalized Power (Arbitrary Units)")

    # Adjust plots
    plt.subplots_adjust(hspace=0, wspace=0)

    # Save the figures.
    path_png = dirpath + source_name + "_fstart_{:0.6f}".format(f_start) \
                + "_fstop_{:0.6f}".format(f_stop) + ".png"
    plt.savefig(path_png, bbox_inches="tight")
    logger.info("Saved plot: {}".format(path_png))

    # show figure before closing if this is an interactive context
    mplbe = matplotlib.get_backend()
    logger.debug("make_waterfall_plots: backend = {}".format(mplbe))
    if mplbe != "agg":
        plt.show()

    # close all figure windows
    plt.close("all")
Esempio n. 17
0
def plot_waterfall(wf, f_start=None, f_stop=None, **kwargs):
    r"""
    Plot waterfall of data in a .fil or .h5 file.

    Parameters
    ----------
    wf : blimpy.Waterfall object
        Waterfall object of an H5 or Filterbank file containing the dynamic spectrum data.
    f_start : float
        Start frequency, in MHz.
    f_stop : float
        Stop frequency, in MHz.
    kwargs : dict
        Keyword args to be passed to matplotlib imshow().

    Notes
    -----
    Plot a single-panel waterfall plot (frequency vs. time vs. intensity)
    for one of the files in the set of interest, at the
    frequency of the expected event.
    """

    # Extract source name.
    source_name = wf.header["source_name"]

    # prepare font
    matplotlib.rc("font", **font)

    # Load in the data from fil
    plot_f, plot_data = wf.grab_data(f_start=f_start, f_stop=f_stop)

    # Make sure waterfall plot is under 4k*4k
    dec_fac_x, dec_fac_y = 1, 1

    # rebinning data to plot correctly with fewer points
    try:
        if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
            dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
        if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
            dec_fac_y = int(np.ceil(plot_data.shape[1] / MAX_IMSHOW_POINTS[1]))
        plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)
    except Exception as ex:
        print(
            "\n*** Oops, grab_data returned plot_data.shape={}, plot_f.shape={}"
            .format(plot_data.shape, plot_f.shape))
        print("Waterfall info for {}:".format(wf.filename))
        wf.info()
        raise ValueError(
            "*** Something is wrong with the grab_data output!") from ex

    # Rolled back PR #82

    # determine extent of the plotting panel for imshow
    extent = (plot_f[0], plot_f[-1],
              (wf.timestamps[-1] - wf.timestamps[0]) * 24. * 60. * 60, 0.0)

    # plot and scale intensity (log vs. linear)
    kwargs["cmap"] = kwargs.get("cmap", "viridis")
    plot_data = 10.0 * np.log10(plot_data)

    # get normalization parameters
    vmin = plot_data.min()
    vmax = plot_data.max()
    normalized_plot_data = (plot_data - vmin) / (vmax - vmin)

    # display the waterfall plot
    this_plot = plt.imshow(normalized_plot_data,
                           aspect="auto",
                           rasterized=True,
                           interpolation="nearest",
                           extent=extent,
                           **kwargs)

    # add plot labels
    plt.xlabel("Frequency [Hz]", fontdict=font)
    plt.ylabel("Time [s]", fontdict=font)

    # add source name
    ax = plt.gca()
    plt.text(0.03,
             0.8,
             source_name,
             transform=ax.transAxes,
             bbox=dict(facecolor="white"))

    return this_plot
Esempio n. 18
0
for i in range(len(low_freqs)):
	f_start=low_freqs[i]
	f_stop=high_freqs[i]
	plt.figure(i)
	fil = Waterfall(filename, f_start=f_start, f_stop=f_stop)

	dummy, plot_data = fil.grab_data()

# rebin data to plot correctly with fewer points
	dec_fac_x, dec_fac_y = 1, 1
	if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
		dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
	if plot_data.shape[1] > MAX_IMSHOW_POINTS[1]:
		dec_fac_y =  int(np.ceil(plot_data.shape[1] /  MAX_IMSHOW_POINTS[1]))
	plot_data = rebin(plot_data, dec_fac_x, dec_fac_y)


	f_mid = round(np.abs(f_start+f_stop)/2., 4)
	mid_f = round(np.abs(f_start+f_stop)/2., 4)


	drift_rate=drift_rates[i]

	# read in data

	fig=plt.figure(1)

	t0 = fil.header['tstart']
	# make plot with plot_waterfall
	source_name = 'TESS_TOI_1449.02'