discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Python block help


From: Marcus Müller
Subject: Re: [Discuss-gnuradio] Python block help
Date: Tue, 30 May 2017 00:02:07 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0

Hi Zach,


On 29.05.2017 22:57, Zach Morris wrote:
Hi Marcus,

Sorry about the trouble with Nabble, I see that my code got cut off. I will communicate via the mailing list from now on.

If I understand your explanation correctly, the forecast function below tells the scheduler that this block needs at least noutput_items on each input port in order to produce noutput_items. In actuality, my arbitrary ratio block would produce anywhere between (0, noutput_items); would this be a valid implementation of forecast() for my arbitrary ratio block?
def forecast(self, noutput_items, ninput_items_required):
    for i in range(len(ninput_items_required)):
         ninput_items_required[i] = noutput_items

yes, that would tell the scheduler that you'll need at least noutput_items input items to produce noutput_items output items, indeed!

Now, the forecast really is just that: a forecast. If you can't produce as many samples as promised, the scheduler won't be upset.

This is my general_work() function right now: it just outputs the elements in the input vector that are above a threshold. My eventual goal is to receive a vector from an FFT and update statistics for each frequency 'bin' as long as its power is above a threshold, then output the statistics when its power drops below the threshold.

def general_work(self, input_items, output_items):
     in0 = input_items[0][:len(output_items[0])]
This is **only** OK if you check that len(output_items[0]) <= len(input_items[0]). You inherently do that with your forecast, but I'd really recommend explicitly checking that condition.
Also, this the following code is really very redundant:
     out0 = output_items[0]
     ninput_items = len(in0)
well, you set in0 to be of len(output_items[0]).

     j = 0
     for i in range(0, ninput_items):
this is very un-pythonic.
         if (in0[i] > self.threshold).all(): 
             out0[j] = in0[i]
              j += 1

I'd just say:

def general_work(self, input_items, output_items):
    super_threshold = filter(lambda x: x > self.threshold, in[0])
    output_items[0][:] = super_threshold
    self.consume_each(len(super_threshold))
    return len(super_threshold)

Best regards,
Marcus

     self.consume(0, ninput_items)
     self.produce(0, j)

     return 0

If I again understand your explanation, the 'self.consume(0, ninput_items)' is correct, because I 'use up' the elements of input_items on each loop. However, it sounds like I should either return WORK_CALLED_PRODUCE or return ninput_tems. Am I on the right track here? Is there a reason to prefer produce() over just returning the number of input items I consume?

Thank you for your help.

Zach


On Sun, May 28, 2017 at 1:31 PM, Marcus Müller <address@hidden> wrote:
Hi Zach,

sorry it took me so long to react:
so, let's dissect a few things:

First, the general purposes of these functions:

* forecast() is called by the *scheduler* to ask your block "hey, if I'd
need you to produce N items, how much would you need on your 0. (and 1.,
and 2.,… if existing) input for that?". The scheduler usually repeatedly
calls that with a decreasing N until the number of samples your block
requires can be fulfilled by the number of input items that the
scheduler has ready. If that never happens, usually, something is broken.

* consume() is something that *you* call from within a (general_)work()
to signal the scheduler how many items you've consumed from the input(s).

* produce() is something that *you* call from within a (general_)work()
to signal the scheduler how many items you've put into the output
buffer. *If* you use produce, you should return the magic
WORK_CALLED_PRODUCE values. You usually don't call produce() – you just
return the number of consumed samples instead.

* noutput_items is **not** a variable that you set – it's the info how
many items you are asked to produce (parameter to forecast()) or how
many items you're **allowed at most** to produce (when it's the
parameter to a (general_)work())

Again, the better parts of your mail have been broken by Nabble. Abandon
Nabble. Subscribe directly:

https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Hope that helps,
Marcus

On 05/26/2017 07:49 PM, Zach Morris wrote:
> That worked to create a general block, but I'm still having some trouble with
> implementing the forecast(), consume() and produce() functions.
>
> The goal of the block is to discard elements in an input vector that are
> below a certain threshold, and eventually update some statistics based on
> the remaining elements. For a vector of 256 elements, there could be
> anywhere between 0 and 256 outputs (the arbitrary ratio you mentioned).
>
> The default forecast function has a 1:1 ratio:
>
> Should I replace "noutput_items" with my "vector_length" parameter, ensuring
> that we always get (for example) 256 inputs?
>
> In the general_work function, I think we want to consume the entire input
> vector once we figure out which elements are above the threshold:
>
> I'm not sure about the produce function; do I need to tell the system how
> many items I produce, or is that covered at the end of general_work:
>
>
> Thank you kindly,
>
> Zach
>
>
>
>
> --
> View this message in context: http://gnuradio.4.n7.nabble.com/Python-block-help-tp51706p64062.html
> Sent from the GnuRadio mailing list archive at Nabble.com.
>
> _______________________________________________
> Discuss-gnuradio mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


_______________________________________________
Discuss-gnuradio mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio



reply via email to

[Prev in Thread] Current Thread [Next in Thread]