InitialReal

This commit is contained in:
2026-02-16 17:12:24 -06:00
parent 3aba4a5a41
commit ebaa8f416b
9 changed files with 337 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,57 @@
%%
clear all
close all
clc
%% Import Data
load('data.mat');
%% Example: Plot the raw signal
signal=Flex.signal;
labels=Flex.trigger;
TRIG = gettrigger(labels,0.5);
TRIGend = gettrigger(-labels,-0.5);
figure('units','normalized','Position',[0.1,0.1,0.7,0.4])
plot((1:length(signal))./fs,zscore(signal));
hold on;
plot((1:length(signal))./fs,zscore(labels),'y');
stem(TRIG./fs,ones(length(TRIG),1)*max(zscore(labels)),'Color','g');
stem(TRIGend./fs,ones(length(TRIG),1)*max(zscore(labels)),'Color','r');
grid on; grid minor;
xlim([0,length(signal)./fs])
xlabel('Time (s)')
ylabel('Amplitude (uV)')
title('Raw VF signal with labels for stimulation periods')
%% Example: PSD estimates
figure('units','normalized','Position',[0.1,0.1,0.5,0.5])
[rows_act,cols_act,values_act] = find(labels>0);
[rows_rest1,cols_rest,values_rest] = find(labels==0);
notOfInterest = signal(rows_rest1);
signalOfInterest=signal(rows_act);
h = spectrum.welch; % creates the Welch spectrum estimator
SOIf=psd(h,signalOfInterest,'Fs',fs); % calculates and plot the one sided PSD
plot(SOIf); % Plot the one-sided PSD.
temp =get(gca);
temp.Children(1).Color = 'b';
% %% Bandpass Filtering
%
% fc1 = 0; % first cutoff frequency in Hz
% fc2 = 100; % second cutoff frequency in Hz
%
% % normalize the frequencies
% Wp = [fc1 fc2]*2/fs;
% Build a Butterworth bandpass filter of 4th order
% check the "butter" function in matlab
% Filter data of both classes with a non-causal filter
% Hint: use "filtfilt" function in MATLAB
% filteredSignal = ;
%%

View File

@@ -0,0 +1,35 @@
filteredSignal = ; % bandapass filtered signal
label = ; % labels of stimulus locations
WSize = ; % window size in s
Olap = ; % overlap percentage
%% Extracting Features over overlapping windows
WSize = floor(WSize*fs); % length of each data frame, 30ms
nOlap = floor(Olap*WSize); % overlap of successive frames, half of WSize
hop = WSize-nOlap; % amount to advance for next data frame
nx = length(signal); % length of input vector
len = fix((nx - (WSize-hop))/hop); %length of output vector = total frames
% preallocate outputs for speed
[MAV_feature, VAR_feature, featureLabels] = deal(zeros(1,len));
Rise1 = gettrigger(label,0.5); % gets the starting points of stimulations
Fall1 = gettrigger(-label,-0.5); % gets the ending points of stimulations
for i = 1:len
segment = filteredSignal(((i-1)*hop+1):((i-1)*hop+WSize));
MAV_feature(i) = ;
VAR_feature(i) = ;
% re-build the label vector to match it with the feature vector
featureLabels(i) = sum(arrayfun(@(t) ((i-1)*hop+1) >= Rise1(t) && ((i-1)*hop+WSize) <= Fall1(t), 1:length(Rise1)));
end
%% Plotting the features
% Note: when plotting the features, scale the featureLabels to the max of
% the feature values for proper visualization

View File

@@ -0,0 +1,107 @@
close all;clc;
%%
% Inputs:
% --------
% MAVClass1: the features of the VF case (stimulus and rest features)
% MAVClass2: the features of the Pinch case (stimulus and rest features)
% TriggerClass1: labels for VF features (stimulus or rest label)
% TriggerClass2: labels for Pinch features (stimulus or rest label)
% Build the datasets
MAV_class1 = MAVClass1(find(TriggerClass1==1));
MAV_rest1 = MAVClass1(find(TriggerClass1==0));
VAR_class1 = VARClass1(find(TriggerClass1==1));
VAR_rest1 = VARClass1(find(TriggerClass1==0));
MAV_class2 = MAVClass2(find(TriggerClass2==1));
MAV_rest2 = MAVClass2(find(TriggerClass2==0));
VAR_class2 = VARClass2(find(TriggerClass2==1));
VAR_rest2 = VARClass2(find(TriggerClass2==0));
% Concantenate the rest classes
MAV_rest = [MAV_rest1 MAV_rest2];
VAR_rest = [VAR_rest1 VAR_rest2];
%%
% Class1 vs Rest dataset
MAV_Data_Class1vsRest = [MAV_class1 MAV_rest];
MAV_Labels_Class1vsRest = [ones(1,length(MAV_class1)) 2*ones(1,length(MAV_rest))];
VAR_Data_Class1vsRest = [VAR_class1 VAR_rest];
VAR_Labels_Class1vsRest = MAV_Labels_Class1vsRest;
% Class2 vs Rest dataset
MAV_Data_Class2vsRest = [MAV_class2 MAV_rest];
MAV_Labels_Class2vsRest = [ones(1,length(MAV_class2)) 2*ones(1,length(MAV_rest))];
VAR_Data_Class2vsRest = [VAR_class2 VAR_rest];
VAR_Labels_Class2vsRest = MAV_Labels_Class2vsRest;
% Class1 vs Class2 dataset
MAV_Data_Class1vsClass2 = [MAV_class1 MAV_class2];
MAV_Labels_Class1vsClass2 = [ones(1,length(MAV_class1)) 2*ones(1,length(MAV_class2))];
VAR_Data_Class1vsClass2 = [VAR_class1 VAR_class2];
VAR_Labels_Class1vsClass2 = MAV_Labels_Class1vsClass2;
%%
% Both feature datasets
MAVVAR_Data_Class1vsRest = [MAV_Data_Class1vsRest; VAR_Data_Class1vsRest];
MAVVAR_Labels_Class1vsRest = MAV_Labels_Class1vsRest;
MAVVAR_Data_Class2vsRest = [MAV_Data_Class2vsRest; VAR_Data_Class2vsRest];
MAVVAR_Labels_Class2vsRest = MAV_Labels_Class2vsRest;
MAVVAR_Data_Class1vsClass2 = [MAV_Data_Class1vsClass2; VAR_Data_Class1vsClass2];
MAVVAR_Labels_Class1vsClass2 = MAV_Labels_Class1vsClass2;
%%
% Classify all combinations (training set)
k = 10; % for k-fold cross validation
c1 = cvpartition(length(MAV_Labels_Class1vsRest),'KFold',k);
c2 = cvpartition(length(VAR_Labels_Class1vsRest),'KFold',k);
c3 = cvpartition(length(MAVVAR_Labels_Class1vsRest),'KFold',k);
c4 = cvpartition(length(MAV_Labels_Class2vsRest),'KFold',k);
c5 = cvpartition(length(VAR_Labels_Class2vsRest),'KFold',k);
c6 = cvpartition(length(MAVVAR_Labels_Class2vsRest),'KFold',k);
c7 = cvpartition(length(MAV_Labels_Class1vsClass2),'KFold',k);
c8 = cvpartition(length(VAR_Labels_Class1vsClass2),'KFold',k);
c9 = cvpartition(length(MAVVAR_Labels_Class1vsClass2),'KFold',k);
% Repeat the following for i=1:k, and average performance metrics across all iterations
i=1;
% loop over all k-folds and avergae the performance
% for i=1:k
[TstMAVFC1Rest TstMAVErrC1Rest] = classify(MAV_Data_Class1vsRest(c1.test(i))',MAV_Data_Class1vsRest(c1.training(i))',MAV_Labels_Class1vsRest(c1.training(i)));
[TstCM_MAV_C1rest dum1 TstAcc_MAV_C1rest dum2] = confusion(MAV_Labels_Class1vsRest(c1.test(i)), TstMAVFC1Rest);
[TstVARFC1Rest TstVARErrC1Rest] = classify(VAR_Data_Class1vsRest(c2.test(i))',VAR_Data_Class1vsRest(c2.training(i))',VAR_Labels_Class1vsRest(c2.training(i)));
[TstCM_VAR_C1rest dum1 TstAcc_VAR_C1rest dum2] = confusion(VAR_Labels_Class1vsRest(c2.test(i)), TstVARFC1Rest);
[TstMAVVARFC1Rest TstMAVVARErrC1Rest] = classify(MAVVAR_Data_Class1vsRest(:,c3.test(i))',MAVVAR_Data_Class1vsRest(:,c3.training(i))',MAVVAR_Labels_Class1vsRest(c3.training(i)));
[TstCM_MAVVAR_C1rest dum1 TstAcc_MAVVAR_C1rest dum2] = confusion(MAVVAR_Labels_Class1vsRest(c3.test(i)), TstMAVVARFC1Rest);
% Class2 vs Rest
[TstMAVFC2Rest TstMAVErrC2Rest] = classify(MAV_Data_Class2vsRest(c4.test(i))',MAV_Data_Class2vsRest(c4.training(i))',MAV_Labels_Class2vsRest(c4.training(i)));
[TstCM_MAV_C2rest dum1 TstAcc_MAV_C2rest dum2] = confusion(MAV_Labels_Class2vsRest(c4.test(i)), TstMAVFC2Rest);
[TstVARFC2Rest TstVARErrC2Rest] = classify(VAR_Data_Class2vsRest(c5.test(i))',VAR_Data_Class2vsRest(c5.training(i))',VAR_Labels_Class2vsRest(c5.training(i)));
[TstCM_VAR_C2rest dum1 TstAcc_VAR_C2rest dum2] = confusion(VAR_Labels_Class2vsRest(c5.test(i)), TstVARFC2Rest);
[TstMAVVARFC2Rest TstMAVVARErrC2Rest] = classify(MAVVAR_Data_Class2vsRest(:,c6.test(i))',MAVVAR_Data_Class2vsRest(:,c6.training(i))',MAVVAR_Labels_Class2vsRest(c6.training(i)));
[TstCM_MAVVAR_C2rest dum1 TstAcc_MAVVAR_C2rest dum2] = confusion(MAVVAR_Labels_Class2vsRest(c6.test(i)), TstMAVVARFC2Rest);
% Class1 vs Class2
[TstMAVFC1C2 TstMAVErrC1C2] = classify(MAV_Data_Class1vsClass2(c7.test(i))',MAV_Data_Class1vsClass2(c7.training(i))',MAV_Labels_Class1vsClass2(c7.training(i)));
[TstCM_MAV_C1C2 dum1 TstAcc_MAV_C1C2 dum2] = confusion(MAV_Labels_Class1vsClass2(c7.test(i)), TstMAVFC1C2);
[TstVARFC1C2 TstVARErrC1C2] = classify(VAR_Data_Class1vsClass2(c8.test(i))',VAR_Data_Class1vsClass2(c8.training(i))',VAR_Labels_Class1vsClass2(c8.training(i)));
[TstCM_VAR_C1C2 dum1 TstAcc_VAR_C1C2 dum2] = confusion(VAR_Labels_Class1vsClass2(c8.test(i)), TstVARFC1C2);
[TstMAVVARFC1C2 TstMAVVARErrC1C2] = classify(MAVVAR_Data_Class1vsClass2(:,c9.test(i))',MAVVAR_Data_Class1vsClass2(:,c9.training(i))',MAVVAR_Labels_Class1vsClass2(c9.training(i)));
[TstCM_MAVVAR_C1C2 dum1 TstAcc_MAVVAR_C1C2 dum2] = confusion(MAVVAR_Labels_Class1vsClass2(c9.test(i)), TstMAVVARFC1C2);
% end
%%

View File

@@ -0,0 +1,78 @@
function [ConfMatClass ConfMatAll Accuracy Error] = confusion(TrueLabels, FoundLabels)
% function [ConfMatClass ConfMatAll Accuracy Error] =
% eegc3_confusion_matrix(TrueLabels, FoundLabels)
%
% Function to recover a confusion matric of classification problem given
% the groiund truth classes and the classes found by a classifier
%
% Inputs:
%
% TrueLabels: Ground truth data labels
%
% FoundLabels: Labels predicted by a classifier
%
% Outputs:
%
% ConfMatClass: Confusion Matrx ClassNum x ClassNum in percentages per
% class
%
% ConfMatAll: Confusion Matrx ClassNum x ClassNum in overall percentages
%
% Accuracy: Total accuracy % (diagonal of Confusion Matrix)
%
% Error: Total Error % (100 - Accuracy)
if(~isvector(TrueLabels) || ~isvector(FoundLabels))
disp('[eegc3_confusion_matrix] Labels must be vectors');
ConfMat = [];
Accuracy = [];
Error = [];
return;
end
N1 = length(TrueLabels);
N2 = length(FoundLabels);
if(N1 ~= N2)
disp('[confusion] True and predicted labels must be the same size');
ConfMat = [];
Accuracy = [];
Error = [];
return;
else
NSample = N1;
end
% Find number of classes
Classes = sort(unique(TrueLabels));
NClass = length(Classes);
if(~isequal(Classes,[1:NClass]) && ~isequal(Classes,[1:NClass]'))
disp('[confusion] Classes must be a vector [1:N] or [1:N]');
end
% Compute Confusion Matrix
ConfMat = zeros(NClass);
ConfMatAll = zeros(NClass);
for i=1:NSample
ConfMat(TrueLabels(i),FoundLabels(i)) = ...
ConfMat(TrueLabels(i),FoundLabels(i)) + 1;
end
ConfMatAll = 100*ConfMat/sum(ConfMat(:));
ConfMatClass = zeros(NClass);
for i=1:NClass
ConfMatClass(i,:) = 100*ConfMat(i,:)/sum(ConfMat(i,:));
end
Accuracy = trace(ConfMatAll);
Error = 100 - Accuracy;

Binary file not shown.

View File

@@ -0,0 +1,60 @@
function TRIG = gettrigger(s,TH,rfp);
% GETTRIGGER identifies trigger points
%
% TRIG = gettrigger( s [,TH [,rfp]]); % trigger at ascending edge
% TRIG = gettrigger(-s [,TH [,rfp]]); % trigger at decending edge
%
% input : s signal
% TH Threshold; default: (max+min)/2
% rfp refractory period (default=0)
% output: TRIG TRIGGER time points
%
% see also: TRIGG
% $Id: gettrigger.m,v 1.4 2008/04/15 14:58:50 schloegl Exp $
% Copyright (C) 2002-2003,2008 by Alois Schloegl <a.schloegl@ieee.org>
% This library is free software; you can redistribute it and/or
% modify it under the terms of the GNU Library General Public
% License as published by the Free Software Foundation; either
% Version 2 of the License, or (at your option) any later version.
%
% This library is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
% Library General Public License for more details.
%
% You should have received a copy of the GNU Library General Public
% License along with this library; if not, write to the
% Free Software Foundation, Inc., 59 Temple Place - Suite 330,
% Boston, MA 02111-1307, USA.
if nargin<2,
TH = (max(s)+min(s))/2;
end;
if nargin<3,
rfp = 0;
end;
TRIG = find(diff(sign(s-TH))>0)+1;
% perform check of trigger points
if (rfp<=0), return; end;
% refractory period
k0=1;
k1=2;
while k1<length(TRIG);
T0 = TRIG(k0);
T1 = TRIG(k1);
if (T1-T0)<rfp,
TRIG(k1)=NaN;
else
k0 = k1;
end
k1 = k1+1;
end;
TRIG=TRIG(~isnan(TRIG));