Пример #1
0
def test_plotting_doesnt_cause_exceptions():
    """ Try running the plotting routines. They should not raise expections even without X windows """
    a = bl.Waterfall(voyager_h5)
    b = bl.Waterfall(voyager_fil)

    a.plot_all()
    plt.clf()
    a.plot_kurtosis()
    plt.clf()
    a.plot_spectrum()
    plt.clf()
    a.plot_spectrum_min_max()
    plt.clf()
    a.plot_waterfall()
    plt.clf()
    a.plot_time_series()
    plt.clf()

    b.plot_all()
    plt.clf()
    b.plot_kurtosis()
    plt.clf()
    b.plot_spectrum()
    plt.clf()
    b.plot_spectrum_min_max()
    plt.clf()
    b.plot_waterfall()
    plt.clf()
    b.plot_time_series()
    plt.clf()
Пример #2
0
def test_waterfall_data_load_range_freq():
    fw = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.fil',
                      f_start=8419.24,
                      f_stop=8419.35)
    hw = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.h5',
                      f_start=8419.24,
                      f_stop=8419.35)

    print(fw.data.shape)
    print(hw.data.shape)
    print(hw.data[0].max(), hw.data[0].argmax())
    print(fw.data[0].max(), fw.data[0].argmax())
    print(hw.data[-1].max(), hw.data[-1].argmax())
    print(fw.data[-1].max(), fw.data[-1].argmax())

    # Assert data is loaded to the same shape and has same values
    assert hw.data.shape == fw.data.shape == (16, 1, 39370)
    assert np.allclose(hw.data, fw.data)

    # Check the Voyager carrier has the known amplitudes at first and last integration
    assert np.allclose(hw.data[0].max(), fw.data[0].max(), 3.09333e+11)
    assert np.allclose(hw.data[-1].max(), fw.data[-1].max(), 2.74257e+11)

    # Check the tone is in the same bin for both
    assert hw.data[0].argmax() == fw.data[0].argmax() == 18959
    assert hw.data[-1].argmax() == fw.data[-1].argmax() == 18996

    # And plot(
    plt.subplot(2, 1, 1)
    fw.plot_spectrum()

    plt.subplot(2, 1, 2)
    hw.plot_spectrum()
    plt.tight_layout()
Пример #3
0
def compare_waterfall_fil_to_h5():
    """ Load Voyager dataset and test that both fil and hdf5 readers return same headers and data """

    print("Loading FIL and HDF5 data with Waterfall()..."),
    a = bl.Waterfall(voyager_h5)
    b = bl.Waterfall(voyager_fil)
    print("OK")

    print("Reading headers..")
    print("\nHDF5 file header:")
    pprint(a.header)
    print("\nFIL file header:")
    pprint(b.header)
    print("Headers are loading OK")

    print("\nChecking header values match..."),
    for key in b.header.keys():
        assert b.header[key] == a.header[key]
    print("OK")

    print("Checking datatype matches..."),
    assert a.data.dtype == b.data.dtype
    print("OK")

    print("Checking data matches..."),
    assert np.allclose(a.data, b.data)
    assert a.data.dtype == b.data.dtype
    print("OK")
Пример #4
0
def test_fil_write():
    try:
        a = bl.Waterfall(voyager_h5)
        b = bl.Waterfall(voyager_fil)

        a.write_to_fil('test.fil')
        b.write_to_fil('test2.fil')

        c = bl.Waterfall('test.fil')
        d = bl.Waterfall('test2.fil')

        for key in a.header.keys():
            if key != 'DIMENSION_LABELS':
                assert a.header[key] == c.header[key]
                assert key in c.header.keys()
                assert a.header[key] == d.header[key]
                assert key in d.header.keys()

        assert np.allclose(a.data, c.data)
        assert np.allclose(a.data, d.data)
    except AssertionError:
        print(key, a.header[key], b.header[key], c.header[key], d.header[key])
        raise

    finally:
        os.remove('test.fil')
        os.remove('test2.fil')
Пример #5
0
def plot_candidate_events(candidate_event_dataframe,
                          fil_file_list,
                          filter_level,
                          source_name_list,
                          offset=0,
                          **kwargs):

    #load in the data for each individual hit
    for i in range(0, len(candidate_event_dataframe)):
        candidate = candidate_event_dataframe.iloc[i]
        on_source_name = candidate['Source']
        f_mid = candidate['Freq']
        drift_rate = candidate['DriftRate']

        #calculate the length of the total cadence from the fil files' headers
        first_fil = bl.Waterfall(fil_file_list[0], load_data=False)
        tfirst = first_fil.header['tstart']
        last_fil = bl.Waterfall(fil_file_list[-1], load_data=False)
        tlast = last_fil.header['tstart']
        t_elapsed = Time(tlast, format='mjd').unix - Time(
            tfirst, format='mjd').unix + (last_fil.n_ints_in_file -
                                          1) * last_fil.header['tsamp']

        #calculate the width of the plot based on making sure the full drift is visible
        bandwidth = 2.4 * abs(drift_rate) / 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_mid - (bandwidth / 2), f_mid + (bandwidth / 2)))

        #Print useful values
        print('')
        print('*************************************************')
        print('***     The Parameters for This Plot Are:    ****')
        print('Target = ', on_source_name)
        print('Bandwidth = ', round(bandwidth, 5), ' MHz')
        print('Time Elapsed (inc. Slew) = ', round(t_elapsed), ' s')
        print('Middle Frequency = ', round(f_mid, 4), " MHz")
        print('Expected Drift = ', round(drift_rate, 4), " Hz/s")
        print('*************************************************')
        print('*************************************************')
        print('')

        #Pass info to make_waterfall_plots() function
        make_waterfall_plots(fil_file_list,
                             on_source_name,
                             f_start,
                             f_stop,
                             drift_rate,
                             f_mid,
                             filter_level,
                             source_name_list,
                             bandwidth,
                             offset=offset,
                             **kwargs)

    return
Пример #6
0
def compare_waterfall_fil_to_h5_methods_and_attributes():
    """ Compare attributes and check methods """
    a = bl.Waterfall(voyager_h5)
    b = bl.Waterfall(voyager_fil)

    print("Comparing attributes of classes match where expected")
    assert a.beam_axis == b.beam_axis
    assert a.freq_axis == b.freq_axis
    assert a.time_axis == b.time_axis
    #assert a.stokes_axis == b.stokes_axis  # Fil shouldn't have stokes axis ...

    assert a.calc_n_coarse_chan() == b.calc_n_coarse_chan()
    assert a.file_shape == b.file_shape

    assert a.n_channels_in_file == b.n_channels_in_file
    assert a.n_ints_in_file == b.n_ints_in_file
    assert a.selection_shape == b.selection_shape

    print("Checking if basic methods run without raising Exceptions")
    # Check they can be run
    a.container.populate_freqs()
    a.container.populate_timestamps()
    a.info()
    a.blank_dc(1)
    a.calibrate_band_pass_N1()

    b.container.populate_freqs()
    b.container.populate_timestamps()
    b.info()
    b.blank_dc(1)
    b.calibrate_band_pass_N1()

    # TODO: 'compute_lsrk' -- need PYSLALIB
    # TODO: 'compute_lst' -- need PYSLALIB

    # Expected to differ between: 'ext', 'file_size_bytes', 'filename', 'container'
    # Unused? Inherited from Filterbank.py 'gen_from_header', 'generate_freqs', 'read_filterbank', 'read_hdf5'

    # TODO: 'grab_data',
    # TODO: 'read_data',
    # TODO: 'write_to_fil',
    # TODO: 'write_to_filterbank',
    # TODO: 'write_to_hdf5']

    dir_a = dir(a)
    dir_b = dir(b)

    print("Attr/methods in HDF5 but not in FIL:")
    for item in dir_a:
        if item not in dir_b:
            print(item)

    print("Attr/methods in FIL but not in HDF5:")
    for item in dir_b:
        if item not in dir_a:
            print(item)
Пример #7
0
def test_read_fns():
    """ These read functions are currently not implemented. """
    a = bl.Waterfall(voyager_fil)
    b = bl.Waterfall(voyager_h5)
    with pytest.raises(NotImplementedError):
        a.container.read_all()
        a.container.read_row(0)
        a.container.read_rows(0, 2)

        b.container.read_all()
        b.container.read_row(0)
        b.container.read_rows(0, 2)
def test_read_fns():
    """ These read functions are currently not implemented. """
    a = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.fil')
    b = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.h5')
    with pytest.raises(NotImplementedError):
        a.container.read_all()
        a.container.read_row(0)
        a.container.read_rows(0, 2)

        b.container.read_all()
        b.container.read_row(0)
        b.container.read_rows(0, 2)
Пример #9
0
def test_get_freqs():
    wf = bl.Waterfall(voyager_h5)
    freqs = wf.container.populate_freqs()
    sum1 = np.sum(freqs)
    freqs = wf.get_freqs()
    sum2 = np.sum(freqs)
    assert sum1 == sum2
    wf = bl.Waterfall(voyager_fil)
    freqs = wf.container.populate_freqs()
    sum1 = np.sum(freqs)
    freqs = wf.get_freqs()
    sum2 = np.sum(freqs)
    assert sum1 == sum2
Пример #10
0
def test_read_fns():
    """ These read functions are currently not implemented. """
    """ L: if that is true, why do the first two lines
        NOT raise NotImplementedError's?"""
    a = bl.Waterfall(voyager_fil)
    b = bl.Waterfall(voyager_h5)
    with pytest.raises(NotImplementedError):
        a.container.read_all()
        a.container.read_row(0)
        a.container.read_rows(0, 2)

        b.container.read_all()
        b.container.read_row(0)
        b.container.read_rows(0, 2)
Пример #11
0
def plot_hit(fil_filename, dat_filename, hit_id, bw=None, offset=0):
    """ Plot a candidate from a .dat file

    Args:
        fil_filename (str): Path to filterbank file to plot
        dat_filename (str): Path to turbosSETI generated .dat output file of events
        hit_id (int): ID of hit in the dat file to plot (TopHitNum)
        offset (float): Offset drift line on plot. Default 0.
    """
    # Load hit details
    dat = make_table(dat_filename)
    hit = dat.iloc[hit_id]

    f0 = hit['Freq']

    if bw is None:
        bw_mhz = np.abs(hit['FreqStart'] - hit['FreqEnd'])
    else:
        bw_mhz = bw * 1e-6

    fil = bl.Waterfall(fil_filename,
                       f_start=f0 - bw_mhz / 2,
                       f_stop=f0 + bw_mhz / 2)
    t_duration = (fil.n_ints_in_file - 1) * fil.header['tsamp']

    fil.plot_waterfall()
    overlay_drift(f0, hit['DriftRate'], t_duration, offset)
Пример #12
0
def test_plot_waterfall_classmethod():
    """ Load Voyager dataset and test plotting """

    a = bl.Waterfall(voyager_h5)

    plt.figure("TEST PLOTTING CLASS", figsize=(10, 8))
    plt.subplot(3, 2, 1)
    a.plot_waterfall()

    plt.subplot(3, 2, 2)
    a.plot_spectrum()

    plt.subplot(3, 2, 3)
    a.plot_spectrum_min_max()

    plt.subplot(3, 2, 4)
    a.plot_kurtosis()

    plt.subplot(3, 2, 5)
    a.plot_time_series()
    plt.tight_layout()

    plt.savefig("test_plotting_classmethod.png")

    plt.figure("TEST PLOT_ALL CLASS", figsize=(10, 8))
    a.plot_all()
    plt.savefig("test_plotting_plot_all_classmethod.png")
Пример #13
0
def test_plot_waterfall():
    """ Load Voyager dataset and test plotting """

    a = bl.Waterfall(voyager_h5)

    plt.figure("TEST PLOTTING", figsize=(10, 8))
    plt.subplot(3, 2, 1)
    plot_waterfall(a)

    plt.subplot(3, 2, 2)
    plot_spectrum(a)

    plt.subplot(3, 2, 3)
    plot_spectrum_min_max(a)

    plt.subplot(3, 2, 4)
    plot_kurtosis(a)

    plt.subplot(3, 2, 5)
    plot_time_series(a)

    plt.tight_layout()
    plt.savefig("test_plotting.png")

    plt.figure("TEST PLOT_ALL", figsize=(10, 8))
    plot_all(a)
    plt.savefig("test_plotting_plot_all.png")
Пример #14
0
def test_grab_data_works_across_all_fil_h5():

    fw = bl.Waterfall(voyager_fil)
    hw = bl.Waterfall(voyager_h5)
    all_readers = [fw, hw]

    for ii, rr in enumerate(all_readers):
        f, d = rr.grab_data(f_start=8419.29, f_stop=8419.30)
        print(f.shape, d.shape)
        assert f.shape == (3580,)
        assert d.shape == (16, 3580)

    for ii, rr in enumerate(all_readers):
        f, d = rr.grab_data(f_start=8419.29685, f_stop=8419.2971)
        print(f.shape, d.shape)
        assert f.shape == (91,)
        assert d.shape == (16, 91)
Пример #15
0
def compare_waterfall_fil_h5_conatiners():
    """ Compare the two containers for fil.container and h5.container """
    a = bl.Waterfall(voyager_h5)
    b = bl.Waterfall(voyager_fil)

    dir_a = dir(a.container)
    dir_b = dir(b.container)

    print("Attr/methods in HDF5 container but not in FIL:")
    for item in dir_a:
        if item not in dir_b:
            print(item)

    print("Attr/methods in FIL container but not in HDF5:")
    for item in dir_b:
        if item not in dir_a:
            print(item)
Пример #16
0
def test_grab_data_works_across_all_fil_h5():

    ff = bl.Filterbank('Voyager_data/Voyager1.single_coarse.fine_res.fil')
    hf = bl.Filterbank('Voyager_data/Voyager1.single_coarse.fine_res.h5')
    fw = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.fil')
    hw = bl.Waterfall('Voyager_data/Voyager1.single_coarse.fine_res.h5')
    all_readers = [ff, hf, fw, hw]

    for ii, rr in enumerate(all_readers):
        f, d = rr.grab_data(f_start=8419.29, f_stop=8419.30)
        print(f.shape, d.shape)
        assert f.shape == (3580, )
        assert d.shape == (16, 3580)

    for ii, rr in enumerate(all_readers):
        f, d = rr.grab_data(f_start=8419.29685, f_stop=8419.2971)
        print(f.shape, d.shape)
        assert f.shape == (91, )
        assert d.shape == (16, 91)
Пример #17
0
def grab_parameters(dat_file, GBT_band, use_defaults, h5_fil_path):
    """
    takes dat file of GBT data and returns frequency parameters 
    used to calculate where the DC spikes will be 

    Arguments
    ----------
    dat_file : str
        filepath to the .dat file
    GBT_band : str
        the band at which the data was collected
        choose from {"L", "S", "C", "X"}
    use_defaults : bool
        if True, the program uses the preset, 
        hardcoded fch1 and foff values; if False,
        fch1 and foff are retrieved from the h5/fil
        files. 
    h5_fil_path : str
        the file path to the h5 or fil file
        corresponding to the given dat file. 
        Program will crash if use_defaults=False
        and no h5_fil_path is specified.
    Returns : fch1, foff, nfpc
    which will be used internally within remove_DC_spike
    """

    tbl = find.read_dat(dat_file)
    if use_defaults:
        if GBT_band == "L":
            fch1 = 1926.2695326677515  # LBAND  --  this is hardcoded, it would be nice to fix that
        if GBT_band == "C":
            fch1 = 8201.66015625  # CBAND                           ""
        if GBT_band == "S":
            fch1 = 2720.80078125  # SBAND                           ""
        if GBT_band == "X":
            fch1 = 11102.05078125  # XBAND                          ""
        foff = float(tbl["DELTAF"][0]) * 1e-6

    else:
        fil = bp.Waterfall(h5_fil_path)
        fch1 = fil.header['fch1']
        foff = fil.header['foff']

    #for Karen's files
    fch1 = float(fch1 - (foff / 2.0))

    nfpc = (1500.0 / 512.0) / abs(foff)

    num_course_channels = np.max(tbl["CoarseChanNum"])
    #print('fch1: {0}, foff: {1}'.format(fch1, foff))
    return fch1, foff, nfpc, num_course_channels
Пример #18
0
def test_info():
    a = bl.Waterfall(voyager_h5)
    print(a)
    a.info()
    a.blank_dc(n_coarse_chan=1)
    a.calibrate_band_pass_N1()
    'Below: orphaned functions. That is a little strange.'
    a.grab_data()
    a.read_data()
    'It is VERY strange for internal functions to be orphaned...'
    a._get_chunk_dimensions()
        # plenty of missed if suites
    a._get_blob_dimensions((300, 300, 300, 300))
    a._update_header()
Пример #19
0
def test_h5_io(frame_setup_no_data):
    frame = copy.deepcopy(frame_setup_no_data)

    fil_fn = 'temp.h5'
    frame.save_hdf5(fil_fn)

    temp_frame = stg.Frame(waterfall=fil_fn)
    assert_allclose(temp_frame.get_data(), frame.get_data())

    wf = bl.Waterfall(fil_fn)
    temp_frame = stg.Frame(waterfall=wf)
    assert_allclose(temp_frame.get_data(), frame.get_data())

    os.remove(fil_fn)
Пример #20
0
def test_info():
    a = bl.Waterfall(voyager_h5)
    print(a)
    a.info()
    a.blank_dc(n_coarse_chan=1)
    a.calibrate_band_pass_N1()
    # Below: orphaned functions (not used anywhere else).
    # That is a little strange...
    a.grab_data()
    a.read_data()
    # It is VERY strange for INTERNAL functions to be orphaned!
    a._get_chunk_dimensions()
    # plenty of missed if suites
    a._get_blob_dimensions((300, 300, 300, 300))
    a._update_header()
Пример #21
0
def calc_max_load(arg_path, verbose=False):
    r''' Calculate the max_load parameter value for a subsequent Waterfall instantiation.

    Algorithm:
        * A = minimum Waterfall object size.
        * B = data array size within one polarisation.
        * Return ceil(A + B in GB)
    '''
    wf = bl.Waterfall(arg_path, load_data=False)
    min_size = float(sys.getsizeof(wf.header)) + float(sys.getsizeof(wf))
    data_size = float(
        wf.header['nchans'] * wf.n_ints_in_file * wf.header['nbits']) / 8.0
    ngbytes = (min_size + data_size) / 1e9
    max_load = np.ceil(ngbytes)
    if verbose:
        print(
            'calc_max_load: Waterfall object size excluding data = {}, data array size = {}, total GBs = {:.1f}'
            .format(min_size, data_size, ngbytes))
    return max_load
Пример #22
0
def test_plotting():
    """ Some basic plotting tests

    TODO: Improve these tests (and the functions for that matter!
    """
    filename_fil = os.path.join(HERE, 'Voyager1.single_coarse.fine_res.h5')
    fil = bl.Waterfall(filename_fil)

    # Test make_waterfall_plots -- needs 6x files
    filenames_list = [filename_fil] * 6
    target  = 'Voyager'
    drates  = [-0.392226]
    fvals   = [8419.274785]
    f_start = 8419.274374 - 600e-6
    f_stop  = 8419.274374 + 600e-6
    node_string = 'test'
    filter_level = 1
    plot_event.make_waterfall_plots(filenames_list, target, drates, fvals, f_start, f_stop, node_string, filter_level)
    plt.show()
Пример #23
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")
Пример #24
0
def plot_candidate_events(candidate_event_dataframe,
                          fil_file_list,
                          filter_level,
                          source_name_list,
                          offset=0,
                          plot_snr_list=False,
                          **kwargs):
    r'''
    Calls :func:`~make_waterfall_plots` on each event in the input .csv file.

    Arguments
    ---------
    candidate_event_dataframe : dict
        A pandas dataframe containing information
        about a candidate event. The necessary data
        includes the start and stop frequencies, the
        drift rate, and the source name. To determine
        the required variable names and formatting
        conventions, see the output of
        find_event_pipeline.
    fil_file_list : list
        A Python list that contains a series of
        strings corresponding to the filenames of .fil
        files, each on a new line, that corresponds to
        the cadence used to create the .csv file used
        for event_csv_string.
    filter_level : int
        A string indicating the filter level of the
        cadence used to generate the
        candidate_event_dataframe. Used only for
        output file naming, convention is "f1", "f2",
        or "f3". Descriptions for the three levels of
        filtering can be found in the documentation
        for find_event.py
    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 panels) cadence.
    offset : int, optional
        The amount that the overdrawn "best guess"
        line from the event parameters in the csv
        should be shifted from its original position
        to enhance readability. Can be set to 0
        (default; draws line on top of estimated
        event) or 'auto' (shifts line to the left by
        an auto-calculated amount, with addition lines
        showing original position).
    plot_snr_list : bool (*** NOT YET IN USE***)
    kwargs : dict


    Examples
    --------
    It is highly recommended that users interact with this program via the
    front-facing plot_event_pipeline.py script. See the usage of that file in
    its own documentation.

    If you would like to run plot_candidate_events without calling
    plot_event_pipeline.py, the usage is as follows:

    >>> plot_event.plot_candidate_events(candidate_event_dataframe, fil_file_list,
    ...                                  filter_level, source_name_list, offset=0)

    '''
    global logger_plot_event

    # load in the data for each individual hit
    if candidate_event_dataframe is None:
        print(
            '*** plot_candidate_events: candidate_event_dataframe is None, nothing to do.'
        )
        return
    len_df = len(candidate_event_dataframe)
    if len_df < 1:
        print(
            '*** plot_candidate_events: len(candidate_event_dataframe) = 0, nothing to do.'
        )
        return
    for i in range(0, len_df):
        candidate = candidate_event_dataframe.iloc[i]
        on_source_name = candidate['Source']
        f_mid = candidate['Freq']
        drift_rate = candidate['DriftRate']

        # calculate the length of the total cadence from the fil files' headers
        first_fil = bl.Waterfall(fil_file_list[0], load_data=False)
        tfirst = first_fil.header['tstart']
        last_fil = bl.Waterfall(fil_file_list[-1], load_data=False)
        tlast = last_fil.header['tstart']
        t_elapsed = Time(tlast, format='mjd').unix - Time(
            tfirst, format='mjd').unix + (last_fil.n_ints_in_file -
                                          1) * last_fil.header['tsamp']

        # calculate the width of the plot based on making sure the full drift is visible
        bandwidth = 2.4 * abs(drift_rate) / 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_mid - (bandwidth / 2), f_mid + (bandwidth / 2)))

        # logger_plot_event.debug useful values
        logger_plot_event.debug(
            '*************************************************')
        logger_plot_event.debug(
            '***     The Parameters for This Plot Are:    ****')
        logger_plot_event.debug('Target = {}'.format(on_source_name))
        logger_plot_event.debug('Bandwidth = {} MHz'.format(round(
            bandwidth, 5)))
        logger_plot_event.debug('Time Elapsed (inc. Slew) = {} s'.format(
            round(t_elapsed)))
        logger_plot_event.debug('Middle Frequency = {} MHz'.format(
            round(f_mid, 4)))
        logger_plot_event.debug('Expected Drift = {} Hz/s'.format(
            round(drift_rate, 4)))
        logger_plot_event.debug(
            '*************************************************')

        # Pass info to make_waterfall_plots() function
        make_waterfall_plots(fil_file_list,
                             on_source_name,
                             f_start,
                             f_stop,
                             drift_rate,
                             f_mid,
                             filter_level,
                             source_name_list,
                             offset=offset,
                             **kwargs)
Пример #25
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
Пример #26
0
def test_write_to_fil():
    """ Load Voyager dataset and test plotting """

    a = bl.Waterfall(voyager_h5)
    a.write_to_fil('test_out.fil')
Пример #27
0
def test_info():
    a = bl.Waterfall(voyager_h5)
    print(a)
    a.info()
    a.blank_dc(n_coarse_chan=1)
    a.calibrate_band_pass_N1()
Пример #28
0
def plot_candidate_events_individually(full_candidate_event_dataframe,
                                       correct_fils,
                                       source_name,
                                       node_string,
                                       filter_level,
                                       show=False,
                                       overwrite=False,
                                       offset=0,
                                       **kwargs):
    trimmed_candidate_event_dataframe = pd.read_csv(
        full_candidate_event_dataframe)
    print('full_candidate_event_dataframe', full_candidate_event_dataframe)
    #get only the events in the dataframe that are from the right target
    #full_candidate_event_dataframe=full_candidate_event_dataframe['Source']
    print('trimmed_candidate_event_dataframe_Source',
          trimmed_candidate_event_dataframe.loc[:, ['Source']])
    #print ('full_candidate_event_dataframe_Source', full_candidate_event_dataframe['Source'])
    candidate_event_dataframe = trimmed_candidate_event_dataframe.loc[:, [
        'Source', 'Freq', 'DriftRate', 'FreqStart'
    ]]
    #candidate_event_dataframe = full_candidate_event_dataframe.loc[full_candidate_event_dataframe['Source'] == source_name]
    print('full_candidate_event_dataframe', candidate_event_dataframe)

    #load in the data for each individual hit
    for i in range(0, len(candidate_event_dataframe)):
        candidate = candidate_event_dataframe.iloc[i]
        source_id = candidate['Source']
        f_mid = candidate['Freq']
        drate = -1 * candidate['DriftRate']

        #load in the list of .fil files
        filelist = open(correct_fils).readlines()
        filelist = [files.replace('\n', '') for files in filelist]
        #print ('dat_file_list', dat_file_list)
        filelist = [files.replace(',', '') for files in filelist]
        #filelist = correct_fils
        print('filelist', filelist)
        #calculate the length of the total ABABAB from the fil files' headers
        fil0 = bl.Waterfall(filelist[0], load_data=True)
        print('fil0', fil0)
        fil0header = fil0.header
        print('fil0header', fil0header)
        y = {}
        for key, value in fil0header.items():
            y[key.decode("utf-8")] = value
        fil0header = y
        print('fil0header', fil0header)
        t0 = fil0header['tstart']

        fil6 = bl.Waterfall(filelist[-1], load_data=True)
        fil6header = fil6.header
        z = {}
        for key, value in fil6header.items():
            z[key.decode("utf-8")] = value
        fil6header = z
        t6 = fil6header['tstart']
        t_elapsed = Time(t6, format='mjd').unix - Time(
            t0, format='mjd').unix + (fil6.n_ints_in_file -
                                      1) * fil6header['tsamp']

        #calculate the width of the plot based on making sure the full drift is visible
        bw = 2.4 * abs(drate) / 1e6 * t_elapsed
        bw = np.max((bw, 500. / 1e6))

        #Get start and stop frequencies based on midpoint and bandwidth
        f_start, f_stop = np.sort((f_mid - bw / 2, f_mid + bw / 2))

        #Print useful values
        print('*************************************************')
        print('***     The Parameters for This Plot Are:     ***')
        print('*************************************************')
        print('Target = ', source_id)
        print('Bandwidth (MHz) = ', bw)
        print('Total Time Elapsed (s) = ', t_elapsed)
        print('Start Frequency (MHz) = ', f_start)
        print('Middle Frequency (MHz) = ', f_mid)
        print('Stop Frequency (MHz) = ', f_stop)
        print('Expected Drift (Hz/s) = ', drate)
        print('*************************************************')
        print('*************************************************')

        #Pass info to make_waterfall_plots() function
        subplots = make_waterfall_plots(filelist, [source_id], [drate],
                                        [f_mid],
                                        f_start,
                                        f_stop,
                                        node_string,
                                        filter_level,
                                        ion=False,
                                        epoch=None,
                                        local_host='',
                                        plot_name='',
                                        save_pdf_plot=True,
                                        saving_fig=True,
                                        offset=offset,
                                        **kwargs)
    return
Пример #29
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.)
    """

    #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'

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

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

    filheader = fil.header
    f = {}
    for key, value in filheader.items():
        f[key] = value
    filheader = f

    print('filheader', filheader)
    t0 = filheader['tstart']
    plot_f, plot_data = fil.grab_data(f_start=f_start, f_stop=f_stop)
    dec_fac_x, dec_fac_y = 1, 1
    #print ('plot_data', plot_data)

    #rebinning data to plot correctly with fewer plots
    if plot_data.shape[0] > MAX_IMSHOW_POINTS[0]:
        dec_fac_x = plot_data.shape[0] / MAX_IMSHOW_POINTS[0]
        print('dec_fac_x', dec_fac_x)
    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 = filheader['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)
        fil = bl.Waterfall(filename, f_start=f_start, f_stop=f_stop)
        filheader = fil.header

        try:
            this_plot = plot_waterfall(fil,
                                       f_start=f_start,
                                       f_stop=f_stop,
                                       drate=drate_max,
                                       vmin=vmin,
                                       vmax=vmax,
                                       **kwargs)
            for drate, fval in zip(drates, fvals):
                t_elapsed = Time(filheader['tstart'],
                                 format='mjd').unix - Time(t0,
                                                           format='mjd').unix
                t_duration = (fil.n_ints_in_file - 1) * filheader['tsamp']
                f_event = fval + drate / 1e6 * t_elapsed
                overlay_drift(f_event, drate, t_duration, offset)
        except:
            raise

    #Titling the plot
        if i == 0:
            srcname = "%s $\dot{\\nu}$=%2.3f Hzs$^{-1}$" % (target, drate_max)
            plt.title(srcname)
    #Plot formatting
        if i < len(filenames_list) - 1:
            plt.xticks(np.arange(f_start, f_stop, delta_f / 4.),
                       ['', '', '', ''])

    #More plot formatting.
    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)

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

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

    #save the figures
    plt.savefig(node_string + '_f' + str(filter_level) + '_' + target[0] +
                '_dr_' + "{:0.2f}".format(drate_max) + '_freq_'
                "{:0.2f}".format(f_start) + ".png",
                bbox_inches='tight')

    return subplots
Пример #30
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