├── +eegtoolkit ├── +aggregation │ ├── @AggregatorBase │ │ └── AggregatorBase.m │ ├── @ChannelAveraging │ │ └── ChannelAveraging.m │ ├── @ChannelConcat │ │ └── ChannelConcat.m │ ├── @ChannelRatio │ │ └── ChannelRatio.m │ ├── @Fisher │ │ └── Fisher.m │ ├── @LateFusion │ │ └── LateFusion.m │ └── @VLAD │ │ └── VLAD.m ├── +classification │ ├── @Adaboost │ │ └── Adaboost.m │ ├── @CSPFilterBankWrapper │ │ └── CSPFilterBankWrapper.m │ ├── @CSPWrapper │ │ └── CSPWrapper.m │ ├── @ClassifierBase │ │ └── ClassifierBase.m │ ├── @CombiCCA │ │ └── CombiCCA.m │ ├── @FusionClassifierWrapper │ │ └── FusionClassifierWrapper.m │ ├── @ITCCA │ │ └── ITCCA.m │ ├── @L1MCCA │ │ └── L1MCCA.m │ ├── @LDA │ │ └── LDA.m │ ├── @LIBSVM │ │ └── LIBSVM.m │ ├── @LIBSVMFast │ │ └── LIBSVMFast.m │ ├── @MLDA │ │ └── MLDA.m │ ├── @MLR │ │ └── MLR.m │ ├── @MLTREE │ │ └── MLTREE.m │ ├── @MLTboxMulticlass │ │ └── MLTboxMulticlass.m │ ├── @MaxChooser │ │ └── MaxChooser.m │ ├── @SBLR │ │ └── SBLR.m │ └── @SMFA │ │ └── SMFA.m ├── +experiment │ ├── @Experimenter │ │ └── Experimenter.m │ └── @ResultEvaluator │ │ └── ResultEvaluator.m ├── +featextraction │ ├── @CCA │ │ └── CCA.m │ ├── @DWT │ │ └── DWT.m │ ├── @ERRPFeatures │ │ └── ERRPFeatures.m │ ├── @FFT │ │ └── FFT.m │ ├── @FeatureExtractionBase │ │ └── FeatureExtractionBase.m │ ├── @Goertzel │ │ └── Goertzel.m │ ├── @L1MCCA │ │ └── L1MCCA.m │ ├── @MLR_Transf │ │ └── MLR_Transf.m │ ├── @PSDExtractionBase │ │ └── PSDExtractionBase.m │ ├── @PWelch │ │ └── PWelch.m │ ├── @PWelchExperimental │ │ └── PWelchExperimental.m │ ├── @PYAR │ │ └── PYAR.m │ ├── @RawSignal │ │ └── RawSignal.m │ └── @STFT │ │ └── STFT.m ├── +featselection │ ├── @FEAST │ │ └── FEAST.m │ ├── @FeatureSelectionBase │ │ └── FeatureSelectionBase.m │ ├── @PCA │ │ └── PCA.m │ └── @SVD │ │ └── SVD.m ├── +preprocessing │ ├── @Amuse │ │ └── Amuse.m │ ├── @DigitalFilter │ │ └── DigitalFilter.m │ ├── @FastICA │ │ └── FastICA.m │ ├── @PreprocessingBase │ │ └── PreprocessingBase.m │ ├── @Rereferencing │ │ └── Rereferencing.m │ ├── @SampleSelection │ │ └── SampleSelection.m │ └── @Windsorize │ │ └── Windsorize.m ├── +services │ └── @StressDetection │ │ └── StressDetection.m └── +util │ ├── @FusionInstanceSet │ └── FusionInstanceSet.m │ ├── @InstanceSet │ └── InstanceSet.m │ ├── @L1MCCAInstanceSet │ └── L1MCCAInstanceSet.m │ ├── @LSLWrapper │ └── LSLWrapper.m │ ├── @RawSignalSet │ └── RawSignalSet.m │ ├── @ResultSet │ └── ResultSet.m │ ├── @Session │ └── Session.m │ ├── @Trial │ └── Trial.m │ └── load_xdf.m ├── LICENSE ├── README.md ├── exampleCSP.m ├── exampleCombiCCA.m ├── exampleDefault.m ├── exampleEPOCCCASVM.m ├── exampleERRP.m ├── exampleERRPSSVEPDemo.m ├── exampleEarlyFusion.m ├── exampleEpoc.m ├── exampleITCCA.m ├── exampleL1MCCA.m ├── exampleLSL.m ├── exampleLateFusion.m ├── exampleMotorPWelch.m ├── exampleOptimal.m ├── exampleSMFA.m └── filters ├── epocfilter.mat └── filt_IIRElliptic.mat /+eegtoolkit/+aggregation/@AggregatorBase/AggregatorBase.m: -------------------------------------------------------------------------------- 1 | classdef (Abstract) AggregatorBase < handle 2 | 3 | properties 4 | featextractors; 5 | instanceSet; 6 | end 7 | 8 | methods (Abstract = true) 9 | obj = aggregate(obj); 10 | configInfo = getConfigInfo(obj); 11 | time = getTime(obj); 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@ChannelAveraging/ChannelAveraging.m: -------------------------------------------------------------------------------- 1 | classdef ChannelAveraging < eegtoolkit.aggregation.AggregatorBase; 2 | 3 | properties 4 | end 5 | 6 | methods 7 | 8 | function CA = ChannelAveraging(CA) 9 | end 10 | 11 | function CA = aggregate(CA) 12 | numExtr = length(CA.featextractors); 13 | numInstances = CA.featextractors{1}.getInstanceSet.getNumInstances; 14 | numFeatures = CA.featextractors{1}.getInstanceSet.getNumFeatures; 15 | fused = zeros(numInstances,numFeatures,numExtr); 16 | for i=1:numExtr 17 | fused(:,:,i) = CA.featextractors{i}.getInstances; 18 | end 19 | fusedMean = mean(fused,3); 20 | CA.instanceSet = eegtoolkit.util.InstanceSet(fusedMean,CA.featextractors{1}.getLabels); 21 | end 22 | 23 | function configInfo = getConfigInfo(CA) 24 | configInfo = 'ChannelAveraging'; 25 | end 26 | 27 | function time = getTime(CA) 28 | time = 0; 29 | end 30 | end 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@ChannelConcat/ChannelConcat.m: -------------------------------------------------------------------------------- 1 | classdef ChannelConcat < eegtoolkit.aggregation.AggregatorBase; 2 | 3 | properties 4 | end 5 | 6 | methods 7 | 8 | function CC = ChannelConcat(CC) 9 | end 10 | 11 | function CC = aggregate(CC) 12 | numExtract = length(CC.featextractors); 13 | fused = []; 14 | for i=1:numExtract 15 | fused = horzcat(fused,CC.featextractors{i}.getInstances); 16 | end 17 | % [~,y] = size(fused); 18 | % ind = randperm(y); 19 | % fused = fused(:,ind); 20 | CC.instanceSet = eegtoolkit.util.InstanceSet(fused,CC.featextractors{1}.getLabels); 21 | end 22 | 23 | function configInfo = getConfigInfo(CC) 24 | configInfo = 'ChannelConcat'; 25 | end 26 | 27 | 28 | function time = getTime(CC) 29 | time = 0; 30 | end 31 | end 32 | 33 | end 34 | 35 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@ChannelRatio/ChannelRatio.m: -------------------------------------------------------------------------------- 1 | classdef ChannelRatio < eegtoolkit.aggregation.AggregatorBase; 2 | 3 | properties 4 | end 5 | 6 | methods 7 | 8 | function CR = ChannelRatio(CR) 9 | end 10 | 11 | function CR = aggregate(CR) 12 | numExtract = length(CR.featextractors); 13 | if numExtract ~=2 14 | error ('ChannelRatio: Number of transformers should be 2'); 15 | end 16 | in1 = CR.featextractors{1}.getInstances; 17 | in2 = CR.featextractors{2}.getInstances; 18 | ratio = in1./in2; 19 | CR.instanceSet = eegtoolkit.util.InstanceSet(ratio,CR.featextractors{1}.getLabels); 20 | end 21 | 22 | function configInfo = getConfigInfo(CR) 23 | configInfo = 'ChannelRatio'; 24 | end 25 | 26 | 27 | function time = getTime(CR) 28 | time = 0; 29 | end 30 | end 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@Fisher/Fisher.m: -------------------------------------------------------------------------------- 1 | classdef Fisher < eegtoolkit.aggregation.AggregatorBase 2 | properties 3 | codebookInfo; 4 | numClusters; 5 | means; 6 | covariances; 7 | priors; 8 | pcanum; 9 | end 10 | 11 | methods 12 | function FA = Fisher(codebookfilename,pcanum) 13 | load(codebookfilename); 14 | FA.means = means; 15 | FA.covariances = covariances; 16 | FA.priors = priors; 17 | FA.numClusters = length(priors); 18 | FA.codebookInfo = codebookInfo; 19 | FA.pcanum = pcanum; 20 | end 21 | 22 | function FA = aggregate(FA) 23 | numExtract = length(FA.featextractors); 24 | numFeatures = FA.featextractors{1}.instanceSet.getNumFeatures; 25 | numTrials = length(FA.featextractors{1}.trials); 26 | instances = zeros(numTrials,numExtract,numFeatures); 27 | pcainstances = zeros(numTrials,numExtract,FA.pcanum); 28 | if FA.pcanum > 0 29 | fishers = zeros(numTrials, FA.numClusters * FA.pcanum *2); 30 | else 31 | fishers = zeros(numTrials,FA.numClusters*numFeatures*2); 32 | end 33 | for i=1:numExtract 34 | instances(:,i,:) = FA.featextractors{i}.getInstances; 35 | if FA.pcanum > 0 36 | [~,pcainstances(:,i,:),~,~,~] = pca(squeeze(instances(:,i,:)),'NumComponents',FA.pcanum); 37 | end 38 | end 39 | for i=1:numTrials 40 | if FA.pcanum > 0 41 | dataToBeEncoded = squeeze(pcainstances(i,:,:)); 42 | else 43 | dataToBeEncoded = squeeze(instances(i,:,:)); 44 | end 45 | fishers(i,:) = vl_fisher(dataToBeEncoded', FA.means, FA.covariances, FA.priors); 46 | end 47 | FA.instanceSet = eegtoolkit.util.InstanceSet(fishers,FA.featextractors{1}.getLabels); 48 | end 49 | 50 | function configInfo = getConfigInfo(FA) 51 | configInfo = sprintf('Fisher:\tcodebook:%s',FA.codebookInfo); 52 | end 53 | 54 | function time = getTime(FA) 55 | time = 0; 56 | end 57 | end 58 | 59 | methods (Static) 60 | function [] = trainCodebook(session, channels, numCenters, codebookfilename,pcanum) 61 | nfft = 512; 62 | extractors = {}; 63 | numChannels = length(channels); 64 | numTrials = length(session.trials); 65 | numFeatures = nfft/2+1; 66 | instances = zeros(numTrials,numChannels,numFeatures); 67 | h = waitbar(0,'message'); 68 | for i=1:length(channels) 69 | waitbar(i/(length(channels)+10),h,sprintf('Computing channel:%d',channels(i))); 70 | extractors{i} = eegtoolkit.featextraction.PWelch; 71 | extractors{i}.trials = session.trials; 72 | extractors{i}.channel = channels(i); 73 | extractors{i}.nfft = nfft; 74 | extractors{i}.seconds = 5; 75 | extractors{i}.extract; 76 | instances(:,i,:) = extractors{i}.getInstances; 77 | end 78 | instances = reshape(instances,numTrials*numChannels,numFeatures); 79 | waitbar(i/(length(channels)+10),h,'Computing gmm..'); 80 | if(pcanum > 0) 81 | [~,instances,~,~,~] = pca(instances,'NumComponents',pcanum); 82 | end 83 | [means, covariances, priors] = vl_gmm(instances', numCenters); 84 | waitbar(i+5/(length(channels)+10),h,'Saving variables..'); 85 | codebookInfo = sprintf('filename:%s\tnumClusters:%d\tnumPCA:%d\tchannels:',codebookfilename, numCenters, pcanum); 86 | for i=1:length(channels) 87 | codebookInfo = sprintf('%s%d ',codebookInfo,channels(i)); 88 | end 89 | save(codebookfilename,'means','covariances','priors','codebookInfo'); 90 | close(h); 91 | end 92 | 93 | 94 | end 95 | 96 | end 97 | 98 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@LateFusion/LateFusion.m: -------------------------------------------------------------------------------- 1 | classdef LateFusion < eegtoolkit.aggregation.AggregatorBase; 2 | 3 | properties 4 | end 5 | 6 | methods 7 | 8 | function LFA = LateFusion(LFA) 9 | end 10 | 11 | function LFA = aggregate(LFA) 12 | numTransf = length(LFA.featextractors); 13 | LFA.instanceSet = eegtoolkit.util.FusionInstanceSet(LFA.featextractors{1}.instanceSet); 14 | 15 | for i=1:numTransf 16 | LFA.instanceSet = LFA.instanceSet.addInstanceSet(LFA.featextractors{i}.instanceSet); 17 | end 18 | end 19 | 20 | function configInfo = getConfigInfo(LFA) 21 | configInfo = 'LateFusion'; 22 | end 23 | 24 | 25 | function time = getTime(LFA) 26 | time = 0; 27 | end 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /+eegtoolkit/+aggregation/@VLAD/VLAD.m: -------------------------------------------------------------------------------- 1 | classdef VLAD < eegtoolkit.aggregation.AggregatorBase; 2 | 3 | properties 4 | kdtree; 5 | centers; 6 | codebookInfo; 7 | numClusters; 8 | end 9 | 10 | methods 11 | 12 | function VA = VLAD(codebookfilename) 13 | load(codebookfilename); 14 | VA.kdtree = kdtree; 15 | VA.centers = centers; 16 | VA.codebookInfo = codebookInfo; 17 | [~,VA.numClusters] = size(centers); 18 | end 19 | 20 | function VA = aggregate(VA) 21 | numExtract = length(VA.transformers); 22 | numFeatures = VA.featextractors{1}.instanceSet.getNumFeatures; 23 | numTrials = length(VA.featextractors{1}.trials); 24 | instances = zeros(numTrials,numExtract,numFeatures); 25 | vlads = zeros(numTrials,VA.kdtree.numData*numFeatures); 26 | for i=1:numExtract 27 | instances(:,i,:) = VA.featextractors{i}.getInstances; 28 | end 29 | for i=1:numTrials 30 | dataToBeEncoded = squeeze(instances(i,:,:)); 31 | nn = vl_kdtreequery(VA.kdtree, VA.centers, dataToBeEncoded'); 32 | assignments = zeros(VA.numClusters, numExtract); 33 | assignments(sub2ind(size(assignments), nn, 1:length(nn))) = 1; 34 | vlads(i,:) = vl_vlad(dataToBeEncoded',VA.centers,assignments); 35 | end 36 | VA.instanceSet = eegtoolkit.util.InstanceSet(vlads,VA.featextractors{1}.getLabels); 37 | end 38 | 39 | function configInfo = getConfigInfo(VA) 40 | configInfo = sprintf('VLAD:\tcodebook:%s',VA.codebookInfo); 41 | end 42 | 43 | 44 | function time = getTime(VA) 45 | time = 0; 46 | end 47 | end 48 | 49 | methods (Static) 50 | function [] = trainCodebook(session, channels, numCenters, codebookfilename) 51 | nfft = 512; 52 | extractors = {}; 53 | numChannels = length(channels); 54 | numTrials = length(session.trials); 55 | numFeatures = nfft/2+1; 56 | instances = zeros(numTrials,numChannels,numFeatures); 57 | h = waitbar(0,'message'); 58 | for i=1:length(channels) 59 | waitbar(i/(length(channels)+10),h,sprintf('Computing channel:%d',channels(i))); 60 | extractors{i} = eegtoolkit.transformer.PWelchTransformer; 61 | extractors{i}.trials = session.trials; 62 | extractors{i}.channel = channels(i); 63 | extractors{i}.nfft = nfft; 64 | extractors{i}.seconds = 5; 65 | extractors{i}.transform; 66 | instances(:,i,:) = extractors{i}.getInstances; 67 | end 68 | instances = reshape(instances,numTrials*numChannels,numFeatures); 69 | waitbar(i/(length(channels)+10),h,'Clustering..'); 70 | centers = vl_kmeans(instances',numCenters); 71 | waitbar(i+4/(length(channels)+10),h,'Building kdtree..'); 72 | kdtree = vl_kdtreebuild(centers); 73 | waitbar(i+5/(length(channels)+10),h,'Saving variables..'); 74 | codebookInfo = sprintf('filename:%s\tnumClusters:%d\tchannels:',codebookfilename, numCenters); 75 | for i=1:length(channels) 76 | codebookInfo = sprintf('%s%d ',codebookInfo,channels(i)); 77 | end 78 | save(codebookfilename,'centers','kdtree','codebookInfo'); 79 | close(h); 80 | end 81 | end 82 | end 83 | 84 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@Adaboost/Adaboost.m: -------------------------------------------------------------------------------- 1 | classdef Adaboost < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | Method % AdaboostM2 (default), TotalBoost, LPBoost, Subspace, etc 9 | NLearn % Number of learners (default 100) 10 | Learners % Tree (default), KNN (only for Subspace), Discriminant(recommended for subspace), Custom 11 | models; 12 | totalTime; 13 | totalCount; 14 | end 15 | 16 | methods (Access = public) 17 | function BOOST = Adaboost(instanceSet, Method, NLearn, Learners) 18 | %set default parameters 19 | BOOST.Method = 'AdaBoostM2'; 20 | BOOST.NLearn=100; 21 | BOOST.Learners = 'Tree'; 22 | if nargin > 0 23 | BOOST.instanceSet = instanceSet; 24 | end 25 | if nargin > 1 26 | BOOST.Method = Method; 27 | end 28 | if nargin > 2 29 | BOOST.NLearn=NLearn; 30 | end 31 | if nargin > 3 32 | BOOST.Learners = Learners; 33 | end 34 | BOOST.totalTime = 0; 35 | BOOST.totalCount = 0; 36 | end 37 | 38 | function BOOST = build(BOOST) 39 | %clear all from previous calls to "build" 40 | BOOST.reset; 41 | numLabels = BOOST.instanceSet.getNumLabels; 42 | uniqueLabels = unique(BOOST.instanceSet.getLabels); 43 | 44 | % ---- Multi-Class ----- % 45 | instances=BOOST.instanceSet.instances; 46 | labels=BOOST.instanceSet.labels; 47 | 48 | BOOST.models{1} = fitensemble(instances,labels,BOOST.Method, BOOST.NLearn, BOOST.Learners,... 49 | 'Type','Classification'); 50 | 51 | % for i=1:numLabels 52 | % currentLabel = uniqueLabels(i); 53 | % labels = zeros(BOOST.instanceSet.getNumInstances,1)-1; 54 | % labels(BOOST.instanceSet.getInstanceIndicesForLabel(currentLabel)) = 1; 55 | % instances = sparse(BOOST.instanceSet.getInstances); 56 | % N = length(labels); % X training labels 57 | % W = 1/N * ones(N,1); %Weights initialization 58 | % M = 10; % Number of boosting iterations 59 | % for m=1:M 60 | % C = 1; %The cost parameters of the linear SVM, you can... 61 | % % perform a grid search for the optimal value as well 62 | % 63 | % %Calculate the error and alpha in adaBoost with cross validation 64 | % cmd = ['-c ', num2str(C), ' -b 1']; 65 | % model = svmtrain(W,labels, instances, cmd); 66 | % [Xout, acc, ~] = svmpredict(labels, instances,model); 67 | % 68 | % err = sum(.5 * W .* acc * N)/sum(W); 69 | % alpha = log( (1-err)/err ); 70 | % 71 | % % update the weight 72 | % W = W.*exp( - alpha.*Xout.*X ); 73 | % W = W/norm(W); 74 | % end 75 | % BOOST.models{i} = model; 76 | % 77 | % end 78 | 79 | end 80 | 81 | function [output, probabilities, ranking] = classifyInstance(BOOST,instance) 82 | %input = instance matrix rows = instances, cols = attributes 83 | %output = predicted class 84 | %probabilities = probability for predicted class 85 | %ranking = propabilities for all classes (e.g. to use with mAP) 86 | 87 | 88 | %TODO:should print an error if 'build' has not been called 89 | numModels = length(BOOST.models); 90 | [numinstance, ~] = size(instance); 91 | scores = zeros(numModels,numinstance); 92 | 93 | % ---- Multi-class ----- % 94 | tic 95 | [label,scores] = predict(BOOST.models{1},instance); 96 | BOOST.totalTime = BOOST.totalTime + toc; 97 | BOOST.totalCount = BOOST.totalCount + numinstance; 98 | 99 | output = zeros(numinstance,1); 100 | probabilities = zeros(numinstance,1); 101 | %we need these for ranking metrics (e.g. mAP) 102 | ranking = scores; 103 | for i=1:numinstance 104 | %select the class with the highest probability 105 | [prob, idx] = max(scores(i,:)); 106 | uniqueLabels = unique(BOOST.instanceSet.getLabels); 107 | %output the label with highest probability 108 | output(i,1) = uniqueLabels(idx); 109 | %return the probability for the output label 110 | probabilities(i,1) = prob; 111 | end 112 | end 113 | 114 | function BOOST = reset(BOOST) 115 | %delete all stored models 116 | BOOST.models = {}; 117 | end 118 | 119 | function configInfo = getConfigInfo(BOOST) 120 | configInfo = sprintf('Adaboost: Method: %s NLearn: %d Learners: %s',... 121 | BOOST.Method, BOOST.NLearn, BOOST.Learners); 122 | end 123 | 124 | 125 | function time = getTime(BOOST) 126 | time = BOOST.totalTime / BOOST.totalCount; 127 | end 128 | 129 | end 130 | end 131 | 132 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@CSPFilterBankWrapper/CSPFilterBankWrapper.m: -------------------------------------------------------------------------------- 1 | classdef CSPFilterBankWrapper < eegtoolkit.classification.ClassifierBase; 2 | properties (Constant) 3 | 4 | end 5 | properties 6 | baseClassifier; 7 | channel; 8 | cspFilters; 9 | filterBanks; 10 | samplingRate; 11 | end 12 | 13 | methods (Access = public) 14 | function CSPFB = CSPFilterBankWrapper(filterBanks, samplingRate) 15 | CSPFB.cspFilters = {}; 16 | CSPFB.filterBanks = filterBanks; 17 | CSPFB.samplingRate = samplingRate; 18 | %filter_banks=[8 12; 12 16; 16 20;20 24;24 28]; 19 | % if(isa(instanceSet,'eegtoolkit.util.RawSignalSet') 20 | % CSP.instanceSet = instanceSet; 21 | % else 22 | % error('RawSignal extractor should be used with CSPWrapper'); 23 | % end 24 | end 25 | 26 | 27 | function CSPFB = build(CSPFB) 28 | % Builds the classification models 29 | CSPFB.learnCSPMatrix(CSPFB.instanceSet.sMatrix,CSPFB.instanceSet.labels); 30 | instanceLocal = CSPFB.extract(CSPFB.instanceSet.sMatrix); 31 | CSPFB.baseClassifier.instanceSet = eegtoolkit.util.InstanceSet(instanceLocal,CSPFB.instanceSet.labels); 32 | CSPFB.baseClassifier.build; 33 | CSPFB.reset; 34 | end 35 | 36 | function [output, probabilities, ranking] = classifyInstance(CSPFB,instance) 37 | 38 | % instance = CSP.extract 39 | %input = instance matrix rows = instances, cols = attributes 40 | %output = predicted class 41 | %probabilities = probability for predicted class 42 | %ranking = propabilities for all classes (e.g. to use with mAP) 43 | 44 | %TODO:should print an error if 'build' has not been called 45 | testInstances = CSPFB.extract(instance); 46 | [output, probabilities, ranking] = CSPFB.baseClassifier.classifyInstance(testInstances); 47 | % numModels = length(LSVM.models); 48 | % [numinstance, ~] = size(testInstances); 49 | % scores = zeros(numModels,numinstance); 50 | % for i=1:numModels 51 | % %predict using the stored models 52 | % [~, ~, t] = svmpredict(eye(numinstance,1),testInstances, LSVM.models{i},'-b 1 -q'); 53 | % %store probability for each class 54 | % scores(i,:) = t(:,1); 55 | % end 56 | % output = zeros(numinstance,1); 57 | % probabilities = zeros(numinstance,1); 58 | % ranking = scores; 59 | % for i=1:numinstance 60 | % %select the class with the highest probability 61 | % [prob, idx] = max(scores(:,i)); 62 | % uniqueLabels = unique(LSVM.instanceSet.getLabels); 63 | % %output the label with highest probability 64 | % output(i,1) = uniqueLabels(idx); 65 | % %return the probability for the output label 66 | % probabilities(i,1) = prob; 67 | % end 68 | end 69 | 70 | function CSPFB = reset(CSPFB) 71 | % 'Resets' the classifier. 72 | % CSP.models = {}; 73 | end 74 | 75 | function configInfo = getConfigInfo(CSPFB) 76 | configInfo = '\n'; 77 | end 78 | 79 | 80 | function time = getTime(CSPFB) 81 | time = 0; 82 | end 83 | end 84 | methods (Access = private) 85 | function [] = learnCSPMatrix(CSPFB, sMatrix, labels) 86 | %[trialsMat,labels] = ssveptoolkit.util.Trial.trialsCellToMat(in); 87 | [numTrials,numChannels,numSamples] = size(sMatrix); 88 | % numTrials = length(CSPFB.trials); 89 | % [numChannels,numSamples] = size(CSPFB.trials{1}.signal); 90 | % samplingRate = CSPFB.trials{1}.samplingRate; 91 | filter_banks= CSPFB.filterBanks; 92 | [nfb, mfb] = size(filter_banks); 93 | 94 | for iter_fb=1:nfb 95 | 96 | [b,a]=butter(3,filter_banks(iter_fb)/(CSPFB.samplingRate/2)); 97 | % labels = zeros(numTrials,1); 98 | %numTrials X numChannels X numSamples 99 | trialsMat = permute(sMatrix,[2,3,1]); 100 | % trialsMat = zeros(numChannels,numSamples,numTrials); 101 | % for i = 1 : length(CSP_Feat.trials) 102 | % for i_ch = 1:numChannels 103 | % trialsMat(i_ch,:,i) = filtfilt(b,a,CSP_Feat.trials{i}.signal(i_ch,:)); 104 | % end 105 | % labels(i) = CSP_Feat.trials{i}.label; 106 | % end 107 | 108 | trialsMat = permute(trialsMat,[2 1 3]); 109 | [N1, Nch1, Ntr1] = size(trialsMat); 110 | for i = 1:Nch1 111 | for j = 1:Ntr1 112 | trialsMat(:,i,j) = (trialsMat(:,i,j) - mean(trialsMat(:,i,j))); 113 | end 114 | end 115 | x_train = trialsMat;%(:,:,CSP_Feat.trainIdx); 116 | y_train = labels;%(CSP_Feat.trainIdx); 117 | [N, Nch, Ntr] = size(x_train); 118 | trialCov=zeros(Nch,Nch,Ntr); 119 | for t=1:length(y_train) 120 | E = x_train(:,:,t)'; 121 | EE = E * E'; 122 | trialCov(:,:,t) = EE ./ trace(EE); 123 | end 124 | for c=1:2 125 | covMat{c} = mean(trialCov(:,:,y_train == c),3); 126 | end 127 | [U, D] = eig(covMat{1},covMat{2},'qz'); 128 | eigenvalues = diag(D); 129 | [~, ind] = sort(eigenvalues, 'descend'); 130 | U = U(:,ind); 131 | CSPFB.cspFilters{iter_fb} = U'; 132 | % CSP_Filter = U'; 133 | end 134 | %trialsMat2=zeros(N,3,Ntr); 135 | 136 | end 137 | 138 | function instances = extract(CSPFB,sMatrix) 139 | trialsMat = permute(sMatrix,[2,3,1]); 140 | trialsMat = permute(trialsMat,[2,1,3]); 141 | [numTrials,numChannels,~] = size(sMatrix); 142 | final_instances = zeros(numTrials, numChannels*length(CSPFB.filterBanks)); 143 | for iter_fb=1:length(CSPFB.cspFilters) 144 | for j = 1:size(trialsMat,3) 145 | trialsMat(:,:,j) = (CSPFB.cspFilters{iter_fb}*trialsMat(:,:,j)')'; 146 | end 147 | 148 | instances = zeros(numTrials, numChannels); 149 | %labels = zeros(numTrials,1); 150 | 151 | for i=1:numTrials 152 | 153 | projectedTrial = trialsMat(:,:,i);%Filter * CSP_Feat.trials{i}.signal(:,i);% EEGSignals.x(:,:,t)'; 154 | %generating the features as the log variance of the projected signals 155 | variances = var(projectedTrial,0,1); 156 | instances(i,:) = log(variances)'; 157 | %labels(i,1) = floor(CSP_Feat.trials{i}.label); 158 | end 159 | final_instances(:,numChannels*(iter_fb-1)+1:numChannels*iter_fb) = instances; 160 | % CSP_Feat.avgTime = toc/numTrials; 161 | % CSP_Feat.instanceSet = ssveptoolkit.util.InstanceSet(final_instances,labels); 162 | end 163 | instances = final_instances; 164 | end 165 | 166 | 167 | 168 | end 169 | % [numTrials,numChannels,~] = size(sMatrix); 170 | % sMatrix = permute(sMatrix,[3,2,1]); 171 | % for i=1:size(sMatrix,3); 172 | % sMatrix(:,:,i) = (CSPFB.cspFilter*sMatrix(:,:,i)')'; 173 | % end 174 | % instances = zeros(numTrials,numChannels); 175 | % for i=1:numTrials 176 | % projectedTrial = sMatrix(:,:,i); 177 | % variances = var(projectedTrial,0,1); 178 | % instances(i,:) = log(variances)'; 179 | % end 180 | % % instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 181 | % end 182 | %end 183 | end 184 | 185 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@CSPWrapper/CSPWrapper.m: -------------------------------------------------------------------------------- 1 | classdef CSPWrapper < eegtoolkit.classification.ClassifierBase; 2 | properties (Constant) 3 | 4 | end 5 | properties 6 | baseClassifier; 7 | channel; 8 | cspFilter; 9 | end 10 | 11 | methods (Access = public) 12 | function CSP = CSPWrapper(instanceSet) 13 | % if(isa(instanceSet,'eegtoolkit.util.RawSignalSet') 14 | % CSP.instanceSet = instanceSet; 15 | % else 16 | % error('RawSignal extractor should be used with CSPWrapper'); 17 | % end 18 | end 19 | 20 | 21 | function CSP = build(CSP) 22 | % Builds the classification models 23 | CSP.learnCSPMatrix(CSP.instanceSet.sMatrix,CSP.instanceSet.labels); 24 | instanceLocal = CSP.extract(CSP.instanceSet.sMatrix); 25 | CSP.baseClassifier.instanceSet = eegtoolkit.util.InstanceSet(instanceLocal,CSP.instanceSet.labels); 26 | CSP.baseClassifier.build; 27 | CSP.reset; 28 | end 29 | 30 | function [output, probabilities, ranking] = classifyInstance(CSP,instance) 31 | 32 | % instance = CSP.extract 33 | %input = instance matrix rows = instances, cols = attributes 34 | %output = predicted class 35 | %probabilities = probability for predicted class 36 | %ranking = propabilities for all classes (e.g. to use with mAP) 37 | 38 | %TODO:should print an error if 'build' has not been called 39 | testInstances = CSP.extract(instance); 40 | [output, probabilities, ranking] = CSP.baseClassifier.classifyInstance(testInstances); 41 | % numModels = length(LSVM.models); 42 | % [numinstance, ~] = size(testInstances); 43 | % scores = zeros(numModels,numinstance); 44 | % for i=1:numModels 45 | % %predict using the stored models 46 | % [~, ~, t] = svmpredict(eye(numinstance,1),testInstances, LSVM.models{i},'-b 1 -q'); 47 | % %store probability for each class 48 | % scores(i,:) = t(:,1); 49 | % end 50 | % output = zeros(numinstance,1); 51 | % probabilities = zeros(numinstance,1); 52 | % ranking = scores; 53 | % for i=1:numinstance 54 | % %select the class with the highest probability 55 | % [prob, idx] = max(scores(:,i)); 56 | % uniqueLabels = unique(LSVM.instanceSet.getLabels); 57 | % %output the label with highest probability 58 | % output(i,1) = uniqueLabels(idx); 59 | % %return the probability for the output label 60 | % probabilities(i,1) = prob; 61 | % end 62 | end 63 | 64 | function CSP = reset(CSP) 65 | % 'Resets' the classifier. 66 | % CSP.models = {}; 67 | end 68 | 69 | function configInfo = getConfigInfo(CSP) 70 | configInfo = '\n'; 71 | end 72 | 73 | 74 | function time = getTime(CSP) 75 | time = 0; 76 | end 77 | end 78 | methods (Access = private) 79 | function [] = learnCSPMatrix(CSP, sMatrix, labels) 80 | [numTrials,numChannels,~] = size(sMatrix); 81 | % labels = CSP.instanceSet.getLabels; 82 | % sMatrix = permute(sMatrix,[2,3,1]); 83 | % sMatrix = permute(sMatrix,[2 1 3]); 84 | sMatrix = permute(sMatrix,[3,2,1]); 85 | for i=1:numChannels 86 | for j=1:numTrials 87 | sMatrix(:,i,j) = (sMatrix(:,i,j) - mean(sMatrix(:,i,j))); 88 | end 89 | end 90 | trialCov = zeros(numChannels,numChannels,numTrials); 91 | for t=1:length(labels) 92 | E = sMatrix(:,:,t)'; 93 | EE = E * E'; 94 | trialCov(:,:,t) = EE ./trace(EE); 95 | end 96 | %TODO: works only for 2 labels, [1,2] 97 | for c=1:2 98 | covMat{c} = mean(trialCov(:,:,labels == c),3); 99 | end 100 | [U, D] = eig(covMat{1},covMat{2},'qz'); 101 | eigenvalues = diag(D); 102 | [~,ind] = sort(eigenvalues,'descend'); 103 | U = U(:,ind); 104 | CSP.cspFilter = U'; 105 | % for i=1:size(sMatrix,3); 106 | % sMatrix(:,:,i) = (cspFilter*sMatrix(:,:,i)')'; 107 | % end 108 | % instances = zeros(numTrials,numChannels); 109 | % for i=1:numTrials 110 | % projectedTrial = sMatrix(:,:,i); 111 | % variances = var(projectedTrial,0,1); 112 | % instances(i,:) = log(variances)'; 113 | % end 114 | % instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 115 | end 116 | 117 | function instances = extract(CSP,sMatrix) 118 | 119 | [numTrials,numChannels,~] = size(sMatrix); 120 | sMatrix = permute(sMatrix,[3,2,1]); 121 | for i=1:size(sMatrix,3); 122 | sMatrix(:,:,i) = (CSP.cspFilter*sMatrix(:,:,i)')'; 123 | end 124 | instances = zeros(numTrials,numChannels); 125 | for i=1:numTrials 126 | projectedTrial = sMatrix(:,:,i); 127 | variances = var(projectedTrial,0,1); 128 | instances(i,:) = log(variances)'; 129 | end 130 | % instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 131 | end 132 | end 133 | end 134 | 135 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@ClassifierBase/ClassifierBase.m: -------------------------------------------------------------------------------- 1 | classdef (Abstract) ClassifierBase < handle 2 | 3 | properties 4 | instanceSet; 5 | end 6 | 7 | methods (Abstract = true) 8 | obj = classifyInstance(obj); 9 | obj = build(obj); 10 | obj = reset(obj); 11 | configInfo = getConfigInfo(obj); 12 | time = getTime(obj); 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@CombiCCA/CombiCCA.m: -------------------------------------------------------------------------------- 1 | classdef CombiCCA < eegtoolkit.classification.ClassifierBase; 2 | %COMBICCA Summary of this class goes here 3 | % Detailed explanation goes here 4 | % fprintf('CombitCCA Processing TW %fs, No.crossvalidation %d \n',TW(tw_length),run); 5 | % it=cell(12,1); 6 | % for iN = 1:nClasses 7 | % it{iN} = mean(SSVEPdata(chan_used,1:TW_p(tw_length),idx_traindata,iN),3); 8 | % end 9 | % % recognize SSVEP 10 | properties 11 | individualTemplates; 12 | refSignals; 13 | % sti_f; 14 | baseClassifier; 15 | end 16 | 17 | methods 18 | function CoCCA = CombiCCA( sti_f, numHarmonics, sampleLength, samplingRate) 19 | % CoCCA.sti_f = sti_f; 20 | % CoCCA.numHarmonics = numHarmonics; 21 | CoCCA.refSignals = CoCCA.ck_signalTrans(sti_f,sampleLength, samplingRate, numHarmonics); 22 | end 23 | 24 | function CoCCA = build(CoCCA) 25 | numLabels = length(unique(CoCCA.instanceSet.labels)); 26 | CoCCA.individualTemplates = cell(numLabels,1); 27 | unLabels = unique(CoCCA.instanceSet.labels); 28 | for i=1:numLabels 29 | trialsIndices = CoCCA.instanceSet.labels==unLabels(i); 30 | CoCCA.individualTemplates{i} = squeeze(mean(CoCCA.instanceSet.sMatrix(trialsIndices,:,:),1)); 31 | end 32 | 33 | end 34 | 35 | function [output, probabilities, ranking] = classifyInstance(CoCCA,instance) 36 | testInstances = CoCCA.extract(instance); 37 | [output, probabilities, ranking] = CoCCA.baseClassifier.classifyInstance(testInstances); 38 | end 39 | 40 | function CSP = reset(CSP) 41 | % 'Resets' the classifier. 42 | % CSP.models = {}; 43 | end 44 | 45 | function configInfo = getConfigInfo(CSP) 46 | configInfo = '\n'; 47 | end 48 | 49 | 50 | function time = getTime(CSP) 51 | time = 0; 52 | end 53 | 54 | end 55 | methods (Access = private) 56 | 57 | function [Wx, Wy, r] = cca(CCA,X,Y) 58 | % 59 | % CCA calculate canonical correlations 60 | % 61 | % [Wx Wy r] = cca(X,Y) where Wx and Wy contains the canonical correlation 62 | 63 | % vectors as columns and r is a vector with corresponding canonical 64 | % correlations. The correlations are sorted in descending order. X and Y 65 | % are matrices where each column is a sample. Hence, X and Y must have 66 | % the same number of columns. 67 | % 68 | % Example: If X is M*K and Y is N*K there are L=MIN(M,N) solutions. Wx is 69 | % then M*L, Wy is N*L and r is L*1. 70 | % 71 | % 72 | % ?? 2000 Magnus Borga, Link?pings universitet 73 | 74 | % --- Calculate covariance matrices ---?????????????? 75 | 76 | z = [X;Y]; 77 | C = cov(z.'); 78 | sx = size(X,1); %X??????(??), 79 | sy = size(Y,1); 80 | Cxx = C(1:sx, 1:sx) + 10^(-8)*eye(sx); 81 | Cxy = C(1:sx, sx+1:sx+sy); 82 | Cyx = Cxy'; 83 | Cyy = C(sx+1:sx+sy, sx+1:sx+sy) + 10^(-8)*eye(sy);%eye()???????? 84 | invCyy = inv(Cyy); 85 | 86 | % --- Calcualte Wx and r --- 87 | 88 | [Wx,r] = eig(inv(Cxx)*Cxy*invCyy*Cyx); % Basis in X eig???????????? 89 | r = sqrt(real(r)); % Canonical correlations 90 | 91 | % --- Sort correlations --- 92 | 93 | V = fliplr(Wx); % reverse order of eigenvectors??????????????????????i??????????i?????? 94 | r = flipud(diag(r)); % extract eigenvalues and reverse their order 95 | [r,I]= sort((real(r))); % sort reversed eigenvalues in ascending order 96 | r = flipud(r); % restore sorted eigenvalues into descending order?????????????? 97 | for j = 1:length(I) 98 | Wx(:,j) = V(:,I(j)); % sort reversed eigenvectors in ascending order 99 | end 100 | Wx = fliplr(Wx); % restore sorted eigenvectors into descending order 101 | 102 | % --- Calcualte Wy --- 103 | 104 | Wy = invCyy*Cyx*Wx; % Basis in Y 105 | % Wy = Wy./repmat(sqrt(sum(abs(Wy).^2)),sy,1); % Normalize Wy 106 | 107 | end 108 | function instancesOutput = extract(CoCCA,sMatrix) 109 | numClasses = length(CoCCA.individualTemplates); 110 | numInstances = size(sMatrix,1); 111 | instancesOutput = zeros(numInstances,numClasses); 112 | for i=1:numInstances 113 | for j=1:numClasses 114 | [wxit,wyit,rit] = CoCCA.cca(squeeze(sMatrix(i,:,:)),CoCCA.individualTemplates{j}); 115 | [wxref,wyref,rref] = CoCCA.cca(squeeze(sMatrix(i,:,:)),CoCCA.refSignals(:,:,j)); 116 | [wxitref,wyitref,ritref] = CoCCA.cca(CoCCA.individualTemplates{j},CoCCA.refSignals(:,:,j)); 117 | q1 = squeeze(sMatrix(i,:,:))'*wxref; 118 | q2 = CoCCA.refSignals(:,:,j)'*wyref; 119 | q3 = squeeze(sMatrix(i,:,:))'*wxit; 120 | q4 = CoCCA.individualTemplates{j}'*wxit; 121 | q5 = q1; 122 | q6 = CoCCA.individualTemplates{j}'*wxref; 123 | q7 = squeeze(sMatrix(i,:,:))'*wxitref; 124 | q8 = CoCCA.individualTemplates{j}'*wxitref; 125 | r_n = [corr(q1(:),q2(:)) corr(q3(:),q4(:)) corr(q5(:),q6(:)) corr(q7(:), q8(:))]; 126 | rho_n = sum(sign(r_n).*r_n.^2); 127 | instancesOutput(i,j) = rho_n; 128 | end 129 | end 130 | end 131 | % for j=1:nClasses 132 | % tempvec=zeros(nClasses,1); 133 | % for jj=1:nClasses 134 | % [wxit,wyit,rit ]=cca(SSVEPdata(chan_used,1:TW_p(tw_length),run,j),it{jj}(:,1:TW_p(tw_length))); 135 | % [wxref,wyref,rref ]=cca(SSVEPdata(chan_used,1:TW_p(tw_length),run,j),sc{jj}(:,1:TW_p(tw_length))); 136 | % [wxitref,wyitref,ritref ]=cca(it{jj}(:,1:TW_p(tw_length)),sc{jj}(:,1:TW_p(tw_length))); 137 | % q1 = SSVEPdata(chan_used,1:TW_p(tw_length),run,j)'*wxref; 138 | % q2 = sc{jj}(:,1:TW_p(tw_length))'*wyref; 139 | % q3 = SSVEPdata(chan_used,1:TW_p(tw_length),run,j)'*wxit; 140 | % q4 = it{jj}(:,1:TW_p(tw_length))'*wxit; 141 | % q5 = q1; 142 | % q6 = it{jj}(:,1:TW_p(tw_length))'*wxref; 143 | % q7 = SSVEPdata(chan_used,1:TW_p(tw_length),run,j)'*wxitref; 144 | % q8 = it{jj}(:,1:TW_p(tw_length))'*wxitref; 145 | % r_n = [corr(q1(:),q2(:)) corr(q3(:),q4(:)) corr(q5(:),q6(:)) corr(q7(:),q8(:))]; 146 | % rho_n = sum(sign(r_n).*r_n.^2); 147 | % tempvec(jj) = rho_n;%max(r1); 148 | % end 149 | % 150 | % [v,idx]=max(tempvec); 151 | % sub_lab(mth,(run-1)*nClasses+j,tw_length)=idx; 152 | % if idx==j 153 | % n_correct(tw_length,mth)=n_correct(tw_length,mth)+1; 154 | % end 155 | % end 156 | function refSignal=ck_signalTrans(CCA,f,mLen,FreqSamp,NumHarm) 157 | 158 | p=mLen;%1250; 159 | fs=FreqSamp;%250; 160 | TP=1/fs:1/fs:p/fs; 161 | for j=1:length(f) 162 | tempComp=[]; 163 | for k=1:NumHarm 164 | Sinh1=sin(2*pi*k*f(j)*TP); 165 | Cosh1=cos(2*pi*k*f(j)*TP); 166 | tempComp = [tempComp; Sinh1;Cosh1;]; 167 | end 168 | refSignal(:,:,j)=tempComp; 169 | end 170 | end 171 | end 172 | end 173 | 174 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@FusionClassifierWrapper/FusionClassifierWrapper.m: -------------------------------------------------------------------------------- 1 | classdef FusionClassifierWrapper < eegtoolkit.classification.ClassifierBase & eegtoolkit.experiment.Experimenter; 2 | 3 | properties 4 | baseClassifier; 5 | classifiers; 6 | end 7 | 8 | methods 9 | function FCW = FusionClassifierWrapper(baseClassifier, fusionInstanceSet) 10 | if nargin>0 11 | FCW.baseClassifier = baseClassifier; 12 | end 13 | if nargin>1 14 | FCW.instanceSet = fusionInstanceSet; 15 | end 16 | end 17 | 18 | function FCW = build(FCW) 19 | numFusion = FCW.instanceSet.numFusion; 20 | FCW.reset; 21 | if ~isa(FCW.baseClassifier,'eegtoolkit.classification.LIBSVM') 22 | error ('Only LIBSVMClassifier supported as base classifier'); 23 | else 24 | for i=1:numFusion 25 | FCW.classifiers{i} = FCW.baseClassifier.copy; 26 | FCW.classifiers{i} = eegtoolkit.classification.LIBSVM; 27 | FCW.classifiers{i}.instanceSet = FCW.instanceSet.instanceSets{i}; 28 | FCW.classifiers{i}.build; 29 | end 30 | end 31 | end 32 | 33 | function [output, probabilities, ranking] = classifyInstance(FCW,instance) 34 | [numInstances,~] = size(instance); 35 | numClass = length(FCW.classifiers); 36 | out = zeros(numInstances,numClass); 37 | output = zeros(numInstances,1); 38 | for i=1:length(FCW.classifiers) 39 | [out(:,i), probabilities, ranking] = FCW.classifiers{i}.classifyInstance(instance(:,:,i)); 40 | end 41 | for i=1:numInstances 42 | x = out(i,:); 43 | [a,b] = hist(x,unique(x)); 44 | [~,idx] = max(a); 45 | output(i,:) = b(idx); 46 | end 47 | probabilities = []; 48 | ranking = []; 49 | %TODO:***** 50 | 51 | end 52 | 53 | function configInfo = getConfigInfo(FCW) 54 | configInfo = 'FusionClassifierWrapper'; 55 | end 56 | 57 | 58 | function time = getTime(FCW) 59 | time = 0; 60 | end 61 | 62 | function FCW = reset(FCW) 63 | FCW.classifiers = {}; 64 | end 65 | 66 | 67 | 68 | end 69 | 70 | end 71 | 72 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@LDA/LDA.m: -------------------------------------------------------------------------------- 1 | classdef LDA < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties (Access = public) 8 | W_LDA; 9 | PCA_mat; 10 | trainFeat; 11 | end 12 | 13 | methods (Access = public) 14 | function LDA = LDA(instanceSet) 15 | if nargin > 0 16 | LDA.instanceSet = instanceSet; 17 | end 18 | 19 | end 20 | 21 | function LDA = build(LDA) 22 | LDA.reset(); 23 | data = LDA.instanceSet.getInstances; 24 | data = data'; 25 | labels = LDA.instanceSet.getLabels; 26 | unique(labels) 27 | numTrials = length(labels); 28 | 29 | PCA_W=pca_func(data); 30 | % PCA_W=eye(8000); 31 | train_Data=PCA_W'*data; 32 | 33 | Par.mode = 'LDA'; 34 | dim = length(unique(labels))-1; 35 | [W,Wp] = SGE_GraphConstruct(labels,Par); 36 | [TransMatrix,~] = SGE_Mapping(train_Data,dim,W,Wp); 37 | LDA.W_LDA = TransMatrix; 38 | LDA.PCA_mat=PCA_W; 39 | mtrainFeat=SGE_Projection(train_Data,1:dim,TransMatrix); 40 | LDA.trainFeat=mtrainFeat; 41 | % figure,gplotmatrix(mtrainFeat',[],labels) 42 | end 43 | 44 | function [output, probabilities, ranking] = classifyInstance(LDA,instance) 45 | 46 | N = size(instance,1); 47 | instance = instance'; 48 | 49 | test_Data=LDA.PCA_mat'*instance; 50 | % test_Data=[ones(1,N);test_Data]; 51 | 52 | testFeat=LDA.W_LDA'*test_Data; 53 | X = LDA.trainFeat; 54 | y = LDA.instanceSet.getLabels; 55 | [~,output] = SGE_Classification(X,y',testFeat,0,'euc'); 56 | output = output(1,:)'; 57 | probabilities=zeros(N,1); 58 | ranking=zeros(N,1); 59 | % figure,gplotmatrix(testFeat',[],output) 60 | 61 | end 62 | 63 | function LDA = reset(LDA) 64 | %delete all stored models 65 | LDA.W_LDA=[]; 66 | LDA.PCA_mat=[]; 67 | LDA.trainFeat=[]; 68 | end 69 | 70 | function configInfo = getConfigInfo(LDA) 71 | configInfo = sprintf('MLR_Classifier'); 72 | end 73 | 74 | 75 | function time = getTime(LDA) 76 | 77 | end 78 | 79 | end 80 | end 81 | 82 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@LIBSVM/LIBSVM.m: -------------------------------------------------------------------------------- 1 | 2 | % LIBSVMCLASSIFIER class 3 | % Wrapper class of the libsvm library (libsvm) .mex files must be added to 4 | % your matlab path before using this class 5 | classdef LIBSVM < eegtoolkit.classification.ClassifierBase 6 | 7 | properties (Constant) 8 | KERNEL_LINEAR = 0; 9 | % KERNEL_POLYNOMIAL = 1; not supported yet 10 | KERNEL_RBF = 2; 11 | % KERNEL_SIGMOID = 3; not supported yet 12 | end 13 | properties 14 | kernel; % The svm kernel 15 | cost; % The cost parameter 16 | gamma; % The gamma parameter (used only with rbf kernel) 17 | models; % The trained models 18 | end 19 | 20 | methods (Access = public) 21 | function LSVM = LIBSVM(instanceSet) 22 | if nargin > 0 23 | LSVM.kernel = LSVM.KERNEL_LINEAR; 24 | LSVM.cost = 1.0; 25 | LSVM.instanceSet = instanceSet; 26 | LSVM.gamma = 1/instanceSet.getNumFeatures; 27 | else 28 | LSVM.kernel = LSVM.KERNEL_LINEAR; 29 | LSVM.cost = 1.0; 30 | LSVM.gamma = 1; 31 | end 32 | end 33 | 34 | function LSVM = build(LSVM) 35 | % Builds the classification models 36 | LSVM.reset; 37 | numLabels = LSVM.instanceSet.getNumLabels; 38 | uniqueLabels = unique(LSVM.instanceSet.getLabels); 39 | for i=1:numLabels 40 | currentLabel = uniqueLabels(i); 41 | labels = zeros(LSVM.instanceSet.getNumInstances,1)-1; 42 | labels(LSVM.instanceSet.getInstanceIndicesForLabel(currentLabel)) = 1; 43 | instances = sparse(LSVM.instanceSet.getInstances); 44 | if LSVM.kernel == LSVM.KERNEL_LINEAR; 45 | %store the models in an instance variable 46 | LSVM.models{i} = svmtrain(labels, instances, sprintf('-t %d -c %f -q', LSVM.kernel, LSVM.cost)); 47 | elseif LSVM.kernel == LSVM.KERNEL_RBF; 48 | LSVM.models{i} = svmtrain(labels, instances, sprintf('-t %d -c %f -g %f -q', LSVM.kernel, LSVM.cost, LSVM.gamma)); 49 | else 50 | error('invalid kernel parameter'); 51 | end 52 | end 53 | end 54 | 55 | function [output, probabilities, ranking] = classifyInstance(LSVM,instance) 56 | %input = instance matrix rows = instances, cols = attributes 57 | %output = predicted class 58 | %probabilities = probability for predicted class 59 | %ranking = propabilities for all classes (e.g. to use with mAP) 60 | 61 | %TODO:should print an error if 'build' has not been called 62 | numModels = length(LSVM.models); 63 | [numinstance, ~] = size(instance); 64 | scores = zeros(numModels,numinstance); 65 | for i=1:numModels 66 | %predict using the stored models 67 | [~, ~, t] = svmpredict(eye(numinstance,1),instance, LSVM.models{i},' -q'); 68 | %store probability for each class 69 | scores(i,:) = t(:,1); 70 | end 71 | output = zeros(numinstance,1); 72 | probabilities = zeros(numinstance,1); 73 | ranking = scores'; 74 | for i=1:numinstance 75 | %select the class with the highest probability 76 | [prob, idx] = max(scores(:,i)); 77 | uniqueLabels = unique(LSVM.instanceSet.getLabels); 78 | %output the label with highest probability 79 | output(i,1) = uniqueLabels(idx); 80 | %return the probability for the output label 81 | probabilities(i,1) = prob; 82 | end 83 | end 84 | 85 | function LSVM = reset(LSVM) 86 | % 'Resets' the classifier. 87 | LSVM.models = {}; 88 | end 89 | 90 | function configInfo = getConfigInfo(LSVM) 91 | % Prints the parameters of the classifier 92 | switch LSVM.kernel 93 | case LSVM.KERNEL_LINEAR 94 | configInfo = sprintf('LIBSVM\tkernel:linear\tcost:%d', LSVM.cost); 95 | case LSVM.KERNEL_RBF 96 | configInfo = sprintf('LIBSVM\tkernel:rbf\tcost:%d\tgamma:%d', LSVM.cost, LSVM.gamma); 97 | otherwise 98 | configInfo = 'Error in configuration (only linear and rbf kernels supported for now)'; 99 | end 100 | end 101 | 102 | function newLSVM = copy(LSVM) 103 | newLSVM = eegtoolkit.classification.LIBSVM; 104 | newLSVM.kernel = LSVM.kernel; 105 | newLSVM.cost = LSVM.cost; 106 | newLSVM.gamma = LSVM.gamma; 107 | end 108 | 109 | 110 | function time = getTime(LSVM) 111 | time = 0; 112 | end 113 | end 114 | end -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@LIBSVMFast/LIBSVMFast.m: -------------------------------------------------------------------------------- 1 | classdef LIBSVMFast < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | properties 7 | kernel; 8 | cost; 9 | gamma; 10 | models; 11 | Ktrain; 12 | Ktest; 13 | maxlag; 14 | scaleopt; 15 | predictTotalTime; 16 | predictCount; 17 | end 18 | 19 | methods (Access = public) 20 | function LSVM = LIBSVMFast (instanceSet,kernel,cost,gamma,maxlag,scaleopt) 21 | %set default parameters 22 | LSVM.predictTotalTime = 0; 23 | LSVM.predictCount = 0; 24 | LSVM.kernel = 'linear'; 25 | LSVM.cost = 1.0; 26 | LSVM.gamma = 0.01; 27 | LSVM.maxlag = 150; 28 | LSVM.scaleopt = 'coeff'; 29 | if nargin > 0 30 | LSVM.instanceSet = instanceSet; 31 | LSVM.gamma = 1/instanceSet.getNumFeatures; 32 | end 33 | if nargin > 1 34 | LSVM.kernel = kernel; 35 | end 36 | if nargin > 2 37 | LSVM.cost = cost; 38 | end 39 | if nargin > 3 40 | LSVM.gamma = gamma; 41 | end 42 | if nargin > 4 43 | LSVM.maxlag = maxlag; 44 | end 45 | if nargin > 5 46 | LSVM.scaleopt = scaleopt; 47 | end 48 | end 49 | 50 | function LSVM = build(LSVM) 51 | %clear all from previous calls to "build" 52 | LSVM.reset; 53 | numLabels = LSVM.instanceSet.getNumLabels; 54 | uniqueLabels = unique(LSVM.instanceSet.getLabels); 55 | for i=1:numLabels 56 | currentLabel = uniqueLabels(i); 57 | labels = zeros(LSVM.instanceSet.getNumInstances,1)-1; 58 | labels(LSVM.instanceSet.getInstanceIndicesForLabel(currentLabel)) = 1; 59 | LSVM.models{i} = svmtrain(labels, [(1:size(LSVM.Ktrain,1))', ... 60 | LSVM.Ktrain+eye(size(LSVM.Ktrain,1))*realmin], ... 61 | sprintf(' -t 4 -c %f -b 1 -q', LSVM.cost)); 62 | end 63 | end 64 | 65 | function [output, probabilities, ranking] = classifyInstance(LSVM) 66 | %input = instance matrix rows = instances, cols = attributes 67 | %output = predicted class 68 | %probabilities = probability for predicted class 69 | %ranking = propabilities for all classes (e.g. to use with mAP) 70 | 71 | %TODO:should print an error if 'build' has not been called 72 | numModels = length(LSVM.models); 73 | [numinstance, ~] = size(LSVM.Ktest); 74 | scores = zeros(numModels,numinstance); 75 | for i=1:numModels 76 | %predict using the stored models 77 | tic 78 | [~, ~, t] = svmpredict(eye(numinstance,1),... 79 | [(1:numinstance)', LSVM.Ktest], LSVM.models{i},'-b 1 -q'); 80 | LSVM.predictTotalTime = LSVM.predictTotalTime + toc; 81 | LSVM.predictCount = LSVM.predictCount + numinstance; 82 | %svmpredict(labels(~idx), [(1:sum(~idx))', K(~idx,idx)], model); 83 | %store probability for each class 84 | scores(i,:) = t(:,1); 85 | end 86 | output = zeros(numinstance,1); 87 | probabilities = zeros(numinstance,1); 88 | %we need these for ranking metrics (e.g. mAP) 89 | ranking = scores; 90 | for i=1:numinstance 91 | %select the class with the highest probability 92 | [prob, idx] = max(scores(:,i)); 93 | uniqueLabels = unique(LSVM.instanceSet.getLabels); 94 | %output the label with highest probability 95 | output(i,1) = uniqueLabels(idx); 96 | %return the probability for the output label 97 | probabilities(i,1) = prob; 98 | end 99 | end 100 | 101 | function LSVM = reset(LSVM) 102 | %delete all stored models 103 | LSVM.models = {}; 104 | end 105 | 106 | function configInfo = getConfigInfo(LSVM) 107 | switch LSVM.kernel 108 | case {'linear','spearman','correlation','cosine'} 109 | configInfo = sprintf('LIBSVMFast\tkernel:%s\tcost:%d', LSVM.kernel, LSVM.cost); 110 | case 'xcorr' 111 | configInfo = sprintf('LIBSVMFast\tkernel:%s\tcost:%d\tgamma:%d\tmaxlag:%d\tscaleopt:%s', LSVM.kernel, LSVM.cost, LSVM.maxlag,LSVM.scaleopt); 112 | otherwise 113 | configInfo = sprintf('LIBSVMFast\tkernel:%s\tcost:%d\tgamma:%d', LSVM.kernel, LSVM.cost, LSVM.gamma); 114 | % otherwise 115 | % configInfo = 'Error in configuration (only linear and rbf kernels supported for now)'; 116 | end 117 | end 118 | 119 | function time = getTime(LSVM) 120 | time = LSVM.predictTotalTime/LSVM.predictCount; 121 | end 122 | end 123 | end 124 | 125 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@MLDA/MLDA.m: -------------------------------------------------------------------------------- 1 | classdef MLDA < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | DiscrimType; % 'linear' (default) | 'quadratic' | 'diagLinear' | 'diagQuadratic' | 'pseudoLinear' | 'pseudoQuadratic' 9 | Delta % 0 (default) | nonnegative scalar value that acts as a linear coefficient threshold. Delta must be 0 for quadratic discriminant models. 10 | Gamma % scalar value in the range [0,1]. Parameter for regularizing the correlation matrix of predictors. 11 | FillCoeffs % on (default) Coeffs property flag, specified as the comma-separated pair consisting of 'FillCoeffs' and 'on' or 'off 12 | ScoreTransform % 'none' (default). Score transform function. Check http://www.mathworks.com/help/stats/fitcdiscr.html 13 | Prior % 'empirical' (default) or 'uniform'. Prior probabilities for each class. 14 | models; 15 | totalTime; 16 | totalCount; 17 | end 18 | 19 | methods (Access = public) 20 | function MLDA = MLDA(instanceSet, discrimType, delta, gamma, fillCoeffs, scoreTransform,prior) 21 | %set default parameters 22 | if nargin > 0 23 | MLDA.instanceSet = instanceSet; 24 | end 25 | if nargin > 1 26 | MLDA.DiscrimType = discrimType; 27 | end 28 | if nargin > 2 29 | MLDA.Delta=delta; 30 | end 31 | if nargin > 3 32 | MLDA.Gamma = gamma; 33 | end 34 | if nargin > 4 35 | MLDA.FillCoeffs = fillCoeffs; 36 | end 37 | if nargin > 5 38 | MLDA.ScoreTransform = scoreTransform; 39 | end 40 | if nargin > 6 41 | MLDA.Prior = prior; 42 | end 43 | end 44 | 45 | function MLDA = build(MLDA) 46 | %clear all from previous calls to "build" 47 | MLDA.reset; 48 | numLabels = MLDA.instanceSet.getNumLabels; 49 | uniqueLabels = unique(MLDA.instanceSet.getLabels); 50 | 51 | % ---- Multi-Class ----- % 52 | instances=MLDA.instanceSet.instances; 53 | labels=MLDA.instanceSet.labels; 54 | 55 | %LDA.models{1}=fitcecoc(instances,labels,'Coding','ternarycomplete'); 56 | MLDA.models{1} = fitcdiscr(instances,labels,'DiscrimType',MLDA.DiscrimType,'Delta',MLDA.Delta,'Gamma',MLDA.Gamma,'FillCoeffs',MLDA.FillCoeffs,'ScoreTransform',MLDA.ScoreTransform, 'Prior',MLDA.Prior); 57 | 58 | % ---- One (vs) All ----- % 59 | % for i=1:numLabels 60 | % currentLabel = uniqueLabels(i); 61 | % labels = zeros(LDA.instanceSet.getNumInstances,1)-1; 62 | % labels(LDA.instanceSet.getInstanceIndicesForLabel(currentLabel)) = 1; 63 | % instances = sparse(LDA.instanceSet.getInstances); 64 | % LDA.models{i} = libsvmtrain(labels,instances, '-t 0 -c 1 -b 1'); 65 | % if LDA.kernel == LDA.KERNEL_LINEAR; 66 | % %store the models in an instance variable 67 | % LDA.models{i} = libsvmtrain(labels, instances, sprintf('-t %d -c %f -b 1 -q', LDA.kernel, LDA.cost)); 68 | % elseif LDA.kernel == LDA.KERNEL_RBF; 69 | % LDA.models{i} = libsvmtrain(labels, instances, sprintf('-t %d -c %f -g %f -b 1 -q', LDA.kernel, LDA.cost, LDA.gamma)); 70 | % else 71 | % error('invalid kernel parameter'); 72 | % end 73 | % end 74 | end 75 | 76 | function [output, probabilities, ranking] = classifyInstance(MLDA,instance) 77 | %input = instance matrix rows = instances, cols = attributes 78 | %output = predicted class 79 | %probabilities = probability for predicted class 80 | %ranking = propabilities for all classes (e.g. to use with mAP) 81 | 82 | 83 | %TODO:should print an error if 'build' has not been called 84 | numModels = length(MLDA.models); 85 | [numinstance, ~] = size(instance); 86 | scores = zeros(numModels,numinstance); 87 | 88 | % ---- Multi-class ----- % 89 | tic 90 | [label,scores,cost] = predict(MLDA.models{1},instance); 91 | MLDA.totalTime = MLDA.totalTime + toc; 92 | MLDA.totalCount = MLDA.totalCount + numinstance; 93 | % ---- One (vs) All -----% 94 | % for i=1:numModels 95 | % %predict using the stored models 96 | % [label,score,cost] = predict(LDA.models{i},instance); 97 | % %libsvmpredict(eye(numinstance,1),instance, LSVM.models{i},'-b 1 -q'); 98 | % %store probability for each class 99 | % scores(i,:) = score(:,1); 100 | % end 101 | 102 | output = zeros(numinstance,1); 103 | probabilities = zeros(numinstance,1); 104 | %we need these for ranking metrics (e.g. mAP) 105 | ranking = scores; 106 | for i=1:numinstance 107 | %select the class with the highest probability 108 | [prob, idx] = max(scores(i,:)); 109 | uniqueLabels = unique(MLDA.instanceSet.getLabels); 110 | %output the label with highest probability 111 | output(i,1) = uniqueLabels(idx); 112 | %return the probability for the output label 113 | probabilities(i,1) = prob; 114 | end 115 | end 116 | 117 | function MLDA = reset(MLDA) 118 | %delete all stored models 119 | MLDA.models = {}; 120 | end 121 | 122 | function configInfo = getConfigInfo(MLDA) 123 | configInfo = sprintf('MLDA\tdiscrimtype:%s\tdelta:%f\tgamma:%f\tfillcoeffs:%d\tscoretransform:%s\tprior:%s',MLDA.DiscrimType, MLDA.Delta, MLDA.Gamma, MLDA.FillCoeffs, MLDA.ScoreTransform, MLDA.Prior); 124 | end 125 | 126 | 127 | function time = getTime(MLDA) 128 | time = MLDA.totalTime/MLDA.totalCount; 129 | end 130 | 131 | end 132 | end 133 | 134 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@MLR/MLR.m: -------------------------------------------------------------------------------- 1 | classdef MLR < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | W_mlr; 9 | PCA_mat; 10 | trainFeat; 11 | end 12 | 13 | methods (Access = public) 14 | function MLR = MLR(instanceSet) 15 | if nargin > 0 16 | MLR.instanceSet = instanceSet; 17 | end 18 | 19 | end 20 | 21 | function MLR = build(MLR) 22 | MLR.reset(); 23 | data = MLR.instanceSet.getInstances; 24 | data = data'; 25 | labels = MLR.instanceSet.getLabels; 26 | numTrials = length(labels); 27 | train_Y = zeros(length(unique(labels)),numTrials); 28 | for i = 1 : numTrials 29 | train_Y(labels(i),i) = 1; 30 | end 31 | [Ydim,Num]=size(train_Y); 32 | PCA_W=MLR.pca_func(data); 33 | train_Data=PCA_W'*data; 34 | train_Data=[ones(1,numTrials);train_Data]; 35 | MLR.W_mlr = MLR.MultiLR(train_Data,train_Y);%inv(train_Data*train_Data')*train_Data*train_Y';%(train_Data'*train_Data)\train_Data'*train_Y;%MultiLR(train_Data,train_Y); 36 | MLR.PCA_mat=PCA_W; 37 | mtrainFeat=MLR.W_mlr'*train_Data; 38 | MLR.trainFeat=mtrainFeat; 39 | end 40 | 41 | function [output, probabilities, ranking] = classifyInstance(MLR,instance) 42 | 43 | N = size(instance,1); 44 | instance = instance'; 45 | test_Data=MLR.PCA_mat'*instance; 46 | test_Data=[ones(1,N);test_Data]; 47 | testFeat=MLR.W_mlr'*test_Data; 48 | output=knnclassify(testFeat',MLR.trainFeat',MLR.instanceSet.getLabels,5,'euclidean'); 49 | probabilities=zeros(N,1); 50 | ranking=zeros(N,1); 51 | 52 | end 53 | 54 | function MLR = reset(MLR) 55 | %delete all stored models 56 | MLR.W_mlr=[]; 57 | MLR.PCA_mat=[]; 58 | MLR.trainFeat=[]; 59 | end 60 | 61 | function configInfo = getConfigInfo(MLR) 62 | configInfo = sprintf('MLR'); 63 | end 64 | 65 | 66 | function time = getTime(MLR) 67 | time = 0; 68 | end 69 | 70 | end 71 | 72 | methods (Access = private) 73 | function Proj_W=pca_func(MLR,data) 74 | Proj_W=[]; 75 | meanData=mean(data,2); 76 | data=data-repmat(meanData,1,size(data,2)); 77 | % stdVar=std(data')'; 78 | % staData=(data-repmat(meanData,1,size(data,2)))./repmat(stdVar,1,size(data,2)); 79 | % data=staData; 80 | [V,S]=eig(data'*data); 81 | [sorted_diagS,sorted_rank]=sort(diag(S),'descend'); 82 | sorted_S=diag(sorted_diagS); 83 | V=V(:,sorted_rank); 84 | r=rank(sorted_S); 85 | S1=sorted_S(1:r,1:r); 86 | V1=V(:,1:r); 87 | U=data*V1*S1^(-0.5); 88 | %[sorted_S,sorted_rank]=sort(diag(S),'descend'); 89 | All_energy=sum(diag(S1)); 90 | sorted_energy=diag(S1); 91 | for j=1:r 92 | if (sum(sorted_energy(1:j))/All_energy)>0.99 93 | break 94 | end 95 | end 96 | Proj_W=U(:,1:j); 97 | end 98 | function W_mlr=MultiLR(MLR,train_Feat,train_Y) 99 | 100 | % Multiple linear regression 101 | % train_Feat: training samples 102 | % train_Y: label matrix 103 | 104 | [U,Sigma,V]=svd(train_Feat,'econ'); 105 | r=rank(Sigma); 106 | U1=U(:,1:r); 107 | V1=V(:,1:r); 108 | Sigma_r=diag(Sigma(1:r, 1:r)); 109 | W_mlr=U1*diag(1./Sigma_r)*V1'*train_Y'; 110 | 111 | 112 | end 113 | end 114 | end 115 | 116 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@MLTREE/MLTREE.m: -------------------------------------------------------------------------------- 1 | classdef MLTREE < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | AlgorithmForCategorical; % Algorithm for best categorical predictor split 'Exact' | 'PullLeft' | 'PCA' | 'OVAbyClass' 9 | MaxNumSplits; % Maximal number of decision splits. size(X,1) - 1 (default) | positive integer 10 | MinLeafSize; % Minimum number of leaf node observations 1 (default) | positive integer value 11 | MinParentSize; % Minimum number of branch node observations 10 (default) | positive integer value 12 | NumVariablesToSample; % Number of predictors to select at random for each split 'all' | positive integer value 13 | ScoreTransform % 'none' (default). Score transform function. Check http://www.mathworks.com/help/stats/fitcdiscr.html 14 | Prior; % Prior probabilities 'empirical' (default) | 'uniform' | vector of scalar values | structure 15 | models; 16 | totalTime; 17 | totalCount; 18 | end 19 | 20 | methods (Access = public) 21 | function MLTREE = MLTREE(instanceSet, algorithmForCategorical, maxNumSplits, minLeafSize, minParentSize, numVariablesToSample, scoreTransform, prior) 22 | %set default parameters 23 | if nargin > 0 24 | MLTREE.instanceSet = instanceSet; 25 | end 26 | if nargin > 1 27 | MLTREE.AlgorithmForCategorical = algorithmForCategorical; 28 | end 29 | if nargin > 2 30 | MLTREE.MaxNumSplits=maxNumSplits; 31 | end 32 | if nargin > 3 33 | MLTREE.MinLeafSize = minLeafSize; 34 | end 35 | if nargin > 4 36 | MLTREE.MinParentSize = minParentSize; 37 | end 38 | if nargin > 5 39 | MLTREE.NumVariablesToSample = numVariablesToSample; 40 | end 41 | if nargin > 6 42 | MLTREE.ScoreTransform = scoreTransform; 43 | end 44 | if nargin > 7 45 | MLTREE.Prior = prior; 46 | end 47 | MLTREE.totalTime = 0; 48 | MLTREE.totalCount = 0; 49 | end 50 | 51 | function MLTREE = build(MLTREE) 52 | %clear all from previous calls to "build" 53 | MLTREE.reset; 54 | numLabels = MLTREE.instanceSet.getNumLabels; 55 | uniqueLabels = unique(MLTREE.instanceSet.getLabels); 56 | 57 | % ---- Multi-Class ----- % 58 | instances=MLTREE.instanceSet.instances; 59 | labels=MLTREE.instanceSet.labels; 60 | 61 | %LDA.models{1}=fitcecoc(instances,labels,'Coding','ternarycomplete'); 62 | MLTREE.models{1} = fitctree(instances,labels,'AlgorithmForCategorical',MLTREE.AlgorithmForCategorical,'MaxNumSplits',MLTREE.MaxNumSplits,'MinLeafSize',MLTREE.MinLeafSize,'MinParentSize',MLTREE.MinParentSize,'NumVariablesToSample', MLTREE.NumVariablesToSample,'ScoreTransform',MLTREE.ScoreTransform, 'Prior',MLTREE.Prior); 63 | 64 | 65 | % ---- One (vs) All ----- % 66 | % for i=1:numLabels 67 | % currentLabel = uniqueLabels(i); 68 | % labels = zeros(LDA.instanceSet.getNumInstances,1)-1; 69 | % labels(LDA.instanceSet.getInstanceIndicesForLabel(currentLabel)) = 1; 70 | % instances = sparse(LDA.instanceSet.getInstances); 71 | % LDA.models{i} = libsvmtrain(labels,instances, '-t 0 -c 1 -b 1'); 72 | % if LDA.kernel == LDA.KERNEL_LINEAR; 73 | % %store the models in an instance variable 74 | % LDA.models{i} = libsvmtrain(labels, instances, sprintf('-t %d -c %f -b 1 -q', LDA.kernel, LDA.cost)); 75 | % elseif LDA.kernel == LDA.KERNEL_RBF; 76 | % LDA.models{i} = libsvmtrain(labels, instances, sprintf('-t %d -c %f -g %f -b 1 -q', LDA.kernel, LDA.cost, LDA.gamma)); 77 | % else 78 | % error('invalid kernel parameter'); 79 | % end 80 | % end 81 | end 82 | 83 | function [output, probabilities, ranking] = classifyInstance(MLTREE,instance) 84 | %input = instance matrix rows = instances, cols = attributes 85 | %output = predicted class 86 | %probabilities = probability for predicted class 87 | %ranking = propabilities for all classes (e.g. to use with mAP) 88 | 89 | 90 | %TODO:should print an error if 'build' has not been called 91 | numModels = length(MLTREE.models); 92 | [numinstance, ~] = size(instance); 93 | scores = zeros(numModels,numinstance); 94 | 95 | % ---- Multi-class ----- % 96 | tic 97 | [label,scores,cost] = predict(MLTREE.models{1},instance); 98 | MLTREE.totalTime = MLTREE.totalTime + toc; 99 | MLTREE.totalCount = MLTREE.totalCount + numinstance; 100 | % ---- One (vs) All -----% 101 | % for i=1:numModels 102 | % %predict using the stored models 103 | % [label,score,cost] = predict(LDA.models{i},instance); 104 | % %libsvmpredict(eye(numinstance,1),instance, LSVM.models{i},'-b 1 -q'); 105 | % %store probability for each class 106 | % scores(i,:) = score(:,1); 107 | % end 108 | 109 | output = zeros(numinstance,1); 110 | probabilities = zeros(numinstance,1); 111 | %we need these for ranking metrics (e.g. mAP) 112 | ranking = scores; 113 | for i=1:numinstance 114 | %select the class with the highest probability 115 | [prob, idx] = max(scores(i,:)); 116 | uniqueLabels = unique(MLTREE.instanceSet.getLabels); 117 | %output the label with highest probability 118 | output(i,1) = uniqueLabels(idx); 119 | %return the probability for the output label 120 | probabilities(i,1) = prob; 121 | end 122 | end 123 | 124 | function MLTREE = reset(MLTREE) 125 | %delete all stored models 126 | MLTREE.models = {}; 127 | end 128 | 129 | function configInfo = getConfigInfo(MLTREE) 130 | configInfo = 'MLTREE (Config info not supported yet)'; 131 | end 132 | 133 | 134 | function time = getTime(MLTREE) 135 | time = MLTREE.totalTime/MLTREE.totalCount; 136 | end 137 | 138 | end 139 | end 140 | 141 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@MLTboxMulticlass/MLTboxMulticlass.m: -------------------------------------------------------------------------------- 1 | classdef MLTboxMulticlass < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | Learners; %'discriminant': Discriminant analysis. | 'knn': k-nearest neighbors. | 'naivebayes': Naive Bayes. 9 | % 'svm': SVM. | 'tree': Classification trees. | any Matlab template classifier 10 | Coding; % Coding design 'onevsall' (default) | 'allpairs' | 'binarycomplete' | 'denserandom' | 'onevsone' | 'ordinal' | 'sparserandom' | 'ternarycomplete' | numeric matrix 11 | FitPosterior; % Flag indicating whether to transform scores to posterior probabilities false or 0 (default) | true or 1 12 | Prior % 'empirical' (default) or 'uniform'. Prior probabilities for each class. 13 | models; 14 | totalTime; 15 | totalCount; 16 | end 17 | 18 | methods (Access = public) 19 | function MLC = MLTboxMulticlass(instanceSet, learners, coding, fitPosterior, prior) 20 | %set default parameters 21 | MLC.Learners = 'svm'; 22 | MLC.Coding='onevsall'; 23 | MLC.FitPosterior='off'; 24 | MLC.Prior='empirical'; 25 | 26 | if nargin > 0 27 | MLC.instanceSet = instanceSet; 28 | end 29 | if nargin > 1 30 | MLC.Learners = learners; 31 | end 32 | if nargin > 2 33 | MLC.Coding=coding; 34 | end 35 | if nargin > 3 36 | MLC.FitPosterior=fitPosterior; 37 | end 38 | if nargin > 4 39 | MLC.Prior=prior; 40 | end 41 | MLC.totalTime = 0; 42 | MLC.totalCount = 0; 43 | end 44 | 45 | function MLC = build(MLC) 46 | %clear all from previous calls to "build" 47 | MLC.reset; 48 | numLabels = MLC.instanceSet.getNumLabels; 49 | uniqueLabels = unique(MLC.instanceSet.getLabels); 50 | 51 | % ---- Multi-Class ----- % 52 | instances=MLC.instanceSet.instances; 53 | labels=MLC.instanceSet.labels; 54 | 55 | %t=templateSVM('KernelFunction','linear'); 56 | MLC.models{1}=fitcecoc(instances,labels,'Coding', MLC.Coding,'FitPosterior', MLC.FitPosterior,'Prior',MLC.Prior,'Learners',MLC.Learners); 57 | end 58 | 59 | function [output, probabilities, ranking] = classifyInstance(MLC,instance) 60 | 61 | %TODO:should print an error if 'build' has not been called 62 | numModels = length(MLC.models); 63 | [numinstance, ~] = size(instance); 64 | %scores = zeros(numModels,numinstance); 65 | 66 | % ---- Multi-class ----- % 67 | tic 68 | [label,scores,loss] = predict(MLC.models{1},instance); 69 | MLC.totalTime = MLC.totalTime + toc; 70 | MLC.totalCount = MLC.totalCount + numinstance; 71 | output = zeros(numinstance,1); 72 | probabilities = zeros(numinstance,1); 73 | %we need these for ranking metrics (e.g. mAP) 74 | ranking = scores; 75 | for i=1:numinstance 76 | %select the class with the highest probability 77 | [prob, idx] = max(scores(i,:)); 78 | uniqueLabels = unique(MLC.instanceSet.getLabels); 79 | %output the label with highest probability 80 | output(i,1) = uniqueLabels(idx); 81 | %return the probability for the output label 82 | probabilities(i,1) = prob; 83 | end 84 | end 85 | 86 | function MLC = reset(MLC) 87 | %delete all stored models 88 | MLC.models = {}; 89 | end 90 | 91 | function configInfo = getConfigInfo(MLC) 92 | configInfo=sprintf('MLTboxMulticlass\tCoding:%s\tFitPosterior:%s\tPrior:%s\n\tLearners:', MLC.Coding, MLC.FitPosterior,MLC.Prior); 93 | disp(MLC.Learners) 94 | %configInfo = 'MLSVMClassifier (Config info not supported yet)'; 95 | end 96 | 97 | 98 | function time = getTime(MLC) 99 | time = MLC.totalTime/MLC.totalCount; 100 | end 101 | 102 | end 103 | end 104 | 105 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@MaxChooser/MaxChooser.m: -------------------------------------------------------------------------------- 1 | classdef MaxChooser < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | 9 | end 10 | 11 | methods (Access = public) 12 | function MaxChooser =MaxChooser(instanceSet) 13 | if nargin > 0 14 | MaxChooser.instanceSet = instanceSet; 15 | end 16 | 17 | end 18 | 19 | function MaxChooser = build(MaxChooser) 20 | 21 | end 22 | 23 | function [output, probabilities, ranking] = classifyInstance(MaxChooser,instance) 24 | 25 | dd_ins=instance; 26 | N = size(instance,1); 27 | pred_lab=zeros(N,1); 28 | for i=1:N 29 | [v,idx]=max(dd_ins(i,:)); 30 | pred_lab(i)=idx; 31 | ranking(i,:) = dd_ins(i,:); 32 | end 33 | 34 | output = pred_lab;%sum(pred_lab)/length(pred_lab) 35 | probabilities=zeros(N,1); 36 | % ranking=zeros(N,1); 37 | end 38 | 39 | function MaxChooser = reset(MaxChooser) 40 | %delete all stored models 41 | end 42 | 43 | function configInfo = getConfigInfo(MaxChooser) 44 | configInfo = sprintf('MaxChooser'); 45 | end 46 | 47 | 48 | function time = getTime(MaxChooser) 49 | time = 0; 50 | end 51 | 52 | end 53 | end 54 | 55 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@SBLR/SBLR.m: -------------------------------------------------------------------------------- 1 | classdef SBLR < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties 8 | %Coding; % Coding design 'onevsall' (default) | 'allpairs' | 'binarycomplete' | 'denserandom' | 'onevsone' | 'ordinal' | 'sparserandom' | 'ternarycomplete' | numeric matrix 9 | %FitPosterior; % Flag indicating whether to transform scores to posterior probabilities false or 0 (default) | true or 1 10 | %Prior % 'empirical' (default) or 'uniform'. Prior probabilities for each class. 11 | models; 12 | Wmatrix; 13 | end 14 | 15 | methods (Access = public) 16 | function SBLR = SBLR(instanceSet) 17 | %set default parameters 18 | if nargin > 0 19 | SBLR.instanceSet = instanceSet; 20 | end 21 | end 22 | 23 | function SBLR = build(SBLR) 24 | %clear all from previous calls to "build" 25 | SBLR.reset; 26 | numLabels = SBLR.instanceSet.getNumLabels; 27 | uniqueLabels = unique(SBLR.instanceSet.getLabels); 28 | 29 | % ---- Multi-Class ----- % 30 | instances=SBLR.instanceSet.instances; 31 | labels=SBLR.instanceSet.labels; 32 | [~,Nfeat] = size(instances) 33 | size(instances) 34 | %X = instances*instances; 35 | %[w, ix_eff, W, AX] = slr_learning_var2(labels, instances,'nlearn', 100, 'nstep', 10); 36 | [w, ix_eff, W, AXall] = smlr_learning(labels, instances, Nfeat,'nlearn', 0,'gamma0', 0);%,... 37 | %'wdisp_mode', 'off', 'nlearn',10,'mean_mode', 'none', 'scale_mode', 'none');%, ... 38 | %'wdisplay', wdisp_mode, 'wmaxiter', wmaxiter', 'nlearn', Nlearn, 'nstep', Nstep,... 39 | %'amax', AMAX, 'isplot', isplot', 'gamma0', gamma0); 40 | 41 | SBLR.Wmatrix = reshape(w, [Nfeat, 5]); 42 | 43 | end 44 | 45 | function [output, probabilities, ranking] = classifyInstance(SBLR,instance) 46 | %input = instance matrix rows = instances, cols = attributes 47 | %output = predicted class 48 | %probabilities = probability for predicted class 49 | %ranking = propabilities for all classes (e.g. to use with mAP) 50 | 51 | 52 | %TODO:should print an error if 'build' has not been called 53 | % numModels = length(MLSVM.models); 54 | [numinstance, ~] = size(instance); 55 | %scores = zeros(numModels,numinstance); 56 | 57 | [output, Pte] = calc_label(instance, SBLR.Wmatrix); 58 | % ---- One (vs) All -----% 59 | % for i=1:numModels 60 | % %predict using the stored models 61 | % [label,score,cost] = predict(LDA.models{i},instance); 62 | % %libsvmpredict(eye(numinstance,1),instance, LSVM.models{i},'-b 1 -q'); 63 | % %store probability for each class 64 | % scores(i,:) = score(:,1); 65 | % end 66 | 67 | ranking=zeros(5,1)'; 68 | probabilities=0; 69 | end 70 | 71 | function SBLR = reset(SBLR) 72 | %delete all stored models 73 | SBLR.models = {}; 74 | SBLR.Wmatrix=[]; 75 | end 76 | 77 | function configInfo = getConfigInfo(SBLR) 78 | 79 | configInfo = 'SBLR_Classifier (Config info not supported yet)'; 80 | end 81 | 82 | function time = getTime(MLR_Classifier) 83 | time = 0; 84 | end 85 | 86 | end 87 | end 88 | 89 | -------------------------------------------------------------------------------- /+eegtoolkit/+classification/@SMFA/SMFA.m: -------------------------------------------------------------------------------- 1 | classdef SMFA < eegtoolkit.classification.ClassifierBase 2 | 3 | properties (Constant) 4 | 5 | end 6 | 7 | properties (Access = public) 8 | W_SMFA; 9 | PCA_mat; 10 | trainFeat; 11 | NumSubclasses; 12 | SigmaCoeff; 13 | kInt; 14 | kPen; 15 | end 16 | 17 | methods (Access = public) 18 | function SMFA = SMFA(instanceSet,NumS,S,kInt,kPen)%,NumSubclasses,SigmaCoeff,kInt,kPen) 19 | if nargin == 1 20 | SMFA.instanceSet = instanceSet; 21 | else 22 | SMFA.NumSubclasses = NumS; 23 | SMFA.SigmaCoeff = S; 24 | SMFA.kInt = kInt; 25 | SMFA.kPen = kPen; 26 | end 27 | 28 | end 29 | 30 | 31 | function SMFA = build(SMFA) 32 | SMFA.reset(); 33 | data = SMFA.instanceSet.getInstances; 34 | data = data'; 35 | labels = SMFA.instanceSet.getLabels; 36 | unique(labels) 37 | numTrials = length(labels); 38 | 39 | PCA_W=SMFA.pca_func(data); 40 | % PCA_W=eye(size(data,1)); 41 | train_Data=PCA_W'*data; 42 | 43 | % Sigma = SMFA_Classifier.SigmaCoeff; 44 | NSubClasses = SMFA.NumSubclasses; 45 | D=pdist2(train_Data',train_Data'); 46 | % STrain = SGE_GramMatrix(train_Data,'gau',Sigma*mean(D(:))); 47 | STrain = 1-(D/max(D(:))); 48 | 49 | pt=0; 50 | ct=0; 51 | ClustersOfClasses = SGE_SubclassExtract(train_Data,labels,NSubClasses,pt,ct); 52 | [yyTrain,~,~] = SGE_SubclassLabels(ClustersOfClasses,labels); 53 | 54 | 55 | Par.mode = 'SMFA'; 56 | Par.SimilMatrix = STrain; 57 | Par.kInt = SMFA.kInt; 58 | Par.kPen = SMFA.kPen; 59 | dim = min([Par.kPen,size(train_Data,1)]); 60 | 61 | [W,Wp] = SGE_GraphConstruct(yyTrain,Par); 62 | [TransMatrix,~] = SGE_Mapping(train_Data,dim,W,Wp); 63 | SMFA.W_SMFA = TransMatrix; 64 | SMFA.PCA_mat=PCA_W; 65 | mtrainFeat=SGE_Projection(train_Data,1:dim,TransMatrix); 66 | SMFA.trainFeat=mtrainFeat; 67 | % figure,gplotmatrix(mtrainFeat',[],labels) 68 | end 69 | 70 | function [output, probabilities, ranking] = classifyInstance(SMFA,instance) 71 | 72 | N = size(instance,1); 73 | instance = instance'; 74 | 75 | test_Data=SMFA.PCA_mat'*instance; 76 | % test_Data=[ones(1,N);test_Data]; 77 | testFeat=SMFA.W_SMFA'*test_Data; 78 | % output=knnclassify(testFeat',SMFA_Classifier.trainFeat',SMFA_Classifier.instanceSet.getLabels,5,'euclidean'); 79 | X = SMFA.trainFeat; 80 | y = SMFA.instanceSet.getLabels; 81 | 82 | %Nearest Centroid 83 | [~,output] = SGE_Classification(X,y',testFeat,0,'euc'); 84 | 85 | % %SVM Linear 86 | % [~,output] = SGE_Classification(X,y',testFeat,[1,1,1,0,1],'euc'); 87 | 88 | % %SVM RBF 89 | % [~,output] = SGE_Classification(X,y',testFeat,[2,3,2/size(X,1),0,1],'euc'); 90 | 91 | output = output(1,:)'; 92 | probabilities=zeros(N,1); 93 | ranking=zeros(N,1); 94 | % figure,gplotmatrix(testFeat',[],output) 95 | 96 | end 97 | 98 | function SMFA = reset(SMFA) 99 | %delete all stored models 100 | SMFA.W_SMFA=[]; 101 | SMFA.PCA_mat=[]; 102 | SMFA.trainFeat=[]; 103 | end 104 | 105 | function configInfo = getConfigInfo(SMFA) 106 | configInfo = sprintf('MLR_Classifier'); 107 | end 108 | 109 | 110 | function time = getTime(SMFA) 111 | 112 | end 113 | 114 | end 115 | methods (Access = private) 116 | function Proj_W=pca_func(MLR,data) 117 | Proj_W=[]; 118 | meanData=mean(data,2); 119 | data=data-repmat(meanData,1,size(data,2)); 120 | % stdVar=std(data')'; 121 | % staData=(data-repmat(meanData,1,size(data,2)))./repmat(stdVar,1,size(data,2)); 122 | % data=staData; 123 | [V,S]=eig(data'*data); 124 | [sorted_diagS,sorted_rank]=sort(diag(S),'descend'); 125 | sorted_S=diag(sorted_diagS); 126 | V=V(:,sorted_rank); 127 | r=rank(sorted_S); 128 | S1=sorted_S(1:r,1:r); 129 | V1=V(:,1:r); 130 | U=data*V1*S1^(-0.5); 131 | %[sorted_S,sorted_rank]=sort(diag(S),'descend'); 132 | All_energy=sum(diag(S1)); 133 | sorted_energy=diag(S1); 134 | for j=1:r 135 | if (sum(sorted_energy(1:j))/All_energy)>0.99 136 | break 137 | end 138 | end 139 | Proj_W=U(:,1:j); 140 | end 141 | end 142 | end 143 | 144 | -------------------------------------------------------------------------------- /+eegtoolkit/+experiment/@ResultEvaluator/ResultEvaluator.m: -------------------------------------------------------------------------------- 1 | % RESULTEVALUATOR class 2 | % Parses the results of an experiment and calculates various metrics 3 | classdef ResultEvaluator < handle 4 | properties 5 | resultSet; % A 'ResultSet' object containing the results of an experiment 6 | subjectid; % The subject ids corresponding 7 | sessionid; 8 | end 9 | 10 | methods 11 | function RE = ResultEvaluator(resultSet) 12 | if nargin > 0 13 | RE.resultSet = resultSet; 14 | end 15 | end 16 | 17 | function acc = getAccuracy(RE) 18 | conf = RE.resultSet.confusionMatrix; 19 | acc = sum(diag(conf))/sum(sum(conf))*100; 20 | end 21 | 22 | function confusionMatrix = getConfusionMatrix(RE) 23 | %Returns the confusion matrix with labels as the last row 24 | %if you want the confusion matrix without labels then 25 | %access the confusionMatrix property of the resultSet directly 26 | labels = unique(RE.resultSet.getLabels); 27 | confusionMatrix = horzcat(RE.resultSet.confusionMatrix, labels); 28 | end 29 | 30 | function acc = getAccuracyForSession(RE,session) 31 | conf = RE.resultSet.subset(RE.sessionid==session).confusionMatrix; 32 | acc = sum(diag(conf))/sum(sum(conf))*100; 33 | end 34 | 35 | function accuracies = getAccuracyBySession(RE) 36 | unsessions = unique(RE.sessionid); 37 | for i=1:length(unsessions) 38 | accuracies(i) = RE.getAccuracyForSession(unsessions(i)); 39 | end 40 | end 41 | 42 | function accuracies = getAccuracyByLabel(RE) 43 | [rows,~] = size(RE.resultSet.confusionMatrix); 44 | for i=1:rows 45 | accuracies(i) = RE.resultSet.confusionMatrix(i,i)/sum(RE.resultSet.confusionMatrix(i,:))*100; 46 | end 47 | end 48 | 49 | 50 | function ITR = getITR(RE,T) 51 | P = RE.getAccuracy/100; 52 | M = RE.resultSet.getNumLabels; 53 | % fprintf('T = %f',T); 54 | % fprintf('P = %f',P); 55 | % fprintf('M = %f',M); 56 | % fprintf('\n'); 57 | ITR = (log2(M) + P*log2(P)+(1-P)*log2((1-P)/(M-1)))/T; 58 | end 59 | 60 | % function TP = getNumTruePositives(RE) 61 | % conf = RE.resultSet.confusionMatrix; 62 | % TP = diag(conf)'; 63 | % end 64 | % 65 | % function TN = getNumTrueNegatives(RE) 66 | % numInstances = RE.resultSet.getNumInstances; 67 | % FN = RE.getNumFalseNegatives; 68 | % TP = RE.getNumTruePositives; 69 | % FP = RE.getNumFalsePositives; 70 | % TN = numInstances - FN - TP - FP; 71 | % end 72 | % 73 | % function FP = getNumFalsePositives(RE) 74 | % conf = RE.resultSet.confusionMatrix; 75 | % FP = sum(conf') - diag(conf)'; 76 | % end 77 | % 78 | % function FN = getNumFalseNegatives(RE) 79 | % conf = RE.resultSet.confusionMatrix; 80 | % FN = sum(conf) - diag(conf)'; 81 | % end 82 | 83 | end 84 | end 85 | 86 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@CCA/CCA.m: -------------------------------------------------------------------------------- 1 | classdef CCA < eegtoolkit.featextraction.PSDExtractionBase%FeatureExtractionBase 2 | % 3 | % works only on our datasets, for other datasets needs modifications 4 | % 5 | properties (Access = public) 6 | channel; 7 | avgTime; 8 | stimulus_freqs; 9 | FreqSamp; 10 | NumHarm; 11 | allFeatures; 12 | end 13 | methods (Access = public) 14 | function CCA = CCA(sti_f,chans,fs,numH) 15 | if ( nargin ~= 4 ) 16 | error('It is needed to define the simulus freqs, the channels, frequency sampling and number of harmonics'); 17 | else 18 | CCA.stimulus_freqs = sti_f; 19 | CCA.channel = chans; 20 | CCA.FreqSamp = fs; 21 | CCA.NumHarm = numH; 22 | CCA.allFeatures = 0; 23 | end 24 | end 25 | 26 | function extract(CCA) 27 | sti_f = CCA.stimulus_freqs; 28 | mLen=size(CCA.trials{1}.signal,2); 29 | refSignals=CCA.ck_signalTrans(sti_f,mLen,CCA.FreqSamp,CCA.NumHarm); 30 | NumStim = size(refSignals,3); 31 | numTrials = length(CCA.trials); 32 | for i=1:numTrials 33 | data = CCA.trials{i}.signal(CCA.channel,:); 34 | if(CCA.allFeatures == 1) 35 | features=NaN*ones(NumStim,min(rank(data),CCA.NumHarm*2)); 36 | for j=1:NumStim 37 | [wx1,wy1,r1] = canoncorr(data',refSignals(:,:,j)'); 38 | features(j,:) = r1; 39 | end 40 | tempfeatures = features(1,:); 41 | for j=2:NumStim 42 | tempfeatures = horzcat(tempfeatures,features(j,:)); 43 | end 44 | instances(i,:) = tempfeatures(:); 45 | labels(i,1) = floor(CCA.trials{i}.label); 46 | else 47 | features=NaN*ones(NumStim,1); 48 | for j=1:NumStim 49 | % [wx1,wy1,r1] = CCA.cca(data,refSignals(:,:,j)); 50 | [wx1,wy1,r1] = canoncorr(data',refSignals(:,:,j)'); 51 | features(j) = max(r1); 52 | end 53 | instances(i,:) = features(:); 54 | labels(i,1) = floor(CCA.trials{i}.label); 55 | end 56 | end 57 | % unique(labels) 58 | if (sum(unique(labels)) == 41) 59 | labels(labels==6)=1; 60 | labels(labels==7)=2; 61 | labels(labels==8)=3; 62 | labels(labels==9)=4; 63 | labels(labels==11)=5; 64 | end 65 | % unique(labels) 66 | CCA.instanceSet = eegtoolkit.util.InstanceSet(instances, labels); 67 | end 68 | 69 | function configInfo = getConfigInfo(CCA) 70 | configInfo = sprintf('CCA'); 71 | end 72 | 73 | % function [Wx, Wy, r] = cca(CCA,X,Y) 74 | % 75 | % % CCA calculate canonical correlations 76 | % % 77 | % % [Wx Wy r] = cca(X,Y) where Wx and Wy contains the canonical correlation 78 | % 79 | % % vectors as columns and r is a vector with corresponding canonical 80 | % % correlations. The correlations are sorted in descending order. X and Y 81 | % % are matrices where each column is a sample. Hence, X and Y must have 82 | % % the same number of columns. 83 | % % 84 | % % Example: If X is M*K and Y is N*K there are L=MIN(M,N) solutions. Wx is 85 | % % then M*L, Wy is N*L and r is L*1. 86 | % % 87 | % % 88 | % % ?? 2000 Magnus Borga, Link?pings universitet 89 | % 90 | % % --- Calculate covariance matrices ---?????????????? 91 | % 92 | % z = [X;Y]; 93 | % C = cov(z.'); 94 | % sx = size(X,1); %X??????(??), 95 | % sy = size(Y,1); 96 | % Cxx = C(1:sx, 1:sx) + 10^(-8)*eye(sx); 97 | % Cxy = C(1:sx, sx+1:sx+sy); 98 | % Cyx = Cxy'; 99 | % Cyy = C(sx+1:sx+sy, sx+1:sx+sy) + 10^(-8)*eye(sy);%eye()???????? 100 | % invCyy = inv(Cyy); 101 | % 102 | % % --- Calcualte Wx and r --- 103 | % 104 | % [Wx,r] = eig(inv(Cxx)*Cxy*invCyy*Cyx); % Basis in X eig???????????? 105 | % r = sqrt(real(r)); % Canonical correlations 106 | % 107 | % % --- Sort correlations --- 108 | % 109 | % V = fliplr(Wx); % reverse order of eigenvectors??????????????????????i??????????i?????? 110 | % r = flipud(diag(r)); % extract eigenvalues and reverse their order 111 | % [r,I]= sort((real(r))); % sort reversed eigenvalues in ascending order 112 | % r = flipud(r); % restore sorted eigenvalues into descending order?????????????? 113 | % for j = 1:length(I) 114 | % Wx(:,j) = V(:,I(j)); % sort reversed eigenvectors in ascending order 115 | % end 116 | % Wx = fliplr(Wx); % restore sorted eigenvectors into descending order 117 | % 118 | % % --- Calcualte Wy --- 119 | % 120 | % Wy = invCyy*Cyx*Wx; % Basis in Y 121 | % % Wy = Wy./repmat(sqrt(sum(abs(Wy).^2)),sy,1); % Normalize Wy 122 | % 123 | % end 124 | 125 | function refSignal=ck_signalTrans(CCA,f,mLen,FreqSamp,NumHarm) 126 | 127 | p=mLen;%1250; 128 | fs=FreqSamp;%250; 129 | TP=1/fs:1/fs:p/fs; 130 | for j=1:length(f) 131 | tempComp=[]; 132 | for k=1:NumHarm 133 | Sinh1=sin(2*pi*k*f(j)*TP); 134 | Cosh1=cos(2*pi*k*f(j)*TP); 135 | tempComp = [tempComp; Sinh1;Cosh1;]; 136 | end 137 | refSignal(:,:,j)=tempComp; 138 | end 139 | end 140 | function time = getTime(CCA) 141 | time = CCA.avgTime; 142 | end 143 | end 144 | 145 | end 146 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@DWT/DWT.m: -------------------------------------------------------------------------------- 1 | classdef DWT < eegtoolkit.featextraction.FeatureExtractionBase 2 | 3 | properties (Access = public) 4 | channel; 5 | seconds; 6 | levelWT; 7 | WavFamily; 8 | avgTime; 9 | end 10 | 11 | methods (Access = public) 12 | function mDWT = DWT(trials, seconds, channel,levWT,WavFam) 13 | if nargin == 0 14 | mDWT.seconds = 0; 15 | mDWT.channel = 1; 16 | mDWT.levelWT = 5; 17 | mDWT.WavFamily = 'db1'; 18 | elseif nargin == 1 19 | mDWT.trials = trials; 20 | mDWT.seconds = 0; 21 | mDWT.channel = 1; 22 | mDWT.levelWT = 5; 23 | mDWT.WavFamily = 'db1'; 24 | elseif nargin == 2 25 | mDWT.trials = trials; 26 | mDWT.channel = 1; 27 | mDWT.seconds = seconds; 28 | mDWT.levelWT = 5; 29 | mDWT.WavFamily = 'db1'; 30 | elseif nargin == 3 31 | mDWT.trials = trials; 32 | mDWT.channel = channel; 33 | mDWT.seconds = seconds; 34 | mDWT.levelWT = 5; 35 | mDWT.WavFamily = 'db1'; 36 | elseif nargin == 4 37 | mDWT.trials = trials; 38 | mDWT.channel = channel; 39 | mDWT.seconds = seconds; 40 | mDWT.levelWT = levWT; 41 | mDWT.WavFamily = 'db1'; 42 | elseif nargin ==5 43 | mDWT.trials = trials; 44 | mDWT.channel = channel; 45 | mDWT.seconds = seconds; 46 | mDWT.levelWT = levWT; 47 | mDWT.WavFamily = WavFam; 48 | else 49 | error('invalid number of arguments'); 50 | end 51 | mDWT.avgTime = 0; 52 | end 53 | 54 | function extract(mDWT) 55 | if length(mDWT.seconds)==1 56 | numsamples = mDWT.trials{1}.samplingRate * mDWT.seconds; 57 | if (numsamples == 0) 58 | numsamples = size(mDWT.trials{1}.signal(mDWT.channel,:),2); 59 | end 60 | numTrials = length(mDWT.trials); 61 | 62 | [C L] = wavedec(mDWT.trials{1}.signal(mDWT.channel, 1:numsamples),mDWT.levelWT,mDWT.WavFamily); 63 | instances = zeros(numTrials, length(C)); 64 | labels = zeros(numTrials,1); 65 | elseif length(mDWT.seconds) == 2 66 | sampleA = mDWT.trials{1}.samplingRate * mDWT.seconds(1) + 1; 67 | sampleB = mDWT.trials{1}.samplingRate * mDWT.seconds(2); 68 | numTrials = length(mDWT.trials); 69 | [C L] = wavedec(mDWT.trials{1}.signal(mDWT.channel, sampleA:sampleB),mDWT.levelWT,mDWT.WavFamily); 70 | instances = zeros(numTrials, length(C)); 71 | labels = zeros(numTrials,1); 72 | else 73 | error('invalid seconds parameter'); 74 | end 75 | tic 76 | for i=1:numTrials 77 | if length(mDWT.seconds) == 1 78 | numsamples = mDWT.trials{i}.samplingRate * mDWT.seconds; 79 | if(numsamples == 0) 80 | y = mDWT.trials{i}.signal(mDWT.channel,:); 81 | else 82 | y = mDWT.trials{i}.signal(mDWT.channel, 1:numsamples); 83 | end 84 | % zero padding to nearest power of 2 85 | if isa(mDWT.filter,'dfilt.df2sos') 86 | y = filter(mDWT.filter,y); 87 | elseif isa(mDWT.filter,'dfilt.dffir') 88 | y = filtfilt(mDWT.filter.Numerator,1,y); 89 | end 90 | [C L] = wavedec(y,mDWT.levelWT,mDWT.WavFamily);%pwelch(y,[],[],512,mDWT.trials{i}.samplingRate,'onesided'); 91 | elseif length(mDWT.seconds) == 2 92 | sampleA = mDWT.trials{i}.samplingRate * mDWT.seconds(1) + 1; 93 | sampleB = mDWT.trials{i}.samplingRate * mDWT.seconds(2); 94 | y = mDWT.trials{i}.signal(mDWT.channel,sampleA:sampleB); 95 | if isa(mDWT.filter,'dfilt.df2sos') || isa(mDWT.filter,'dfilt.df2') 96 | y = filter(mDWT.filter,y); 97 | elseif isa(mDWT.filter,'dfilt.dffir') 98 | y = filtfilt(mDWT.filter.Numerator,1,y); 99 | end 100 | [C L] = wavedec(y,mDWT.levelWT,mDWT.WavFamily);%pwelch(y,[],[],512,mDWT.trials{i}.samplingRate,'onesided'); 101 | else 102 | error('invalid seconds parameter'); 103 | end 104 | instances(i,:) = C; 105 | labels(i,1) = floor(mDWT.trials{i}.label); 106 | end 107 | mDWT.avgTime = toc/numTrials; 108 | mDWT.instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 109 | end 110 | 111 | function configInfo = getConfigInfo(mDWT) 112 | configInfo = sprintf('DWT\tchannel:%d\tseconds:%d\tlevelWT:%d\tWavFamily:%s',mDWT.channel,mDWT.seconds,mDWT.levelWT,mDWT.WavFamily); 113 | end 114 | 115 | 116 | function time = getTime(mDWT) 117 | time = mDWT.avgTime; 118 | end 119 | end 120 | 121 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@ERRPFeatures/ERRPFeatures.m: -------------------------------------------------------------------------------- 1 | classdef ERRPFeatures < eegtoolkit.featextraction.PSDExtractionBase%FeatureExtractionBase 2 | properties (Access = public) 3 | channel; 4 | avgTime; 5 | % downSampleFactor; 6 | end 7 | methods (Access = public) 8 | function ERRP = ERRPFeatures() 9 | % ERRP.downSampleFactor = 8; 10 | ERRP.channel = 1; 11 | end 12 | 13 | function extract(ERRP) 14 | 15 | numTrials = length(ERRP.trials); 16 | [~,numSamples] = size(ERRP.trials{1}.signal(ERRP.channel,:)); 17 | % numFeatures = floor(numSamples/ERRP.downSampleFactor); 18 | instances = zeros(numTrials,numSamples); 19 | labels = zeros(numTrials,1); 20 | for i=1:numTrials 21 | instances(i,:) = ERRP.trials{i}.signal(ERRP.channel,:); 22 | labels(i) = ERRP.trials{i}.label; 23 | end 24 | ERRP.instanceSet = eegtoolkit.util.InstanceSet(instances, labels); 25 | end 26 | 27 | function configInfo = getConfigInfo(ERRP) 28 | configInfo = sprintf('ERRP features'); 29 | end 30 | 31 | function time = getTime(ERRP) 32 | time = ERRP.avgTime; 33 | end 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@FFT/FFT.m: -------------------------------------------------------------------------------- 1 | classdef FFT < eegtoolkit.featextraction.FeatureExtractionBase 2 | 3 | properties (Access = public) 4 | channel; 5 | seconds; 6 | nfft; 7 | avgTime; 8 | end 9 | 10 | methods (Access = public) 11 | function mFFT = FFT(trials, seconds, channel,nfft) 12 | if nargin == 0 13 | mFFT.seconds = 0; 14 | mFFT.channel = 1; 15 | mFFT.nfft = 512; 16 | elseif nargin == 1 17 | mFFT.trials = trials; 18 | mFFT.seconds = 0; 19 | mFFT.channel = 1; 20 | mFFT.nfft = 512; 21 | elseif nargin == 2 22 | mFFT.trials = trials; 23 | mFFT.channel = 1; 24 | mFFT.seconds = seconds; 25 | mFFT.nfft = 512; 26 | elseif nargin == 3 27 | mFFT.trials = trials; 28 | mFFT.channel = channel; 29 | mFFT.seconds = seconds; 30 | mFFT.nfft = 512; 31 | elseif nargin == 4 32 | mFFT.trials = trials; 33 | mFFT.channel = channel; 34 | mFFT.seconds = seconds; 35 | mFFT.nfft = nfft; 36 | error('invalid number of arguments'); 37 | end 38 | end 39 | 40 | function extract(mFFT) 41 | NUM_FEATURES = mFFT.nfft/2+1; 42 | numTrials = length(mFFT.trials); 43 | instances = zeros(numTrials, NUM_FEATURES); 44 | labels = zeros(numTrials,1); 45 | tic 46 | for i=1:numTrials 47 | if length(mFFT.seconds) == 1 48 | numsamples = mFFT.trials{i}.samplingRate * mFFT.seconds; 49 | if(numsamples == 0) 50 | y = mFFT.trials{i}.signal(mFFT.channel,:); 51 | else 52 | y = mFFT.trials{i}.signal(mFFT.channel, 1:numsamples); 53 | end 54 | elseif length(mFFT.seconds) == 2 55 | sampleA = mFFT.trials{i}.samplingRate * mFFT.seconds(1) + 1; 56 | sampleB = mFFT.trials{i}.samplingRate * mFFT.seconds(2); 57 | y = mFFT.trials{i}.signal(mFFT.channel, sampleA:sampleB); 58 | else 59 | 60 | error ('invalid seconds parameter'); 61 | end 62 | if isa(mFFT.filter,'dfilt.df2sos') || isa(mFFT.filter,'dfilt.df2') 63 | y = filter(mFFT.filter,y); 64 | elseif isa(mFFT.filter,'dfilt.dffir') 65 | y = filtfilt(mFFT.filter.Numerator,1,y); 66 | end 67 | %Y = fft(y,(NUM_FEATURES-1)*2)/((NUM_FEATURES-1)*2); 68 | %f = Fs/2*linspace(0,1,NFFT/2+1); 69 | %pyy = abs(Y(1:(NUM_FEATURES-1)*2/2+1)).^2; 70 | [pyy,f] = periodogram(y,[],mFFT.nfft,mFFT.trials{i}.samplingRate); 71 | instances(i,:) = pyy; 72 | labels(i,1) = floor(mFFT.trials{i}.label); 73 | end 74 | mFFT.avgTime = toc/numTrials; 75 | mFFT.instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 76 | end 77 | 78 | function configInfo = getConfigInfo(mFFT) 79 | configInfo = sprintf('FFT\tchannel:%d\tseconds:%d\tnfft:%d',mFFT.channel,mFFT.seconds,mFFT.nfft); 80 | end 81 | 82 | 83 | function time = getTime(mFFT) 84 | time = mFFT.avgTime; 85 | end 86 | end 87 | 88 | end 89 | 90 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@FeatureExtractionBase/FeatureExtractionBase.m: -------------------------------------------------------------------------------- 1 | classdef (Abstract) FeatureExtractionBase < handle 2 | %Base class for a feature transformer 3 | %For writing your own FeatureTransformer extend this class and 4 | %implement the 'transform' function 5 | properties (Access = public) 6 | instanceSet; % Output: The dataset 7 | trials;% Input: The trial signals 8 | filter; 9 | end 10 | 11 | methods (Abstract = true) 12 | obj = extract(obj); 13 | configInfo = getConfigInfo(obj); 14 | time = getTime(obj); 15 | end 16 | 17 | methods (Access = public) 18 | function instances = getInstances(obj) 19 | %Get the instances (no class labels) 20 | instances = obj.instanceSet.getInstances; 21 | end 22 | function labels = getLabels(obj) 23 | %Get the labels 24 | labels = obj.instanceSet.getLabels; 25 | end 26 | 27 | function dataset = getDataset(obj) 28 | % same with getInstances but includes the labels as the last 29 | % row 30 | dataset = obj.instanceSet.getDataset; 31 | end 32 | 33 | function instanceSet = getInstanceSet(obj) 34 | % Get the dataset as an 'InstanceSet' class object 35 | instanceSet = obj.instanceSet; 36 | end 37 | function writeCSV(obj, csvname) 38 | % write the dataset to a csv file 39 | % Example: 40 | % obj.writeCSV('data.csv'); 41 | obj.instanceSet.writeCSV(csvname); 42 | end 43 | function writeArff(obj, fname) 44 | % write the dataset to a weka-readable file (arff) 45 | % Caution: filename without extension 46 | % Example: 47 | % obj.writeArff('data') 48 | obj.instanceSet.writeArff(fname); 49 | end 50 | end 51 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@Goertzel/Goertzel.m: -------------------------------------------------------------------------------- 1 | classdef Goertzel < eegtoolkit.featextraction.FeatureExtractionBase 2 | %Computes the psd using the welch method 3 | %Usage: 4 | % session = eegtoolkit.util.Session(); 5 | % session.loadSubject(1); 6 | % pwt = ssveptolkit.transform.PWelchTransformer(session.trials); 7 | %Specify the channel to be used (default = 126) 8 | % pwt.channel = 150; 9 | %Specify the number of seconds to be used (default = 0, use all signal) 10 | % pwt.seconds = 3; 11 | %Specify the nfft parameter (default = 512, computes 257 features) 12 | % pwt.nfft = 512; 13 | %Transform the signal 14 | % pwt.transform(); 15 | properties (Access = public) 16 | channel; 17 | seconds; 18 | nfft; 19 | pff; 20 | avgTime; 21 | end 22 | 23 | methods (Access = public) 24 | function GT = Goertzel(trials, seconds, channel, nfft) 25 | % if ~iscell(trials) 26 | % error('trials must be cell array of Trial object'); 27 | % end 28 | if nargin == 0 29 | GT.trials = {}; 30 | GT.seconds = 0; 31 | GT.channel = 1; 32 | GT.nfft = 512; 33 | elseif nargin == 1 34 | GT.trials = trials; 35 | GT.seconds = 0; 36 | GT.channel = 1; 37 | GT.nfft = 512; 38 | elseif nargin == 2 39 | GT.trials = trials; 40 | GT.channel = 1; 41 | GT.seconds = seconds; 42 | GT.nfft = 512; 43 | elseif nargin == 3 44 | GT.trials = trials; 45 | GT.channel = channel; 46 | GT.seconds = seconds; 47 | GT.nfft = 512; 48 | elseif nargin == 4 49 | GT.trials = trials; 50 | GT.channel = channel; 51 | GT.seconds = seconds; 52 | GT.nfft = nfft; 53 | else 54 | % error('invalid number of arguments'); 55 | end 56 | end 57 | 58 | function extract(GT) 59 | 60 | numFeatures = length(GT.nfft); 61 | numTrials = length(GT.trials); 62 | instances = zeros(numTrials, numFeatures); 63 | labels = zeros(numTrials,1); 64 | % PWT.instances = zeros(numTrials, numFeatures); 65 | % PWT.labels = zeros(numTrials,1); 66 | tic; 67 | for i=1:numTrials 68 | numsamples = GT.trials{i}.samplingRate * GT.seconds; 69 | if(numsamples == 0) 70 | y = GT.trials{i}.signal(GT.channel,:); 71 | else 72 | y = GT.trials{i}.signal(GT.channel, 1:numsamples); 73 | end 74 | % N = (length(y)+1)/2; 75 | % f = (PWT.trials{i}.samplingRate/2)/N*(0:N-1); 76 | % indxs = find(f>1.2e3 & f<1.3e3); 77 | % X = goertzel(x,indxs); 78 | freq_indices = round(GT.nfft/GT.trials{i}.samplingRate*length(y)) + 1; 79 | % ff = [0:1/512:1/2]*250; 80 | % freq_indices = round(ff/PWT.trials{i}.samplingRate*length(y))+1 81 | dft_data = goertzel(y,freq_indices);%goertzel(y,freq_indices); general_shortened 82 | instances(i,:) = abs(dft_data) ./ length(y); 83 | labels(i,1) = floor(GT.trials{i}.label); 84 | end 85 | GT.avgTime = toc/numTrials; 86 | GT.instanceSet = eegtoolkit.util.InstanceSet(instances, labels); 87 | GT.pff = GT.nfft; 88 | end 89 | 90 | function configInfo = getConfigInfo(GT) 91 | configInfo = sprintf('Goertzel\tchannel:%d\tseconds:%d\tfreq range:%.3f to %.3f',GT.channel,GT.seconds,GT.nfft(1),GT.nfft(end)); 92 | end 93 | 94 | function time = getTime(GT) 95 | time = GT.avgTime; 96 | end 97 | end 98 | 99 | end 100 | 101 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@L1MCCA/L1MCCA.m: -------------------------------------------------------------------------------- 1 | classdef L1MCCA < eegtoolkit.featextraction.PSDExtractionBase%FeatureExtractionBase 2 | % 3 | % works only on our datasets, for other datasets needs modifications 4 | % 5 | properties (Access = public) 6 | channel; 7 | avgTime; 8 | stimulus_freqs; 9 | FreqSamp; 10 | NumHarm; 11 | end 12 | methods (Access = public) 13 | function L1MCCA = L1MCCA() 14 | end 15 | 16 | function extract(L1MCCA) 17 | L1MCCA.instanceSet = eegtoolkit.util.L1MCCAInstanceSet(L1MCCA.trials); 18 | end 19 | 20 | function configInfo = getConfigInfo(L1MCCA) 21 | configInfo = sprintf('L1MCCA'); 22 | end 23 | function time = getTime(L1MCCA) 24 | time = 0; 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@MLR_Transf/MLR_Transf.m: -------------------------------------------------------------------------------- 1 | classdef MLR_Transf < eegtoolkit.featextraction.PSDExtractionBase%FeatureExtractionBase 2 | %Computes the psd using the welch method 3 | %Usage: 4 | % session = eegtoolkit.util.Session(); 5 | % session.loadSubject(1); 6 | % pwt = ssveptolkit.transform.PWelchTransformer(session.trials); 7 | %Specify the channel to be used (default = 126) 8 | % pwt.channel = 150; 9 | %Specify the number of seconds to be used (default = 0, use all signal) 10 | % pwt.seconds = 3; 11 | %Specify the nfft parameter (default = 512, computes 257 features) 12 | % pwt.nfft = 512; 13 | %Transform the signal 14 | % pwt.transform(); 15 | properties (Access = public) 16 | channel; 17 | avgTime; 18 | end 19 | methods (Access = public) 20 | function PWT = MLR_Transf(chns) 21 | if nargin == 1 22 | PWT.trials = {}; 23 | PWT.channel = [1:length(chns)]; 24 | else 25 | error('invalid number of arguments'); 26 | end 27 | end 28 | 29 | function extract(PWT) 30 | 31 | numTrials = length(PWT.trials); 32 | [m n]=size(PWT.trials{1}.signal(PWT.channel,:)); 33 | data = zeros(m,n,numTrials); 34 | labels = zeros(numTrials,1); 35 | 36 | for i = 1 : numTrials % 37 | for j=1:m 38 | data(j,:,i) = PWT.trials{i}.signal(j,:);%data(j,:,i)./norm(data(j,:,i)); 39 | data(j,:,i) = (data(j,:,i) - mean(data(j,:,i)))./std(data(j,:,i)); 40 | % data(j,:,i) = data(j,:,i)./norm(data(j,:,i)); 41 | end% 42 | labels(i) = floor(PWT.trials{i}.label); 43 | end 44 | %data= reshape(data,m*n,size(data,3)); 45 | for i=1:numTrials 46 | newData(i,:) = [data(1,:,i) data(2,:,i)]; 47 | end 48 | % MeanTrainData=mean(data,2); 49 | % data=data-repmat(MeanTrainData,1,numTrials); 50 | data = newData; 51 | PWT.instanceSet = eegtoolkit.util.InstanceSet(data, labels); 52 | end 53 | 54 | function configInfo = getConfigInfo(PWT) 55 | configInfo = sprintf('MLR_Transf_rawdata'); 56 | end 57 | 58 | function time = getTime(PWT) 59 | time = PWT.avgTime; 60 | end 61 | end 62 | 63 | end 64 | 65 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@PSDExtractionBase/PSDExtractionBase.m: -------------------------------------------------------------------------------- 1 | classdef (Abstract) PSDExtractionBase < eegtoolkit.featextraction.FeatureExtractionBase 2 | %Base class for a feature transformer based on power spectral density 3 | %estimates 4 | properties (Access = public) 5 | pff; % The frequencies of the spectrum 6 | end 7 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@PWelch/PWelch.m: -------------------------------------------------------------------------------- 1 | classdef PWelch < eegtoolkit.featextraction.PSDExtractionBase 2 | %Computes the psd using the welch method 3 | %Usage: 4 | % session = eegtoolkit.util.Session(); 5 | % session.loadSubject(1); 6 | % pwt = ssveptolkit.transform.PWelchTransformer(session.trials); 7 | %Specify the channel to be used (default = 126) 8 | % pwt.channel = 150; 9 | %Specify the number of seconds to be used (default = 0, use all signal) 10 | % pwt.seconds = 3; 11 | %Specify the nfft parameter (default = 512, computes 257 features) 12 | % pwt.nfft = 512; 13 | %Transform the signal 14 | % pwt.transform(); 15 | properties (Access = public) 16 | channel; 17 | seconds; 18 | nfft; 19 | avgTime; 20 | end 21 | 22 | methods (Access = public) 23 | function PW = PWelch(trials, seconds, channel, nfft) 24 | % if ~iscell(trials) 25 | % error('trials must be cell array of Trial object'); 26 | % end 27 | if nargin == 0 28 | PW.trials = {}; 29 | PW.seconds = 0; 30 | PW.channel = 1; 31 | PW.nfft = 512; 32 | elseif nargin == 1 33 | PW.trials = trials; 34 | PW.seconds = 0; 35 | PW.channel = 1; 36 | PW.nfft = 512; 37 | elseif nargin == 2 38 | PW.trials = trials; 39 | PW.channel = 1; 40 | PW.seconds = seconds; 41 | PW.nfft = 512; 42 | elseif nargin == 3 43 | PW.trials = trials; 44 | PW.channel = channel; 45 | PW.seconds = seconds; 46 | PW.nfft = 512; 47 | elseif nargin == 4 48 | PW.trials = trials; 49 | PW.channel = channel; 50 | PW.seconds = seconds; 51 | PW.nfft = nfft; 52 | else 53 | % error('invalid number of arguments'); 54 | end 55 | end 56 | 57 | function extract(PW) 58 | if length(PW.nfft)==1 59 | numFeatures = PW.nfft/2+1; 60 | else 61 | numFeatures = length(PW.nfft); 62 | end 63 | numTrials = length(PW.trials); 64 | instances = zeros(numTrials, numFeatures); 65 | labels = zeros(numTrials,1); 66 | % PWT.instances = zeros(numTrials, numFeatures); 67 | % PWT.labels = zeros(numTrials,1); 68 | tic; 69 | for i=1:numTrials 70 | if length(PW.seconds) == 1 71 | numsamples = PW.trials{i}.samplingRate * PW.seconds; 72 | if(numsamples == 0) 73 | y = PW.trials{i}.signal(PW.channel,:); 74 | else 75 | y = PW.trials{i}.signal(PW.channel, 1:numsamples); 76 | end 77 | elseif length(PW.seconds) == 2 78 | sampleA = PW.trials{i}.samplingRate*PW.seconds(1) +1; 79 | sampleB = PW.trials{i}.samplingRate*PW.seconds(2); 80 | y = PW.trials{i}.signal(PW.channel, sampleA:sampleB); 81 | else 82 | error('invalid seconds parameter'); 83 | end 84 | if isa(PW.filter,'dfilt.df2sos') || isa(PW.filter,'dfilt.df2') 85 | y = filter(PW.filter,y); 86 | elseif isa(PW.filter,'dfilt.dffir') 87 | y = filtfilt(PW.filter.Numerator,1,y); 88 | end 89 | if length(PW.nfft>1) 90 | [pxx, pff]=pwelch(y,[],[],PW.nfft,PW.trials{i}.samplingRate); 91 | else 92 | [pxx, pff]=pwelch(y,[],[],PW.nfft,PW.trials{i}.samplingRate,'onesided'); 93 | end 94 | instances(i,:) = pxx; 95 | labels(i,1) = floor(PW.trials{i}.label); 96 | end 97 | total = toc; 98 | PW.avgTime = total/numTrials; 99 | PW.instanceSet = eegtoolkit.util.InstanceSet(instances, labels); 100 | PW.pff = pff; 101 | end 102 | 103 | function configInfo = getConfigInfo(PW) 104 | if length(PW.nfft)>1 105 | configInfo = sprintf('PWelch\tchannel:%d\tseconds:%d\t freq range:%.3f to %.3f',PW.channel,PW.seconds,PW.nfft(1),PW.nfft(end)); 106 | else 107 | configInfo = sprintf('PWelch\tchannel:%d\tseconds:%d\tnfft:%d',PW.channel,PW.seconds,PW.nfft); 108 | end 109 | end 110 | 111 | function time = getTime(PW) 112 | time = PW.avgTime; 113 | end 114 | end 115 | 116 | end 117 | 118 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@PWelchExperimental/PWelchExperimental.m: -------------------------------------------------------------------------------- 1 | classdef PWelchExperimental < eegtoolkit.featextraction.FeatureExtractionBase 2 | %Computes the psd using the welch method 3 | %Usage: 4 | % session = eegtoolkit.util.Session(); 5 | % session.loadSubject(1); 6 | % pwt = ssveptolkit.transform.PWelchTransformer(session.trials); 7 | %Specify the channel to be used (default = 126) 8 | % pwt.channel = 150; 9 | %Specify the number of seconds to be used (default = 0, use all signal) 10 | % pwt.seconds = 3; 11 | %Specify the nfft parameter (default = 512, computes 257 features) 12 | % pwt.nfft = 512; 13 | %Transform the signal 14 | % pwt.transform(); 15 | properties (Access = public) 16 | channel; 17 | seconds; 18 | nfft; 19 | pff; 20 | win_len; 21 | over_len; 22 | avgTime; 23 | end 24 | 25 | methods (Access = public) 26 | function PWT = PWelchExperimental(trials, seconds, channel, nfft,win_len,over_len) 27 | % if ~iscell(trials) 28 | % error('trials must be cell array of Trial object'); 29 | % end 30 | if nargin == 0 31 | PWT.trials = {}; 32 | PWT.seconds = 0; 33 | PWT.channel = 1; 34 | PWT.nfft = 512; 35 | PWT.win_len=[]; 36 | PWT.over_len=[]; 37 | elseif nargin == 1 38 | PWT.trials = trials; 39 | PWT.seconds = 0; 40 | PWT.channel = 1; 41 | PWT.nfft = 512; 42 | PWT.win_len=[]; 43 | PWT.over_len=[]; 44 | elseif nargin == 2 45 | PWT.trials = trials; 46 | PWT.channel = 1; 47 | PWT.seconds = seconds; 48 | PWT.nfft = 512; 49 | PWT.win_len=[]; 50 | PWT.over_len=[]; 51 | elseif nargin == 3 52 | PWT.trials = trials; 53 | PWT.channel = channel; 54 | PWT.seconds = seconds; 55 | PWT.nfft = 512; 56 | PWT.win_len=[]; 57 | PWT.over_len=[]; 58 | elseif nargin == 4 59 | PWT.trials = trials; 60 | PWT.channel = channel; 61 | PWT.seconds = seconds; 62 | PWT.nfft = nfft; 63 | PWT.win_len=[]; 64 | PWT.over_len=[]; 65 | elseif nargin == 5 66 | PWT.trials = trials; 67 | PWT.channel = channel; 68 | PWT.seconds = seconds; 69 | PWT.nfft = nfft; 70 | PWT.win_len=win_len; 71 | PWT.over_len=[]; 72 | elseif nargin == 6 73 | PWT.trials = trials; 74 | PWT.channel = channel; 75 | PWT.seconds = seconds; 76 | PWT.nfft = nfft; 77 | PWT.win_len=win_len; 78 | PWT.over_len=over_len; 79 | else 80 | % error('invalid number of arguments'); 81 | end 82 | end 83 | 84 | function extract(PWT) 85 | if length(PWT.nfft)==1 86 | numFeatures = PWT.nfft/2+1; 87 | else 88 | numFeatures = length(PWT.nfft); 89 | end 90 | numTrials = length(PWT.trials); 91 | instances = zeros(numTrials, numFeatures); 92 | labels = zeros(numTrials,1); 93 | % PWT.instances = zeros(numTrials, numFeatures); 94 | % PWT.labels = zeros(numTrials,1); 95 | tic; 96 | for i=1:numTrials 97 | numsamples = PWT.trials{i}.samplingRate * PWT.seconds; 98 | if(numsamples == 0) 99 | y = PWT.trials{i}.signal(PWT.channel,:); 100 | else 101 | y = PWT.trials{i}.signal(PWT.channel, 1:numsamples); 102 | end 103 | % if length(PWT.nfft>1) 104 | % [pxx, pff]=pwelch(y,[],[],PWT.nfft,PWT.trials{i}.samplingRate); 105 | % else 106 | [pxx, pff]=pwelch(y,PWT.win_len,round(PWT.over_len*PWT.win_len),PWT.nfft,PWT.trials{i}.samplingRate,'onesided'); 107 | % end 108 | %xv = [1 -2 1 zeros(1,length(pxx)-3)]; 109 | % xv = [1/5 1/5 1/5 1/5 1/5 zeros(1,length(pxx)-5)]; 110 | % A = gallery('circul',xv); 111 | instances(i,:) = pxx; 112 | labels(i,1) = floor(PWT.trials{i}.label); 113 | end 114 | PWT.avgTime = toc/numTrials; 115 | PWT.instanceSet = eegtoolkit.util.InstanceSet(instances, labels); 116 | PWT.pff = pff; 117 | end 118 | 119 | function configInfo = getConfigInfo(PWT) 120 | if length(PWT.nfft)>1 121 | configInfo = sprintf('PWelchExperimental\tchannel:%d\tseconds:%d\t freq range:%.3f to %.3f',PWT.channel,PWT.seconds,PWT.nfft(1),PWT.nfft(end)); 122 | else 123 | configInfo = sprintf('PWelchExperimental\tchannel:%d\tseconds:%d\tnfft:%d',PWT.channel,PWT.seconds,PWT.nfft); 124 | end 125 | end 126 | 127 | function time = getTime(PWT) 128 | time = PWT.avgTime; 129 | end 130 | end 131 | 132 | end 133 | 134 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@PYAR/PYAR.m: -------------------------------------------------------------------------------- 1 | classdef PYAR < eegtoolkit.featextraction.FeatureExtractionBase 2 | 3 | properties (Access = public) 4 | channel; 5 | seconds; 6 | order; 7 | nfft; 8 | avgTime; 9 | end 10 | 11 | methods (Access = public) 12 | function mAR = PYAR(trials, seconds, channel,m_ord, nfft) 13 | if nargin == 0 14 | mAR.seconds = 0; 15 | mAR.channel = 1; 16 | mAR.order = 20; 17 | mAR.nfft = 512; 18 | elseif nargin == 1 19 | mAR.trials = trials; 20 | mAR.seconds = 0; 21 | mAR.channel = 1; 22 | mAR.order = 20; 23 | mAR.nfft = 512; 24 | elseif nargin == 2 25 | mAR.trials = trials; 26 | mAR.channel = 1; 27 | mAR.seconds = seconds; 28 | mAR.order = 20; 29 | mAR.nfft = 512; 30 | elseif nargin == 3 31 | mAR.trials = trials; 32 | mAR.channel = channel; 33 | mAR.seconds = seconds; 34 | mAR.order=20; 35 | mAR.nfft = 512; 36 | elseif nargin == 4 37 | mAR.trials = trials; 38 | mAR.channel = channel; 39 | mAR.seconds = seconds; 40 | mAR.order = m_ord; 41 | mAR.nfft = 512; 42 | elseif nargin == 5 43 | mAR.trials = trials; 44 | mAR.channel = channel; 45 | mAR.seconds = seconds; 46 | mAR.order = m_ord; 47 | mAR.nfft = nfft; 48 | else 49 | error('invalid number of arguments'); 50 | end 51 | end 52 | 53 | function extract(mAR) 54 | NUM_FEATURES = mAR.nfft/2+1; 55 | numTrials = length(mAR.trials); 56 | instances = zeros(numTrials, NUM_FEATURES); 57 | labels = zeros(numTrials,1); 58 | tic 59 | for i=1:numTrials 60 | if length(mAR.seconds) ==1 61 | numsamples = mAR.trials{i}.samplingRate * mAR.seconds; 62 | if(numsamples == 0) 63 | y = mAR.trials{i}.signal(mAR.channel,:); 64 | else 65 | y = mAR.trials{i}.signal(mAR.channel, 1:numsamples); 66 | end 67 | elseif length(mAR.seconds) ==2 68 | sampleA = mAR.trials{i}.samplingRate*mAR.seconds(1) + 1; 69 | sampleB = mAR.trials{i}.samplingRate*mAR.seconds(2); 70 | else 71 | error('invalid seconds parameter'); 72 | end 73 | if isa(mAR.filter,'dfilt.df2sos') || isa(mAR.filter,'dfilt.df2') 74 | y = filter(mAR.filter,y); 75 | elseif isa(mAR.filter,'dfilt.dffir') 76 | y = filtfilt(mAR.filter.Numerator,1,y); 77 | end 78 | [pyy pff] = pyulear(y,mAR.order,mAR.nfft,mAR.trials{i}.samplingRate); 79 | instances(i,:) = pyy; 80 | labels(i,1) = floor(mAR.trials{i}.label); 81 | end 82 | mAR.avgTime = toc/numTrials; 83 | mAR.instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 84 | end 85 | 86 | function configInfo = getConfigInfo(mAR) 87 | configInfo = sprintf('PYAR\tchannel:%d\tseconds:%d\tnfft:%d\torder:%d',mAR.channel,mAR.seconds,mAR.nfft,mAR.order); 88 | end 89 | 90 | 91 | function time = getTime(mAR) 92 | time = mAR.avgTime; 93 | end 94 | end 95 | 96 | end 97 | 98 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@RawSignal/RawSignal.m: -------------------------------------------------------------------------------- 1 | classdef RawSignal < eegtoolkit.featextraction.FeatureExtractionBase 2 | %RAWSIGNAL Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties (Access = public) 6 | end 7 | 8 | methods (Access = public) 9 | function RS = RawSignal() 10 | % RS.instanceSet = eegtoolkit.util.RawSignalSet(RS.trials); 11 | end 12 | 13 | function RS = extract(RS) 14 | RS.instanceSet = eegtoolkit.util.RawSignalSet(RS.trials); 15 | end 16 | 17 | function configInfo = getConfigInfo(RS) 18 | configInfo = '\n'; 19 | end 20 | 21 | function time = getTime(RS) 22 | time = 0; 23 | end 24 | end 25 | 26 | end 27 | 28 | -------------------------------------------------------------------------------- /+eegtoolkit/+featextraction/@STFT/STFT.m: -------------------------------------------------------------------------------- 1 | classdef STFT < eegtoolkit.featextraction.FeatureExtractionBase 2 | 3 | properties (Access = public) 4 | channel; 5 | seconds; 6 | Frange; 7 | avgTime; 8 | end 9 | 10 | methods (Access = public) 11 | function mSTFT = STFT(trials, seconds, channel,rangeFreq) 12 | if nargin == 0 13 | mSTFT.seconds = 0; 14 | mSTFT.channel = 1; 15 | mSTFT.Frange(1) = 0; 16 | % mSTFT.Frange(2) = mSTFT.trials{1}.samplingRate; 17 | elseif nargin == 1 18 | mSTFT.trials = trials; 19 | mSTFT.seconds = 0; 20 | mSTFT.channel = 1; 21 | mSTFT.Frange(1) = 0; 22 | mSTFT.Frange(2) = mSTFT.trials{1}.samplingRate; 23 | elseif nargin == 2 24 | mSTFT.trials = trials; 25 | mSTFT.channel = 1; 26 | mSTFT.seconds = seconds; 27 | mSTFT.Frange(1) = 0; 28 | mSTFT.Frange(2) = mSTFT.trials{1}.samplingRate; 29 | elseif nargin == 3 30 | mSTFT.trials = trials; 31 | mSTFT.channel = channel; 32 | mSTFT.seconds = seconds; 33 | mSTFT.Frange(1) = 0; 34 | mSTFT.Frange(2) = mSTFT.trials{1}.samplingRate; 35 | elseif nargin==4 36 | 37 | mSTFT.trials = trials; 38 | 39 | if prod(size(rangeFreq)) ~=2 40 | error('vector for frequency range must has two elements') 41 | end 42 | if rangeFreq(1)>=rangeFreq(2) 43 | error('first element must be smaller.'); 44 | end 45 | if (rangeFreq(1)<0 || rangeFreq(2)>mSTFT.trials{1}.samplingRate) 46 | error('invalid values for frequency range'); 47 | end 48 | 49 | mSTFT.channel = channel; 50 | mSTFT.seconds = seconds; 51 | mSTFT.Frange(1) = rangeFreq(1); 52 | mSTFT.Frange(2) = rangeFreq(2); 53 | else 54 | error('invalid number of arguments'); 55 | end 56 | end 57 | 58 | function extract(mSTFT) 59 | mSTFT.Frange(2) = mSTFT.trials{1}.samplingRate; 60 | numsamples = mSTFT.trials{1}.samplingRate * mSTFT.seconds; 61 | if (numsamples == 0) 62 | numsamples = size(mSTFT.trials{1}.signal(mSTFT.channel,:),2); 63 | end 64 | tic 65 | numTrials = length(mSTFT.trials); 66 | y = mSTFT.trials{1}.signal(mSTFT.channel, 1:numsamples); 67 | [S,F,T,P]=spectrogram(y,[],[],[mSTFT.Frange(1):0.5:mSTFT.Frange(2)],mSTFT.trials{1}.samplingRate); 68 | instances = zeros(numTrials, length(P(:))); 69 | labels = zeros(numTrials,1); 70 | for i=1:numTrials 71 | numsamples = mSTFT.trials{i}.samplingRate * mSTFT.seconds; 72 | if(numsamples == 0) 73 | y = mSTFT.trials{i}.signal(mSTFT.channel,:); 74 | else 75 | y = mSTFT.trials{i}.signal(mSTFT.channel, 1:numsamples); 76 | end 77 | 78 | [S,F,T,P]=spectrogram(y,[],[],[mSTFT.Frange(1):0.5:mSTFT.Frange(2)],mSTFT.trials{i}.samplingRate); 79 | instances(i,:) = P(:); 80 | labels(i,1) = floor(mSTFT.trials{i}.label); 81 | end 82 | mSTFT.avgTime = toc/numTrials; 83 | mSTFT.instanceSet = eegtoolkit.util.InstanceSet(instances,labels); 84 | end 85 | 86 | function configInfo = getConfigInfo(mSTFT) 87 | if length(mSTFT.Frange) == 2 88 | configInfo = sprintf('STFT\tchannel:%d\tseconds:%d\tfrange1:%d\tfrange2:%d',mSTFT.channel,mSTFT.seconds,mSTFT.Frange(1),mSTFT.Frange(2)); 89 | else 90 | configInfo = sprintf('STFT\tchannel:%d\tseconds:%d\tfrange1:%d\tfrange2:unset',mSTFT.channel,mSTFT.seconds,mSTFT.Frange(1)); 91 | end 92 | end 93 | 94 | 95 | function time = getTime(mSTFT) 96 | time = mSTFT.avgTime; 97 | end 98 | end 99 | 100 | end 101 | 102 | -------------------------------------------------------------------------------- /+eegtoolkit/+featselection/@FEAST/FEAST.m: -------------------------------------------------------------------------------- 1 | classdef FEAST < eegtoolkit.featselection.FeatureSelectionBase 2 | properties (Constant) 3 | ALGORITHM_MIM = 'mim'; 4 | ALGORITHM_MRMR = 'mrmr'; 5 | ALGORITHM_CMIM = 'cmim'; 6 | ALGORITHM_JMI = 'jmi'; 7 | ALGORITHM_DISR = 'disr'; 8 | ALGORITHM_CIFE = 'cife'; 9 | ALGORITHM_ICAP = 'icap'; 10 | ALGORITHM_CONDRED = 'condred'; 11 | ALGORITHM_CMI = 'cmi'; 12 | ALGORITHM_RELIEF = 'relief'; 13 | ALGORITHM_MIFS = 'mifs' %beta parameter required 14 | ALGORITHM_BETAGAMMA = 'betagamma'; %beta and gamma parameters required 15 | ALGORITHM_FCBF = 'fcbf'; %threshold parameter required 16 | end 17 | properties (Access = public) 18 | algorithm; 19 | numToSelect; 20 | parameter1; 21 | parameter2; 22 | avgTime; 23 | end 24 | 25 | methods 26 | function FF = FEAST(instanceSet,algorithm, numtoSelect, param1, param2) 27 | if nargin == 0 28 | FF.algorithm = 'icap'; 29 | FF.numToSelect = 85; 30 | end 31 | if nargin > 1 32 | FF.originalInstanceSet = instanceSet; 33 | FF.algorithm = algorithm; 34 | end 35 | if nargin > 2 36 | FF.numToSelect = numtoSelect; 37 | end 38 | if nargin > 3 39 | FF.parameter1 = param1; 40 | end 41 | if nargin > 4 42 | FF.parameter2 = param2; 43 | end 44 | end 45 | 46 | function FF = compute(FF) 47 | tic 48 | if (strcmp(FF.algorithm,FF.ALGORITHM_MIFS) == 1) || (strcmp(FF.algorithm, FF.ALGORITHM_FCBF) == 1) 49 | indices = feast(FF.algorithm, FF.numToSelect, FF.originalInstanceSet.getInstances, FF.originalInstanceSet.getLabels, FF.parameter1); 50 | elseif strcmp(FF.algorithm, FF.ALGORITHM_BETAGAMMA) == 1 51 | indices = feast(FF.algorithm, FF.numToSelect, FF.originalInstanceSet.getInstances, FF.originalInstanceSet.getLabels, FF.parameter1, FF.parameter2); 52 | else 53 | indices = feast(FF.algorithm, FF.numToSelect, FF.originalInstanceSet.getInstances, FF.originalInstanceSet.getLabels); 54 | end 55 | dataset = FF.originalInstanceSet.getInstances; 56 | [inst, ~] = size(dataset); 57 | FF.avgTime = toc/inst; 58 | FF.filteredInstanceSet = eegtoolkit.util.InstanceSet([dataset(:,indices) FF.originalInstanceSet.getLabels]); 59 | end 60 | 61 | function configInfo = getConfigInfo(FF) 62 | if (strcmp(FF.algorithm,FF.ALGORITHM_MIFS) == 1) || (strcmp(FF.algorithm, FF.ALGORITHM_FCBF) == 1) 63 | configInfo = sprintf('FEAST\talgorithm:%s\tnumtoselect:%d\tparam1:%d',FF.algorithm, FF.numToSelect, FF.parameter1); 64 | elseif strcmp(FF.algorithm, FF.ALGORITHM_BETAGAMMA) == 1 65 | configInfo = sprintf('FEAST\talgorithm:%s\tnumtoselect:%d\tparam1:%d\tparam2:%d',FF.algorithm, FF.numToSelect, FF.parameter1, FF.parameter2); 66 | else 67 | configInfo = sprintf('FEAST\talgorithm:%s\tnumtoselect:%d',FF.algorithm, FF.numToSelect); 68 | end 69 | end 70 | 71 | function time = getTime(FF) 72 | time = FF.avgTime; 73 | end 74 | end 75 | 76 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featselection/@FeatureSelectionBase/FeatureSelectionBase.m: -------------------------------------------------------------------------------- 1 | classdef (Abstract) FeatureSelectionBase < handle 2 | %Base class for a FeatureExtractor 3 | %Subclasses must implement the filter method 4 | properties 5 | originalInstanceSet; % Input: The original dataset 6 | filteredInstanceSet; % Output: The filtered dataset 7 | end 8 | 9 | methods (Abstract = true) 10 | obj = compute(obj); 11 | configInfo = getConfigInfo(obj); 12 | time = getTime(obj); 13 | end 14 | 15 | end 16 | 17 | -------------------------------------------------------------------------------- /+eegtoolkit/+featselection/@PCA/PCA.m: -------------------------------------------------------------------------------- 1 | classdef PCA < eegtoolkit.featselection.FeatureSelectionBase 2 | properties (Access = public) 3 | componentNum; 4 | avgTime; 5 | end 6 | methods 7 | function PCA = PCA(instanceSet,componentNum) 8 | if nargin == 0 9 | PCA.componentNum = 50; 10 | else 11 | PCA.componentNum = componentNum; 12 | PCA.originalInstanceSet = instanceSet; 13 | end 14 | end 15 | 16 | function PCA = compute(PCA) 17 | ins = PCA.originalInstanceSet.getInstances; 18 | [numInst,~] = size(ins); 19 | tic 20 | [~,score,~,~,~] = pca(ins,'NumComponents',PCA.componentNum); 21 | PCA.avgTime = toc/numInst; 22 | PCA.filteredInstanceSet = eegtoolkit.util.InstanceSet(score,PCA.originalInstanceSet.getLabels); 23 | end 24 | function configInfo = getConfigInfo(PCA) 25 | configInfo = sprintf('PCA\tcomponents:%d', PCA.componentNum); 26 | end 27 | 28 | function time = getTime(PCA) 29 | time = PCA.avgTime; 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /+eegtoolkit/+featselection/@SVD/SVD.m: -------------------------------------------------------------------------------- 1 | classdef SVD < eegtoolkit.featselection.FeatureSelectionBase; 2 | properties (Access = public) 3 | modes; 4 | avgTime; 5 | end 6 | methods 7 | function SVD = SVD(instanceSet,modes) 8 | if nargin == 0 9 | SVD.modes = 80; 10 | else 11 | SVD.modes = modes; 12 | SVD.originalInstanceSet = instanceSet; 13 | end 14 | end 15 | 16 | function SVD = compute(SVD) 17 | tic 18 | [U, S, V] = svd(SVD.originalInstanceSet.getInstances); 19 | data_svd = U*S(:,1:SVD.modes)*V(1:SVD.modes,1:SVD.modes)'; 20 | [numInst, ~] = size(data_svd); 21 | SVD.avgTime = toc/numInst; 22 | SVD.filteredInstanceSet = eegtoolkit.util.InstanceSet(data_svd, SVD.originalInstanceSet.getLabels); 23 | end 24 | function configInfo = getConfigInfo(SVD) 25 | configInfo = sprintf('SVD\tmodes:%d', SVD.modes); 26 | end 27 | 28 | function time = getTime(SVD) 29 | time = SVD.avgTime; 30 | end 31 | end 32 | end -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@Amuse/Amuse.m: -------------------------------------------------------------------------------- 1 | classdef Amuse < eegtoolkit.preprocessing.PreprocessingBase 2 | 3 | properties 4 | first; 5 | last; 6 | avgTime; 7 | end 8 | 9 | methods 10 | function AM = Amuse() 11 | AM.first = 2; 12 | AM.last = 256; 13 | end 14 | 15 | function out = process(AM,in ) 16 | out = {}; 17 | total = 0; 18 | for i=1:length(in) 19 | % i 20 | % in{i}.signal(end,:) = []; 21 | tic 22 | signal = in{i}.signal; 23 | % signal(end,:) = []; 24 | [W,~,yest] = AM.amuse(signal); 25 | signal = pinv(W(AM.first:AM.last,:))*yest(AM.first:AM.last,: ); 26 | total = total + toc; 27 | in{i}.signal = signal; 28 | % out{i} = eegtoolkit.util.Trial(signal,in{i}.label,in{i}.samplingRate,in{i}.subjectid); 29 | end 30 | out = in; 31 | % total = toc; 32 | AM.avgTime = total/length(in); 33 | end 34 | 35 | function configInfo = getConfigInfo(AM) 36 | configInfo = sprintf('Amuse:\t%d-%d',AM.first,AM.last); 37 | end 38 | 39 | function time = getTime(AM) 40 | time = AM.avgTime; 41 | end 42 | end 43 | 44 | methods (Access = private) 45 | function [W,D1,y] = amuse(AM,X) 46 | % BSS using eigenvalue value decomposition 47 | % Program written by A. Cichocki and R. Szupiluk 48 | % 49 | % X [m x N] matrix of observed (measured) signals, 50 | % W separating matrix, 51 | % y estimated separated sources 52 | % p time delay used in computation of covariance matrices 53 | % optimal time-delay default p= 1 54 | % 55 | % First stage: Standard prewhitening 56 | 57 | [m,N]=size(X); 58 | if nargin==2, 59 | n=m; % 60 | end; 61 | 62 | Rxx=(X*X')/N; 63 | 64 | [Ux,Dx,Vx]=svd(Rxx); 65 | Dx=diag(Dx); 66 | % n=xxx; 67 | if n1e-199)); %Detection the number of sources 75 | Q= diag(real(sqrt(1./Dx(1:n))))*Ux(:,1:n)'; 76 | end; 77 | 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 | % Second stage: Fast separation using sorting EVD 80 | % notation the same as used in the Chapter 4 81 | Xb=Q*X; 82 | p=1; 83 | % paramter p can take here value different than 1 84 | % for example -1 or 2. 85 | N=max(size(Xb)); 86 | Xb=Xb-kron(mean(Xb')',ones(1,N)); 87 | 88 | Rxbxbp=(Xb(:,1:N-1)*Xb(:,2:N)')/(N-1); 89 | Rxbxbp= Rxbxbp+Rxbxbp'; 90 | [Vxb Dxb]=eig(Rxbxbp); 91 | [D1 perm]=sort(diag(Dxb)); 92 | D1=flipud(D1); 93 | Vxb=Vxb(:,flipud(perm)); 94 | W = Vxb'*Q; 95 | y = Vxb' * Xb;%change Xb instead of x1 96 | end 97 | end 98 | 99 | 100 | 101 | end 102 | 103 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@DigitalFilter/DigitalFilter.m: -------------------------------------------------------------------------------- 1 | classdef DigitalFilter < eegtoolkit.preprocessing.PreprocessingBase 2 | properties 3 | filt; 4 | info; 5 | avgTime; 6 | end 7 | 8 | methods 9 | function DF = DigitalFilter(filt) 10 | if(nargin > 0) 11 | DF.filt = filt; 12 | end 13 | end 14 | 15 | function out = process(DF,in ) 16 | tic; 17 | for i=1:length(in) 18 | % i 19 | signal = in{i}.signal; 20 | [numChannels, ~] = size(signal); 21 | for j=1:numChannels 22 | if isa(DF.filt,'dfilt.df2sos') || isa(DF.filt,'dfilt.df2') 23 | % signal(j,:) = filter(DF.filt,signal(j,:)); 24 | signal(j,:) = filtfilt(DF.filt.sosMatrix,DF.filt.ScaleValues,signal(j,:)); 25 | elseif isa(DF.filt,'dfilt.dffir') 26 | signal(j,:) = filtfilt(DF.filt.Numerator,1,signal(j,:)); 27 | end 28 | end 29 | in{i}.signal = signal; 30 | end 31 | out = in; 32 | total = toc; 33 | DF.avgTime = total/length(in); 34 | end 35 | 36 | function configInfo = getConfigInfo(DF) 37 | if isempty(DF.info) 38 | configInfo = 'DigitalFilter'; 39 | else 40 | configInfo = strcat('DigitalFilter:\t',info); 41 | end 42 | end 43 | 44 | function time = getTime(DF) 45 | time = DF.avgTime; 46 | end 47 | end 48 | 49 | end 50 | 51 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@FastICA/FastICA.m: -------------------------------------------------------------------------------- 1 | classdef FastICA < eegtoolkit.preprocessing.PreprocessingBase 2 | 3 | properties 4 | first; 5 | last; 6 | avgTime; 7 | end 8 | 9 | methods 10 | function ICA = FastICA() 11 | ICA.first = 2; 12 | ICA.last = 256; 13 | end 14 | 15 | function out = process(ICA,in ) 16 | out = {}; 17 | total = 0; 18 | for i=1:length(in) 19 | i 20 | % in{i}.signal(end,:) = []; 21 | tic 22 | signal = in{i}.signal; 23 | % signal(end,:) = []; 24 | % [W,~,yest] = amuse(signal); 25 | % signal = pinv(W(ICA.first:ICA.last,:))*yest(ICA.first:ICA.last,: ); 26 | [icasig, A, W] = fastica (signal); 27 | signal = A(:,ICA.first:end)*icasig(ICA.first:end,:); 28 | total = total + toc; 29 | % in{i}.signal = signal; 30 | out{i} = eegtoolkit.util.Trial(signal,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid,in{i}.type); 31 | end 32 | % out = in; 33 | % total = toc; 34 | ICA.avgTime = total/length(in); 35 | end 36 | 37 | function configInfo = getConfigInfo(ICA) 38 | configInfo = sprintf('FastICA:\t%d-%d',ICA.first,ICA.last); 39 | end 40 | 41 | function time = getTime(ICA) 42 | time = ICA.avgTime; 43 | end 44 | end 45 | 46 | end 47 | 48 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@PreprocessingBase/PreprocessingBase.m: -------------------------------------------------------------------------------- 1 | classdef PreprocessingBase < handle 2 | 3 | properties 4 | originalTrials; 5 | processedTrials; 6 | end 7 | 8 | methods (Abstract = true) 9 | out = process(obj,in); 10 | configInfo = getConfigInfo(obj); 11 | time = getTime(obj); 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@Rereferencing/Rereferencing.m: -------------------------------------------------------------------------------- 1 | classdef Rereferencing < eegtoolkit.preprocessing.PreprocessingBase 2 | 3 | properties 4 | %meanSignal=1: Subtract the mean from the signal 5 | %meanSignal=2: Average rereferencing 6 | meanSignal; 7 | avgTime; 8 | end 9 | 10 | methods 11 | function RR = Rereferencing() 12 | RR.meanSignal = 1; 13 | end 14 | 15 | function out = process(RR,in) 16 | out = {}; 17 | tic; 18 | for i=1:length(in) 19 | if RR.meanSignal == 1 20 | [numChannels,~] = size(in{i}.signal); 21 | for j=1:numChannels 22 | in{i}.signal(j,:) = in{i}.signal(j,:) - mean(in{i}.signal(j,:)); 23 | end 24 | elseif RR.meanSignal == 2 25 | meanChann = mean(in{i}.signal); 26 | in{i}.signal = in{i}.signal-repmat(meanChann,257,1); 27 | end 28 | out = in; 29 | end 30 | RR.avgTime = toc/length(in); 31 | end 32 | 33 | function configInfo = getConfigInfo(RR) 34 | configInfo = sprintf('Rereferencing:\tmeanSignal:%d',RR.meanSignal); 35 | end 36 | 37 | 38 | function time = getTime(RR) 39 | time = RR.avgTime; 40 | end 41 | 42 | end 43 | 44 | end 45 | 46 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@SampleSelection/SampleSelection.m: -------------------------------------------------------------------------------- 1 | classdef SampleSelection < eegtoolkit.preprocessing.PreprocessingBase 2 | properties 3 | channels; 4 | sampleRange; 5 | samplingRate; 6 | end 7 | 8 | methods 9 | function CS = SampleSelection(channels,sampleRange) 10 | if(nargin == 0) 11 | CS.channels = 126; 12 | CS.sampleRange = [1,1250]; 13 | end 14 | if(nargin > 0) 15 | CS.channels = channels; 16 | end 17 | if nargin > 1 18 | CS.sampleRange = sampleRange; 19 | end 20 | end 21 | 22 | function out = process(CS,in) 23 | out = {}; 24 | CS.samplingRate = in{1}.samplingRate; 25 | for i=1:length(in) 26 | if(length(CS.channels) > 0) 27 | if(length(CS.sampleRange) > 2) 28 | signal = in{i}.signal(CS.channels,CS.sampleRange); 29 | out{i} = eegtoolkit.util.Trial(signal ... 30 | ,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid); 31 | elseif(length(CS.sampleRange) > 0) 32 | %channels AND sampleRange 33 | signal = in{i}.signal(CS.channels,CS.sampleRange(1):CS.sampleRange(2)); 34 | out{i} = eegtoolkit.util.Trial(signal ... 35 | ,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid); 36 | else 37 | %ONLY channels 38 | signal = in{i}.signal(CS.channels,:); 39 | out{i} = eegtoolkit.util.Trial(signal ... 40 | ,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid); 41 | end 42 | else 43 | if(length(CS.sampleRange) > 2) 44 | signal = in{i}.signal(:,CS.sampleRange); 45 | out{i} = eegtoolkit.util.Trial(signal ... 46 | ,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid); 47 | elseif(length(CS.sampleRange) > 0) 48 | %ONLY sampleRange 49 | signal = in{i}.signal(:,CS.sampleRange(1):CS.sampleRange(2)); 50 | out{i} = eegtoolkit.util.Trial(signal ... 51 | ,in{i}.label,in{i}.samplingRate,in{i}.subjectid,in{i}.sessionid); 52 | else 53 | %NOTHING (?) 54 | disp('Warning: No parameter specified for SampleSelection, using all channels and samples'); 55 | end 56 | end 57 | end 58 | end 59 | 60 | function configInfo = getConfigInfo(CS) 61 | if(length(CS.channels) > 0) 62 | if(length(CS.sampleRange) > 0) 63 | configInfo = 'SampleSelection\tChannels:'; 64 | for i=1:length(CS.channels) 65 | configInfo = strcat(configInfo,sprintf('%d+',CS.channels(i))); 66 | end 67 | configInfo = strcat(configInfo,sprintf('\tsampleRange:%d-%d',CS.sampleRange(1),CS.sampleRange(2))); 68 | else 69 | configInfo = 'SampleSelection\tChannels:'; 70 | for i=1:length(CS.channels) 71 | configInfo = strcat(configInfo,sprintf('%d+',CS.channels(i))); 72 | end 73 | end 74 | else 75 | if(length(CS.sampleRange) > 0) 76 | configInfo = sprintf('SampleSelection\tSampleRange:%d-%d',CS.sampleRange(1),CS.sampleRange(2)); 77 | %ONLY sampleRange 78 | else 79 | %NOTHING (?) 80 | configInfo = sprintf('SampleSelection\tNothing specified'); 81 | end 82 | end 83 | end 84 | 85 | 86 | function time = getTime(CS) 87 | time = 0; 88 | end 89 | 90 | end 91 | 92 | end 93 | 94 | -------------------------------------------------------------------------------- /+eegtoolkit/+preprocessing/@Windsorize/Windsorize.m: -------------------------------------------------------------------------------- 1 | classdef Windsorize < eegtoolkit.preprocessing.PreprocessingBase 2 | properties 3 | limit_l; 4 | limit_h; 5 | subjectids; 6 | end 7 | 8 | methods 9 | function obj = Windsorize(low,high) 10 | if nargin == 0 11 | obj.limit_l = 0.05; 12 | obj.limit_h = 0.95; 13 | elseif nargin == 2 14 | obj.limit_l = low; 15 | obj.limit_h = high; 16 | else 17 | error('2 inputs are required for windsorize, the low and high limits'); 18 | end 19 | end 20 | 21 | function trials = process(obj,trials) 22 | subs = unique(obj.subjectids); 23 | nchannels = size(trials{1}.signal,1); 24 | trial_length = size(trials{1}.signal,2); 25 | for i=1:numel(subs) 26 | ids = find(obj.subjectids == subs(i)); 27 | ntrials = numel(ids); 28 | % Concatenate signal 29 | signal = []; 30 | for j=1:numel(ids) 31 | signal = [signal trials{ids(j)}.signal]; 32 | end 33 | %windsorize 34 | sorted_sig = sort(signal,2); 35 | upbound = sorted_sig(:,round(obj.limit_h*size(signal,2))); 36 | uprep = sorted_sig(:,round(obj.limit_h*size(signal,2))-1); 37 | lowbound = sorted_sig(:,round(obj.limit_l*size(signal,2))); 38 | lowrep = sorted_sig(:,round(obj.limit_l*size(signal,2))+1); 39 | for ch=1:nchannels 40 | signal(ch,signal(ch,:)>upbound(ch)) = uprep(ch); 41 | signal(ch,signal(ch,:)0) 22 | numTrials = length(trials); 23 | lbls = zeros(numTrials,1); 24 | for i=1:numTrials 25 | lbls(i) = trials{i}.label; 26 | end 27 | 28 | L1.labelss = lbls; 29 | [numChannels, numSamples] = size(trials{1}.signal); 30 | 31 | L1.matrix4D = zeros(numChannels,numSamples,numTrials,1); 32 | 33 | for i=1:numTrials 34 | L1.matrix4D(:,:,i) = trials{i}.signal; 35 | end 36 | end 37 | 38 | end 39 | 40 | function newL1 = removeInstancesWithIndices(L1,indices) 41 | newL1 = eegtoolkit.util.L1MCCAInstanceSet; 42 | newL1.labelss = L1.labelss; 43 | newL1.labelss(indices) = []; 44 | newL1.matrix4D = L1.matrix4D; 45 | newL1.matrix4D(:,:,indices) = []; 46 | end 47 | 48 | function instances = getInstancesWithIndices(L1,indices) 49 | instances = L1.matrix4D(:,:,indices); 50 | end 51 | 52 | function dataset = getDatasetWithIndices(L1,indices) 53 | instances = zeros(length(indices),1000); 54 | labels = L1.labelss(indices); 55 | dataset = horzcat(instances,labels); 56 | end 57 | 58 | function numInstances = getNumInstances(L1) 59 | [~,~,numInstances] = size(L1.matrix4D); 60 | end 61 | 62 | function dataset = getDataset(L1) 63 | instances = zeros(L1.getNumInstances,1000); 64 | labels = L1.labelss; 65 | dataset = horzcat(instances,labels); 66 | end 67 | 68 | function numLabels = getNumLabels(L1) 69 | numLabels = length(unique(L1.labelss)); 70 | end 71 | end 72 | 73 | end 74 | 75 | -------------------------------------------------------------------------------- /+eegtoolkit/+util/@RawSignalSet/RawSignalSet.m: -------------------------------------------------------------------------------- 1 | classdef RawSignalSet < eegtoolkit.util.InstanceSet 2 | %RAWSIGNALSET Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties 6 | %numTrials X numChannels X numSamples 7 | signalMatrix; 8 | end 9 | 10 | methods 11 | function RSS = RawSignalSet(trials) 12 | % RSS = RSS@eegtoolkit.util.InstanceSet(zeros(1,1000),ones(1,1000)); 13 | if(nargin~=1) 14 | error('trials parameter not set'); 15 | end 16 | % if(nargin>0) 17 | numTrials = length(trials); 18 | labels = zeros(numTrials,1); 19 | for i=1:numTrials 20 | labels(i) = trials{i}.label; 21 | end 22 | [numChannels, numSamples] = size(trials{i}.signal); 23 | sMatrix = zeros(numTrials,numChannels,numSamples); 24 | for i=1:numTrials 25 | sMatrix(i,:,:) = trials{i}.signal; 26 | end 27 | RSS = RSS@eegtoolkit.util.InstanceSet(squeeze(sMatrix(:,1,:)),labels); 28 | RSS.signalMatrix = sMatrix; 29 | % end 30 | end 31 | 32 | function sMatrix = get(indices) 33 | sMatrix = squeeze(RSS.signalMatrix(indices,:,:)); 34 | end 35 | 36 | function sMatrix = getInstancesWithIndices(RSS,indices) 37 | sMatrix = RSS.signalMatrix(indices,:,:); 38 | end 39 | 40 | function instanceStruct = removeInstancesWithIndices(RSS,indices) 41 | % newRSS = eegtoolkit.util.RawSignalSet; 42 | % newRSS.labels = RSS.labels; 43 | % newRSS.labels(indices) = []; 44 | % newRSS.signalMatrix = RSS.signalMatrix; 45 | % newRSS.signalMatrix(indices,:,:) = []; 46 | sMatrix = RSS.signalMatrix; 47 | sMatrix(indices,:,:) = []; 48 | 49 | labels = RSS.labels; 50 | labels(indices) = []; 51 | instanceStruct = struct('sMatrix',sMatrix, 'labels', labels); 52 | end 53 | 54 | function numInstances = getNumInstances(RSS) 55 | [numInstances,~,~] = size(RSS.signalMatrix); 56 | end 57 | 58 | end 59 | 60 | 61 | end 62 | 63 | -------------------------------------------------------------------------------- /+eegtoolkit/+util/@ResultSet/ResultSet.m: -------------------------------------------------------------------------------- 1 | % RESULTSET class 2 | % Stores the results of an experiment 3 | classdef ResultSet < eegtoolkit.util.InstanceSet 4 | 5 | properties 6 | outputLabels; % The output labels 7 | outputProbabilities; % Probabilities 8 | outputRanking; % Confidence scores 9 | confusionMatrix; % The Confusion Matrix 10 | end 11 | 12 | methods 13 | function RS = ResultSet(instanceSet, labels, probabilities, ranking) 14 | %Constructor method 15 | %Input: 16 | %(InstanceSet object): the original instanceSet 17 | %Labels: a vector containing the output labels of the 18 | %experiment 19 | %Proababilities: a vector containing the probabilities of each 20 | %label 21 | %Ranking (optional): a matrix containing a score for each label 22 | 23 | RS = RS@eegtoolkit.util.InstanceSet(instanceSet); 24 | RS.outputLabels = labels; 25 | 26 | %compute the confusion matrix 27 | labels = unique(RS.getLabels); 28 | numLabels = length(labels); 29 | RS.confusionMatrix = zeros(numLabels); 30 | trueLabels = RS.getLabels; 31 | numInstances = RS.getNumInstances; 32 | for k=1:numInstances 33 | idx1 = find(labels==RS.outputLabels(k,1)); 34 | idx2 = find(labels==trueLabels(k,1)); 35 | RS.confusionMatrix(idx1,idx2) = RS.confusionMatrix(idx1,idx2)+ 1; 36 | end 37 | RS.confusionMatrix = RS.confusionMatrix'; 38 | %if classifier supports ranking/probabilities 39 | if nargin > 2 40 | RS.outputProbabilities = probabilities; 41 | RS.outputRanking = ranking; 42 | end 43 | end 44 | 45 | function RSSubset = subset(RS,indices) 46 | sOutputLabels = RS.outputLabels(indices); 47 | sOutputProbabilities = RS.outputProbabilities(indices); 48 | sInstanceSet = RS.getDatasetWithIndices(indices); 49 | if isempty(RS.outputProbabilities) 50 | RSSubset = eegtoolkit.util.ResultSet(sInstanceSet,sOutputLabels,sOutputProbabilities); 51 | else 52 | sOutputRanking = RS.outputRanking(indices); 53 | RSSubset = eegtoolkit.util.ResultSet(sInstanceSet,sOutputLabels,sOutputProbabilities,sOutputRanking); 54 | end 55 | end 56 | 57 | end 58 | 59 | end 60 | 61 | -------------------------------------------------------------------------------- /+eegtoolkit/+util/@Trial/Trial.m: -------------------------------------------------------------------------------- 1 | classdef Trial < handle 2 | %A class that defines a Trial 3 | 4 | properties (Constant) 5 | %Type of trial 6 | SSVEP = 1; 7 | ERRP = 2; 8 | MI = 3; 9 | end 10 | 11 | properties (Access = public) 12 | signal; % the signal of the trial 13 | label; % a label for the trial (typically assigned with the frequency that is calculated using DIN data) 14 | duration; % the duration of the trial in seconds 15 | samplingRate; % the samling rate used to capture the signal 16 | subjectid; %the subject from 17 | sessionid; %the session id 18 | type; 19 | end 20 | 21 | methods (Access = public) 22 | function T = Trial(signal, label, samplingRate, subjectID, sessionID,type) 23 | T.signal = signal; 24 | T.label = label; 25 | T.samplingRate = samplingRate; 26 | T.duration = length(signal)/samplingRate; 27 | T.subjectid = subjectID; 28 | T.sessionid = sessionID; 29 | if nargin>5 30 | T.type = type; 31 | end 32 | end 33 | 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EEG processing toolbox 2 | ## Description 3 | This software is released as part of the EU-funded research project [MAMEM](https://www.mamem.eu/) for supporting experimentation in EEG signals. 4 | It follows a modular architecture that allows the fast execution of experiments of different configurations with minimal adjustments of the code. The experimental pipeline consists of the **Experimenter** class which acts as a wrapper of five more underlying parts; 5 | 6 | - The **Session** object: Used for loading the dataset and segmenting the signal according to the periods that the SSVEP stimuli were presented during the experiment. The signal parts are also annotated with a label according to the stimulus frequency. 7 | - The **Preprocessing** object: Includes methods for modifying the raw EEG signal. 8 | - The **Feature Extraction** object: Performs feature extraction algorithms for extracting numerical features from the EEG signals. 9 | - The **Feature Selection** object: Selects the most important features that were extracted in the previous step. 10 | - The **Classification** object: Trains a classification model for predicting the label of unknown samples. 11 | 12 | ## Instructions 13 | The usage of some classes of the framework is limited by the following requirements. 14 | 15 | | Package | Class | Description | 16 | | --- | --- | --- | 17 | | preprocessing | FastICA | Requires the [FastICA](http://research.ics.aalto.fi/ica/fastica/code/dlcode.shtml) library 18 | | aggregation | Vlad | Requires the [vlfeat](http://www.vlfeat.org/) library 19 | | aggregation | Fisher | Requires the [vlfeat](http://www.vlfeat.org/) library 20 | | featselection | FEAST | Requires the [FEAST](http://mloss.org/software/view/386/) library (download link is next to "Archive" somewhere in the middle of the page) and MIToolbox (included in the FEAST zip file) | 21 | | classification | L1MCCA | Requires the [tensor] (http://www.sandia.gov/~tgkolda/TensorToolbox/index-2.6.html) toolbox| 22 | | classification | LIBSVMFast | Requires the [libsvm](https://www.csie.ntu.edu.tw/~cjlin/libsvm/) library| 23 | | classification | MLTboxMulticlass | Requires Matlab version r2015a or newer | 24 | | classification | MLDA | Requires Matlab version r2014 or newer | 25 | | classification | SMFA | Requires [SGE-SMFA] (https://github.com/amaronidis/SGE-SMFA) | 26 | | util | LSLWrapper | Requires the [Labstreaminglayer](https://github.com/sccn/labstreaminglayer) library| 27 | 28 | ## Examples 29 | 30 | Some examples are available that are based on the datasets that can be found below. 31 | - **exampleCSP**, extract common spatial patterns in dataset III of [BCI competition II] (http://www.bbci.de/competition/ii/) 32 | - **exampleCombiCCA**, SSVEP recognition using the CombinedCCA method from [2]. Based on this [dataset] (ftp://sccn.ucsd.edu/pub/cca_ssvep) 33 | - **exampleDefault**, performs a simple experiment on Dataset I & II 34 | - **exampleEPOCCCASVM**, SSVEP recognition using SVM on the CCA coefficients, based on Dataset III 35 | - **exampleERRP**, recognition of error related potentials, based on the [dataset] (https://github.com/flowersteam/self_calibration_BCI_plosOne_2015) provided by [3] 36 | - **exampleEarlyFusion**, demonstrates how to merge features extracted by different electrode channels, based on Dataset II. 37 | - **exampleEpoc**, performs an experiment for the dataset that was recorded with an EPOC device (Dataset III) 38 | - **exampleITCCA**, SSVEP recognition using the ITCCA method from [2]. Based on this [dataset] (ftp://sccn.ucsd.edu/pub/cca_ssvep) 39 | - **exampleL1MCCA**, SSVEP recognition using the L1MCCA method from [2]. Based on this [dataset] (ftp://sccn.ucsd.edu/pub/cca_ssvep) 40 | - **exampleLSL**, Online recognition of SSVEP signals using the [LSL library] (https://github.com/sccn/labstreaminglayer). 41 | - **exampleLateFusion**, merging the output of different classifiers by majority voting, based on Dataset II. 42 | - **exampleMotorPWelch**, classification of right/left hand motor imagery based on the dataset III of [BCI competition II] (http://www.bbci.de/competition/ii/) 43 | - **exampleOptimal**, performs an experiment with the optimal settings for Dataset I & II 44 | - **exampleSMFA**, SSVEP recognition with using SMFA [4] 45 | 46 | ## Datasets 47 | 48 | | Title | Description | Download Link | 49 | | --- | --- | --- | 50 | |EEG SSVEP Dataset I | EEG signals with 256 channels captured from 11 subjects executing a SSVEP-based experimental protocol. **Five different frequencies (6.66, 7.50, 8.57, 10.00 and 12.00 Hz) presented in isolation** have been used for the visual stimulation. The EGI 300 Geodesic EEG System (GES 300), using a 256-channel HydroCel Geodesic Sensor Net (HCGSN) and a sampling rate of 250 Hz has been used for capturing the signals. | [Dataset I](https://dx.doi.org/10.6084/m9.figshare.2068677) | 51 | |EEG SSVEP Dataset II | EEG signals with 256 channels captured from 11 subjects executing a SSVEP-based experimental protocol. **Five different frequencies (6.66, 7.50, 8.57, 10.00 and 12.00 Hz) presented simultaneously** have been used for the visual stimulation. The EGI 300 Geodesic EEG System (GES 300), using a 256-channel HydroCel Geodesic Sensor Net (HCGSN) and a sampling rate of 250 Hz has been used for capturing the signals. | [Dataset II](https://dx.doi.org/10.6084/m9.figshare.3153409) | 52 | |EEG SSVEP Dataset III | EEG signals with 14 channels captured from 11 subjects executing a SSVEP-based experimental protocol. **Five different frequencies (6.66, 7.50, 8.57, 10.00 and 12.00 Hz) presented simultaneously** have been used for the visual stimulation, **and the Emotiv EPOC, using 14 wireless channels** has been used for capturing the signals. | [Dataset III](https://dx.doi.org/10.6084/m9.figshare.3413851) | 53 | 54 | ## References 55 | [\[1\]](http://arxiv.org/abs/1602.00904) Vangelis P. Oikonomou, Georgios Liaros, Kostantinos Georgiadis, Elisavet Chatzilari, Katerina Adam, Spiros Nikolopoulos and Ioannis Kompatsiaris, "Comparative evaluation of state-of-the-art algorithms for SSVEP-based BCIs", Technical Report - eprint arXiv:1602.00904, February 2016 56 | 57 | \[2\] M. Nakanishi, Y. Wang, Y.T. Wang, and T.P. Jung, “A comparison study of canonical correlation analysis based methods for detecting steady-state visual evoked potentials,” PLoS ONE, p. e0140703, October 2015. 58 | 59 | \[3\] Iturrate, Iñaki, Jonathan Grizou, Jason Omedes, Pierre-Yves Oudeyer, Manuel Lopes, and Luis Montesano. "Exploiting task constraints for self-calibrated brain-machine interface control using error-related potentials." PloS one 10, no. 7 (2015): e0131491. 60 | Harvard 61 | 62 | \[4\] Maronidis, Anastasios, Anastasios Tefas, and Ioannis Pitas. "Subclass Marginal Fisher Analysis." In Computational Intelligence, 2015 IEEE Symposium Series on, pp. 1391-1398. IEEE, 2015. 63 | 64 | 65 | -------------------------------------------------------------------------------- /exampleCSP.m: -------------------------------------------------------------------------------- 1 | 2 | sess = eegtoolkit.util.Session; 3 | sess.loadAll(6); 4 | % 5 | 6 | % load('testingMotorVag1'); 7 | % % load 8 | % sess = eegtoolkit.util.Session; 9 | % % sess.loadMOTOR(labels,trials); 10 | % sess.loadVag(trials,labels); 11 | 12 | ss = eegtoolkit.preprocessing.SampleSelection; 13 | ss.channels = [1,3]; 14 | ss.sampleRange = [384,896]; 15 | 16 | [z,p,k]=butter(3,[8,16]/64); 17 | [s,g]=zp2sos(z,p,k); 18 | Hd = dfilt.df2sos(s,g); 19 | df = eegtoolkit.preprocessing.DigitalFilter; % 20 | df.filt = Hd; 21 | 22 | refer = eegtoolkit.preprocessing.Rereferencing; 23 | refer.meanSignal = 1; 24 | 25 | extr = eegtoolkit.featextraction.RawSignal; 26 | 27 | classif = eegtoolkit.classification.CSPWrapper; 28 | classif.baseClassifier = eegtoolkit.classification.LIBSVM; 29 | 30 | experiment = eegtoolkit.experiment.Experimenter; 31 | experiment.session = sess; 32 | experiment.preprocessing = {ss,refer,df}; 33 | experiment.featextraction = extr; 34 | experiment.classification = classif; 35 | experiment.evalMethod = experiment.EVAL_METHOD_LOOCV; 36 | % experiment.run(); 37 | % experiment.evalMethod = experiment.EVAL_METHOD_XFOLD_CV; 38 | experiment.run(3); 39 | accuracy = experiment.results{1}.getAccuracy(); 40 | 41 | -------------------------------------------------------------------------------- /exampleCombiCCA.m: -------------------------------------------------------------------------------- 1 | m_secs = 0.5:0.5:4; 2 | for ii=1:8 3 | for jj = 1:8 4 | sess = eegtoolkit.util.Session; 5 | % sess.loadAll(4); 6 | % sess.loadAll(4); 7 | sess.loadSubject(4,ii); 8 | 9 | ss = eegtoolkit.preprocessing.SampleSelection; 10 | ss.channels = 1:8; 11 | % ss.sampleRange = [75,1024+74]; 12 | ss.sampleRange = [75,74+256*m_secs(jj)]; 13 | % ss.sampleRange = [1,1140]; 14 | % 75:1024+74 15 | [z,p,k]=butter(3,[6,80]/128); 16 | [s,g]=zp2sos(z,p,k); 17 | Hd = dfilt.df2sos(s,g); 18 | df = eegtoolkit.preprocessing.DigitalFilter; % 19 | df.filt = Hd; 20 | 21 | refer = eegtoolkit.preprocessing.Rereferencing; 22 | refer.meanSignal = 1; 23 | 24 | extr = eegtoolkit.featextraction.RawSignal; 25 | sti_f = [9.25, 11.25, 13.25, 9.75, 11.75, 13.75, 10.25, 12.25, 14.25, 10.75, 12.75, 14.75]; 26 | classif = eegtoolkit.classification.CombiCCA(sti_f,4,256*m_secs(jj),256); 27 | classif.baseClassifier = eegtoolkit.classification.MaxChooser; 28 | 29 | experiment = eegtoolkit.experiment.Experimenter; 30 | experiment.session = sess; 31 | experiment.preprocessing = {ss,refer,df}; 32 | experiment.featextraction = extr; 33 | experiment.classification = classif; 34 | % experiment.evalMethod = experiment.EVAL_METHOD_LOOCV; 35 | % experiment.run(); 36 | experiment.evalMethod = experiment.EVAL_METHOD_LOBO; 37 | experiment.run(); 38 | for i=1:length(experiment.results) 39 | accuracy(i) = experiment.results{i}.getAccuracy(); 40 | end 41 | acc2(ii,jj) = mean(accuracy); 42 | 43 | % accuracy = experiment.results{1}.getAccuracy(); 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /exampleDefault.m: -------------------------------------------------------------------------------- 1 | % Load the data. Call this once outside of the script so you dont have to 2 | % load the data again and again. Make sure the dataset is included in your 3 | % Matlab path 4 | % sess = eegtoolkit.util.Session; 5 | % sess.loadAll(1); %Loads dataset I 6 | 7 | %Load a filter from the samples 8 | load filters/filt_IIRElliptic.mat; 9 | 10 | %Extract features with the pwelch method 11 | extr = eegtoolkit.featextraction.PWelch; 12 | 13 | refer = eegtoolkit.preprocessing.Rereferencing; 14 | %Subtract the mean from the signal 15 | refer.meanSignal = 1; 16 | 17 | ss = eegtoolkit.preprocessing.SampleSelection; 18 | ss.sampleRange = [1,1250]; % Specify the sample range to be used for each Trial 19 | ss.channels = 126; % Specify the channel(s) to be used 20 | 21 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 22 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 23 | 24 | %Configure the classifier 25 | classif = eegtoolkit.classification.LIBSVMFast; 26 | 27 | %Set the Experimenter wrapper class 28 | experiment = eegtoolkit.experiment.Experimenter; 29 | experiment.session = sess; 30 | % Add the preprocessing steps (order is taken into account) 31 | experiment.preprocessing = {ss,refer,df}; 32 | experiment.featextraction = extr; 33 | experiment.classification = classif; 34 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 35 | experiment.run(); 36 | for i=1:length(experiment.results) 37 | accuracies(i) = experiment.results{i}.getAccuracy(); 38 | end 39 | 40 | accuracies' 41 | %mean accuracy for all subjects 42 | fprintf('mean acc = %f\n', mean(accuracies)); 43 | %get the configuration used (for reporting) 44 | experiment.getExperimentInfo 45 | experiment.getTime 46 | -------------------------------------------------------------------------------- /exampleEPOCCCASVM.m: -------------------------------------------------------------------------------- 1 | % Load the data. Call this once outside of the script so you dont have to 2 | % load the data again and again. Make sure the dataset is included in your 3 | % Matlab path 4 | % sess = eegtoolkit.util.Session; 5 | % sess.loadAll(3); %its best to do this once, outside the script (too much 6 | % time) 7 | 8 | %Load a filter from the samples 9 | load filters/epocfilter; 10 | % 7 = O1 11 | % 8 = O2 12 | 13 | % Stimulus frequencies for generating the CCA reference signals 14 | sti_f = [12,10,8.57,7.5,6.66]; 15 | 16 | % CCA feat extraction method 17 | extr = eegtoolkit.featextraction.CCA(sti_f,1:4,128,4); 18 | extr.allFeatures = 1; 19 | 20 | refer = eegtoolkit.preprocessing.Rereferencing; 21 | %Subtract the mean from the signal 22 | refer.meanSignal = 1; 23 | 24 | ss = eegtoolkit.preprocessing.SampleSelection; 25 | ss.sampleRange = [64,640]; % Specify the sample range to be used for each Trial 26 | ss.channels = 6:9; % Specify the channel(s) to be used 27 | 28 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 29 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 30 | 31 | %Configure the classifier 32 | classif = eegtoolkit.classification.LIBSVM; 33 | 34 | %Set the Experimenter wrapper class 35 | experiment = eegtoolkit.experiment.Experimenter; 36 | experiment.session = sess; 37 | % Add the preprocessing steps (order is taken into account) 38 | experiment.preprocessing = {ss,df}; 39 | experiment.featextraction = extr; 40 | experiment.classification = classif; 41 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 42 | experiment.run(); 43 | for i=1:length(experiment.results) 44 | accuracies(i) = experiment.results{i}.getAccuracy(); 45 | end 46 | 47 | accuracies' 48 | %mean accuracy for all subjects 49 | fprintf('mean acc = %f\n', mean(accuracies)); 50 | %get the configuration used (for reporting) 51 | % experiment.getExperimentInfo 52 | % experiment.getTime -------------------------------------------------------------------------------- /exampleERRP.m: -------------------------------------------------------------------------------- 1 | % d2 = designfilt('bandpassiir', 'SampleRate', 256, 'FilterOrder', 8 ,'HalfPowerFrequency1', 1, 'HalfPowerFrequency2', 10,'DesignMethod', 'butter'); 2 | 3 | sess = eegtoolkit.util.Session; 4 | sess.loadSubject(5,6); 5 | 6 | [z,p,k]=butter(3,[6,40]/128); 7 | [s,g]=zp2sos(z,p,k); 8 | Hd = dfilt.df2sos(s,g); 9 | df = eegtoolkit.preprocessing.DigitalFilter; % 10 | df.filt = Hd; 11 | 12 | ss = eegtoolkit.preprocessing.SampleSelection; 13 | ss.channels = [4,9,14]; 14 | ss.sampleRange = 1500:1:1655; 15 | 16 | extr = {}; 17 | for i=1:3 18 | extr{i} = eegtoolkit.featextraction.ERRPFeatures; 19 | extr{i}.channel = 1; 20 | end 21 | 22 | aggr = eegtoolkit.aggregation.ChannelConcat; 23 | 24 | classif = eegtoolkit.classification.LIBSVM; 25 | 26 | %Setup experiment 27 | experiment = eegtoolkit.experiment.Experimenter; 28 | experiment.session = sess; 29 | experiment.preprocessing = {df,ss}; 30 | experiment.featextraction = extr; 31 | experiment.aggregator = aggr; 32 | experiment.classification = classif; 33 | experiment.evalMethod = experiment.EVAL_METHOD_XFOLD_CV; 34 | 35 | experiment.run(10); 36 | 37 | accuracies = []; 38 | for i=1:length(experiment.results) 39 | accuracies(i) = experiment.results{i}.getAccuracy(); 40 | end 41 | 42 | accuracies' 43 | fprintf('mean acc = %.2f\n',mean(accuracies)); -------------------------------------------------------------------------------- /exampleERRPSSVEPDemo.m: -------------------------------------------------------------------------------- 1 | % d2 = designfilt('bandpassiir', 'SampleRate', 256, 'FilterOrder', 8 ,'HalfPowerFrequency1', 1, 'HalfPowerFrequency2', 10,'DesignMethod', 'butter'); 2 | 3 | sess = eegtoolkit.util.Session; 4 | sess.loadSubjectSession(8,5,2); 5 | 6 | [z,p,k]=butter(3,[1,10]/64); 7 | [s,g]=zp2sos(z,p,k); 8 | Hd = dfilt.df2sos(s,g); 9 | df = eegtoolkit.preprocessing.DigitalFilter; % 10 | df.filt = Hd; 11 | 12 | ss = eegtoolkit.preprocessing.SampleSelection; 13 | ss.channels = [1:14]; 14 | ss.sampleRange = [1:6:200]; 15 | 16 | extr = {}; 17 | for i=1:3 18 | extr{i} = eegtoolkit.featextraction.PWelch; 19 | extr{i}.channel = 1; 20 | end 21 | 22 | aggr = eegtoolkit.aggregation.ChannelConcat; 23 | 24 | classif = eegtoolkit.classification.LIBSVM; 25 | classif.kernel = classif.KERNEL_RBF; 26 | classif.gamma = 1/9; 27 | classif.cost = 1; 28 | 29 | %Setup experiment 30 | experiment = eegtoolkit.experiment.Experimenter; 31 | experiment.session = sess; 32 | experiment.preprocessing = {df,ss}; 33 | experiment.featextraction = extr; 34 | experiment.aggregator = aggr; 35 | experiment.classification = classif; 36 | experiment.evalMethod = experiment.EVAL_METHOD_XFOLD_CV; 37 | 38 | experiment.run(10); 39 | 40 | accuracies = []; 41 | for i=1:length(experiment.results) 42 | accuracies(i) = experiment.results{i}.getAccuracy(); 43 | end 44 | 45 | accuracies' 46 | fprintf('mean acc = %.2f\n',mean(accuracies)); -------------------------------------------------------------------------------- /exampleEarlyFusion.m: -------------------------------------------------------------------------------- 1 | % Leave one subject out testing 2 | % load filtMAMEM; % load a filter 3 | % sess = eegtoolkit.util.Session(Hhp); 4 | % sess.loadAll(1); %its best to do this once, outside the script (too much 5 | % time) 6 | % transf = eegtoolkit.transformer.PWelchTransformer(); 7 | % Load the data. Call this once outside of the script so you dont have to 8 | % load the data again and again. Make sure the dataset is included in your 9 | % Matlab path 10 | % sess = eegtoolkit.util.Session; 11 | % sess.loadAll(1); %Loads dataset I 12 | 13 | %Load a filter from the samples 14 | load filters/filt_IIRElliptic; 15 | 16 | 17 | 18 | refer = eegtoolkit.preprocessing.Rereferencing; 19 | %Subtract the mean from the signal 20 | refer.meanSignal = 1; 21 | 22 | ss = eegtoolkit.preprocessing.SampleSelection; 23 | ss.sampleRange = [1,1250]; % Specify the sample range to be used for each Trial 24 | ss.channels = [138,139,150]; % Specify the channel(s) to be used 25 | 26 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 27 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 28 | 29 | 30 | %Extract features with the pwelch method 31 | extr1 = eegtoolkit.featextraction.PWelch; 32 | extr1.channel = 1; %will use channel 138 33 | 34 | extr2 = eegtoolkit.featextraction.PWelch; 35 | extr2.channel = 2; %will use channel 139 36 | 37 | extr3 = eegtoolkit.featextraction.PWelch; 38 | extr3.channel = 3; %will use channel 150 39 | 40 | extr = {extr1,extr2,extr3}; 41 | % Average all three channels so as to get a new feature vector 42 | aggr = eegtoolkit.aggregation.ChannelAveraging; 43 | %Configure the classifier 44 | classif = eegtoolkit.classification.LIBSVM; 45 | 46 | %Set the Experimenter wrapper class 47 | experiment = eegtoolkit.experiment.Experimenter; 48 | experiment.session = sess; 49 | % Add the preprocessing steps (order is taken into account) 50 | experiment.preprocessing = {ss,refer,df}; 51 | experiment.featextraction = {extr1,extr2,extr3}; 52 | experiment.aggregator = aggr; 53 | experiment.classification = classif; 54 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 55 | experiment.run(); 56 | for i=1:length(experiment.results) 57 | accuracies(i) = experiment.results{i}.getAccuracy(); 58 | end 59 | 60 | accuracies' 61 | %mean accuracy for all subjects 62 | fprintf('mean acc = %f\n', mean(accuracies)); 63 | %get the configuration used (for reporting) 64 | experiment.getExperimentInfo 65 | experiment.getTime -------------------------------------------------------------------------------- /exampleEpoc.m: -------------------------------------------------------------------------------- 1 | % Load the data. Call this once outside of the script so you dont have to 2 | % load the data again and again. Make sure the dataset is included in your 3 | % Matlab path 4 | % sess = eegtoolkit.util.Session; 5 | % sess.loadAll(3); %its best to do this once, outside the script (too much 6 | % time) 7 | 8 | %Load a filter from the samples 9 | load filters/epocfilter; 10 | % 7 = O1 11 | % 8 = O2 12 | 13 | % Stimulus frequencies. The order corresponds to the label id (12Hz=1, 14 | % 10Hz=2, 8.57Hz=3, 7.5Hz=4, 6.66Hz=5) 15 | % If the order is wrong, then the "Max" classifier will not work properly 16 | sti_f = [12,10,8.57,7.5,6.66]; 17 | 18 | % CCA feat extraction method 19 | extr = eegtoolkit.featextraction.CCA(sti_f,1:4,128,4); 20 | 21 | refer = eegtoolkit.preprocessing.Rereferencing; 22 | %Subtract the mean from the signal 23 | refer.meanSignal = 1; 24 | 25 | ss = eegtoolkit.preprocessing.SampleSelection; 26 | ss.sampleRange = [64,640]; % Specify the sample range to be used for each Trial 27 | ss.channels = 6:9; % Specify the channel(s) to be used 28 | 29 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 30 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 31 | 32 | %Configure the classifier 33 | classif = eegtoolkit.classification.MaxChooser; 34 | 35 | %Set the Experimenter wrapper class 36 | experiment = eegtoolkit.experiment.Experimenter; 37 | experiment.session = sess; 38 | % Add the preprocessing steps (order is taken into account) 39 | experiment.preprocessing = {ss,df}; 40 | experiment.featextraction = extr; 41 | experiment.classification = classif; 42 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 43 | experiment.run(); 44 | for i=1:length(experiment.results) 45 | accuracies(i) = experiment.results{i}.getAccuracy(); 46 | end 47 | 48 | accuracies' 49 | %mean accuracy for all subjects 50 | fprintf('mean acc = %f\n', mean(accuracies)); 51 | %get the configuration used (for reporting) 52 | % experiment.getExperimentInfo 53 | % experiment.getTime -------------------------------------------------------------------------------- /exampleITCCA.m: -------------------------------------------------------------------------------- 1 | m_secs = 0.5:0.5:4; 2 | for ii=1:8 3 | for jj = 1:8 4 | sess = eegtoolkit.util.Session; 5 | % sess.loadAll(4); 6 | % sess.loadAll(4); 7 | sess.loadSubject(4,ii); 8 | ss = eegtoolkit.preprocessing.SampleSelection; 9 | ss.channels = 1:8; 10 | ss.sampleRange = [75,74+256*m_secs(jj)]; 11 | % ss.sampleRange = [1,1140]; 12 | % 75:1024+74 13 | h = fdesign.bandpass('N,F3dB1,F3dB2',10,6,80,256); 14 | d1 = design(h,'butter'); 15 | df = eegtoolkit.preprocessing.DigitalFilter; % 16 | df.filt = d1; 17 | 18 | refer = eegtoolkit.preprocessing.Rereferencing; 19 | refer.meanSignal = 1; 20 | 21 | extr = eegtoolkit.featextraction.RawSignal; 22 | 23 | classif = eegtoolkit.classification.ITCCA; 24 | classif.baseClassifier = eegtoolkit.classification.MaxChooser; 25 | 26 | experiment = eegtoolkit.experiment.Experimenter; 27 | experiment.session = sess; 28 | experiment.preprocessing = {ss,refer,df}; 29 | experiment.featextraction = extr; 30 | experiment.classification = classif; 31 | % experiment.evalMethod = experiment.EVAL_METHOD_LOOCV; 32 | % experiment.run(); 33 | experiment.evalMethod = experiment.EVAL_METHOD_LOBO; 34 | experiment.run(); 35 | for i=1:length(experiment.results) 36 | accuracy(i) = experiment.results{i}.getAccuracy(); 37 | end 38 | acc2(ii,jj) = mean(accuracy); 39 | % accuracy = experiment.results{1}.getAccuracy(); 40 | 41 | end 42 | end -------------------------------------------------------------------------------- /exampleL1MCCA.m: -------------------------------------------------------------------------------- 1 | 2 | sess = eegtoolkit.util.Session; 3 | sess.loadSubject(4,1); 4 | % load filters/epocfilter; 5 | 6 | sti_f = [9.25, 11.25, 13.25, 9.75, 11.75, 13.75, 10.25, 12.25, 14.25, 10.75, 12.75, 14.75];%Reference signals - 7 | extr = eegtoolkit.featextraction.L1MCCA; 8 | 9 | refer = eegtoolkit.preprocessing.Rereferencing; 10 | refer.meanSignal = 1; 11 | 12 | [z,p,k]=butter(3,[6,80]/128); 13 | % [z,p,k]=butter(3,[5,48]/125); 14 | [s,g]=zp2sos(z,p,k); 15 | Hd = dfilt.df2sos(s,g); 16 | 17 | m_secs = 5; 18 | ss = eegtoolkit.preprocessing.SampleSelection; 19 | ss.sampleRange = [1,1114]; % Specify the sample range to be used for each Trial 20 | ss.channels = [1:8];%Specify the channel(s) to be used 21 | % 22 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 23 | df.filt = Hd; % Hbp is a filter built with "filterbuilder" matlab function 24 | 25 | lcca = eegtoolkit.classification.L1MCCA(256,1114/256,4,sti_f); 26 | 27 | experiment = eegtoolkit.experiment.Experimenter; 28 | experiment.session = sess; 29 | experiment.preprocessing = {ss,refer,df};% Order of preprocessing steps matters. 30 | experiment.featextraction = extr; 31 | experiment.classification = lcca; 32 | experiment.evalMethod = experiment.EVAL_METHOD_LOBO; % specify that you want a "leave one subject out" (default is LOOCV) 33 | %run the experiment 34 | experiment.run(); 35 | accuracies = []; 36 | for i=1:length(experiment.results) 37 | accuracies(i) = experiment.results{i}.getAccuracy(); 38 | end 39 | accuracies' 40 | %mean accuracy for all subjects 41 | fprintf('mean acc = %.2f\n', mean(accuracies)); -------------------------------------------------------------------------------- /exampleLSL.m: -------------------------------------------------------------------------------- 1 | %Add dependencies to the Matlab path, LibLSL is required for this example 2 | %to work 3 | % addpath liblsl-Matlab\; 4 | % addpath liblsl-Matlab\bin\; 5 | % addpath liblsl-Matlab\mex\; 6 | %Initialize LSL Wrapper class 7 | % h = errordlg('Cannot find GazeTheWeb','Error'); 8 | % error('Cannot find GazeTheWeb'); 9 | try 10 | pathtogaze = winqueryreg('HKEY_LOCAL_MACHINE','SOFTWARE\MAMEM','GAZETHEWEBPATH'); 11 | catch 12 | pathtogaze = ''; 13 | end 14 | try 15 | pathtoepoc = winqueryreg('HKEY_LOCAL_MACHINE','SOFTWARE\MAMEM','EPOCPATH'); 16 | catch 17 | pathtoepoc = ''; 18 | end 19 | datastream = 'EMOTIVStream'; 20 | eventstream = 'BrowserOutputStream'; 21 | answer = inputdlg({'Path to GazeTheWeb','Path to EPOC','Data Stream','Event Stream'},'Setup',1,{pathtogaze,pathtoepoc,datastream,eventstream}); 22 | pathtogaze = answer{1}; 23 | pathtoepoc = answer{2}; 24 | datastream = answer{3}; 25 | eventstream = answer{4}; 26 | 27 | % system(['start "EPOC2LSL" cmd /c "' pathtoepoc '"']); 28 | system(['pushd ' pathtoepoc ' &start cmd /c EPOC2LSL.exe']); 29 | disp(['pushd ' pathtogaze ' & start cmd /c Client.exe http://160.40.50.238/mamem']); 30 | system(['pushd ' pathtogaze ' &start cmd /c Client.exe http://160.40.50.238/mamem']); 31 | % try 32 | % pathtogaze = winqueryreg('HKEY_LOCAL_MACHINE','SOFTWARE\MAMEM','GAZETHEWEBPATH'); 33 | % pathtoepoc = winqueryreg('HKEY_LOCAL_MACHINE','SOFTWARE\MAMEM','EPOCPATH'); 34 | % % system(['start "GazeTheWeb" cmd /c "' pathtogaze '"']);%build\EPOC2LSL\EPOC2LSL.exe']); 35 | % % system('start "GazeTheWeb" cmd /c cd "C:\Users\MAMEM\Downloads\Gaze-exe (11)\Client.exe"'); 36 | % % system('start "GazeTheWeb" cmd /c pushd C:\Users\MAMEM\Downloads\Gaze-exe (11) & call Client.exe"'); 37 | % % system('cd "C:\Users\MAMEM\Downloads\Gaze-exe (11) & Client.exe"'); 38 | % % system(pathtogaze); 39 | % % disp(['start "EPOC2LSL" cmd /c "' pathtoepoc '"']); 40 | % system(['start "EPOC2LSL" cmd /c "' pathtoepoc '"']); 41 | % % system('pushd C:\Users\MAMEM\Downloads\Gaze-exe (11) &start cmd /c Client.exe http://160.40.50.238/mamem'); 42 | % % system('start "Gaze" cmd /c C: & C: & cd "C:\Users\MAMEM\Downloads\Gaze-exe (11)" &start cmd /c Client.exe http://160.40.50.238/mamem/'); 43 | % % system(['start "GazeTheWeb" cmd /c C: & cd C:\Users\MAMEM\Downloads\Gaze-exe (11) & Client.exe"&']); 44 | % catch 45 | % pathtogaze = ''; 46 | % path 47 | % warning('GazeTheWeb is not installed'); 48 | % end 49 | lsl = eegtoolkit.util.LSLWrapper; 50 | %Size of signal that will be used for the recognition task 51 | bufferSize = 5; %in seconds 52 | %The event code that will trigger the recognition task 53 | eventCode = 100; 54 | 55 | 56 | % RECOGNITION ALGORITHM CONFIGURATION 57 | 58 | %Indicate the number of stimuli (5) and their frequencies 59 | stimulus_frequencies = [12 10 8.57 7.5 6.66]; 60 | 61 | %Filtering the eeg data 62 | % df = eegtoolkit.preprocessing.DigitalFilter; 63 | % %This filter was created via the 'filterbuilder' method of Matlab 64 | % df.filt = Hbp; 65 | 66 | %Indicate which channels of the data (different electrodes) will be used 67 | ss = eegtoolkit.preprocessing.SampleSelection; 68 | %We will use all EPOC channels for this example 69 | channels = 1:1:14; 70 | ss.channels = channels; 71 | ss.sampleRange = [1,128]; 72 | 73 | %Sampling rate for the EPOC headset is 128Hz 74 | samplingRate = 128; 75 | 76 | %Another required parameter for the CCA algorithm 77 | numberOfHarmonics = 4; 78 | %Initialize the Canonical Correlation Analysis class for the stimuli 79 | %recognition 80 | cca = eegtoolkit.featextraction.CCA(stimulus_frequencies,channels,samplingRate,numberOfHarmonics); 81 | 82 | %Simple classifier that uses the max value of the features to assign the 83 | %label 84 | maxC = eegtoolkit.classification.MaxChooser; 85 | 86 | %Assign the algorithm configuration to the LSL Wrapper class 87 | lsl.preprocessing = {ss}; 88 | lsl.featextraction = cca; 89 | lsl.classification = maxC; 90 | 91 | %Find the streams in the network 92 | lsl.resolveStreams(datastream,bufferSize,eventstream); 93 | %Pause for 5 seconds to allow the stream to gather some data 94 | % pause(bufferSize); 95 | %Run the recognition task. The task runs indefinetely until is specifically 96 | %interrupted 97 | lsl.runSSVEP(eventCode); 98 | -------------------------------------------------------------------------------- /exampleLateFusion.m: -------------------------------------------------------------------------------- 1 | % Leave one subject out testing 2 | % load filtMAMEM; % load a filter 3 | % sess = eegtoolkit.util.Session(Hhp); 4 | % sess.loadAll(1); %its best to do this once, outside the script (too much 5 | % time) 6 | % transf = eegtoolkit.transformer.PWelchTransformer(); 7 | % Load the data. Call this once outside of the script so you dont have to 8 | % load the data again and again. Make sure the dataset is included in your 9 | % Matlab path 10 | % sess = eegtoolkit.util.Session; 11 | % sess.loadAll(1); %Loads dataset I 12 | 13 | %Load a filter from the samples 14 | load filters/filt_IIRElliptic; 15 | 16 | 17 | 18 | refer = eegtoolkit.preprocessing.Rereferencing; 19 | %Subtract the mean from the signal 20 | refer.meanSignal = 1; 21 | 22 | ss = eegtoolkit.preprocessing.SampleSelection; 23 | ss.sampleRange = [1,1250]; % Specify the sample range to be used for each Trial 24 | ss.channels = [138,139,150]; % Specify the channel(s) to be used 25 | 26 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 27 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 28 | 29 | 30 | %Extract features with the pwelch method 31 | extr1 = eegtoolkit.featextraction.PWelch; 32 | extr1.channel = 1; % will use channel 138 33 | 34 | extr2 = eegtoolkit.featextraction.PWelch; 35 | extr2.channel = 2; % will use channel 139 36 | 37 | extr3 = eegtoolkit.featextraction.PWelch; 38 | extr3.channel = 3; % will use channel 150 39 | 40 | extr = {extr1,extr2,extr3}; 41 | % Generate a special feature vector to be used with fusion classifier 42 | aggr = eegtoolkit.aggregation.LateFusion; 43 | %Configure the classifier 44 | % Generate 3 instances of the "baseClassifier" and output the label by 45 | % majority vote 46 | classif = eegtoolkit.classification.FusionClassifierWrapper; 47 | classif.baseClassifier = eegtoolkit.classification.LIBSVM; 48 | 49 | %Set the Experimenter wrapper class 50 | experiment = eegtoolkit.experiment.Experimenter; 51 | experiment.session = sess; 52 | % Add the preprocessing steps (order is taken into account) 53 | experiment.preprocessing = {ss,refer,df}; 54 | experiment.featextraction = {extr1,extr2,extr3}; 55 | experiment.aggregator = aggr; 56 | experiment.classification = classif; 57 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 58 | experiment.run(); 59 | for i=1:length(experiment.results) 60 | accuracies(i) = experiment.results{i}.getAccuracy(); 61 | end 62 | 63 | accuracies' 64 | %mean accuracy for all subjects 65 | fprintf('mean acc = %f\n', mean(accuracies)); 66 | %get the configuration used (for reporting) 67 | experiment.getExperimentInfo 68 | experiment.getTime -------------------------------------------------------------------------------- /exampleMotorPWelch.m: -------------------------------------------------------------------------------- 1 | sess = eegtoolkit.util.Session; 2 | sess.loadAll(6); 3 | % 4 | 5 | % load('testingMotorVag1'); 6 | % % load 7 | % sess = eegtoolkit.util.Session; 8 | % % sess.loadMOTOR(labels,trials); 9 | % sess.loadVag(trials,labels); 10 | 11 | ss = eegtoolkit.preprocessing.SampleSelection; 12 | ss.channels = [1,3]; 13 | ss.sampleRange = [384,896]; 14 | 15 | extr1 = eegtoolkit.featextraction.PWelch; 16 | extr1.channel = 1; 17 | 18 | extr2 = eegtoolkit.featextraction.PWelch; 19 | extr2.channel = 2; 20 | 21 | aggr = eegtoolkit.aggregation.ChannelConcat; 22 | 23 | classif = eegtoolkit.classification.MLR; 24 | experiment = eegtoolkit.experiment.Experimenter; 25 | experiment.session = sess; 26 | experiment.preprocessing = {ss}; 27 | experiment.featextraction = {extr1, extr2}; 28 | experiment.aggregator = aggr; 29 | experiment.classification = classif; 30 | experiment.evalMethod = experiment.EVAL_METHOD_LOOCV; 31 | % experiment.run(); 32 | % experiment.evalMethod = experiment.EVAL_METHOD_XFOLD_CV; 33 | experiment.run(); 34 | accuracy = experiment.results{1}.getAccuracy(); 35 | 36 | -------------------------------------------------------------------------------- /exampleOptimal.m: -------------------------------------------------------------------------------- 1 | % Load the data. Call this once outside of the script so you dont have to 2 | % load the data again and again. Make sure the dataset is included in your 3 | % Matlab path 4 | % sess = eegtoolkit.util.Session; 5 | % sess.loadAll(1); %Loads dataset I 6 | 7 | %Load a filter from the samples 8 | load filters/filt_IIRElliptic; 9 | 10 | extr = eegtoolkit.featextraction.PWelchExperimental; 11 | extr.nfft = 512; 12 | extr.over_len = 0.75; 13 | extr.win_len = 350; 14 | 15 | amu = eegtoolkit.preprocessing.Amuse; 16 | amu.first = 15; 17 | amu.last = 252; 18 | 19 | refer = eegtoolkit.preprocessing.Rereferencing; 20 | %Subtract the mean from the signal 21 | refer.meanSignal = 1; 22 | 23 | ss = eegtoolkit.preprocessing.SampleSelection; 24 | ss.sampleRange = [1,1250]; % Specify the sample range to be used for each Trial 25 | ss.channels = 138; % Specify the channel(s) to be used 26 | 27 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 28 | df.filt = Hbp; % Hbp is a filter built with "filterbuilder" matlab function 29 | 30 | svd = eegtoolkit.featselection.SVD; 31 | svd.modes = 90; 32 | 33 | %Configure the classifier 34 | classif = eegtoolkit.classification.LIBSVMFast; 35 | 36 | %Set the Experimenter wrapper class 37 | experiment = eegtoolkit.experiment.Experimenter; 38 | experiment.session = sess; 39 | % Add the preprocessing steps (order is taken into account) 40 | experiment.preprocessing = {amu,ss,refer,df}; 41 | experiment.featselection = svd; 42 | experiment.featextraction = extr; 43 | experiment.classification = classif; 44 | experiment.evalMethod = experiment.EVAL_METHOD_LOSO; % specify that you want a "leave one subject out" (default is LOOCV) 45 | experiment.run(); 46 | for i=1:length(experiment.results) 47 | accuracies(i) = experiment.results{i}.getAccuracy(); 48 | end 49 | 50 | accuracies' 51 | %mean accuracy for all subjects 52 | fprintf('mean acc = %f\n', mean(accuracies)); 53 | %get the configuration used (for reporting) 54 | experiment.getExperimentInfo 55 | experiment.getTime 56 | -------------------------------------------------------------------------------- /exampleSMFA.m: -------------------------------------------------------------------------------- 1 | clear 2 | 3 | % fileID = fopen('SMFA_Results.txt','a'); 4 | for subn=1:10 5 | 6 | %Dataset 4 7 | sess = eegtoolkit.util.Session; 8 | % sess.loadAll(4); 9 | sess.loadSubject(4,subn); 10 | 11 | % %Dataset 2 12 | % sess = ssveptoolkit.util.Session; 13 | % sess.loadAll(2); 14 | 15 | load filters/filt_IIRElliptic; 16 | 17 | %Dataset 4 18 | % sti_f = [9.25, 11.25, 13.25, 9.75, 11.75, 13.75, 10.25, 12.25, 14.25, 10.75, 12.75, 14.75]; 19 | % extr = ssveptoolkit.featextraction.CCA(sti_f,[1:8],256,4); 20 | 21 | extr = eegtoolkit.featextraction.MLR_Transf(1:8); 22 | % sti_f = [9.25, 9.75, 10.25, 10.75, 11.25, 11.75, 12.25, 12.75, 13.25, 13.75, 14.25, 14.75]; 23 | % extr = ssveptoolkit.featextraction.CCA(sti_f,1:8,256,4); 24 | 25 | %%Dataset 2 26 | % sti_f = [12 10 8.57 7.50 6.66]; 27 | % sti_f = [6.66 7.5 8.57 10 12]; 28 | % extr = ssveptoolkit.featextraction.CCA(sti_f,[1:2],250,4); 29 | 30 | % extr = ssveptoolkit.featextraction.OMP(sti_f,[1:2],250,4,16,0); 31 | %sti_f: reference signals 32 | %[1:2]: input=2 channels. Depends on what you set on "ss.channels" e.g. if 33 | %you select 10 channels you need to set "[1:10]" 34 | %250: sampling rate (Dataset 1&2=250) 35 | %4: number of harmonics of the reference signals 36 | 37 | % %Dataset 2 38 | % amu = ssveptoolkit.preprocessing.Amuse; 39 | % amu.first = 15; 40 | % amu.last = 252; 41 | 42 | refer = eegtoolkit.preprocessing.Rereferencing; 43 | %Subtract the mean from the signal 44 | refer.meanSignal = 1; 45 | 46 | %Dataset 4 47 | % m_secs = 2; 48 | 49 | % %Dataset 2 50 | % m_secs = 5; 51 | 52 | ss = eegtoolkit.preprocessing.SampleSelection; 53 | 54 | %Dataset 4 55 | onset=39; 56 | %delay of the visual system 57 | visual_delay = 35; 58 | ss.sampleRange = [onset+visual_delay+1,onset+visual_delay+1*256]; 59 | ss.channels = 1:8; 60 | % ss.channels = 7; 61 | 62 | % %Dataset 2 63 | % ss.sampleRange = [1,250*m_secs]; % Specify the sample range to be used for each Trial 64 | % % ss.channels = [116,126,137,138,139,147,150];%[126,138]%Specify the channel(s) to be used 65 | % ss.channels = [126,138]; 66 | 67 | %Dataset 4 68 | df = eegtoolkit.preprocessing.DigitalFilter; % Apply a filter to the raw data 69 | [z,p,k]=butter(3,[6,80]/128); 70 | [s,g]=zp2sos(z,p,k); 71 | Hd = dfilt.df2sos(s,g); 72 | df.filt = Hd; 73 | 74 | Res = zeros(length(1:4:10),length(1:4:100)); 75 | 76 | % Set parameter grid to search 77 | % for qq=1:10 78 | % for ww=1:25 79 | 80 | %Number of subclasses per class 81 | NumS = 2*ones(1,12); 82 | 83 | S = 0.4; 84 | % kInt = qq; 85 | % kPen = 4*(ww-1)+1; 86 | kInt = 3; 87 | kPen = 50; 88 | classif = eegtoolkit.classification.SMFA(0,NumS,S,kInt,kPen); 89 | 90 | experiment = eegtoolkit.experiment.Experimenter; 91 | experiment.session = sess; 92 | 93 | %Dataset 4 94 | experiment.preprocessing = {ss,refer,df}; 95 | 96 | % %Dataset 2 97 | % experiment.preprocessing = {amu,ss,refer,df};% Order of preprocessing steps matters. 98 | 99 | experiment.featextraction = extr; 100 | experiment.classification = classif; 101 | experiment.evalMethod = experiment.EVAL_METHOD_LOBO; % specify that you want a "leave one subject out" (default is LOOCV) 102 | % experiment.evalMethod = experiment.EVAL_METHOD_LOOCV; 103 | 104 | %run the experiment 105 | experiment.run(); 106 | accuracies = []; 107 | for i=1:length(experiment.results) 108 | accuracies(i) = experiment.results{i}.getAccuracy(); 109 | end 110 | % accuracies' 111 | % mean accuracy for all subjects 112 | % fprintf('mean acc = %.2f\n', mean(accuracies)); 113 | subaccuracies(subn) = mean(accuracies); 114 | end 115 | fprintf('mean acc for all subjects %.2f\n',mean(subaccuracies)); -------------------------------------------------------------------------------- /filters/epocfilter.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MAMEM/eeg-processing-toolbox/5a03abe2a6a874e9adaceea29a52c2fce35d8a03/filters/epocfilter.mat -------------------------------------------------------------------------------- /filters/filt_IIRElliptic.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MAMEM/eeg-processing-toolbox/5a03abe2a6a874e9adaceea29a52c2fce35d8a03/filters/filt_IIRElliptic.mat --------------------------------------------------------------------------------