def test_001(self): fg = self.fg src1_data = (0,0.2,-0.3,0,12,0) src2_data = (0,0.0,3.0,0,10,0) src3_data = (0,0.0,3.0,0,1,0) src1 = gr.vector_source_f (src1_data) s2v1 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) fg.connect( src1, s2v1 ) src2 = gr.vector_source_f (src2_data) s2v2 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) fg.connect( src2, s2v2 ) src3 = gr.vector_source_f (src3_data) s2v3 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) fg.connect( src3, s2v3 ) dst1 = gr.vector_sink_s () dst2 = gr.vector_sink_s () argmax = gr.argmax_fs (len(src1_data)) fg.connect (s2v1, (argmax, 0)) fg.connect (s2v2, (argmax, 1)) fg.connect (s2v3, (argmax, 2)) fg.connect ((argmax,0), dst1) fg.connect ((argmax,1), dst2) fg.run () index = dst1.data () source = dst2.data () self.assertEqual ( index, (4,)) self.assertEqual ( source, (0,))
def test_001(self): tb = self.tb src1_data = (0, 0.2, -0.3, 0, 12, 0) src2_data = (0, 0.0, 3.0, 0, 10, 0) src3_data = (0, 0.0, 3.0, 0, 1, 0) src1 = gr.vector_source_f(src1_data) s2v1 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) tb.connect(src1, s2v1) src2 = gr.vector_source_f(src2_data) s2v2 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) tb.connect(src2, s2v2) src3 = gr.vector_source_f(src3_data) s2v3 = gr.stream_to_vector(gr.sizeof_float, len(src1_data)) tb.connect(src3, s2v3) dst1 = gr.vector_sink_s() dst2 = gr.vector_sink_s() argmax = gr.argmax_fs(len(src1_data)) tb.connect(s2v1, (argmax, 0)) tb.connect(s2v2, (argmax, 1)) tb.connect(s2v3, (argmax, 2)) tb.connect((argmax, 0), dst1) tb.connect((argmax, 1), dst2) tb.run() index = dst1.data() source = dst2.data() self.assertEqual(index, (4, )) self.assertEqual(source, (0, ))
def __init__(self, fs, svn, alpha, fd_range, dump_bins=False): gr.hier_block2.__init__(self, "acquisition", gr.io_signature(1,1, gr.sizeof_gr_complex), gr.io_signature(3,3, gr.sizeof_float)) fft_size = int( 1e-3*fs) doppler_range = self.get_doppler_range(fd_range) agc = gr.agc_cc( 1.0/fs, 1.0, 1.0, 1.0) s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size) fft = gr.fft_vcc(fft_size, True, []) argmax = gr.argmax_fs(fft_size) max = gr.max_ff(fft_size) self.connect( self, s2v, fft) self.connect( (argmax, 0), gr.short_to_float(), (self, 0)) self.connect( (argmax,1), gr.short_to_float(), gr.add_const_ff(-fd_range), gr.multiply_const_ff(1e3), (self,1)) self.connect( max, (self, 2)) # Connect the individual channels to the input and the output. self.correlators = [ single_channel_correlator( fs, fd, svn, alpha, dump_bins) for fd in doppler_range ] for (correlator, i) in zip( self.correlators, range(len(self.correlators))): self.connect( fft, correlator ) self.connect( correlator, (argmax, i) ) self.connect( correlator, (max, i) )
def __init__(self, fs, svn, alpha, fd_range, dump_bins=False): gr.hier_block2.__init__(self, "acquisition", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(3, 3, gr.sizeof_float)) fft_size = int(1e-3 * fs) doppler_range = self.get_doppler_range(fd_range) agc = gr.agc_cc(1.0 / fs, 1.0, 1.0, 1.0) s2v = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size) fft = gr.fft_vcc(fft_size, True, []) argmax = gr.argmax_fs(fft_size) max = gr.max_ff(fft_size) self.connect(self, s2v, fft) self.connect((argmax, 0), gr.short_to_float(), (self, 0)) self.connect((argmax, 1), gr.short_to_float(), gr.add_const_ff(-fd_range), gr.multiply_const_ff(1e3), (self, 1)) self.connect(max, (self, 2)) # Connect the individual channels to the input and the output. self.correlators = [ single_channel_correlator(fs, fd, svn, alpha, dump_bins) for fd in doppler_range ] for (correlator, i) in zip(self.correlators, range(len(self.correlators))): self.connect(fft, correlator) self.connect(correlator, (argmax, i)) self.connect(correlator, (max, i))
def __init__(self, N_id_2, decim=16, avg_halfframes=2 * 8, freq_corr=0, dump=None): gr.hier_block2.__init__( self, "PSS correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float), ) vec_half_frame = 30720 * 5 / decim self.taps = [] for i in range(0, 3): self.taps.append( gen_pss_td(i, N_re=2048 / decim, freq_corr=freq_corr).get_data_conj_rev()) self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2]) self.mag = gr.complex_to_mag_squared() self.vec = gr.stream_to_vector(gr.sizeof_float * 1, vec_half_frame) self.deint = gr.deinterleave(gr.sizeof_float * vec_half_frame) self.add = gr.add_vff(vec_half_frame) self.argmax = gr.argmax_fs(vec_half_frame) self.null = gr.null_sink(gr.sizeof_short * 1) self.max = gr.max_ff(vec_half_frame) self.to_float = gr.short_to_float(1, 1. / decim) self.interleave = gr.interleave(gr.sizeof_float) #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5) self.connect(self, self.corr, self.mag, self.vec) self.connect((self.argmax, 1), self.null) #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self) self.connect(self.argmax, self.to_float, self.interleave, self) self.connect(self.max, (self.interleave, 1)) if avg_halfframes == 1: self.connect(self.vec, self.argmax) self.connect(self.vec, self.max) else: self.connect(self.vec, self.deint) self.connect(self.add, self.argmax) self.connect(self.add, self.max) for i in range(0, avg_halfframes): self.connect((self.deint, i), (self.add, i)) if dump != None: self.connect( self.mag, gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile")) self.connect( self.add, gr.file_sink(gr.sizeof_float * vec_half_frame, dump + "_pss_corr_add_f.cfile"))
def __init__(self, N_id_2, decim=16, avg_halfframes=2*8, freq_corr=0, dump=None): gr.hier_block2.__init__( self, "PSS correlator", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float), ) vec_half_frame = 30720*5/decim self.taps = [] for i in range(0,3): self.taps.append(gen_pss_td(i, N_re=2048/decim, freq_corr=freq_corr).get_data_conj_rev()) self.corr = filter.fir_filter_ccc(1, self.taps[N_id_2]) self.mag = gr.complex_to_mag_squared() self.vec = gr.stream_to_vector(gr.sizeof_float*1, vec_half_frame) self.deint = gr.deinterleave(gr.sizeof_float*vec_half_frame) self.add = gr.add_vff(vec_half_frame) self.argmax = gr.argmax_fs(vec_half_frame) self.null = gr.null_sink(gr.sizeof_short*1) self.max = gr.max_ff(vec_half_frame) self.to_float = gr.short_to_float(1, 1./decim) self.interleave = gr.interleave(gr.sizeof_float) #self.framestart = gr.add_const_ii(-160-144*5-2048*6+30720*5) self.connect(self, self.corr, self.mag, self.vec) self.connect((self.argmax,1), self.null) #self.connect(self.argmax, self.to_float, self.to_int, self.framestart, self) self.connect(self.argmax, self.to_float, self.interleave, self) self.connect(self.max, (self.interleave,1)) if avg_halfframes == 1: self.connect(self.vec, self.argmax) self.connect(self.vec, self.max) else: self.connect(self.vec, self.deint) self.connect(self.add, self.argmax) self.connect(self.add, self.max) for i in range(0, avg_halfframes): self.connect((self.deint, i), (self.add, i)) if dump != None: self.connect(self.mag, gr.file_sink(gr.sizeof_float, dump + "_pss_corr_f.cfile")) self.connect(self.add, gr.file_sink(gr.sizeof_float*vec_half_frame, dump + "_pss_corr_add_f.cfile"))
def __init__(self, fft_length, block_length, block_header, range, options): gr.hier_block2.__init__(self, "integer_fo_estimator", gr.io_signature3(3,3,gr.sizeof_gr_complex,gr.sizeof_float,gr.sizeof_char), gr.io_signature2(3,3,gr.sizeof_float,gr.sizeof_char)) raise NotImplementedError,"Obsolete class" self._range = range # threshold after integer part frequency offset estimation # if peak value below threshold, assume false triggering self._thr_lo = 0.4 #0.19 # empirically found threshold. see ioe_metric.float self._thr_hi = 0.4 #0.2 # stuff to be removed after bugfix for hierblock2s self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.time_sync = gr.kludge_copy(gr.sizeof_char) self.epsilon = (self,1) self.connect((self,0),self.input) self.connect((self,2),self.time_sync) delay(gr.sizeof_char, block_header.schmidl_fine_sync[0]*block_length) # sample ofdm symbol (preamble 1 and 2) sampler_symbol1 = vector_sampler(gr.sizeof_gr_complex,fft_length) sampler_symbol2 = vector_sampler(gr.sizeof_gr_complex,fft_length) time_delay1 = delay(gr.sizeof_char,block_length*block_header.schmidl_fine_sync[1]) self.connect(self.input, (sampler_symbol1,0)) self.connect(self.input, (sampler_symbol2,0)) if block_header.schmidl_fine_sync[0] > 0: time_delay0 = delay(gr.sizeof_char,block_length*block_header.schmidl_fine_sync[0]) self.connect(self.time_sync, time_delay0, (sampler_symbol1,1)) else: self.connect(self.time_sync, (sampler_symbol1,1)) self.connect(self.time_sync, time_delay1, (sampler_symbol2,1)) # negative fractional frequency offset estimate epsilon = gr.multiply_const_ff(-1.0) self.connect(self.epsilon, epsilon) # compensate for fractional frequency offset on per symbol base # freq_shift: vector length, modulator sensitivity # freq_shift third input: reset phase accumulator # symbol/preamble 1 freq_shift_sym1 = frequency_shift_vcc(fft_length, 1.0/fft_length) self.connect(sampler_symbol1, (freq_shift_sym1,0)) self.connect(epsilon, (freq_shift_sym1,1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym1,2)) # symbol/preamble 2 freq_shift_sym2 = frequency_shift_vcc(fft_length, 1.0/fft_length) self.connect(sampler_symbol2, (freq_shift_sym2,0)) self.connect(epsilon, (freq_shift_sym2,1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym2,2)) # fourier transfrom on both preambles fft_sym1 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift fft_sym2 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift # calculate schmidl's metric for estimation of freq. offset's integer part assert(hasattr(block_header, "schmidl_fine_sync")) pre1 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[0]] pre2 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[1]] diff_pn = concatenate([[conjugate(math.sqrt(2)*pre2[2*i]/pre1[2*i]),0.0j] for i in arange(len(pre1)/2)]) cfo_estimator = schmidl_cfo_estimator(fft_length, len(pre1), self._range, diff_pn) self.connect(freq_shift_sym1, fft_sym1, (cfo_estimator,0)) # preamble 1 self.connect(freq_shift_sym2, fft_sym2, (cfo_estimator,1)) # preamble 2 # search for maximum and its argument in interval [-range .. +range] #arg_max = arg_max_vff(2*self._range + 1) arg_max_s = gr.argmax_fs(2*self._range+1) arg_max = gr.short_to_float() ifo_max = gr.max_ff(2*self._range + 1) # vlen ifo_estimate = gr.add_const_ff(-self._range) self.connect(cfo_estimator, arg_max_s, arg_max, ifo_estimate) self.connect(cfo_estimator, ifo_max) self.connect((arg_max_s,1),gr.null_sink(gr.sizeof_short)) # threshold maximal value ifo_threshold = gr.threshold_ff(self._thr_lo, self._thr_hi, 0.0) ifo_thr_f2b = gr.float_to_char() self.connect(ifo_max, ifo_threshold, ifo_thr_f2b) # gating the streams ifo_estimate (integer part) and epsilon (frac. part) # if the metric's peak value was above the chosen threshold, assume to have # found a new burst. peak value below threshold results in blocking the # streams self.gate = gate_ff() self.connect(ifo_thr_f2b, (self.gate,0)) # threshold stream self.connect(ifo_estimate, (self.gate,1)) self.connect(epsilon, (self.gate,2)) # peak filtering # resynchronize and suppress peaks that didn't match a preamble filtered_time_sync = peak_resync_bb(True) # replace self.connect(self.time_sync, (filtered_time_sync,0)) self.connect(ifo_thr_f2b, (filtered_time_sync,1)) # find complete estimation for frequency offset # add together fractional and integer part freq_offset = gr.add_ff() self.connect((self.gate,1), gr.multiply_const_ff(-1.0), (freq_offset,0)) # integer offset self.connect((self.gate,2), (freq_offset,1)) # frac offset # output connections self.connect(freq_offset, (self,0)) self.connect(filtered_time_sync, (self,1)) self.connect((self.gate,0), (self,2)) # used for frame trigger ######################################### # debugging if options.log: self.epsilon2_sink = gr.vector_sink_f() self.connect(epsilon, self.epsilon2_sink) self.connect(cfo_estimator, gr.file_sink(gr.sizeof_float*(self._range*2+1), "data/ioe_metric.float")) # output joint stream preamble_stream = gr.streams_to_vector(fft_length * gr.sizeof_gr_complex, 2) self.connect(fft_sym1, (preamble_stream,0)) self.connect(fft_sym2, (preamble_stream,1)) self.connect(preamble_stream, gr.file_sink(gr.sizeof_gr_complex * 2 * fft_length, "data/preambles.compl")) # output, preambles before and after correction, magnitude and complex spectrum self.connect(sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1_bef.compl")) self.connect(sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1_bef.float")) self.connect(sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2_bef.compl")) self.connect(sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2_bef.float")) self.connect(freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length,"data/pre1.compl")) self.connect(freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length,"data/pre1.float")) self.connect(freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length,"data/pre2.compl")) self.connect(freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length,"data/pre2.float")) # calculate epsilon from corrected source to check function test_cp = cyclic_prefixer(fft_length, block_length) test_eps = foe(fft_length) self.connect(freq_shift_sym1, test_cp, test_eps, gr.file_sink(gr.sizeof_float, "data/eps_after.float")) try: gr.hier_block.update_var_names(self, "ifo_estimator", vars()) gr.hier_block.update_var_names(self, "ifo_estimator", vars(self)) except: pass
def __init__( self, vlen, cp_len ): gr.hier_block2.__init__( self, "channel_estimator_003", gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ), gr.io_signature( 1, 1, gr.sizeof_gr_complex * vlen ) ) self.ch_est = channel_estimator_001( vlen ) self.connect( self, self.ch_est ) cir_len = cp_len + 1 self.cir_len = cir_len self.vlen = vlen self.preamble_td = self.ch_est.td self.preamble_fd = self.ch_est.fd # CTF -> CIR self.cir_est = gr.fft_vcc( vlen, False, [], False ) # IFFT self.connect( self.ch_est, self.cir_est ) # CIR -> energy per sample self.cir_energy = gr.complex_to_mag_squared( vlen ) self.connect( self.cir_est, self.cir_energy ) # prepare cyclic convolution of CIR vector self.cyclic_cir = gr.streams_to_vector( gr.sizeof_float * vlen, 2 ) self.connect( self.cir_energy, ( self.cyclic_cir, 0 ) ) self.connect( self.cir_energy, ( self.cyclic_cir, 1 ) ) # Cyclic convolution of CIR vector # Pad CIR vector: 0 x cp_len, CIR, CIR, 0 x cp_len self.serial_ccir = gr.vector_to_stream( gr.sizeof_float, vlen * 2 ) self.padded_sccir = gr.stream_mux( gr.sizeof_float, [ cir_len-1, 2*vlen, cir_len-1 ] ) if cir_len > 1: self.conv = gr.fir_filter_fff( 1, [ 1 ] * cir_len ) else: self.conv = gr.kludge_copy( gr.sizeof_float ) self.connect( self.padded_sccir, self.conv ) self.null_source = gr.null_source( gr.sizeof_float ) self.connect( self.cyclic_cir, self.serial_ccir ) self.connect( self.null_source, ( self.padded_sccir, 0 ) ) self.connect( self.serial_ccir, ( self.padded_sccir, 1 ) ) self.connect( self.null_source, ( self.padded_sccir, 2 ) ) # Extract search window self.search_window = ofdm.vector_sampler( gr.sizeof_float, vlen ) periodic_trigger_seq = [ 0 ] * ( ( vlen + cir_len-1 ) * 2 ) periodic_trigger_seq[ cir_len-1 + cir_len-1 + vlen-1 ] = 1 self.sampler_trigsrc = gr.vector_source_b( periodic_trigger_seq, True ) self.connect( self.conv, self.search_window ) self.connect( self.sampler_trigsrc, ( self.search_window, 1 ) ) # Find point of maximum energy self.cir_start = gr.argmax_fs( vlen ) self.connect( self.search_window, self.cir_start ) self.connect( ( self.cir_start, 1 ), gr.null_sink( gr.sizeof_short ) ) # Set to zero all samples that do not belong to the CIR self.filtered_cir = ofdm.interp_cir_set_noncir_to_zero( vlen, cir_len ) #self.filtered_cir = gr.kludge_copy( gr.sizeof_gr_complex * vlen ) self.connect( self.cir_est, self.filtered_cir ) self.connect( self.cir_start, ( self.filtered_cir, 1 ) ) #self.connect( self.cir_start, gr.null_sink( gr.sizeof_short ) ) # CIR -> CTF self.filtered_ctf = gr.fft_vcc( vlen, True, [], False ) # FFT self.scaled_fctf = gr.multiply_const_vcc( [1./vlen]*vlen ) self.connect( self.filtered_cir, self.filtered_ctf ) self.connect( self.filtered_ctf, self.scaled_fctf ) # Output connection self.connect( self.scaled_fctf, self )
def __init__(self, fft_length, block_length, block_header, range, options): gr.hier_block2.__init__( self, "integer_fo_estimator", gr.io_signature3(3, 3, gr.sizeof_gr_complex, gr.sizeof_float, gr.sizeof_char), gr.io_signature2(3, 3, gr.sizeof_float, gr.sizeof_char)) raise NotImplementedError, "Obsolete class" self._range = range # threshold after integer part frequency offset estimation # if peak value below threshold, assume false triggering self._thr_lo = 0.4 #0.19 # empirically found threshold. see ioe_metric.float self._thr_hi = 0.4 #0.2 # stuff to be removed after bugfix for hierblock2s self.input = gr.kludge_copy(gr.sizeof_gr_complex) self.time_sync = gr.kludge_copy(gr.sizeof_char) self.epsilon = (self, 1) self.connect((self, 0), self.input) self.connect((self, 2), self.time_sync) delay(gr.sizeof_char, block_header.schmidl_fine_sync[0] * block_length) # sample ofdm symbol (preamble 1 and 2) sampler_symbol1 = vector_sampler(gr.sizeof_gr_complex, fft_length) sampler_symbol2 = vector_sampler(gr.sizeof_gr_complex, fft_length) time_delay1 = delay(gr.sizeof_char, block_length * block_header.schmidl_fine_sync[1]) self.connect(self.input, (sampler_symbol1, 0)) self.connect(self.input, (sampler_symbol2, 0)) if block_header.schmidl_fine_sync[0] > 0: time_delay0 = delay( gr.sizeof_char, block_length * block_header.schmidl_fine_sync[0]) self.connect(self.time_sync, time_delay0, (sampler_symbol1, 1)) else: self.connect(self.time_sync, (sampler_symbol1, 1)) self.connect(self.time_sync, time_delay1, (sampler_symbol2, 1)) # negative fractional frequency offset estimate epsilon = gr.multiply_const_ff(-1.0) self.connect(self.epsilon, epsilon) # compensate for fractional frequency offset on per symbol base # freq_shift: vector length, modulator sensitivity # freq_shift third input: reset phase accumulator # symbol/preamble 1 freq_shift_sym1 = frequency_shift_vcc(fft_length, 1.0 / fft_length) self.connect(sampler_symbol1, (freq_shift_sym1, 0)) self.connect(epsilon, (freq_shift_sym1, 1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym1, 2)) # symbol/preamble 2 freq_shift_sym2 = frequency_shift_vcc(fft_length, 1.0 / fft_length) self.connect(sampler_symbol2, (freq_shift_sym2, 0)) self.connect(epsilon, (freq_shift_sym2, 1)) self.connect(gr.vector_source_b([1], True), (freq_shift_sym2, 2)) # fourier transfrom on both preambles fft_sym1 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift fft_sym2 = gr.fft_vcc(fft_length, True, [], True) # Forward + Blockshift # calculate schmidl's metric for estimation of freq. offset's integer part assert (hasattr(block_header, "schmidl_fine_sync")) pre1 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[0]] pre2 = block_header.pilotsym_fd[block_header.schmidl_fine_sync[1]] diff_pn = concatenate( [[conjugate(math.sqrt(2) * pre2[2 * i] / pre1[2 * i]), 0.0j] for i in arange(len(pre1) / 2)]) cfo_estimator = schmidl_cfo_estimator(fft_length, len(pre1), self._range, diff_pn) self.connect(freq_shift_sym1, fft_sym1, (cfo_estimator, 0)) # preamble 1 self.connect(freq_shift_sym2, fft_sym2, (cfo_estimator, 1)) # preamble 2 # search for maximum and its argument in interval [-range .. +range] #arg_max = arg_max_vff(2*self._range + 1) arg_max_s = gr.argmax_fs(2 * self._range + 1) arg_max = gr.short_to_float() ifo_max = gr.max_ff(2 * self._range + 1) # vlen ifo_estimate = gr.add_const_ff(-self._range) self.connect(cfo_estimator, arg_max_s, arg_max, ifo_estimate) self.connect(cfo_estimator, ifo_max) self.connect((arg_max_s, 1), gr.null_sink(gr.sizeof_short)) # threshold maximal value ifo_threshold = gr.threshold_ff(self._thr_lo, self._thr_hi, 0.0) ifo_thr_f2b = gr.float_to_char() self.connect(ifo_max, ifo_threshold, ifo_thr_f2b) # gating the streams ifo_estimate (integer part) and epsilon (frac. part) # if the metric's peak value was above the chosen threshold, assume to have # found a new burst. peak value below threshold results in blocking the # streams self.gate = gate_ff() self.connect(ifo_thr_f2b, (self.gate, 0)) # threshold stream self.connect(ifo_estimate, (self.gate, 1)) self.connect(epsilon, (self.gate, 2)) # peak filtering # resynchronize and suppress peaks that didn't match a preamble filtered_time_sync = peak_resync_bb(True) # replace self.connect(self.time_sync, (filtered_time_sync, 0)) self.connect(ifo_thr_f2b, (filtered_time_sync, 1)) # find complete estimation for frequency offset # add together fractional and integer part freq_offset = gr.add_ff() self.connect((self.gate, 1), gr.multiply_const_ff(-1.0), (freq_offset, 0)) # integer offset self.connect((self.gate, 2), (freq_offset, 1)) # frac offset # output connections self.connect(freq_offset, (self, 0)) self.connect(filtered_time_sync, (self, 1)) self.connect((self.gate, 0), (self, 2)) # used for frame trigger ######################################### # debugging if options.log: self.epsilon2_sink = gr.vector_sink_f() self.connect(epsilon, self.epsilon2_sink) self.connect( cfo_estimator, gr.file_sink(gr.sizeof_float * (self._range * 2 + 1), "data/ioe_metric.float")) # output joint stream preamble_stream = gr.streams_to_vector( fft_length * gr.sizeof_gr_complex, 2) self.connect(fft_sym1, (preamble_stream, 0)) self.connect(fft_sym2, (preamble_stream, 1)) self.connect( preamble_stream, gr.file_sink(gr.sizeof_gr_complex * 2 * fft_length, "data/preambles.compl")) # output, preambles before and after correction, magnitude and complex spectrum self.connect( sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1_bef.compl")) self.connect( sampler_symbol1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1_bef.float")) self.connect( sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2_bef.compl")) self.connect( sampler_symbol2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2_bef.float")) self.connect( freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre1.compl")) self.connect( freq_shift_sym1, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre1.float")) self.connect( freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.file_sink(gr.sizeof_gr_complex * fft_length, "data/pre2.compl")) self.connect( freq_shift_sym2, gr.fft_vcc(fft_length, True, [], True), gr.complex_to_mag(fft_length), gr.file_sink(gr.sizeof_float * fft_length, "data/pre2.float")) # calculate epsilon from corrected source to check function test_cp = cyclic_prefixer(fft_length, block_length) test_eps = foe(fft_length) self.connect(freq_shift_sym1, test_cp, test_eps, gr.file_sink(gr.sizeof_float, "data/eps_after.float")) try: gr.hier_block.update_var_names(self, "ifo_estimator", vars()) gr.hier_block.update_var_names(self, "ifo_estimator", vars(self)) except: pass