def __init__(self, numchans, taps=None, oversample_rate=1, atten=100): gr.hier_block2.__init__( self, "pfb_channelizer_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) self._nchans = numchans self._oversample_rate = oversample_rate if (taps is not None) and (len(taps) > 0): self._taps = taps else: # Create a filter that covers the full bandwidth of the input signal bw = 0.4 tb = 0.2 ripple = 0.1 made = False while not made: try: self._taps = optfir.low_pass(1, self._nchans, bw, bw + tb, ripple, atten) made = True except RuntimeError: ripple += 0.01 made = False print( "Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) # Build in an exit strategy; if we've come this far, it ain't working. if (ripple >= 1.0): raise RuntimeError( "optfir could not generate an appropriate filter.") self.s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, self._nchans) self.pfb = filter.pfb_channelizer_ccf(self._nchans, self._taps, self._oversample_rate) self.connect(self, self.s2ss) for i in xrange(self._nchans): self.connect((self.s2ss, i), (self.pfb, i)) self.connect((self.pfb, i), (self, i))
def __init__(self, numchans, taps=None, oversample_rate=1, atten=100): gr.hier_block2.__init__(self, "pfb_channelizer_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) self._nchans = numchans self._oversample_rate = oversample_rate if (taps is not None) and (len(taps) > 0): self._taps = taps else: # Create a filter that covers the full bandwidth of the input signal bw = 0.4 tb = 0.2 ripple = 0.1 made = False while not made: try: self._taps = optfir.low_pass(1, self._nchans, bw, bw+tb, ripple, atten) made = True except RuntimeError: ripple += 0.01 made = False print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) # Build in an exit strategy; if we've come this far, it ain't working. if(ripple >= 1.0): raise RuntimeError("optfir could not generate an appropriate filter.") self.s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, self._nchans) self.pfb = filter.pfb_channelizer_ccf(self._nchans, self._taps, self._oversample_rate) self.connect(self, self.s2ss) for i in xrange(self._nchans): self.connect((self.s2ss,i), (self.pfb,i)) self.connect((self.pfb,i), (self,i))
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 1000 # baseband sampling rate ifs = M * fs # input samp rate to channelizer taps = filter.firdes.low_pass_2( 1, ifs, 500, 50, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = gr.add_cc() freqs = [-200, -100, 0, 100, 200] for i in xrange(len(freqs)): f = freqs[i] + (M / 2 - M + i + 1) * fs signals.append(gr.sig_source_c(ifs, gr.GR_SIN_WAVE, f, 1)) self.tb.connect(signals[i], (add, i)) head = gr.head(gr.sizeof_gr_complex, N) s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, head, s2ss) snks = list() for i in xrange(M): snks.append(gr.vector_sink_c()) self.tb.connect((s2ss, i), (pfb, i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) t = map(lambda x: float(x) / fs, xrange(L)) # Adjusted phase rotations for data p0 = 0 p1 = math.pi * 0.51998885 p2 = -math.pi * 0.96002233 p3 = math.pi * 0.96002233 p4 = -math.pi * 0.51998885 # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 1000 # baseband sampling rate ifs = M*fs # input samp rate to channelizer taps = filter.firdes.low_pass_2(1, ifs, 500, 50, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = blocks.add_cc() freqs = [-200, -100, 0, 100, 200] for i in xrange(len(freqs)): f = freqs[i] + (M/2-M+i+1)*fs data = sig_source_c(ifs, f, 1, N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add,i)) s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, s2ss) snks = list() for i in xrange(M): snks.append(blocks.vector_sink_c()) self.tb.connect((s2ss,i), (pfb,i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) t = map(lambda x: float(x)/fs, xrange(L)) # Adjusted phase rotations for data p0 = 0 p1 = math.pi*0.51998885 p2 = -math.pi*0.96002233 p3 = math.pi*0.96002233 p4 = -math.pi*0.51998885 # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)