diff options
Diffstat (limited to 'docs/doxygen/other/python_blocks.dox')
-rw-r--r-- | docs/doxygen/other/python_blocks.dox | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/docs/doxygen/other/python_blocks.dox b/docs/doxygen/other/python_blocks.dox deleted file mode 100644 index 2381b0cad0..0000000000 --- a/docs/doxygen/other/python_blocks.dox +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright (C) 2017 Free Software Foundation, Inc. -# -# Permission is granted to copy, distribute and/or modify this document -# under the terms of the GNU Free Documentation License, Version 1.3 -# or any later version published by the Free Software Foundation; -# with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. -# A copy of the license is included in the section entitled "GNU -# Free Documentation License". - -/*! \page page_python_blocks Python Blocks - -How to create blocks in Python - -\section pyblocks_streaming Streaming Data Blocks - -We create blocks in Python very much like we would in C++, just with -more Python. Figure out which type of block you want to create: - -\li general block (gr.basic_block) -\li synchronous block (gr.sync_block) -\li decimator (gr.sync_decimator) -\li interpolator (gr.sync_interpolator) - -The block class inherits from one of these base classes, and then in -defining the parent class, we set the I/O signature. However, unlike -in C++ where we use the gr::io_signature class, here we can just -create a Python list of the I/O data sizes using numpy data types: - -\li numpy.int8 -\li numpy.int16 -\li numpy.int32 -\li numpy.float32 -\li numpy.float64 - -Like a normal C++ version of the block, we then create and initialize -any variables in the constructor, define any setters and getters, and -create the work function. The prototype for the work function is quite -simple: - -\code -def work(self, input_items, output_items) -\endcode - -The input_items and output_items are lists of lists. The input_items -contains a vector of input samples for every input stream, and the -output_items is a vector for each output stream where we can place -items. Then length of output_items[0] is equivalent to the -noutput_items concept we are so familiar with from the C++ blocks. - -Following is an example Python block that adds two input streams -together. This block is used in the qa_block_gateway.py test code. - -\code -class add_2_f32_1_f32(gr.sync_block): - def __init__(self): - gr.sync_block.__init__( - self, - name = "add 2 f32", - in_sig = [numpy.float32, numpy.float32], - out_sig = [numpy.float32], - ) - - def work(self, input_items, output_items): - output_items[0][:] = input_items[0] + input_items[1] - return len(output_items[0]) -\endcode - -The block defines two input floating point streams by setting in_sig -to "[numpy.float32, numpy.float32]" and a single output float stream -in out_sig of "[numpy.float32]." - -The work function then just adds the two input streams together. The -streams are input_items[0] and input_items[1]. The block still returns -the concept of noutput_items like we use in C++, only we get it here -by getting len(output_items[0]). Because this is a sync_block, we also -know that the size of the input_items for both streams is the same as -the size of the output_items vector. - - - -\section pyblocks_tags Using Stream Tags - -Python blocks have access to the stream tag system like their C++ -counterparts. The interface is almost identical except they behave -just a bit more like we would expect in Python. - -To add tags to the data stream, we use the add_item_tag function: - -\code -def work(self, input_items, output_items): - .... - add_item_tag(which_output, abs_offset, - key, value, srcid) - .... -\endcode - -The abs_offset is an integer of the sample that the tag is attached -to, and key and value are both PMTs to set the key:value pair of the -tag information, and the srcid is an optional PMT to define the source -of the block that generate the tag. - -We then can get tags using either the get_tags_in_range or -get_tags_in_window. Again, like their C++ counter parts, the -get_tags_in_range uses the absolute item offset numbering (using -nitems_read) while the get_tags_in_window uses relative offsets within -the current window of items available to the work function. The main -difference from the C++ function is that instead of having the first -argument be a vector where the tags are stored, the Python version -just returns a list of tags. We would use it like this: - -\code -def work(self, input_items, output_items): - .... - tags = get_tags_in_window(which_input, rel_start, rel_end) - .... -\endcode - - - -\section pyblocks_msgs Using Message Passing - -Again, like their C++ counterparts, Python blocks can use the -asynchronous message passing interface. We define output message -handlers using: - -\code -self.message_port_register_out(pmt.intern("<port name>")) -\endcode - -We can then post messages to this using the message_port_pub function: - -\code -self.message_port_pub(pmt.intern("<port name>"), <pmt message>) -\endcode - -We then register input messages and handlers in similar ways: - -\code -self.message_port_register_in(pmt.intern("<port name>")) -self.set_msg_handler(pmt.intern("<port name>"), <msg handler function>) -\endcode - -Putting this together below is a very simple example: - -\code -class msg_block(gr.basic_block): - def __init__(self): - gr.basic_block.__init__( - self, - name="msg_block", - in_sig=None, - out_sig=None) - - self.message_port_register_out(pmt.intern('msg_out')) - self.message_port_register_in(pmt.intern('msg_in')) - self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg) - - def handle_msg(self, msg): - self.message_port_pub(pmt.intern('msg_out'), - pmt.intern('message received!')) -\endcode - -*/ |