Skip to content
jtorniainen edited this page May 30, 2015 · 5 revisions

Nodes are capable of running multiple background processes. Background processes can be used to, e.g., continuously analyze a signal and extract features from it. An example of this is to do real-time R-peak detection of an ECG signal, to be used as a basis for, e.g., HRV-analysis.

A background process is always written as a class method, i.e., the body of a basic node with one background process is written as follows:

class MidasNodeExample(MidasNodeBase):
    def __init__(self, *args):
        super().__init__(*args)

        ## Add example process to the list of background processes
        self.process_list.append(self.my_background_process)

    # ------------------------------------------------------------------------------
    # Function running in the background
    # ------------------------------------------------------------------------------
    def my_background_process(self):
        # this is an example, so do nothing
        pass

Any function added to the array self.process_list is automatically started and stopped. All such processes are run using the multiprocessing library in Python.

A more complete example of a background process is described next. In this example the process is constantly updating two secondary channels by calculating values from 10 second time-windows of primary data. The self.run_state.value is the poison-pill variable of the BaseNode, which is used to determine whether the node is running or not.

   def background_process_example2(self):
        # The process loops while the node is running. The variable run_state.value is 
        # the poison-pill of the node.
        
        while self.run_state.value:
            # Pull 10 seconds of 'primary' data
            snapshot = self.snapshot_data(self.channel_names)
            data, times = self.unpack_snapshot(snapshot, self.channel_names, [10, 10])
        
            # Calculate mean and standard deviation of this 10 second chunk from
            # channel 0
            if data[0]:
                new_value1 = np.mean(data[0])
                new_value2 = np.std(data[0])
            else:
                new_value1 = 0.0
                new_value2 = 0.0
        
            # Obtain a time-stamp for new values
            time_stamp = lsl.local_clock()
        
            # Push mean to first secondary data channel
            self.push_sample_secondary(0, time_stamp, new_value1)
            
            # Push standard deviation to second secondary data channel
            self.push_sample_secondary(1, time_stamp, new_value2)
            
            # Sleep until next sample (note: for accurate timing you don't want 
            # to use time.sleep)
            time.sleep(1.0)

Clone this wiki locally