예제 #1
0
def plot_hit(fil_filename, dat_filename, hit_id, bw=None, offset=0):
    r"""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, optional): Offset drift line on plot. Default 0.
      bw:  (Default value = None)

    Returns:

    """
    # Load hit details
    dat = find_event.read_dat(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 = 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()
    plot_event.overlay_drift(f0, f0, f0, hit['DriftRate'], t_duration, offset)
예제 #2
0
def grab_parameters(dat_file, GBT_band):
    """
    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"}
        
    Returns : fch1, foff, nfpc
    which will be used internally within remove_DC_spike
    """
    
    tbl = find.read_dat(dat_file)
    
    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 
    
    nfpc=(1500.0/512.0)/abs(foff)
    
    num_course_channels = np.max(tbl["CoarseChanNum"])
    return fch1, foff, nfpc, num_course_channels
예제 #3
0
def validate_voyager_hits(filename_dat):
    """ This checks voyager hits against known values.

    Known values:
    # --------------------------
    # ID  Drift_Rate SNR 	      Unc_Freq 	      Corr_Freq 	Index   	freq_start 	   freq_end 	...
    # --------------------------
    001	 -0.392226	 30.612128	   8419.319368	   8419.319368	739933	   8419.319779	   8419.318963	...
    002	 -0.373093	245.707984	   8419.297028	   8419.297028	747929	   8419.297439	   8419.296623	...
    003	 -0.392226	 31.220652	   8419.274374	   8419.274374	756037	   8419.274785	   8419.273969	...
    (from flipped)
    003	 -0.392226	 30.612118	   8419.319366	   8419.319366	308642	   8419.318955	   8419.319771	...
    002	 -0.373093	245.707905	   8419.297025	   8419.297025	300646	   8419.296614	   8419.297430	...
    001	 -0.392226	 31.220642	   8419.274372	   8419.274372	292538	   8419.273961	   8419.274777	...
    """
    print("\n===== validate_voyager_hits =====")
    h = find_event.read_dat(filename_dat)
    print(h)

    valid_data = [
        {
            'Freq': 8419.319368,
            'FreqStart': 8419.319779,
            'FreqEnd': 8419.318963,
            'SNR': 30.612128,
            'DriftRate': -0.392226,
        },
        {
            'Freq': 8419.297028,
            'FreqStart': 8419.297439,
            'FreqEnd': 8419.296623,
            'SNR': 245.707984,
            'DriftRate': -0.373093,
        },
        {
            'Freq': 8419.274374,
            'FreqStart': 8419.274785,
            'FreqEnd': 8419.273969,
            'SNR': 31.220652,
            'DriftRate': -0.392226,
        }
    ]

    atols = {'Freq': 0.000005, 'FreqStart': 0.00001, 'FreqEnd': 0.00001, 'SNR': 0.001, 'DriftRate': 0.02}

    for vd in valid_data:
        hmax = h[np.isclose(h['Freq'], vd['Freq'], rtol=0.000001)].iloc[0]

        for key in vd.keys():
            print(key, hmax[key], vd[key])
            if key in ('FreqStart', 'FreqEnd'):
                upper = np.isclose(hmax[key], vd['FreqStart'], atol=atols[key], rtol=0)
                lower = np.isclose(hmax[key], vd['FreqEnd'], atol=atols[key], rtol=0)
                assert upper or lower
            else:
                assert np.isclose(hmax[key], vd[key], atol=atols[key], rtol=0)
    return hmax
예제 #4
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
예제 #5
0
def validate_voyager_hits(filename_dat):
    r""" This checks voyager hits against known values.
    """
    print("\n===== validate_voyager_hits =====")
    df_hits = find_event.read_dat(filename_dat)
    print(df_hits)

    valid_data = [ # in unflipped order
        { # 001
            'Freq': 8419.319368,
            'FreqStart': 8419.32,
            'FreqEnd': 8419.32,
            'SNR': 30.612128,
        },
        { # 002
            'Freq': 8419.30,
            'FreqStart': 8419.30,
            'FreqEnd': 8419.30,
            'SNR': 245.707984,
        },
        { # 003
            'Freq': 8419.274374,
            'FreqStart': 8419.27,
            'FreqEnd': 8419.27,
            'SNR': 31.220652,
        }
    ]

    atols = {'Freq': 0.001, 'FreqStart': 0.001, 'FreqEnd': 0.001, 'SNR': 0.001}

    for vd in valid_data:
        hmax = df_hits[np.isclose(df_hits['Freq'], vd['Freq'],
                                  rtol=0.000001)].iloc[0]
        for key in vd.keys():
            #print('validate_voyager_hits: key, hmax[key], vd[key]: ', key, hmax[key], vd[key])
            if key in ('FreqStart', 'FreqEnd'):
                upper = np.isclose(hmax[key], vd['FreqStart'], atol=atols[key])
                lower = np.isclose(hmax[key], vd['FreqEnd'], atol=atols[key])
                if not (upper and lower):
                    raise ValueError(
                        'validate_voyager_hits: upper or lower: hmax[key]={}, vd[FreqStart]={}, vd[FreqEnd]={}'
                        .format(hmax[key], vd['FreqStart'], vd['FreqEnd']))
            else:
                if not np.isclose(hmax[key], vd[key], atol=atols[key]):
                    raise ValueError(
                        'validate_voyager_hits: other: key={}, hmax[key]={}, vd[key]={}'
                        .format(key, hmax[key], vd[key]))

    print('\nvalidate_voyager_hits: SUCCESS\n')
예제 #6
0
def calculate_hist(dat_file, GBT_band, bin_width=1, tbl=None):
    """
    calculates a histogram of the number of hits for a single .dat file
    
    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"}
    bin_width : float
        width of the hisrogram bins in units of MHz
        The default is 1 Mhz
    tbl : pandas.core.frame.DataFrame
        Alternate way of providing contents of a dat file
        
    Returns
    --------
    hist : numpy.ndarray 
        the count of hits in each bin
    bin_edges : numpy.ndarray
        the edge values of each bin. Has length Nbins+1
    """
    #read the file into a pandas dataframe
    if type(tbl) != pandas.core.frame.DataFrame:
        tbl = find.read_dat(dat_file)

    #make the bins for the histogram
    # band boundaries as listed in Traas 2021
    if GBT_band == "L":
        min_freq = 1100
        max_freq = 1900
    if GBT_band == "S":
        min_freq = 1800
        max_freq = 2800
    if GBT_band == "C":
        min_freq = 4000
        max_freq = 7800
    if GBT_band == "X":
        min_freq = 7800
        max_freq = 11200
    bins = np.linspace(min_freq,
                       max_freq,
                       int((max_freq - min_freq) / bin_width),
                       endpoint=True)
    hist, bin_edges = np.histogram(tbl["Freq"], bins=bins)
    return hist, bin_edges
예제 #7
0
def plot_hits(filename_fil, filename_dat):
    r""" Plot the hits in a .dat file. """
    print("\n===== plot_hits =====")
    table = find_event.read_dat(filename_dat)
    print(table)

    plt.figure(figsize=(10, 8))
    N_hit = len(table)
    if N_hit > 10:
        print("Warning: More than 10 hits found. Only plotting first 10")
        N_hit = 10

    for ii in range(N_hit):
        plt.subplot(N_hit, 1, ii + 1)
        plot_hit(filename_fil, filename_dat, ii)
    plt.tight_layout()
    plt.savefig(filename_dat.replace('.dat', '.png'))