How to perform a BCI experiment using the MD-BCI toolbox Preparing the experiment After starting MATLAB, please make sure that all the paths are set correctly on your system. Start all required further programs (e.g. VR applications, etc.) The scripts are designed to be executed in a folder created for the present experiment. Thus, create a folder for each BCI-session and copy the latest bciGetParam.m file to this folder. In the Matlab command window, change the working directory to this folder. With this procedure you make sure to save the configuration of the experiment for each BCI-session for post processing. Pay attention that no other version of bciGetParam.m is on the Matlab path (using which bciGetParam) The parameter file is the central file to configure the experiment. Make sure to open the parameter file bciGetParam.m of the current session and modify it according to your requirements. After the first recording block you may want to select frequencies if you use a frequency decomposition approach. For this purpose set bci.param.freq to an empty matrix []. This causes the use of all possible frequencies (up to 100 Hz) regarding the interval length and sampling rate. In the parameter block of your recording system define bci.preprocChan, where channel indices have to be set according to the buffer the corresponding recording function is reading. Example: The recording function reads 256 channels. We only want to process the first 64 channels and exclude channel 1. Then set bci.preprocChan = 2:64; If you want to use all these channels for classification, use bci.chanOfInterest = bci.preprocChan; Run an Experiment All the data that are required for processing are stored in global variables to be available during the whole BCI session and to avoid manual keeping of variables. At the end of each block the data additionally will be saved on disk. Make sure that bci.param.saveRawDat is set true. Calibration In order to determine the signal strength and frequency range of the channels to process, start a calibration measurement. It is recommended that any kind of movement (in particular eye movements or blinks) is prevented during this measurement. bciCalib; starts the measurement of 10 seconds duration. This function opens a figure that depicts the ratio of standard deviation of frequency bins and channels to the average standard deviation over channels. Channels with high differences will be marked. The values in parentheses are the channel indices that you may want to exclude from bci.preprocChan (eg. channel 9(10) is marked, then change bci.preprocChan = 2:64; to bci.preprocChan = setdiff([2:64],[10]));. Furthermore, an artifact threshold will be suggested in the title of the figure. Set bci.param.artifactThresh to this threshold. If the artifact threshold is too high artifacts will not be detected; if it is to low many or even all epochs will be excluded. The calibration measurement can be repeated to secure reliable estimates. Record a train block To run a block, make sure that your matlab working folder is the desired session path and then start the run with the command bciRun(‘subjID_run_’,1,’train’); The second argument is the number of the run and therefore must be changed for each new recording block. Otherwise data in memory and on disk will be overwritten. Data will be saved in the working directory (use absolute path to save it somewhere else). You can run another training run by changing just the second argument of the function call. bciRun(‘subjID_run_’,2,’train’); Feature and parameter selection (manually) Selection of features can be made by selecting channels and frequencies by hand. The function bciCheckFeatures([1 2]); shows T-values of the train data of run 1 and 2 (optionally you can use run 1 only) for each combination of condition pairs. With the help of the color coded plots you can decide which channels and frequencies you are interested in. The function also displays suggestions of informative frequencies in the command windows by selecting frequencies of defined bands and fulfilling threshold criterions. However, the final frequency selection you have to do by hand. Use help function to read about additional arguments. A more general function for selecting features is bciFeatureRanking. See helpful functions section for more details. bciCheckClassifier([1 2]); gives an estimate of the accuracy the classification can achieve. The recall values give an estimate if a particular class is biased. The number of bad epochs and bad channels can signal an over or under estimate of the artifact threshold. When checking several runs a leave-one-run-out cross validation is performed, 3-fold crossvalidation otherwise. Before you apply the selected frequencies, you can test several combinations by selecting frequencies for the classifier only. bciSelectFrequencies([ 10 20 30]); selects the given frequencies as features of interest. All selected frequencies must be defined in bci.param.freq (if empty in the parameter file, frequencies were automatically determined). An empty matrix as argument bciSelectFrequencies([]) reselects all available frequencies from bci.param.freq. A repeated bciCheckClassifier call will give you a cross validation estimate when using these frequencies for classification. However, it is recommended to enter the best performing frequency set into the parameter file instead of selecting it as features of interest to reduce memory consumption. In order to test or apply your feature selection, change the corresponding parameters in bciGetParam (e.g. you selected channels 40, 50-60 and frequencies 10 and 30 Hz, then set bci.chanOfInterest = [40,50:60] and bci.param.freq=[10,30]). Then test your selection by recreating the epoched data from raw data: bciRecreate(‘subjID_run_’,1:2) Repeat the procedure of checking features and classifier, respectively. You can also use this procedure by changing other essential parameters, as bci.param.tapers, bci.refChanCAR or bci.param.artifactThresh. Some changes of parameters don’t need the recreation of epochs. (e.g. classifier related parameters). In this case it is sufficient to refresh the parameter file after a change was made: bciRefreshParam After that, checking the classifier would use the new parameters. If you have decided which runs and feature set you want to use for the classifier training, run bciTrain([1 2]); Note that it is not sufficient to run bciCheckClassifier(<runs>) to train the classifier because this function performs a cross validation and trains only subsets which are not globally saved. Feature selection (unsupervised) Alternatively or additionally to the subjective selection of frequencies and channels you can enable a feature selection that automatically selects the specified number or ratio of features using a specified method at the specified dimension. Specification is done by defining a string bci.param.featureSelection with the following substrings. As method you can define ‘svm’, ‘tval’ and ‘rsqu’, followed by the dimension ‘chan’, ‘freq’ or ‘raw’, followed by the destination number or ratio of features. When defining a cell string of feature selections, multiple feature selection methods can be applied sequentially. Theoretically the following combination would by possible: bci.param.featureSelection = {‘rsquchan16’,’tvalfreq3’,’svmraw0.3’}; This example first selects 16 channels with highest R² values, then selects out of this feature set the 3 frequency bands with highest t-values and finally selects from this feature set 30 percent of highest weights using a support vector machine training. See bciFeatureRanking description for detailed information on arguments. Start a feedback Run Before you can start a feedback run you have to call bciTrain(<runs>) to train on the whole run(s) and make the classifier available for the test function. bciRun(‘subjID_run_’,3,’test’); starts a feedback run. Again the data are stored in the global cell array and saved on disk. Don’t forget to change the run number for each test run to avoid overwriting. Further helpful functions bciGlobals() makes the global variables visible. bciLoad(‘subjID_run_’,<runs>,doLoadRawdata,doLoadEpochedData) loads the data of runs into the global structures. Useful for post processing or if something went wrong during an experiment. bciRefreshParam() must be called if something was changed in the bciGetParam file to accept the new settings. bciFeatureRanking(<runs>,nFeat,method,category,validation) calculates highest ranked features of a channel-frequency feature space. At multi class mode, for each class pair same number of features are selected and padded to total number if intersections appear. You can specify nFeat as a fix number of features or as ratio of available features by defining between 0 and 1. Comparison method can be ‘tval’, ‘rsqu’ and ‘svm’. Feature category can be ‘freq’ for frequencies ‘chan’ for channels and ‘raw’ for the reshaped feature vector representing the classifier space. Finally, different validation methods induce different results. If you like to apply a validation method different from the absolute maximum (‘max’) you can define validation also as ‘mean’ for absolute mean value and ‘ssq’ for the sum of squares measure. The result is given as parameter-file-conform output in selectedFeat. See help for default values of the arguments. bciTopoplot(<runs>,method,conds) shows the SVM weighting or t-value maps for the feature space (e.g. a spectrogram if using multi taper). If you have specified a channel location file, additional topographic maps are shown. Define method as ‘svm’, ‘tval’ or ‘rsqu’ and define the conditions to compare as a two element vector conds (in the Motor paradigms the conditions match 1,2,3 representing left, base, right; default is [1 3]). Important parameters The following parameters are suggested to be checked: bci.recordingSystem – your recording system bci.paradigm.id – paradigm you want to use bci.numTrials – number of trials per block and class, usually 15 bci.testRunDur – length of a feedback run, usually 300 to 360 seconds bci.param.artifactThresh – threshold to detect artifacts. if unsure, set a high value bci.param.freq – frequencies for creating spectral epochs, if empty, all possible frequencies are used bci.param.specMethod – most promising is 2 (multi tapers) bci.param.balanceTrainSet – balancing prevents biasing bci.param.bootstrapSize - number of maximum samples after bootstrap, 0 if no bootstrap bci.param.maxTrainSamp - maximum number of train data per class bci.param.retrainClassifierTrialLength - trial length(in sec) of feedback data to include for retraining the classifier after each trial; 0 for no retraining bci.refChanCAR – define the channels for calculating CAR generally bci.preProcChan, current implementation ignores channels: empty means no CAR, not empty means CAR on bci.preProcChan bci.param.doSendTrigger – set true if you use a working trigger system bci.param.doReceiveTrigger – set to false if your recording system is not configured to provide the trigger in the real time buffer bci.param.saveRawDat – set always to true in experiments, in order to reuse the data Implemented Paradigms Continuous Cursor control In the train phase, a matlab figure will open and show a cross to indicate the baseline condition and a left or right pointing arrow to indicate the respective direction condition. In the feedback phase, a circle has to be moved to a target cross. If the classifier detects right or left movement condition the cursor moves to the respective direction, if baseline was classified, the cursor stops. This paradigm can be performed in 3 class and 2 class mode. Set bci. eventsToClassify to the conditions you wish to use. If you use two conditions set bci.param.classifier to a two class classifier (e.g. ‘svm’), if you use three conditions, set the classifier parameter to ‘svmmulti’ or ‘logreg’. To activate this paradigm, set bci.paradigm.id=1. Continuous Virtual Arm control The parameter setting is identical to the continuous cursor control paradigm except bci.paradigm.id must be set to 2. Instead of a cursor, the virtual arm of the Fraunhofer VR Grasping application can be controlled. The target is an object on a table to reach. See “Fraunhofer virtual arm manual” for instructions to start the application. Actuated Virtual Arm grasp in two directions This paradigm is designated to control the grasp by three classes. Two targets are located on the virtual table. The color of the targets signalizes the action to perform. Baseline condition: both targets appear yellow, grip condition: one target changes color, indicating that the respective direction condition must be performed. A threshold bci.paradigm.fbPredRate defines the rate of classifier windows that must be classified as one class to start the feedback action. A minimum duration of bci.paradigm.fbPredictionWindow will be met but a timeout bci.paradigm.fbTrialTimeOut terminates the trial if only baseline was classified. Actuated Virtual Arm grasp in one direction Here only one target is shown in the VR application. An attention event is signalized by a yellow target, followed by a GO (green target) or STOP (red target) event. The parameter bci.eventsToClassify must be set to baseline condition and one direction condition (depending on where the target may appear), bci.param.classifier must be set to ‘svm’ (or another 2 class classifier). Trial durations are fixed (parameters bci.numTrials, bci.movDur, bci.fixDur, and the feedback parameter define the duration of a run). Further parameters for actuated grasp paradigms: bci.stimulation.targetColor – first triplet defines GO-color, second triplet defines STOP color bci.stimulation.armSystem - activates left or right arm bci.paradigm.fbPredictionWindow – length of interval used to train on feedback data bci.paradigm.stimVelocityToDestination – set non-zero to get feedback in train runs, too Utilities Signal generator In order to simulate the data transfer the signal generator can be used to send predefined signals and modulate it with the mouse cursor. Data are sent to a fieldtrip buffer, i.e. you have to run a buffer.exe application on the local or a remote machine. By default the function bciSignalGenerator(nChan,srate) sends noisy sine waves of nChans channels at a sampling rate of srate Hz. However, as a third argument you can define a parameter struct. The fields of the struct overwrite the default parameters. Thus you are able to simulate your data recorder properties and experimental setup as similar as possible. Fields of the parameter struct are: Fs – sampling rate mouseXChan – modulation channel for horizontal position of the mouse pointer (default: 1) mouseYChan – modulation channel for vertical position of the mouse pointer (default: 2) amplitudeInChans - vector of length nChans that defines amplitude per channel (default: 1 each) SNRdB – white noise strength in decibel (default: 1 (snr≈1.26)) freqsInChans: - vector of length nChans that defines a sine signal frequency per channel (default: channel ID as frequency in Hz) offsetInChans - vector of length nChans that defines an offset per channel (default: channel ID as offset) blockSize – length of a data sample block in seconds (default: 0.1) duration- length of simulation in seconds (default: 300) IP – host address where the fieldtrip buffer is running (default: 127.0.0.1) Mapping Tool Christoph Reichert, last update 07/29/2011
© Copyright 2024