diff options
author | Tom Rondeau <trondeau@vt.edu> | 2013-03-07 10:21:23 -0500 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2013-03-07 10:21:23 -0500 |
commit | 242997af1838146a56547d8ac9e2719eadebe66f (patch) | |
tree | 43d29b68fb7685f17b1a8b93de1428d66606285b | |
parent | 6e5dfe1a3e2613df24fd1b47f5eb764eaf3dbd9f (diff) |
blocks: moving bin_statistics_f into gr-blocks.
QA worked, but keeping disabled for now in reference to issue #199.
-rw-r--r-- | gr-blocks/include/blocks/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-blocks/include/blocks/bin_statistics_f.h | 65 | ||||
-rw-r--r-- | gr-blocks/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-blocks/lib/bin_statistics_f_impl.cc | 178 | ||||
-rw-r--r-- | gr-blocks/lib/bin_statistics_f_impl.h | 82 | ||||
-rwxr-xr-x | gr-blocks/python/qa_bin_statistics.py | 227 | ||||
-rw-r--r-- | gr-blocks/swig/blocks_swig.i | 3 |
7 files changed, 557 insertions, 0 deletions
diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt index 16f495616e..684639e07e 100644 --- a/gr-blocks/include/blocks/CMakeLists.txt +++ b/gr-blocks/include/blocks/CMakeLists.txt @@ -102,6 +102,7 @@ install(FILES count_bits.h log2_const.h add_ff.h + bin_statistics_f.h burst_tagger.h char_to_float.h char_to_short.h diff --git a/gr-blocks/include/blocks/bin_statistics_f.h b/gr-blocks/include/blocks/bin_statistics_f.h new file mode 100644 index 0000000000..2fc603067b --- /dev/null +++ b/gr-blocks/include/blocks/bin_statistics_f.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BIN_STATISTICS_F_H +#define INCLUDED_GR_BIN_STATISTICS_F_H + +#include <blocks/api.h> +#include <gr_sync_block.h> +#include <gr_msg_queue.h> +#include <gr_feval.h> + +namespace gr { + namespace blocks { + + /*! + * \brief control scanning and record frequency domain statistics + * \ingroup sink_blk + */ + class BLOCKS_API bin_statistics_f : virtual public gr_sync_block + { + protected: + std::vector<float> d_max; // per bin maxima + + virtual size_t vlen() const = 0; + virtual double center_freq() const = 0; + virtual gr_msg_queue_sptr msgq() const = 0; + + virtual void reset_stats() = 0; + virtual void accrue_stats(const float *input) = 0; + virtual void send_stats() = 0; + + public: + // gr::blocks::bin_statistics_f::sptr + typedef boost::shared_ptr<bin_statistics_f> sptr; + + static sptr make(unsigned int vlen, // vector length + gr_msg_queue_sptr msgq, + gr_feval_dd *tune, // callback + size_t tune_delay, // samples + size_t dwell_delay); // samples + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_BIN_STATISTICS_F_H */ diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt index 8afc77822f..ac5e3056d8 100644 --- a/gr-blocks/lib/CMakeLists.txt +++ b/gr-blocks/lib/CMakeLists.txt @@ -138,6 +138,7 @@ list(APPEND gr_blocks_sources ${generated_sources} count_bits.cc add_ff_impl.cc + bin_statistics_f_impl.cc burst_tagger_impl.cc char_to_float_impl.cc char_to_short_impl.cc diff --git a/gr-blocks/lib/bin_statistics_f_impl.cc b/gr-blocks/lib/bin_statistics_f_impl.cc new file mode 100644 index 0000000000..014222a63d --- /dev/null +++ b/gr-blocks/lib/bin_statistics_f_impl.cc @@ -0,0 +1,178 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "bin_statistics_f_impl.h" +#include <gr_io_signature.h> +#include <string.h> + +namespace gr { + namespace blocks { + + bin_statistics_f::sptr + bin_statistics_f::make(unsigned int vlen, + gr_msg_queue_sptr msgq, + gr_feval_dd *tune, + size_t tune_delay, + size_t dwell_delay) + { + return gnuradio::get_initial_sptr + (new bin_statistics_f_impl(vlen, msgq, tune, + tune_delay, dwell_delay)); + } + + bin_statistics_f_impl::bin_statistics_f_impl(unsigned int vlen, + gr_msg_queue_sptr msgq, + gr_feval_dd *tune, + size_t tune_delay, + size_t dwell_delay) + : gr_sync_block("bin_statistics_f", + gr_make_io_signature(1, 1, sizeof(float) * vlen), + gr_make_io_signature(0, 0, 0)), + d_vlen(vlen), d_msgq(msgq), d_tune(tune), + d_tune_delay(tune_delay), d_dwell_delay(dwell_delay), + d_center_freq(0), d_delay(0), + d_max(vlen) + { + enter_init(); + } + + bin_statistics_f_impl::~bin_statistics_f_impl() + { + } + + void + bin_statistics_f_impl::enter_init() + { + d_state = ST_INIT; + d_delay = 0; + } + + void + bin_statistics_f_impl::enter_tune_delay() + { + d_state = ST_TUNE_DELAY; + d_delay = d_tune_delay; + d_center_freq = d_tune->calleval(0); + } + + void + bin_statistics_f_impl::enter_dwell_delay() + { + d_state = ST_DWELL_DELAY; + d_delay = d_dwell_delay; + reset_stats(); + } + + void + bin_statistics_f_impl::leave_dwell_delay() + { + send_stats(); + } + + int + bin_statistics_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *input = (const float*)input_items[0]; + size_t vlen = d_max.size(); + + int n = 0; + int t; + + while(n < noutput_items) { + switch(d_state) { + + case ST_INIT: + enter_tune_delay(); + break; + + case ST_TUNE_DELAY: + t = std::min(noutput_items - n, int(d_delay)); + n += t; + d_delay -= t; + assert(d_delay >= 0); + if(d_delay == 0) + enter_dwell_delay(); + break; + + case ST_DWELL_DELAY: + t = std::min(noutput_items - n, int(d_delay)); + for(int i = 0; i < t; i++) { + accrue_stats(&input[n * vlen]); + n++; + } + d_delay -= t; + assert(d_delay >= 0); + if(d_delay == 0) { + leave_dwell_delay(); + enter_tune_delay(); + } + break; + + default: + assert(0); + } + } + + return noutput_items; + } + + ////////////////////////////////////////////////////////////////////////// + // virtual methods for gathering stats + ////////////////////////////////////////////////////////////////////////// + + void + bin_statistics_f_impl::reset_stats() + { + for (size_t i = 0; i < vlen(); i++){ + d_max[i] = 0; + } + } + + void + bin_statistics_f_impl::accrue_stats(const float *input) + { + for(size_t i = 0; i < vlen(); i++) { + d_max[i] = std::max(d_max[i], input[i]); // compute per bin maxima + } + } + + void + bin_statistics_f_impl::send_stats() + { + if(msgq()->full_p()) // if the queue is full, don't block, drop the data... + return; + + // build & send a message + gr_message_sptr msg = gr_make_message(0, center_freq(), vlen(), vlen() * sizeof(float)); + memcpy(msg->msg(), &d_max[0], vlen() * sizeof(float)); + msgq()->insert_tail(msg); + } + + } /* namespace blocks */ +} /* namespace gr */ + diff --git a/gr-blocks/lib/bin_statistics_f_impl.h b/gr-blocks/lib/bin_statistics_f_impl.h new file mode 100644 index 0000000000..0abb60ed38 --- /dev/null +++ b/gr-blocks/lib/bin_statistics_f_impl.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BIN_STATISTICS_F_IMPL_H +#define INCLUDED_GR_BIN_STATISTICS_F_IMPL_H + +#include <blocks/bin_statistics_f.h> +#include <gr_feval.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +namespace gr { + namespace blocks { + + class bin_statistics_f_impl : public bin_statistics_f + { + private: + enum state_t { ST_INIT, ST_TUNE_DELAY, ST_DWELL_DELAY }; + + size_t d_vlen; + gr_msg_queue_sptr d_msgq; + gr_feval_dd *d_tune; + size_t d_tune_delay; + size_t d_dwell_delay; + double d_center_freq; + + state_t d_state; + size_t d_delay; // nsamples remaining to state transition + + void enter_init(); + void enter_tune_delay(); + void enter_dwell_delay(); + void leave_dwell_delay(); + + protected: + std::vector<float> d_max; // per bin maxima + + size_t vlen() const { return d_vlen; } + double center_freq() const { return d_center_freq; } + gr_msg_queue_sptr msgq() const { return d_msgq; } + + virtual void reset_stats(); + virtual void accrue_stats(const float *input); + virtual void send_stats(); + + public: + bin_statistics_f_impl(unsigned int vlen, + gr_msg_queue_sptr msgq, + gr_feval_dd *tune, + size_t tune_delay, + size_t dwell_delay); + ~bin_statistics_f_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + }; + + } /* namespace blocks */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_BIN_STATISTICS_F_IMPL_H */ diff --git a/gr-blocks/python/qa_bin_statistics.py b/gr-blocks/python/qa_bin_statistics.py new file mode 100755 index 0000000000..c1b3072530 --- /dev/null +++ b/gr-blocks/python/qa_bin_statistics.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# +# Copyright 2006,2007,2010,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +import blocks_swig as blocks +import random +import struct + +""" +Note: There has been an issue with this block in the past, see Issue +#199. This looks like it might have fixed itself over the years. I am +leaving these tests disabled on our master branch for v3.6 for now, +though, just in case. TWR. +""" + +class counter(gr.feval_dd): + def __init__(self, step_size=1): + gr.feval_dd.__init__(self) + self.step_size = step_size + self.count = 0 + + def eval(self, input): + #print "eval: self.count =", self.count + t = self.count + self.count = self.count + self.step_size + return t + + +class counter3(gr.feval_dd): + def __init__(self, f, step_size): + gr.feval_dd.__init__(self) + self.f = f + self.step_size = step_size + self.count = 0 + + def eval(self, input): + try: + #print "eval: self.count =", self.count + t = self.count + self.count = self.count + self.step_size + self.f(self.count) + except Exception, e: + print "Exception: ", e + return t + +def foobar3(new_t): + #print "foobar3: new_t =", new_t + pass + + +class counter4(gr.feval_dd): + def __init__(self, obj_instance, step_size): + gr.feval_dd.__init__(self) + self.obj_instance = obj_instance + self.step_size = step_size + self.count = 0 + + def eval(self, input): + try: + #print "eval: self.count =", self.count + t = self.count + self.count = self.count + self.step_size + self.obj_instance.foobar4(self.count) + except Exception, e: + print "Exception: ", e + return t + + +class parse_msg(object): + def __init__(self, msg): + self.center_freq = msg.arg1() + self.vlen = int(msg.arg2()) + assert(msg.length() == self.vlen * gr.sizeof_float) + self.data = struct.unpack('%df' % (self.vlen,), msg.to_string()) + +class test_bin_statistics(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block () + + def tearDown(self): + self.tb = None + + def xtest_001(self): + vlen = 4 + tune = counter(1) + tune_delay = 0 + dwell_delay = 1 + msgq = gr.msg_queue() + + src_data = tuple([float(x) for x in + ( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + )]) + + expected_results = tuple([float(x) for x in + ( 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + )]) + + src = gr.vector_source_f(src_data, False) + s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) + stats = blocks.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay) + self.tb.connect(src, s2v, stats) + self.tb.run() + self.assertEqual(4, msgq.count()) + for i in range(4): + m = parse_msg(msgq.delete_head()) + #print "m =", m.center_freq, m.data + self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data) + + def xtest_002(self): + vlen = 4 + tune = counter(1) + tune_delay = 1 + dwell_delay = 2 + msgq = gr.msg_queue() + + src_data = tuple([float(x) for x in + ( 1, 2, 3, 4, + 9, 6, 11, 8, + 5, 10, 7, 12, + 13, 14, 15, 16 + )]) + + expected_results = tuple([float(x) for x in + ( 9, 10, 11, 12)]) + + src = gr.vector_source_f(src_data, False) + s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) + stats = blocks.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay) + self.tb.connect(src, s2v, stats) + self.tb.run() + self.assertEqual(1, msgq.count()) + for i in range(1): + m = parse_msg(msgq.delete_head()) + #print "m =", m.center_freq, m.data + self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data) + + + + def xtest_003(self): + vlen = 4 + tune = counter3(foobar3, 1) + tune_delay = 1 + dwell_delay = 2 + msgq = gr.msg_queue() + + src_data = tuple([float(x) for x in + ( 1, 2, 3, 4, + 9, 6, 11, 8, + 5, 10, 7, 12, + 13, 14, 15, 16 + )]) + + expected_results = tuple([float(x) for x in + ( 9, 10, 11, 12)]) + + src = gr.vector_source_f(src_data, False) + s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) + stats = blocks.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay) + self.tb.connect(src, s2v, stats) + self.tb.run() + self.assertEqual(1, msgq.count()) + for i in range(1): + m = parse_msg(msgq.delete_head()) + #print "m =", m.center_freq, m.data + self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data) + + def foobar4(self, new_t): + #print "foobar4: new_t =", new_t + pass + + def xtest_004(self): + vlen = 4 + tune = counter4(self, 1) + tune_delay = 1 + dwell_delay = 2 + msgq = gr.msg_queue() + + src_data = tuple([float(x) for x in + ( 1, 2, 3, 4, + 9, 6, 11, 8, + 5, 10, 7, 12, + 13, 14, 15, 16 + )]) + + expected_results = tuple([float(x) for x in + ( 9, 10, 11, 12)]) + + src = gr.vector_source_f(src_data, False) + s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) + stats = blocks.bin_statistics_f(vlen, msgq, tune, tune_delay, dwell_delay) + self.tb.connect(src, s2v, stats) + self.tb.run() + self.assertEqual(1, msgq.count()) + for i in range(1): + m = parse_msg(msgq.delete_head()) + #print "m =", m.center_freq, m.data + self.assertEqual(expected_results[vlen*i:vlen*i + vlen], m.data) + + +if __name__ == '__main__': + gr_unittest.run(test_bin_statistics, "test_bin_statistics.xml") diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i index 2c734cd60c..1c0f49dfeb 100644 --- a/gr-blocks/swig/blocks_swig.i +++ b/gr-blocks/swig/blocks_swig.i @@ -52,6 +52,7 @@ #include "blocks/argmax_fs.h" #include "blocks/argmax_is.h" #include "blocks/argmax_ss.h" +#include "blocks/bin_statistics_f.h" #include "blocks/burst_tagger.h" #include "blocks/char_to_float.h" #include "blocks/char_to_short.h" @@ -203,6 +204,7 @@ %include "blocks/argmax_is.h" %include "blocks/argmax_ss.h" %include "blocks/char_to_float.h" +%include "blocks/bin_statistics_f.h" %include "blocks/burst_tagger.h" %include "blocks/char_to_short.h" %include "blocks/complex_to_interleaved_short.h" @@ -351,6 +353,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, and_const_ii); GR_SWIG_BLOCK_MAGIC2(blocks, argmax_fs); GR_SWIG_BLOCK_MAGIC2(blocks, argmax_is); GR_SWIG_BLOCK_MAGIC2(blocks, argmax_ss); +GR_SWIG_BLOCK_MAGIC2(blocks, bin_statistics_f); GR_SWIG_BLOCK_MAGIC2(blocks, burst_tagger); GR_SWIG_BLOCK_MAGIC2(blocks, char_to_float); GR_SWIG_BLOCK_MAGIC2(blocks, char_to_short); |