Skip to content

Commit fbf9f40

Browse files
committed
Update documentation
1 parent 557d181 commit fbf9f40

File tree

5 files changed

+87
-152
lines changed

5 files changed

+87
-152
lines changed

Diff for: User-Manual/Plugins/Python-Processor.html

+38-36
Original file line numberDiff line numberDiff line change
@@ -561,91 +561,92 @@ <h3>Setting the Python Interpreter Path<a class="headerlink" href="#setting-the-
561561
<section id="creating-loading-a-python-module">
562562
<h2>Creating &amp; loading a Python Module<a class="headerlink" href="#creating-loading-a-python-module" title="Permalink to this heading">#</a></h2>
563563
<p>Once the plugin is loaded into the signal chain, a Python module (script) needs to be loaded into the GUI. This module should take the same form as the <a class="reference external" href="https://github.com/open-ephys-plugins/python-processor/blob/main/Modules/template/processor_template.py">processor template</a> provided in the plugin’s GitHub repository. The <code class="code docutils literal notranslate"><span class="pre">PyProcessor</span></code> class is designed to expose the following functions to the Python module to allow interaction with the incoming data:</p>
564-
<dl class="py function">
564+
<dl class="py method">
565565
<dt class="sig sig-object py" id="init__">
566-
<span class="sig-name descname"><span class="pre">__init__</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_channels</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_rate</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#init__" title="Permalink to this definition">#</a></dt>
566+
<span class="sig-name descname"><span class="pre">__init__</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">processor</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_channels</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_rate</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#init__" title="Permalink to this definition">#</a></dt>
567567
<dd><p>A new processor is initialized when the module is imported/reloaded, or the plugin’s settings are updated (i.e., the number of input channels changes, or a new stream is selected).</p>
568568
<dl class="field-list simple">
569569
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
570570
<dd class="field-odd"><ul class="simple">
571-
<li><p><strong>num_channels</strong> – number of input channels from the selected stream</p></li>
572-
<li><p><strong>sample_rate</strong> – the selected stream’s sample rate</p></li>
571+
<li><p><strong>processor</strong> (<em>object</em>) – Python Processor class object used for adding events from python.</p></li>
572+
<li><p><strong>num_channels</strong> (<em>int</em>) – number of input channels from the selected stream</p></li>
573+
<li><p><strong>sample_rate</strong> (<em>float</em>) – the selected stream’s sample rate</p></li>
573574
</ul>
574575
</dd>
575576
</dl>
576577
</dd></dl>
577578

578-
<dl class="py function">
579+
<dl class="py method">
579580
<dt class="sig sig-object py" id="process">
580-
<span class="sig-name descname"><span class="pre">process</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#process" title="Permalink to this definition">#</a></dt>
581+
<span class="sig-name descname"><span class="pre">process</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#process" title="Permalink to this definition">#</a></dt>
581582
<dd><p>Process each incoming data buffer. Any modifications to the <code class="code docutils literal notranslate"><span class="pre">data</span></code> variable will be passed to downstream processors.</p>
582583
<dl class="field-list simple">
583584
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
584-
<dd class="field-odd"><p><strong>data</strong> (<em>ndarray</em>) – incoming data buffer</p>
585+
<dd class="field-odd"><p><strong>data</strong> (<em>ndarrary</em>) – N x M numpy array, where N = num_channles, M = num of samples in the buffer.</p>
585586
</dd>
586587
</dl>
587588
</dd></dl>
588589

589-
<dl class="py function">
590+
<dl class="py method">
590591
<dt class="sig sig-object py" id="start_acquisition">
591-
<span class="sig-name descname"><span class="pre">start_acquisition</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#start_acquisition" title="Permalink to this definition">#</a></dt>
592+
<span class="sig-name descname"><span class="pre">start_acquisition</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#start_acquisition" title="Permalink to this definition">#</a></dt>
592593
<dd><p>Called before starting acquisition. Allows the script to do some setup/initialization before acquisition starts.</p>
593594
</dd></dl>
594595

595-
<dl class="py function">
596+
<dl class="py method">
596597
<dt class="sig sig-object py" id="stop_acquisition">
597-
<span class="sig-name descname"><span class="pre">stop_acquisition</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#stop_acquisition" title="Permalink to this definition">#</a></dt>
598+
<span class="sig-name descname"><span class="pre">stop_acquisition</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#stop_acquisition" title="Permalink to this definition">#</a></dt>
598599
<dd><p>Called after stopping acquisition. Allows the script to do some finalization after acquisition stops.</p>
599600
</dd></dl>
600601

601-
<dl class="py function">
602+
<dl class="py method">
602603
<dt class="sig sig-object py" id="start_recording">
603-
<span class="sig-name descname"><span class="pre">start_recording</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">recording_dir</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#start_recording" title="Permalink to this definition">#</a></dt>
604+
<span class="sig-name descname"><span class="pre">start_recording</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">recording_dir</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#start_recording" title="Permalink to this definition">#</a></dt>
604605
<dd><p>Called before starting recording. Informs the plugin that the GUI is now recording data, in case it needs to save any information of its own.</p>
605606
<dl class="field-list simple">
606607
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
607-
<dd class="field-odd"><p><strong>recording_dir</strong> – directory where recording related files are supposed to be stored</p>
608+
<dd class="field-odd"><p><strong>recording_dir</strong> (<em>str</em>) – directory where recording related files are supposed to be stored</p>
608609
</dd>
609610
</dl>
610611
</dd></dl>
611612

612-
<dl class="py function">
613+
<dl class="py method">
613614
<dt class="sig sig-object py" id="stop_recording">
614-
<span class="sig-name descname"><span class="pre">stop_recording</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#stop_recording" title="Permalink to this definition">#</a></dt>
615+
<span class="sig-name descname"><span class="pre">stop_recording</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#stop_recording" title="Permalink to this definition">#</a></dt>
615616
<dd><p>Called before stopping recording. Informs the plugin that the GUI is no longer recording data.</p>
616617
</dd></dl>
617618

618-
<dl class="py function">
619+
<dl class="py method">
619620
<dt class="sig sig-object py" id="handle_ttl_event">
620-
<span class="sig-name descname"><span class="pre">handle_ttl_event</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">source_node</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">channel</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_number</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">line</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">state</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_ttl_event" title="Permalink to this definition">#</a></dt>
621+
<span class="sig-name descname"><span class="pre">handle_ttl_event</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">source_node</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">channel</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_number</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">line</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">state</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_ttl_event" title="Permalink to this definition">#</a></dt>
621622
<dd><p>Handle each incoming ttl event.</p>
622623
<dl class="field-list simple">
623624
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
624625
<dd class="field-odd"><ul class="simple">
625-
<li><p><strong>source_node</strong> – id of the processor this event was generated from</p></li>
626-
<li><p><strong>channel</strong> – name of the event channel</p></li>
627-
<li><p><strong>sample_number</strong> – sample number of the event</p></li>
628-
<li><p><strong>line</strong> – the line on which event was generated (0-255)</p></li>
629-
<li><p><strong>state</strong> – event state True (ON) or False (OFF)</p></li>
626+
<li><p><strong>source_node</strong> (<em>int</em>) – id of the processor this event was generated from</p></li>
627+
<li><p><strong>channel</strong> (<em>str</em>) – name of the event channel</p></li>
628+
<li><p><strong>sample_number</strong> (<em>int</em>) – sample number of the event</p></li>
629+
<li><p><strong>line</strong> (<em>int</em>) – the line on which event was generated (0-255)</p></li>
630+
<li><p><strong>state</strong> (<em>bool</em>) – event state True (ON) or False (OFF)</p></li>
630631
</ul>
631632
</dd>
632633
</dl>
633634
</dd></dl>
634635

635-
<dl class="py function">
636+
<dl class="py method">
636637
<dt class="sig sig-object py" id="handle_spike">
637-
<span class="sig-name descname"><span class="pre">handle_spike</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">self</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">source_node</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">electrode_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_channels</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_samples</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_number</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sorted_id</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">spike_data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_spike" title="Permalink to this definition">#</a></dt>
638+
<span class="sig-name descname"><span class="pre">handle_spike</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">source_node</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">electrode_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_channels</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">num_samples</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sample_number</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">sorted_id</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">spike_data</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_spike" title="Permalink to this definition">#</a></dt>
638639
<dd><p>Handle each incoming spike.</p>
639640
<dl class="field-list simple">
640641
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
641642
<dd class="field-odd"><ul class="simple">
642-
<li><p><strong>source_node</strong> – id of the processor this spike was generated from</p></li>
643-
<li><p><strong>electrode_name</strong> – name of the electrode</p></li>
644-
<li><p><strong>num_channels</strong> – number of channels associated with the electrode type</p></li>
645-
<li><p><strong>num_samples</strong> – total number of samples in the spike waveform</p></li>
646-
<li><p><strong>sample_number</strong> – sample number of the spike</p></li>
647-
<li><p><strong>sorted_id</strong> – the sorted ID for this spike</p></li>
648-
<li><p><strong>spike_data</strong> – waveform as N x M numpy array, where N = num_channels &amp; M = num_samples (read-only).</p></li>
643+
<li><p><strong>source_node</strong> (<em>int</em>) – id of the processor this spike was generated from</p></li>
644+
<li><p><strong>electrode_name</strong> (<em>str</em>) – name of the electrode</p></li>
645+
<li><p><strong>num_channels</strong> (<em>int</em>) – number of channels associated with the electrode type</p></li>
646+
<li><p><strong>num_samples</strong> (<em>int</em>) – total number of samples in the spike waveform</p></li>
647+
<li><p><strong>sample_number</strong> (<em>int</em>) – sample number of the spike</p></li>
648+
<li><p><strong>sorted_id</strong> (<em>int</em>) – the sorted ID for this spike</p></li>
649+
<li><p><strong>spike_data</strong> (<em>ndarrary</em>) – waveform as N x M numpy array, where N = num_channels &amp; M = num_samples (read-only).</p></li>
649650
</ul>
650651
</dd>
651652
</dl>
@@ -656,21 +657,22 @@ <h2>Creating &amp; loading a Python Module<a class="headerlink" href="#creating-
656657
<p class="admonition-title">Note</p>
657658
<p>Pay careful attention to the latency introduced by processing data in Python, especially with high-channel-count data.</p>
658659
</div>
659-
<p>There is also a way to send TTL events back from Python to C++. These events will be added to the event buffer for the downstream processors to handle. It is possible using a C++ function exposed to the Python module via an embedded module called <code class="code docutils literal notranslate"><span class="pre">oe_pyprocessor</span></code>. To use this function, the <code class="code docutils literal notranslate"><span class="pre">oe_pyprocessor</span></code> module needs to be imported inside the script and then the C++ function can be invoked like this: <code class="code docutils literal notranslate"><span class="pre">oe_pyprocessor.add_python_event(line,</span> <span class="pre">state)</span></code></p>
660-
<dl class="py function">
660+
<p>There is also a way to send TTL events back from Python to C++. These events will be added to the event buffer for the downstream processors to handle. It is possible using a C++ function exposed to the Python module via an embedded module called <code class="code docutils literal notranslate"><span class="pre">oe_pyprocessor</span></code>.</p>
661+
<dl class="py method">
661662
<dt class="sig sig-object py" id="add_python_event">
662663
<span class="sig-name descname"><span class="pre">add_python_event</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">line</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">state</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#add_python_event" title="Permalink to this definition">#</a></dt>
663664
<dd><p>Send TTL event from Python to C++</p>
664665
<dl class="field-list simple">
665666
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
666667
<dd class="field-odd"><ul class="simple">
667-
<li><p><strong>line</strong> – (int) event line number [0-255]</p></li>
668-
<li><p><strong>electrode_name</strong> – (bool) event state True (ON) or False (OFF)</p></li>
668+
<li><p><strong>line</strong> (<em>int</em>) – event line number [0-255]</p></li>
669+
<li><p><strong>state</strong> (<em>bool</em>) – event state True (ON) or False (OFF)</p></li>
669670
</ul>
670671
</dd>
671672
</dl>
672673
</dd></dl>
673674

675+
<p>To use this function, the <code class="code docutils literal notranslate"><span class="pre">oe_pyprocessor</span></code> module needs to be imported inside the script and then the C++ function can be invoked by using the processor object provided in the <a class="reference internal" href="#init__" title="__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> method, like this: <code class="code docutils literal notranslate"><span class="pre">self.processor.add_python_event(line,</span> <span class="pre">state)</span></code></p>
674676
<p>An example script is provided in the plugin’s GitHub repository in the form of a <a class="reference external" href="https://github.com/open-ephys-plugins/python-processor/blob/main/Modules/examples/bandpass_filter.py">Butterworth Bandpass filter</a>. This filter is the same as the one used in the GUI’s built-in Filter Node plugin.</p>
675677
</section>
676678
<section id="limitations">

0 commit comments

Comments
 (0)