I recently posted about receiving UDP messages and generating stimulations from their content using the python scripting Box.
This approach seems to be working right now, but I'd like to make sure I don't miss any potential issue and that my stimulations are properly written together with the eeg stream in a file for use with classifiers.
In the meantime I came across the page about tcp tagging so I know I'm not doing things the recommended way, but for now let's consider my use case is not time critical enough to require the use of tcp tagging.
Also, if I understand correctly the motivation behind tcp tagging, maybe my approach could be useful for cases where the stimulations are not predefined but come from an unpredictable real-time input
What actually bothers me is that after some time I don't see the stimulations appear in the Signal display window anymore.
They are still all properly logged by a Stimulation listener box.
I also had a quick look at a csv recording test file, and it seems that the stimulations are still written into it, even those which don't appear in the Signal display window.
So I guess it might be a known issue with the signal display box ... could anyone confirm (or infirm) this ?
Here is my most recent python script, based on the python-clock-stimulator example.
As you can see I'm making sure to send continuously time tagged stimulation chunks, with no stimulation inside if no UDP message was received :
Code: Select all
from pyOSC3 import OSCServer
ip = "0.0.0.0"
port = 8005
class MyOVBox(OVBox):
def __init__(self):
OVBox.__init__(self)
def initialize(self):
self.server = OSCServer((ip, port))
self.server.socket.setBlocking(0)
self.server.addMsgHandler("/ov/stimulation", self.onMessage)
self.server.addMsgHandler("/ov/scenario", self.onMessage)
self.negativeStimLabel = self.setting['Negative Stim Label']
self.neutralStimLabel = self.setting['Neutral Stim Label']
self.positiveStimLabel = self.setting['Positive Stim Label']
self.noPicStimLabel = self.setting['No Pic Stim Label']
self.endStimLabel = self.setting['End Stim Label']
self.stimCode = None
self.negativeStimCode = OpenViBE_stimulation[self.negativeStimLabel]
self.neutralStimCode = OpenViBE_stimulation[self.neutralStimLabel]
self.positiveStimCode = OpenViBE_stimulation[self.positiveStimLabel]
self.noPicStimCode = OpenViBE_stimulation[self.noPicStimLabel]
self.endStimCode = OpenViBE_stimulation[self.endStimLabel]
self.output[0].append(OVStimulationHeader(0., 0.))
def process(self):
self.stimCode = None
stimSet = OVStimulationSet(self.getCurrentTime(), self.getCurrentTime()+1./self.getClock()
# handle_request will eventually update self.stimCode if it triggers a call to onMessage()
self.server.handle_request()
if self.stimCode is not None:
stimSet.append(OVStimulation(self.stimCode, self.getCurrentTime(), 0.))
self.output[0].append(stimSet)
def uninitialize(self):
self.server.close()
def onMessage(self, path, tags, args, data):
arg = args[0]
if path == "/ov/stimulation":
if arg == "negative":
self.stimCode = self.negativeStimCode
elif arg == "neutral":
self.stimCode = self.neutralStimCode
elif arg == "positive":
self.stimCode = self.positiveStimCode
elif arg in ("snow", "nopic"):
self.stimCode = self.noPicStimCode
elif path == "/ov/scenario":
if arg == "stop":
self.stimCode = self.endStimCode
box = MyOVBox()
My stimulations have a duration of 0 as in the python-clock-stimulator example.
My guess is that a classifier will consider that all signal chunks after a specific stimulation belong to this stimulation's class, until a new stimulation is received and then it will consider that the following signal chunks belong to the new stimulation's class, and so on ...
Is this a right guess, or should I generate stimulations with non null durations in order to train the classifier properly ?
Many thanks for any feedback.
Best,
Joseph