Exemple #1
0
def analyze(P: dict):

    tx = loadbin(P['txfn'], P['txfs'], tlim=(0, P['tm']))
    if P['verbose']:
        plotraw(tx, None, P['txfs'])
    print(
        f'Using {P["pri"]*1000} ms PRI for {P["tm"]*1e6} us chirp, with {P["Nchirp"]} pulses incoherently integrated'
    )
    # %%
    NrxPRI = int(P['pri'] * rxfs)  # samples in a PRI
    Lrx = NrxPRI * P['Nchirp']

    if P['rxfn'] is not None:
        Nsampfile = P['rxfn'].stat().st_size // LSAMP
        Tfile = Nsampfile / P['rxfs']
        print(P['rxfn'], f'is {Tfile:0.1f} seconds long')
        isamp = range(0, Nsampfile, Lrx)

    else:
        print('simulation')
        isamp = range(0, Nsim * Lrx, Lrx)

    t = np.array(isamp) / P['txfs']  # elapsed time seconds
    if P['t0'] is not None:
        t += P['t0']


# %%
    if P['outfn']:
        print('writing', outfn)
        with h5py.File(outfn, 'w') as f:
            f.create_dataset('Rxy',
                             shape=(t.size, int(NrxPRI * P['resample'])),
                             dtype=np.complex128,
                             chunks=True,
                             compression='gzip')
            f['t'] = t
            f['lags'] = np.arange(-NrxPRI // 2, NrxPRI // 2)
            f['t0'] = P['t0']
            f['cmd'] = ' '.join(sys.argv)
            f['fs'] = P['txfs']

    for k, (i, j) in enumerate(zip(isamp, isamp[1:])):
        if P['rxfn'] is None:
            rx = 0.05 * tx + 0.1 * tx.max() * (
                np.random.randn(P['Nchirp'], tx.size) +
                1j * np.random.randn(P['Nchirp'], tx.size))
            rx = rx.ravel()
        else:
            rx = loadbin(P['rxfn'], P['rxfs'], tlim=P['t0'], isamp=(i, j))

        lags = procchunk(rx, tx, P)

        if outfn:
            with h5py.File(outfn, 'a') as f:
                f['Rxy'][k, :] = lags

        print(
            f'processing t={t[k]:.2f} sec., {t[k]/Tfile*100:.3f} % complete.\r',
            end="")
Exemple #2
0
def analyze(P: dict):

    tx = loadbin(P["txfn"], P["txfs"], tlim=(0, P["tm"]))
    if P["verbose"]:
        plotraw(tx, None, P["txfs"])
    print(
        f'Using {P["pri"]*1000} ms PRI for {P["tm"]*1e6} us chirp, with {P["Nchirp"]} pulses incoherently integrated'
    )
    # %%
    NrxPRI = int(P["pri"] * rxfs)  # samples in a PRI
    Lrx = NrxPRI * P["Nchirp"]

    if P["rxfn"] is not None:
        Nsampfile = P["rxfn"].stat().st_size // LSAMP
        Tfile = Nsampfile / P["rxfs"]
        print(P["rxfn"], f"is {Tfile:0.1f} seconds long")
        isamp = range(0, Nsampfile, Lrx)

    else:
        print("simulation")
        isamp = range(0, Nsim * Lrx, Lrx)

    t = np.array(isamp) / P["txfs"]  # elapsed time seconds
    if P["t0"] is not None:
        t += P["t0"]
    # %%
    if P["outfn"]:
        print("writing", outfn)
        with h5py.File(outfn, "w") as f:
            f.create_dataset(
                "Rxy",
                shape=(t.size, int(NrxPRI * P["resample"])),
                dtype=np.complex128,
                chunks=True,
                compression="gzip",
            )
            f["t"] = t
            f["lags"] = np.arange(-NrxPRI // 2, NrxPRI // 2)
            f["t0"] = P["t0"]
            f["cmd"] = " ".join(sys.argv)
            f["fs"] = P["txfs"]

    for k, (i, j) in enumerate(zip(isamp, isamp[1:])):
        if P["rxfn"] is None:
            rx = 0.05 * tx + 0.1 * tx.max() * (
                np.random.randn(P["Nchirp"], tx.size) +
                1j * np.random.randn(P["Nchirp"], tx.size))
            rx = rx.ravel()
        else:
            rx = loadbin(P["rxfn"], P["rxfs"], tlim=P["t0"], isamp=(i, j))

        lags = procchunk(rx, tx, P)

        if outfn:
            with h5py.File(outfn, "a") as f:
                f["Rxy"][k, :] = lags

        print(
            f"processing t={t[k]:.2f} sec., {t[k]/Tfile*100:.3f} % complete.\r",
            end="")
def analyze(P:dict):

    tx = loadbin(P['txfn'], P['txfs'], tlim=(0,P['tm']))
    if P['verbose']:
        plotraw(tx, None, P['txfs'])
    print(f'Using {P["pri"]*1000} ms PRI for {P["tm"]*1e6} us chirp, with {P["Nchirp"]} pulses incoherently integrated')
# %%
    NrxPRI = int(P['pri']*rxfs)  # samples in a PRI
    Lrx = NrxPRI*P['Nchirp']

    if P['rxfn'] is not None:
        Nsampfile = P['rxfn'].stat().st_size//LSAMP
        Tfile = Nsampfile / P['rxfs']
        print(P['rxfn'], f'is {Tfile:0.1f} seconds long')
        isamp = range(0, Nsampfile, Lrx)

    else:
        print('simulation')
        isamp = range(0, Nsim*Lrx, Lrx)

    t = np.array(isamp) / P['txfs']  # elapsed time seconds
    if P['t0'] is not None:
        t += P['t0']
# %%
    if P['outfn']:
        print('writing',outfn)
        with h5py.File(outfn,'w') as f:
            f.create_dataset('Rxy',shape=(t.size, int(NrxPRI*P['resample'])),
                             dtype=np.complex128,chunks=True,compression='gzip')
            f['t'] = t
            f['lags'] = np.arange(-NrxPRI//2,NrxPRI//2)
            f['t0'] = P['t0']
            f['cmd'] = ' '.join(sys.argv)
            f['fs'] = P['txfs']


    for k,(i,j) in enumerate(zip(isamp,isamp[1:])):
        if P['rxfn'] is None:
            rx = 0.05*tx + 0.1*tx.max()*(np.random.randn(P['Nchirp'],tx.size)
                                         + 1j*np.random.randn(P['Nchirp'],tx.size))
            rx = rx.ravel()
        else:
            rx = loadbin(P['rxfn'], P['rxfs'], tlim=P['t0'], isamp=(i, j))

        lags = procchunk(rx, tx, P)

        if outfn:
            with h5py.File(outfn,'a') as f:
                f['Rxy'][k,:] = lags

        print(f'processing t={t[k]:.2f} sec., {t[k]/Tfile*100:.3f} % complete.\r',end="")
Exemple #4
0
def cwproc(fn, fsaudio, tlim, fc, ax=None):
    fn = Path(p.fn).expanduser()

    fs = int(p.fs)  # to allow 100e3 on command line
    fsaudio = int(fsaudio)

    dat, t = loadbin(fn, fs, tlim)
    dat = freq_translate(dat, fc, fs)
    dat = downsample(dat, fs, fsaudio)
    # %% play sound
    if 0:  # not for when looping, it will try to play dozens of files at once.
        playaudio(dat, fsaudio, p.outwav)
    #%% plots
    if 0 and dat.size < 500e3:  # plots will crash if too many points
        if ax is None:
            ax = figure().gca()
        ax.plot(t + tlim[0], dat.real[:])
        ax.set_title(f"{fn.name} Fs: {fs} Hz  t={tlim[0]}..{tlim[1]}")
        ax.set_xlabel("time [sec]")
        ax.set_ylabel("amplitude")

    f, tt, Sxx, Sp = spec(dat,
                          fsaudio,
                          p.flim,
                          tlim,
                          be,
                          vlim=p.vlim,
                          zpad=p.zeropad)
    # %% analysis
    Abin = np.empty(be.size - 1)
    for i in range(len(be) - 1):
        ibin = (f < be[i + 1]) & (f > be[i])
        Abin[i] = Sp[ibin].sum()

    return Abin
Exemple #5
0
def cwproc(fn, fsaudio, tlim, fc, ax=None):
    fn=Path(p.fn).expanduser()

    fs = int(p.fs) # to allow 100e3 on command line
    fsaudio = int(fsaudio)

    dat,t = loadbin(fn, fs, tlim)
    dat = freq_translate(dat,fc,fs)
    dat = downsample(dat,fs,fsaudio)
# %% play sound
    if 0:  # not for when looping, it will try to play dozens of files at once.
        playaudio(dat, fsaudio, p.outwav)
#%% plots
    if 0 and dat.size < 500e3: # plots will crash if too many points
        if ax is None:
            ax = figure().gca()
        ax.plot(t + tlim[0], dat.real[:])
        ax.set_title(f'{fn.name} Fs: {fs} Hz  t={tlim[0]}..{tlim[1]}')
        ax.set_xlabel('time [sec]')
        ax.set_ylabel('amplitude')

    f,tt,Sxx,Sp = spec(dat, fsaudio, p.flim, tlim, be, vlim=p.vlim, zpad=p.zeropad)
# %% analysis
    Abin = np.empty(be.size-1)
    for i in range(len(be)-1):
        ibin = (f < be[i+1]) & (f > be[i])
        Abin[i] = Sp[ibin].sum()

    return Abin
Exemple #6
0
def dodemod(rx, P: dict):
    aud = None
    fs = P["rxfs"]

    if P["demod"] == "chirp":
        tx = loadbin(P["txfn"], P["txfs"])
        if tx is None:
            warnings.warn("simulated chirp reception")
            tx = rx
            rx = 0.05 * rx + 0.1 * rx.max() * (np.random.randn(rx.size) +
                                               1j * np.random.randn(rx.size))
            txfs = fs
        else:
            rx = scipy.signal.resample_poly(rx, UP, DOWN)
            fs = txfs = P["txfs"]

        txsec = tx.size / txfs  # length of TX in seconds
        if P["pri"] is None:
            pri = txsec
        print(
            f'Using {pri*1000} ms PRI and {P["Npulse"]} pulses incoherently integrated'
        )

        # %% integration
        NrxPRI = int(fs * pri)  # Number of RX samples per PRI
        NrxStack = rx.size // NrxPRI  # number of complete PRIs received in this data
        Nint = NrxStack // P["Npulse"]  # Number of steps we'll take iterating
        Nextract = (
            P["Npulse"] * NrxPRI
        )  # total number of samples to extract (in general part of one PRI is discarded after numerous PRIs)

        ax = None
        for i in range(Nint):
            ci = slice(i * Nextract, (i + 1) * Nextract)
            rxint = rx[ci].reshape((NrxPRI, P["Npulse"])).mean(axis=1)
            Rxy = np.correlate(tx, rxint, "full")
            ax = plotxcor(Rxy, txfs, ax)
            draw()
            pause(0.5)
    elif P["demod"] == "am":
        aud = am_demod(P["again"] * rx,
                       fs,
                       fsaudio,
                       P["fc"],
                       p.audiobw,
                       frumble=p.frumble,
                       verbose=True)
    elif P["demod"] == "ssb":
        aud = ssb_demod(P["again"] * rx,
                        fs,
                        fsaudio,
                        P["fc"],
                        p.audiobw,
                        verbose=True)

    return aud, fs
Exemple #7
0
def main():
    p = ArgumentParser()
    p.add_argument('fn', help='binary raw IQ capture SDR file to analyze')
    p.add_argument('fs', help='sampling frequency [Hz]', type=int)
    p.add_argument('-fc', help='baseband tunding freq [Hz]', type=float)
    p.add_argument('-t', '--tlim',
                   help='start stop increment [seconds] to load',
                   type=float, nargs=2, default=(0., None))
    p.add_argument('-v', '--verbose', action='store_true')

    P = p.parse_args()

    fn = Path(P.fn).expanduser()

    assert isinstance(P.fs, (float, int))
    fs = int(P.fs)
# %%
    sig = loadbin(fn, fs, P.tlim)
# %%
    m = fm_demod(sig, fs, fsaudio, P.fc, 75e3, P.verbose)
    playaudio(m, fsaudio)

    show()
Exemple #8
0
def getrx(P: dict):
    rx = loadbin(P["rxfn"], P["rxfs"], P["tlim"])
    plotraw(rx, None, P["rxfs"])

    return rx
Exemple #9
0
                   help='subspace method (esprit,rootmusic)',
                   default='esprit')
    p.add_argument('--noest',
                   help='skip estimation (just plot) for debugging',
                   action='store_true')
    p.add_argument(
        '--python',
        help='force Python subspace (disable Fortran) for debugging',
        action='store_true')
    p.add_argument('--all',
                   help='show all tone freq, including feedthrough',
                   action='store_true')
    p = p.parse_args()

    fs = int(p.fs)

    if p.fn is None:  #simulation
        rx, t = cwsim(fs, p.Np, p.T)
    else:  # load data file
        rx = loadbin(p.fn, fs, p.tlim)
        rx = freq_translate(rx, p.fx0, fs)
        rx = downsample(rx, fs, fsaudio)
#%% estimate beat frequency
    if not p.noest:
        fb_est, conf = cw_est(rx, fsaudio, p.Nt, p.method, p.python, p.all)
        print('estimated beat frequencies', fb_est)
        print('sigma', conf)
#%% plot
    cwplot(fb_est, rx.squeeze(), t, fsaudio, p.fn)
    show()
Exemple #10
0
def getrx(P: dict):
    rx = loadbin(P['rxfn'], P['rxfs'], P['tlim'])
    plotraw(rx, None, P['rxfs'])

    return rx
Exemple #11
0
    p = ArgumentParser()
    p.add_argument('fn',help='data file .bin to analyze',nargs='?',default=None)
    p.add_argument('-fs',help='baseband sampling frequency [Hz]',type=float,default=16e3)
    p.add_argument('-Np',help='number of pulses to integrate',type=int,default=1)
    p.add_argument('-fx0',help='frequency translation center frequency',type=float)
    p.add_argument('-Nt',help='number of tones to find',type=int,default=2)
    p.add_argument('-T',help='pulse length (seconds)',type=float,default=0.1)
    p.add_argument('-t','--tlim',help='time to analyze e.g. -t 3 4 means process from t=3  to t=4 seconds',nargs=2,type=float )
    p.add_argument('-m','--method',help='subspace method (esprit,rootmusic)',default='esprit')
    p.add_argument('--noest',help='skip estimation (just plot) for debugging',action='store_true')
    p.add_argument('--python',help='force Python subspace (disable Fortran) for debugging',action='store_true')
    p.add_argument('--all',help='show all tone freq, including feedthrough',action='store_true')
    p = p.parse_args()

    fs = int(p.fs)

    if p.fn is None: #simulation
        rx,t = cwsim(fs, p.Np, p.T)
    else: # load data file
        rx = loadbin(p.fn, fs, p.tlim)
        rx = freq_translate(rx,p.fx0,fs)
        rx = downsample(rx, fs, fsaudio)
#%% estimate beat frequency
    if not p.noest:
        fb_est,conf = cw_est(rx, fsaudio, p.Nt, p.method, p.python, p.all)
        print('estimated beat frequencies',fb_est)
        print('sigma',conf)
#%% plot
    cwplot(fb_est,rx.squeeze(),t, fsaudio, p.fn)
    show()