Session Saves

A problem that has arisen with BCI Essentials is that sometimes it crashes without warning and without telling you what went wrong. This is annoying at best and infuriating at worst, depending on when the crash happens.

First, it is important to understand how data from each BCI session is currently stored. Different parts of BCI Essentials create different LSL streams. The headset creates a stream of EEG data, unity creates a stream of markers, and python creates a stream of responses/selections. These streams are recorded by Lab Recorder software, which time synchronizes and records these streams in an XDF file.

Crashes occur in python or unity for unknown reasons, ending their respective streams, but all streams up to the point of the crash are salvageable by lab recorder. For this reason, it would be possible to reload the training data from the XDF to retrain the classifier.

Unfortunately, these streams only include the messages sent between the headset, unity, and python. They don’t include detailed information from inside unity or python, such as the state of the application or the trained classifier model. It would also be ideal to be able to resume a session, even if we are not using lab recorder, so it is likely best that the solution be saved within python. Pickle is the best option to save objects in python.

What remains is to decide on what to pickle, when to pickle, how to manage pickles, and how to reload pickles.

What to pickle

The entire EEG/ERP data object. If storage becomes constraining, we can reduce the scope later.

When to pickle

This could be done at checkpoints(ie. each round of calibration) OR using exception handling (ie. put all of main into a try-except condition and have the exception pickle to save data). The latter feels janky, even for BCI essentials python, so I think we should start by saving at checkpoints. Let’s say each time the classifier is updated, this way upon reload you will always have the latest version of the classifier.

How to manage pickles

If we are saving a new pickle for every retrain of the classifier, we will quickly run out of space. We will need some kind of garbage collection to only keep the latest pickle for a given user. However, this requires some kind of user ID to be known to Bessy. If we want to build user IDs in later, then we could hard code a user ID of 0000 shared by everyone.

How to restore

We could add a method to the EEG data object that checks for pickles which match the user ID. We would also need a setting to say whether we should reload from the pickle or start fresh. Furthermore, we could also have it work on a timer such that if the pickle is more than 30 minutes old it will automatically start from scratch.