%This is the first code used in a set for preprocessing. Proprocessing data helps to filter out unwanted noise and extract '.dat' files from raw files

%THIS CODE CANNOT BE USED TO RUN DATA AND IS ONLY A TUTORIAL

%{
Useful symbols and terms:

-Path: The directory on your machine that Matlab has to go through in order to run something. If a toolbox is not added to the path, Matlab can't run it.

-%: Used to comment out a line for explanation or instruction. A line following this symbol will not be read by Matlab.

-%%: Used to separate different sections of code. Helps keep things tidy.
When an error occurs, you can create breaks and sections to run one at a time to find out where the message is coming from.

;: Put this at the end of a line to end it and move on to the next.

%}
%%
cd 'C:\Users\Caroline\Desktop\LABFILES\Collier\';
addpath(genpath('C:\Users\Caroline\Desktop\LABFILES\Collier\'));
saveResults = true;

%{
cd: current working directory; Apostrphes are used for folder locations on your machine.
addpath: Add something to Matlab's path. You have to change this to your own machine's directory when adding a path.
saveResults: Put in place before running bulk of code so your processed data will save. See more on this step at the end of the code.

%}

targetDataFolder = 'C:\Users\Caroline\Desktop\LABFILES\Collier\Data';
dataFileName = dir(strcat(targetDataFolder,'\','P300-18-*S001R01.dat')); % Clean data example

typesOfEvents   = {'FF','UF','RO'};
noTypesOfEvents = length(typesOfEvents);

cutoffFrequencyHighpass = 1;
cutoffFrequencyLowpass  = 30;
timeLimits              = [-0.2 0.8];
noChannels              = 16;

% Channel information and XYZ-coordinates
channelData_62 = load('ChannelConfiguration_62.mat'); % This contains the channel lables and MNI-coordinates
channelData_16 = load('ChannelConfiguration_16.mat'); % It contains only the channel lables

%{
TargetDataFolder: Use this to tell Matlab the EXACT place of the data folder you want to use. All raw data files must be put into ONE folder to
read. This is easier than trying to load up subfolders containing the file under each subject's specific file. Included in this folder will be an image of how this should look.

dataFileName: This is used as the name of each subject's data file. Pay attention to the semantics and symbols ([] vs {}) used here.
   'P300-18-*S001R01.dat': The * indicates a subject ID included in each file name

dir: Directory

strcat: String categorization

typesOfEvents: Familiar face, unfamiliar face, and a random object

noTypesOfEvents: Number of events you just gave, so 3 in this case.

timeLimits: Negative numbers are before the image is shown, 0 is the image being shown, and positive numbers are the time in milliseconds after the image.
ERPs should happen around 0.3, so the time window must extend before and after that.

noChannels: Number of EEG channels on the g.SAHARA cap. For this experiment, 16 electrodes were used.

channelData_62: This contains the channel lables and MNI-coordinates, which can be used later for plotting more detailed models.
Don't worry about MNI coordinates for now.
   The 62 Channel Configuration is used along with the 16 Channel Configuration for the locations of the electrodes.

'ChannelConfiguration_16.mat': This file has to already be in the cd to load it in like this.

%}
%%
addpath('C:\Users\Caroline\Desktop\LABFILES\EEGLab15');
eeglab;
%Loads eeglab to make sure it was added to the path correctly in the previous step. EEGLab15 is the update used for this experiment but you may see it with other names.
close;
%Closes GUI window that will pop up with the 'No Current Dataset' message.
%% Loop over the individual subjects
%%
noSubjects = length(dataFileName);
for ctSubject = 1:noSubjects
    
    EEG = pop_loadBCI2000(strcat(targetDataFolder,'\',dataFileName(ctSubject).name),{'StimulusCode'});
%Loads a raw BCI2000 data file into EEGLab
    
    EEG = eeg_checkset(EEG); 
%Checks dataset parameter consistency

%{

noSubjects: Number of raw subject files. In this case, it's 15.
for ctSubject = 1:noSubjects: This basically means that MatLab will go through and use this location as the origin of all subjects 1-15 in order. 

%}
%%
%Highpass filtering, from -1 Hz to 0 Hz
    EEG = pop_eegfiltnew(EEG,cutoffFrequencyHighpass,0); 

%Lowpass filtering, from 0 Hz to 30 Hz
    EEG = pop_eegfiltnew(EEG,0,cutoffFrequencyLowpass);

%Noise removal via artificial subspace reconstruction: EEG = clean_rawdata(EEG,flatline,highpass,channel,noisy,burst,window)
    EEG = clean_rawdata(EEG, -1, -1, -1, -1, 5, 0.5); %A relaxed parameter setting
   %EEG = clean_rawdata(EEG, 5, -1, 0.85, 4, 5, 0.3); % Default setting
    
% Formatting of data event due to the discrepancey between BCI2000 and other sofware data structure
    for ct = 1:length(EEG.event)
        EEG.event(ct).type = num2str(EEG.event(ct).position);
    end

%{
    
EEG data is measured in waves, but not all waves are indicative of
significant data. To filter through unwanted signals that may be too high
or too low to be significant, Highpass and Lowpass filters are applied.
    
    **NOTE: ERP waves are read with spikes being more negative and valleys
    being more positive. P300 waves are more positive in nature and will
    have a large downward (positive/lowpass) dip.

Highpass Filtering: This filter allows signals to be detected between -1 and
0 Hz. Anything higher than this is not significant and will be seen as
noise.
    
Lowpass Filtering: This filter allows signals to be detected between 0 and
30 Hz. Anything above this is not significant and will be seen as noise.

Noise Removal: 'Noise' is categorized as readings in EEG waves that aren't
attributed to ERPs. Noise is considered movement, blinking, and other
responses that are not what we're looking for. This process weeds out
noise.
   

%}
%%
    for ctEvent = 1:3
        if ctEvent==1
            eventInterest = 'FF'; 
            idEvents = {'1' '2' '3' '4'};
       elseif ctEvent==2
            eventInterest = 'UF';
            idEvents = {'9' '10' '11' '12' '13' '14' '15' '16' '17' '18' '19' '20' '21' '22' '23' '24'}; 
        elseif ctEvent==3
            eventInterest = 'RO';
            idEvents = {'5' '6' '7' '8'};        
        end
%{

This section is called a loop because it involves going through each data file and separating out 3 different events.
The 'if' function identifies a condition where you're telling Matlab to do something whenever it comes across a certain event.
'elseif' is another condition under the same kind of event loop.

ctEvent: Which ever events you want to look at when running data. The 1:3 indicates that you're working with 3 variables.
   If you set up your ctEvent = A:B, this basically tells Matlet to go through it as [A, A+1, ..., B]
eventInterest: Familiar Face, Unfamiliar Face, or Random Object.
idEvents: These numbers correspond with the values in the BCI2000 software. See the notes on Austin White's tutorial for more info on getting these IDs

%}
%%
        EEG_Epoch = pop_epoch(EEG,idEvents,timeLimits);

%Convert "eventtype" from strings into numeric values
        for ct = 1:length(EEG_Epoch.epoch)
            if ischar(EEG_Epoch.epoch(ct).eventtype)
                EEG_Epoch.epoch(ct).eventtype = str2double(EEG_Epoch.epoch(ct).eventtype);
            end
            if ischar(EEG_Epoch.event(ct).type)
                EEG_Epoch.event(ct).type = str2double(EEG_Epoch.event(ct).type);
            end
        end

%{

Epoch: An epoch is a time period that contains a specific event you want to measure. The events are locked to their own time of occurance in response to a visual stimulus.

EEG_Epoch: This is used for time epoching for each event in EEGLab. Remember that our time limits are between -0.2 and 0.8 ms, so we're telling
Matlab to look for these specific events (FF, UF, RO) in the EEGs within the time frame of -0.2 to 0.8 ms.
        
%}
        
        % Incorporate the XYZ-coordinates of channels into EEG_Epoch structure
        for ct = 1:noChannels
            idChannel = find(strcmp({channelData_62.channelData(:).labels},channelData_16.channelData(ct).labels)==1);    
            EEG_Epoch.chanlocs(ct).X = channelData_62.channelData(idChannel).X;
            EEG_Epoch.chanlocs(ct).Y = channelData_62.channelData(idChannel).Y;
            EEG_Epoch.chanlocs(ct).Z = channelData_62.channelData(idChannel).Z;
            EEG_Epoch.chanlocs(ct).labels = channelData_62.channelData(idChannel).labels;
        end

        % Convert an EEGLab data structure into a FieldTrip data structure
        dataFT = eeglab2ft(EEG_Epoch);

        if saveResults
            ftDataFileName = strcat(targetDataFolder,'\',dataFileName(ctSubject).name(1:end-4),'-',eventInterest);
            save(ftDataFileName,'dataFT');
%{
1:noChannels: Using all channels

strcmp: When set to 1, this shows that you're telling Matlab that 2 things are identical.
   Channel 62 data labels and Channel 16 data labels here are the same so they're set equal to 1

EEG_Epoch.chanlocs: EEG channel locations. 

saveResults: One of the most important lines in the code. This allows you to tell Matlab where to save all the data you just preprocessed.
By saving it in the original target data folder, you'll have the raw file along with the 3 event files together in one place.
Once you see the name of the saved file, you'll start to understand all the specifics in the 'ftDataFileName' line.            

%}
        end
    end
end
%%
%{
Some last few notes:
-Remember to always end your 'for' statements with 'end', both with the same spacing.
-Have a folder dedicated to one project at a time with codes and data in their own respective folders.
-If you have problems with an error message or don't know what something is, you can type "help '(command or object here)'" to get an answer.
 If nothing pops up, look for it on Google or on the official FieldTrip/Matlab website.
-Some codes take a long time to work through themsleves. If you aren't sure if a run is complete, look in the bottom left window corner for the 'Busy' message. 
-Make sure your workspace looks correct. If you're supposed to have 16 channels, and your noChannels shows up as being something other than 1x16, something isn't right.
-To check if something like EEGlab is in the path, just type 'EEGlab' in the command window and it should run. This works with other values like 'subjectID' or 'ftDataFileName'