embedding the P3 Speller in a Python application

Forum for discussion on different user applications
Post Reply
facubrt
Posts: 4
Joined: 19 Oct 2020, 17:47

embedding the P3 Speller in a Python application

Post by facubrt » 20 Oct 2020, 23:00

Hi, I am relatively new when it comes to BCI2000. I am trying to modify the P3 Speller application module and transform it into a sequence order game for my thesis. I've been looking at the source code for P3Speller, but I can't find a simple way to modify the interface from there (I don't really need to modify the base array, just add more functionality).

Searching the forum, I found this interesting idea to embed P3 Speller inside a WinForm

viewtopic.php?f=5&t=1083&sid=1d8821e48c ... b9f604d07f

My question is if it would be possible to do something similar to this using python and BCI2000Remote. That is, I would like to have the P3 Speller inside a frame or panel of my own Python application. I think this would allow me to focus only on my application code

Currently, using BCI2000Remote.py I can run BCI2000 from python, but this opens as separate windows

I would appreciate if someone could help me with this.

mellinger
Posts: 1210
Joined: 12 Feb 2003, 11:06

Re: embedding the P3 Speller in a Python application

Post by mellinger » 21 Oct 2020, 08:52

I think that's a good path to follow.

The link you gave contains some information about how to achieve this using the Windows API. There is some outdated reference to "VCL Forms," but the general idea is the same:
* get a handle to the P3Speller process' main window,
* create a subwindow inside your own application to hold the P3Speller,
* make the P3Speller process' main window the only child of the new subwindow.

Unfortunately, I cannot guide you how to use the Windows API from python. The Windows API itself is extensively documented on MSDN (www.msdn.com).

Regards,
Juergen

facubrt
Posts: 4
Joined: 19 Oct 2020, 17:47

Re: embedding the P3 Speller in a Python application

Post by facubrt » 22 Oct 2020, 11:37

mellinger wrote: 21 Oct 2020, 08:52 I think that's a good path to follow.

The link you gave contains some information about how to achieve this using the Windows API. There is some outdated reference to "VCL Forms," but the general idea is the same:
* get a handle to the P3Speller process' main window,
* create a subwindow inside your own application to hold the P3Speller,
* make the P3Speller process' main window the only child of the new subwindow.

Unfortunately, I cannot guide you how to use the Windows API from python. The Windows API itself is extensively documented on MSDN (www.msdn.com).

Regards,
Juergen
Hi Juergen,

Thanks for your quick response. Indeed I have consulted how to do this in Python and I have found the solution using win32gui which also has the FindWindow () and SetParent () methods that allow me to embed the matrix within its own interface.

I would like to consult you, taking advantage of this space, if you think that there could be some problem with the performance when carrying out the application in this way, because the intention is that it be later used online for cognitive rehabilitation.

In the case where it is best to make the array completely in Python, instead of embedding it, I understand that this could be achieved by using the DummyApplication module to connect BCI2000 with my application. However, I have some doubts with this, mainly on how to insert the StimulusType and StimulusCode states. I understand that I should create these states using "-INSERT STATE StimulusCode 8 0; INSERT STATE StimulusType 1 0" but I'm not sure I fully understand how this works.

On the other hand, in the case of having a separate application written in Python, would it be necessary for my application to control the lighting of the characters in my array, or is it possible to make BCI2000 control this?

I apologize for so many questions, but I would appreciate if you could give me a hand to better understand this.

Greetings

mellinger
Posts: 1210
Joined: 12 Feb 2003, 11:06

Re: embedding the P3 Speller in a Python application

Post by mellinger » 27 Oct 2020, 11:26

Hi,
if you think that there could be some problem with the performance when carrying out the application in this way
I don't expect any performance, or timing, problems when embedding the P3Speller window into a different application. The P3Speller remains a separate process, and is able to utilize system resources just like before. The general caveat is that you should not run too many or resource-hungry applications on the same machine as you run BCI2000.
create these states using "-INSERT STATE StimulusCode 8 0; INSERT STATE StimulusType 1 0" but I'm not sure I fully understand how this works
INSERT STATE is an Operator scripting command. For more information about Operator scripting commands, see this wiki page:
https://www.bci2000.org/mediawiki/index ... _Scripting
On the other hand, in the case of having a separate application written in Python, would it be necessary for my application to control the lighting of the characters in my array, or is it possible to make BCI2000 control this?
I'm not sure whether I correctly understand what you are asking. If the Python side is responsible for building the matrix (array), it will also be responsible for doing the flashing of rows and columns, and for determining the matrix element selected. The BCI2000 P3Speller provides a StimulusCode state which could be used by the Python side in order to determine when and what to flash, but you would need to have the BCI2000 configuration in sync with the Python configuration, and I cannot imagine any advantage over the embedding solution we were discussing so far.

Regards,
Juergen

facubrt
Posts: 4
Joined: 19 Oct 2020, 17:47

Re: embedding the P3 Speller in a Python application

Post by facubrt » 27 Oct 2020, 20:23

Hello,

Thank you very much for your help. I have finally made the application by embedding the P3 Speller matrix and it works great at the moment.
I make a small contribution on the implementation of BCI2000Remote.py because I ran into some issues that were fortunately easy to solve.

GetSystemStates () did not correctly return the system state 'Resting', 'Running', 'Suspended', etc.
In my case this was fixed by simply changing

Code: Select all

GetSystemStates (self):
return self._lib.BCI2000Remote_GetSystemState (self._instance)
by

Code: Select all

GetSystemStates (self, name):
return self._get_string_result (self._lib.BCI2000Remote_GetSystemState, string_arg (name))
I needed to add the string name as an argument for that to be the result, but maybe there is another way to do it

In the GetStateVariable (self, name) function the return is simply missing. For this you only need to add "return result.value" at the end

Greetings

mellinger
Posts: 1210
Joined: 12 Feb 2003, 11:06

Re: embedding the P3 Speller in a Python application

Post by mellinger » 29 Oct 2020, 11:20

Hi,

thanks a lot for sharing this.
In the GetStateVariable (self, name) function the return is simply missing. For this you only need to add "return result.value" at the end
Straightforward fix, thank you.
GetSystemStates () did not correctly return the system state 'Resting', 'Running', 'Suspended', etc.
There is no function with this name. I assume you mean GetSystemState()? That function does not take an argument, what would you specify as such when calling your version? What happened when you called the original version?

Best regards,
Jürgen

facubrt
Posts: 4
Joined: 19 Oct 2020, 17:47

Re: embedding the P3 Speller in a Python application

Post by facubrt » 04 Nov 2020, 08:08

mellinger wrote: 29 Oct 2020, 11:20 Hi,

thanks a lot for sharing this.
In the GetStateVariable (self, name) function the return is simply missing. For this you only need to add "return result.value" at the end
Straightforward fix, thank you.
GetSystemStates () did not correctly return the system state 'Resting', 'Running', 'Suspended', etc.
There is no function with this name. I assume you mean GetSystemState()? That function does not take an argument, what would you specify as such when calling your version? What happened when you called the original version?

Best regards,
Jürgen
Hi,

I apologize for the delay. As you said, I was referring to the GetSystemState () function. As I said earlier, I'm not sure this is the most practical solution, however the function as it was:

Code: Select all

def GetSystemState (self):
         return self._lib.BCI2000Remote_GetSystemState (self._instance)
it only returned numbers that I wasn't sure I understood (something like: 123950123). Testing I was able to actually get the states 'Running' 'Suspended', etc. Indeed GetSystemState () does not need to receive any parameters. So this function will work fine just by rewriting it like this

Code: Select all

def GetSystemState (self):
         return self._get_string_result (self._lib.BCI2000Remote_GetSystemState)
I am currently using it like this, and this works fine

mellinger
Posts: 1210
Joined: 12 Feb 2003, 11:06

Re: embedding the P3 Speller in a Python application

Post by mellinger » 06 Nov 2020, 14:48

I see. I applied the GetSystemState() fix as well.

Thanks and regards,
Juergen

Post Reply

Who is online

Users browsing this forum: No registered users and 23 guests