Page 1 of 1
Application Output
Posted: 25 Jul 2012, 09:59
by akhambhati
Hi,
I am currently using a signal processing chain that results in linear classification. I'd like to develop an application that takes the linear classification output and drives a particular line on a serial port. I am familiar with the System.IO.Ports class that is available in Visual C++ and .NET, however recognizing the event to monitor in order to drive a particular line is unclear to me.
Let's say I were to use the simple binary event of attended/unattended stimuli that is employed by the P3Speller application.
Any help or direction on this matter is appreciated.
Thanks,
Ankit
Re: Application Output
Posted: 25 Jul 2012, 10:06
by mellinger
Hi,
it is impossible to control individual lines of hardware ports using standard drivers. You will need to install a special kernel driver that allows you to execute privileged hardware access from user code. Such a driver is available here:
http://www.bci2000.org/svn/trunk/src/co ... d_bins.zip
Regards,
Juergen
Re: Application Output
Posted: 25 Jul 2012, 16:02
by akhambhati
Thank you, Juergen.
It turns out we have developed a way to interface with the COM ports using the HANDLE methods (similar to
http://bci2000.org/phpbb/viewtopic.php? ... 67&start=0)
I want to embed something like this that sends a binary signal out whenever a LinearClassifer detects a positive (or negative) classification result. I have the serial interface complete already, but I am confused how to explicitly obtain the LinearClassifier result into my Application module. Am I required to inherit from the StimulusTask class (OnClassResult method)? Is this a callback method that will continuously have the current classification result "pushed in" or is there more to it? I am wondering what the absolute minimum methods would be in order to obtain these classifications.
Thank you,
Ankit
Re: Application Output
Posted: 26 Jul 2012, 06:27
by mellinger
Hi,
I'm not sure what your signal processing chain looks like, but I guess it is a stimulus-related signal processing chain. And I suppose you are using an existing application module in order to present stimuli, either the StimulusTask or P3Speller module, right?
These modules write out information about classification results in form of BCI2000 state variables. For the P3Speller module, these are the states SelectedTarget, SelectedRow, SelectedColumn:
http://www.bci2000.org/wiki/index.php/U ... ctedColumn
For the StimulusTask module, it is the state SelectedStimulus:
http://www.bci2000.org/wiki/index.php/U ... edStimulus
You have a number of quite different possibilities to transfer that information to a COM port. One is to write a very simple program that reads BCI2000 state information from a UDP port, and forwards it to a COM port, as discussed on the thread that you are quoting.
Alternatives would be to use one of the BCI2000 remote control components, which would be most appropriate if you want to embed BCI2000 into an external application, or to write a BCI2000 filter that forwards state information to a COM port, and place it into the application module.
Let me know if you need more information.
Juergen
Re: Application Output
Posted: 26 Jul 2012, 09:50
by akhambhati
Sorry for the confusion, Juergen.
Let me preface this by saying this is a very basic study just to get my hands dirty with BCI. I am exploring a tremendously simple, "open loop" concept. I want to continuously inspect the power spectrum for increases in particular bands above manually set thresholds. When these thresholds are exceeded I want to send a simple pulse using the serial out.
My signal processing chain looks like <SpatialFilter> --> <SpectralEstimator>. Potentially with a Normalizer at the end of this sequence, might this be necessary?
My application module would then allow the user to set these thresholds as parameters and whenever the threshold is exceeded the program sends out a pulse.
I am confused with two things: 1. How do I access the output of my signal processing module? Should I be looking at a particular state variable or elsewhere? 2. How do I frame my application to continuously acquire the the updated spectrum from the signal processing module? I have setup using an ApplicationBase class, but it is unclear to me which methods enable the signal processing output to be "pushed in."
Thanks very much for your continued help,
Ankit
Re: Application Output
Posted: 26 Jul 2012, 10:11
by akhambhati
Hi Juergen,
After reading a bit more carefully on the wiki, it seems that I want to use the "Process" method in my ApplicationBase derived app module. This is my understanding:
The GenericSignal class in the Process method contains the signal processing module output (from the last filter in the sigproc. chain). I can call a pointer to the GenericSignal as (channel # , element ) and get a value out. This value, presumably from the SpectralEstimator can be compared to the threshold I set and therefore signal a particular COM event.
My one last question is, does the Process method automatically get called throughout the run? That is, can I be assured that if I call my relevant COM code in Process it will be executed every time new spectral estimates are generated?
Ankit
Re: Application Output
Posted: 26 Jul 2012, 12:16
by mellinger
Hi Ankit,
you are right, and things will work as you think they should.
However, you should be aware that thresholding is typically done inside the signal processing module, and that the Normalizer filter is available for that purpose (its offset entries correspond to the threshold). The application module can then decide according to the sign of the signal processing module's output, rather than being aware of thresholds.
This approach has two important advantages:
1) It is compatible with existing application modules, i.e. you can switch from your own application to using the CursorTask if you want to try cursor feedback in between.
2) Using the Normalizer has the advantage that it can adapt thresholds automatically. For more information, see
http://www.bci2000.org/wiki/index.php/U ... Normalizer
The Normalizer should be the last filter in the chain, and should be preceded with the LinearClassifier. The LinearClassifier will allow you to select a subset of features from its input, so you don't need to transfer all the information to the application module. It will also bring your data into a shape that is compatible with the Normalizer (a number of channels with a single element per channel each).
For details about the LinearClassifier, see
http://www.bci2000.org/wiki/index.php/U ... Classifier
Regards,
Juergen
Re: Application Output
Posted: 27 Jul 2012, 09:47
by akhambhati
Thank you! I was able to get it working as you suggested.
Interestingly, getting a proper control switch involved some logic within the application module itself. To avoid continuous false-positive COM signals in the case that the feature value is jittering above and below the threshold, I had to prescribe some time requirements about how long the signal had to be above threshold before it is considered a "true" response.
As I mentioned, this logic is something I wrote in the application module with the duration above threshold as a parameter. I then set the adaptation buffer size in the Normalizer to equal this above threshold duration such that the feature value would immediately decay to a new baseline. Is this the best way to handle these cases? I am aware that the Normalizer allows some boolean expressions but I'm not sure if it's possible to recreate this "above threshold" constraint using the Normalizer's buffer matrix.
Ankit
Re: Application Output
Posted: 27 Jul 2012, 10:36
by mellinger
Hi,
your "minimum time above threshold" approach is actually a variant of low pass filtering. You will obtain equivalent results by e.g., using a low pass filter with a time constant similar to your time requirement. That low pass filter should be located between Linear Classifier, and Normalizer.
The cursor feedback task uses its own variant of low pass filtering, effected by the fact that the control signal determines cursor speed. When the cursor hits a target, the target's coordinates will be the integral/sum of cursor speed values over the entire trial. As trials tend to be of similar duration, this means that, in 1D, the selected target actually corresponds to the sign of the averaged control signal.
A typical trial duration with SMR feedback is 2-3 seconds, so you might start out with a time constant of 2s when you decide to try the low pass filter approach.
Regards,
Juergen