diff --git a/applications/lofar2/model/pfb_os/dsp.py b/applications/lofar2/model/pfb_os/dsp.py index d14f59f46db71123b03bebfa1945225679cbd9f5..017ac10ca2c939f80132cb4ca85b33b95bb5fd1e 100644 --- a/applications/lofar2/model/pfb_os/dsp.py +++ b/applications/lofar2/model/pfb_os/dsp.py @@ -121,15 +121,15 @@ def impulse_at_zero_crossing(x): # Windowed sinc filter design ############################################################################### -def raised_cosine_response(Ntaps, Nsps, beta): +def raised_cosine_response(Ntaps, Nsps, roBeta): """Generate a raised cosine (RC) FIR filter impulse response. Input: . Ntaps : FIR filter length . Nsps: symbol period Tsymbol in number of samples per symbol - . beta : Roll off factor in [0, 1.0], BW = (1 + beta) / Tsymbol, so: - - beta = 0.0: rectangular spectrum with BW = 1 / Tsymbol - - beta = 1.0: cosine spectrum with BW = 2 / Tsymbol + . roBeta : Roll off factor in [0, 1.0], BW = (1 + roBeta) / Tsymbol, so: + - roBeta = 0.0: rectangular spectrum with BW = 1 / Tsymbol + - roBeta = 1.0: cosine spectrum with BW = 2 / Tsymbol Return: . hRc : impulse response of the raised cosine filter. """ @@ -145,12 +145,12 @@ def raised_cosine_response(Ntaps, Nsps, beta): # apply cos term, use for loop instead of array assignment, to detect divide by 0 for tI in tIndices: t = tI - tCenter - if np.abs(t) != Tsymbol / (2 * beta): - hRc[tI] *= np.cos(np.pi * beta * t / Tsymbol) / (1 - (2 * beta * t / Tsymbol)**2) + if np.abs(t) != Tsymbol / (2 * roBeta): + hRc[tI] *= np.cos(np.pi * roBeta * t / Tsymbol) / (1 - (2 * roBeta * t / Tsymbol)**2) return hRc -def square_root_raised_cosine_response(Ntaps, Nsps, beta): +def square_root_raised_cosine_response(Ntaps, Nsps, roBeta): """Generate a square root raised cosine (SRRC) FIR filter impulse response. Reference: @@ -160,7 +160,7 @@ def square_root_raised_cosine_response(Ntaps, Nsps, beta): Input: . Ntaps : FIR filter length . Nsps: symbol period Tsymbol in number of samples per symbol - . beta : Roll off factor in [0, 1.0] + . roBeta : Roll off factor in [0, 1.0] Return: . hSrRc : impulse response of the square root raised cosine filter. """ @@ -171,20 +171,20 @@ def square_root_raised_cosine_response(Ntaps, Nsps, beta): t = tIndices - tCenter # numerator term, using array assignment - hSrRc = 1 / Tsymbol * (np.cos(np.pi * (1 + beta) * t / Tsymbol) * 4 * beta * t / Tsymbol + - np.sin(np.pi * (1 - beta) * t / Tsymbol)) + hSrRc = 1 / Tsymbol * (np.cos(np.pi * (1 + roBeta) * t / Tsymbol) * 4 * roBeta * t / Tsymbol + + np.sin(np.pi * (1 - roBeta) * t / Tsymbol)) # apply denumerator term, use for loop instead of array assignment, to detect divide by 0 for tI in tIndices: t = tI - tCenter if t == 0.0: - hSrRc[tI] = 1 / Tsymbol * (1 + beta * (4 / np.pi - 1)) - elif np.abs(t) == Tsymbol / (4 * beta): - hSrRc[tI] = 1 / Tsymbol * beta / np.sqrt(2) * \ - ((1 + 2 / np.pi) * np.sin(np.pi / (4 * beta)) + - (1 - 2 / np.pi) * np.cos(np.pi / (4 * beta))) + hSrRc[tI] = 1 / Tsymbol * (1 + roBeta * (4 / np.pi - 1)) + elif np.abs(t) == Tsymbol / (4 * roBeta): + hSrRc[tI] = 1 / Tsymbol * roBeta / np.sqrt(2) * \ + ((1 + 2 / np.pi) * np.sin(np.pi / (4 * roBeta)) + + (1 - 2 / np.pi) * np.cos(np.pi / (4 * roBeta))) else: - hSrRc[tI] /= (1 - (4 * beta * t / Tsymbol)**2) * (np.pi * t / Tsymbol) + hSrRc[tI] /= (1 - (4 * roBeta * t / Tsymbol)**2) * (np.pi * t / Tsymbol) return hSrRc @@ -195,7 +195,7 @@ def square_root_raised_cosine_response(Ntaps, Nsps, beta): def nof_taps_kaiser_window(fs, fpass, fstop, atten_db): """Number of FIR LPF taps using Kaiser window based design - Reference: [HARRIS 3.2, Fig. 3.8 for beta] + Reference: [HARRIS 3.2, Fig. 3.8 for kaiserBeta] """ df = fstop - fpass return int((fs / df) * (atten_db - 8) / 14) @@ -242,7 +242,7 @@ def ideal_low_pass_filter(Npoints, Npass, bandEdgeGain=1.0): def prototype_fir_low_pass_filter(method='firls', Npoints=1024, Ntaps=16, Ncoefs=1024*16, - hpFactor=0.9, transitionFactor=0.4, stopRippleFactor=1000000, beta=1, fs=1.0): + hpFactor=0.9, transitionFactor=0.4, stopRippleFactor=1000000, kaiserBeta=1, fs=1.0): """Derive FIR coefficients for prototype low pass filter Use method 'firls' or 'remez'. @@ -274,7 +274,7 @@ def prototype_fir_low_pass_filter(method='firls', - hpFactor : Half power bandwidth of the filter relative to BWbin - transitionFactor: transition bandwidth factor relative to fpass - stopRippleFactor: stopband ripple factor relative to pass band ripple - - beta: When beta > 0 then additionally apply a Kaiser window on FIR + - kaiserBeta: When kaiserBeta > 0 then additionally apply a Kaiser window on FIR coefficients - fs: sample frequency, for logging Return: @@ -292,12 +292,12 @@ def prototype_fir_low_pass_filter(method='firls', rippleWeights = [1, stopRippleFactor] # Design subband filter - h = design_fir_low_pass_filter(method, Ncoefs, fpass, fstop, fcutoff, cutoffGain, rippleWeights, beta, fs) + h = design_fir_low_pass_filter(method, Ncoefs, fpass, fstop, fcutoff, cutoffGain, rippleWeights, kaiserBeta, fs) return h def design_fir_low_pass_filter(method, - Ncoefs, fpass, fstop, fcutoff=0, cutoffGain=0.5, rippleWeights=[1, 1], beta=0, fs=1.0): + Ncoefs, fpass, fstop, fcutoff=0, cutoffGain=0.5, rippleWeights=[1, 1], kaiserBeta=0, fs=1.0): """Derive FIR coefficients for prototype low pass filter Use method 'firls' or 'remez', fs = 1.0 @@ -318,7 +318,7 @@ def design_fir_low_pass_filter(method, - fcutoff: when fcutoff > 0, then define cutoff frequency point in transition band, fpass < fcutoff < fstop - cutoffGain: normalized LPF gain at fcutoff - rippleWeights: relative ripple factors for pass band, optional fcutoff, and stop band - - beta: When beta > 0, then additionally apply a Kaiser window on FIR + - kaiserBeta: When kaiserBeta > 0, then additionally apply a Kaiser window on FIR coefficients Return: - h: FIR coefficients for requested Ncoefs @@ -368,11 +368,11 @@ def design_fir_low_pass_filter(method, hFir = signal.remez(N, [0, f_pb, f_co, f_co, f_sb, fNyquist], [1, cutoffGain, 0], rippleWeights, fs=fs) - # Additionally apply a Kaiser window, with beta = 1 like in pfs_coeff_final.m, this improves + # Additionally apply a Kaiser window, with kaiserBeta = 1 like in pfs_coeff_final.m, this improves # the stopband attenuation near the transition band somewhat - # . beta: 0 rect, 5 hamming, 6 hanning - if beta: - win = signal.windows.kaiser(N, beta) + # . kaiserBeta: 0 rect, 5 hamming, 6 hanning + if kaiserBeta: + win = signal.windows.kaiser(N, kaiserBeta) hFir *= win # Normalize DC gain