Fails to save SMI data with triggers
Hi all,
I'm running a combined EEG (actiChamp) - ET (SMI RED250 mobile) experiment using OpenSesame 3.2.7. In my experiment, I send triggers both to the EEG and SMI. However, at the end of the experiment, the eye data fails to be saved with the following error:
Unexpected error item-stack: exception type: Exception exception message: Error in libsmi.SMItracker.close: failed to save data; unknown error with decimal code 204; please refer to the iViewX SDK Manual time: Tue May 21 17:08:26 2019 Traceback: File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libqtopensesame\misc\process.py", line 157, in run exp.run() File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\experiment.py", line 463, in run self.end() File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\experiment.py", line 536, in end self.cleanup() File "C:\Program Files (x86)\OpenSesame\lib\site-packages\libopensesame\experiment.py", line 522, in cleanup func() File "C:\Program Files (x86)\OpenSesame\share\opensesame_plugins\pygaze_init\pygaze_init.py", line 82, in close self.experiment.pygaze_eyetracker.close() File "C:\Program Files (x86)\OpenSesame\lib\site-packages\pygaze\_eyetracker\libsmi.py", line 416, in close raise Exception("Error in libsmi.SMItracker.close: failed to save data; %s" % err) Exception: Error in libsmi.SMItracker.close: failed to save data; unknown error with decimal code 204; please refer to the iViewX SDK Manual
According to the iViewX SDK Manual, the decimal code 204 refers to "ERR_IVIEWX_ACCESS_INCOMPLETE", which means that the LPT signal recording is still in progress. This error is returned under the function intiV SetupLptRecording( constchar∗portName, intenableRecording )
. This function specifically says, "Enables or disables the LPT signal recording functionality. When enabling the LPT port signal recording the LPT port name has to be specified. The LPT ports available for recording can be queried by using the iV_GetAvailableLptPorts API function. The function must not be called during a running recording."
I'm not sure if this is the problem, but if it is, does anyone know how to close/disable the LPT signal recording from within OpenSesame (if it's possible at all)? Or what is the real problem here?
Your help will be very helpful!
p.s. I'm desperate
Cheers,
intan
Comments
Hi Intan,
I don't have hands-on experience with the SMI, so I'm kind of groping in the dark here. Have you managed to successfully collect data with the SMI with OpenSesame before? I.e. should it work in principle?
> According to the iViewX SDK Manual, the decimal code 204 refers to "ERR_IVIEWX_ACCESS_INCOMPLETE", which means that the LPT signal recording is still in progress.
If that's correct, one thing that comes to mind is that there may not be enough time between the moment that the recording is stopped (by
pygaze_stop_recording
), and the moment that the experiment ends (and the connection to the eye tracker is closed, where things go wrong).What is the structure of your experiment? If you add, say, a goodbye screen at the very end of the experiment that stays on for a few seconds before the experiment actually ends, does that solve the issue?
Cheers!
Sebastiaan
Check out SigmundAI.eu for our OpenSesame AI assistant!
Hei Sebastiaan,
thank you for your response! I did data collection with SMI and OpenSesame before, but without triggers and it was fine. Now I want to send triggers both to the EEG and ET. However, it keeps giving me the aforementioned error message.
Roughly speaking, the structure of my experiment is that after the
pygaze_stop_recording
item, there is a feedback item to show them their final scores. Between these two items, I put an inline script to explicitly close the port usings.close()
(s = serial.Serial('COM1')
). Even after closing the connection to the port explicitly I still get this error...Is it a problem to put a feedback item at the very end of the experiment? Should I use a sketchpad item instead??
Cheersies,
intan
> thank you for your response! I did data collection with SMI and OpenSesame before, but without triggers and it was fine. Now I want to send triggers both to the EEG and ET. However, it keeps giving me the aforementioned error message.
I initially assumed that you'd send a message to the SMI log file, and the separately send a trigger to the EEG recording device through the parallel port. So that the two triggers are completely independent of each other, in other words.
But now that I read the error message again, it seems that the SMI library is also involved in sending triggers to the EEG. So that the two triggers are *not* independent of each other, in other words.
Could you clarify how this works?
> Is it a problem to put a feedback item at the very end of the experiment? Should I use a sketchpad item instead??
No that's totally fine!
Check out SigmundAI.eu for our OpenSesame AI assistant!
Why is the SMI library involved in sending triggers to the EEG?
Your initial assumption is correct - that's how I (was supposed to) program the experiment. The experiment should send triggers that are split by a serial-to-parallel box to the EEG and ET independently. To initialise the triggers, I do the following.
so I use code A for EEG and code B for ET (that's how the serial-to-LPT box works). For instance,
trig = 'A015'
andtrig = 'B015'
. That's why I do not see why the triggers aren't independent. Can you explain to me, maybe I've done something wrong here (i.e., I thought I made it work in a way it's supposed to when it's something completely different)?I also thought the problem was that libsmi was still actively sending triggers when the experiment was over (given that error)? If need be, I can try to attach the experiment.
Thank you for your help!
intan
Hi Intan,
Ah, I think I understand now. So it seems that are (at least) two ways to send information to the SMI log file:
eyetracker.log()
function, which in turn uses theiViewXAPI
Python library.I suspect that PyGaze doesn't properly handle the second case, and that's where the error comes from. (Ping @Edwin )
But I also don't think it's necessary to use the parallel port, which is essentially a historical artifact that I wouldn't use for anything unless it's strictly necessary. Is there any reason why you wouldn't use the
eyetracker.log()
function to send trigger messages to the SMI device, and then use the serial-to-LPT box only for the EEG?Cheers!
Sebastiaan
Check out SigmundAI.eu for our OpenSesame AI assistant!
Hei Sebastiaan,
So, the idea is to send triggers for each phase to the EEG but to send triggers at least at the start and end of the experiment to SMI such that we can synchronise the EEG and ET data. Why do we need to do this? Because the SMI eyetracker is quite unreliable and sometimes it freezes in the middle of the experiment :( To make sure we know during which phase we lose the data, we need the ET triggers. Is synchronisation possible with
eyetracker.log()
together with EEG triggers? I have usedeyetracker.log()
for each phase as well. If it's possible to sync with the EEG triggers, maybe I will just useeyetracker.log()
.Cheersies,
intan
Just thinking that this may be useful: I thought maybe it was a good idea to add something like
iViewXAPI.iV_SetupLptRecording("LPT name", 0)
within theSMItracker.close()
function in libsmi to disable the signal recording to the port after an experiment has ended. I am not sure if this can be a solution, but it seems that this is what the SDK manual suggests. (ping @Edwin )Other than that, just to reiterate, if
eyetracker.log()
can be used to sync with the EEG triggers, I will use this (faster) solution in the meantime. :)> Just thinking that this may be useful: I thought maybe it was a good idea to add something like
iViewXAPI.iV_SetupLptRecording("LPT name", 0)
within theSMItracker.close()
function in libsmi to disable the signal recording to the port after an experiment has ended.Perhaps you can already add this to the Run phase od an
inline_script
at the very end of the experiment? Perhaps that will resolve the whole issue.> Other than that, just to reiterate, if
eyetracker.log()
can be used to sync with the EEG triggers, I will use this (faster) solution in the meantime. :)I think (but I say this without actually knowing how the SMI API works) that sending log messages through the API (i.e. with
eyetracker.log()
) and sending triggers through the parallel port are two different ways to accomplish the same thing. So yes, I think you can safely useeyetracker.log()
instead. The added advantage will be that you can then send more informative log messages than just single-byte trigger codes.Check out SigmundAI.eu for our OpenSesame AI assistant!
Perhaps you can already add this to the Run phase od an
inline_script
at the very end of the experiment? Perhaps that will resolve the whole issue.I indeed did this already, but it didn't resolve the issue.
In fact, it seems to me that the error message may be misleading. I tried to just connect to the SMI computer and send log messages using
eyetracker.log()
, but it threw the same error. The stimulus PC (where I run OpenSesame) is a different computer from the SMI computer and they are connected via an ethernet cable. Is the problem maybe then they don't know where to save the the .idf files (i.e., ET data)? Do I have to define the file path where I want to save my .idf files?Cheersies,
intan
> I indeed did this already, but it didn't resolve the issue.
Yes, I figured you would've tried that ;-)
> The stimulus PC (where I run OpenSesame) is a different computer from the SMI computer and they are connected via an ethernet cable. Is the problem maybe then they don't know where to save the the .idf files (i.e., ET data)? Do I have to define the file path where I want to save my .idf files?
Hmm, it could be, actually. It's so difficult to debug without actually having access to the computer (or even an other SMI device). But yes, looking at the code, it seems that if you don't specify a logfile, pygaze will try to save the output data to a file called 'automatic', without specifying a path. More specifically, 'automatic' will be the first argument to
iViewXAPI.iV_SaveData()
.What happens if you specify, in the
pygaze_init
item, a full path to a log file where you know that you have write access? Something likec:\my writable folder\output.idf
.Check out SigmundAI.eu for our OpenSesame AI assistant!
Hi all,
Interesting problem! My thoughts:
I'd be quite hestiant to add iViewXAPI.iV_SetupLptRecording("LPT name", 0) to the close function, for starters because it would require knowing the LPT name (which we don't, and should thus be user-specified), but more importantly because it doesn't seem to work. (Adding it in an inline_script like you did should have had the same effect, but didn't.) On top of that, with SMI being bunk, I don't think it's wise to further edit code that is essentially there for legacy purposes (i.e. until all SMI trackers have broken down). Of practical note: I can't debug anything, due to no longer having access to an SMI tracker. Sorry :(
Despite that, we should still try to figure out what's going on in your situation, and whether we can resolve it!
I think @sebastiaan's suggestion of simply using eyetracker.log should do just fine. The log function was intended for this exact purpose (including triggers in your data file), so should do the trick. Suggested code for your trigger sending in inline_scripts:
This has the added benefit of not having your triggers come in at different times too, which is what your current code does. (There's a minimum of 20 ms delay between the triggers if you're using trigA followed by trigB.)
Good luck!
Edwin
Just noted your additional messages, on `eyetracker.log` throwing the same error. There are a few things you should keep in mind when using a second computer to record your data:
Hi Sebastiaan,
What happens if you specify, in the
pygaze_init
item, a full path to a log file where you know that you have write access? Something likec:\my writable folder\output.idf
.I tried this already as well, but it still did not work. It spewed another error telling me that it failed to set up a log file. :/
Hi @Edwin ,
thank you for your comprehensive response! I have changed the IP address of the iViewX computer and defined the log file. The problem is, it seems that it cannot save the .idf file because, despite this error, I still get the OpenSesame .txt and SMILOG .txt files. I just cannot obtain (or save) the .idf file although I tried what Sebastiaan suggested above.
Here I attach a screenshot from the iViewX SDK manual about the "ERR_IVIEWX_ACCESS_INCOMPLETE".
Genuinely appreciate your help!
UPDATE:
I have been successful in connecting the stimulus PC with the eyetracker PC. In the end, there are 3 outputs from one run of an experiment: the OpenSesame .txt file, the SMILOG .txt file, and the .idf file (for the eye data). The .txt files are stored automatically in the same folder as the experiment in the stimulus PC. The .idf file is saved in the eyetracker PC. I did make some changes in the libsmi.py library to make my experiment work. What I did was as follow.
Define different IP addresses (one for iViewX computer, one for the stimulus computer):
Define the file path (folder into which data is saved) for .idf file. The slicing refers to how I identify each participant:
I still don't understand why the error message says "recording in progress", but perhaps because previously the file path for the idf data was not clearly defined, the access to iViewX was considered incomplete.
Thanks again all for the inspiration to solve this problem! It is ineed unnecessary to add
That's pretty impressive, and thank you for sharing!
Just to clarify the solution for me. You're saying that the second IP address (
169.254.181.139
) is the stimulus computer, i.e. the computer that OpenSesame is running on, right? So basically, you're telling iViewX at which address to reach OpenSesame?Check out SigmundAI.eu for our OpenSesame AI assistant!
Wow, the end of my previous message was cut off! I was saying "It is indeed unnecessary to add more things in the
close()
function" :)You're saying that the second IP address (
169.254.181.139
) is the stimulus computer, i.e. the computer that OpenSesame is running on, right?Oh yes, I didn't make it clear before. The second IP address is the computer running OpenSesame.
So basically, you're telling iViewX at which address to reach OpenSesame?
It looks like that, and also the other way around. My understanding is that you need to explicitly state which computer is running what.
I can also, apparently, define the participant ID and experiment description that will be saved in the .idf files (wow, if only I knew this earlier).
Very glad to see this resolved! Thanks for sharing the solution :)