From 7a1fd24dbacbab3956b03a96dc128ff22af4b0c4 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Thu, 29 Aug 2024 16:43:29 +0200 Subject: [PATCH] Correct inData order in non_maximal_downsample_bpf() --- applications/lofar2/model/rtdsp/multirate.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/applications/lofar2/model/rtdsp/multirate.py b/applications/lofar2/model/rtdsp/multirate.py index 145e6e38cf..2378f6cd6f 100644 --- a/applications/lofar2/model/rtdsp/multirate.py +++ b/applications/lofar2/model/rtdsp/multirate.py @@ -190,7 +190,7 @@ class PolyPhaseFirFilterStructure: def map_to_poly_delays(self, delayLine): self.polyDelays = delayLine.reshape((self.Ntaps, self.Nphases)).T - def shift_in_data(self, inData): + def shift_in_data(self, inData, flipped=False): """Shift block of data into the polyDelays structure. View polyDelays as delay line if L < Nphases. Shift in from the left @@ -202,22 +202,25 @@ class PolyPhaseFirFilterStructure: . inData: Block of one or more input samples with index as time index n in inData[n], so oldest sample at index 0 and newest sample at index -1. + . flipped: False then inData order is inData[n] and still needs to be + flipped. If True then the inData is already flipped. """ L = len(inData) + xData = inData if flipped else np.flip(inData) if L < self.Nphases: delayLine = self.map_to_delay_line() # Equivalent code: # delayLine = np.concatenate((inData, delayLine[L:])) delayLine = np.roll(delayLine, L) - delayLine[:L] = np.flip(inData) + delayLine[:L] = xData self.map_to_poly_delays(delayLine) else: # Equivalent code for L == Nphases: Shift in inData block directly # at column 0 self.polyDelays = np.roll(self.polyDelays, 1, axis=1) - self.polyDelays[:, 0] = np.flip(inData) + self.polyDelays[:, 0] = xData - def filter_block(self, inData): + def filter_block(self, inData, flipped=False): """Filter block of inData per polyphase. Input: @@ -228,9 +231,11 @@ class PolyPhaseFirFilterStructure: Return: . pfsData: block of polyphase FIR filtered output data for Nphase, with pfsData[p] and p = 0:Nphases-1 from top to bottom. + . flipped: False then inData order is inData[n] and still needs to be + flipped. If True then the inData is already flipped. """ # Shift in one block of input data (1 <= len(inData) <= Nphases) - self.shift_in_data(inData) + self.shift_in_data(inData, flipped) # Apply FIR coefs per delay element zData = self.polyDelays * self.polyCoefs # Sum FIR taps per polyphase @@ -353,7 +358,7 @@ def polyphase_frontend(x, Nphases, coefs, sampling): Ndown = Nphases Nzeros = Ndown - 1 polyX, Nx, Nxp = polyphase_data_for_downsampling_whole_x(x, Ndown, Nzeros) - print(polyX[:, 0]) + # print(polyX[:, 0]) # Filter Ndown parts of x per polyphase, because the FIR filter output # y will sum. The commutator index order for downsampling is p = # Ndown - 1,..., 1, 0, so from bottom to top in the PFS. However, the @@ -709,7 +714,7 @@ def non_maximal_downsample_bpf(x, Ndown, k, Ndft, coefs, verbosity=1): for b in range(Nblocks): # Filter block inData = xBlocks[:, b] - pfsData = pfs.filter_block(inData) + pfsData = pfs.filter_block(inData, flipped=True) # Phase rotate polyphases for bin k [HARRIS Eq 6.8] pfsBinData = pfsData * phasors # Sum the polyphases to get single downsampled and downconverted output value -- GitLab