GRABMyoFlow - Dataset extension 1.0.0

File: <base>/grabmyoflow_feature_extraction.m (6,145 bytes)
% =========================================================================
% Feature Extraction Script for GRABMyoFlow (Wrist Data)
% =========================================================================
% This script processes the .mat files generated by the Python converter.
% It extracts features for the WRIST electrodes (using the first 6 channels).
%
% INPUT:
% - Folder generated by Python script (e.g., 'static_extension_MATLAB')
% - Structure: Root/SessionX/sessionX_participantY.mat
%
% OPTIONS:
% 1. Whole Set (W): IDs 1-63
% 2. Extension Set (E): IDs 44-63
% 3. Original Set (O): IDs 1-43
%
% OUTPUT:
% - Folder: 'Feature_Extracted_BM_[POSTFIX]'
% - Files: 'Wrist_Session1_[POSTFIX].mat', etc.
% =========================================================================

clear; clc;

% =========================================================================
% STEP 1: USER CONFIGURATION
% =========================================================================

disp('---------------------------------------------------------');
disp('   GRABMyoFlow Wrist Feature Extraction');
disp('---------------------------------------------------------');
disp('Which dataset do you want to process?');
disp(' [W] Whole Dataset     (IDs 1-63)');
disp(' [E] Extension Only    (IDs 44-63)');
disp(' [O] Original Only     (IDs 1-43)');
disp('---------------------------------------------------------');

choice = input('Enter selection (W/E/O): ', 's');

if strcmpi(choice, 'W')
    sub_list = 1:63;
    dataset_postfix = '_whole_set';
    default_title = 'Select the "static_whole_MATLAB" folder';
elseif strcmpi(choice, 'E')
    sub_list = 44:63;
    dataset_postfix = '_extension_set';
    default_title = 'Select the "static_extension_MATLAB" or the "static_whole_MATLAB" folder';
elseif strcmpi(choice, 'O')
    sub_list = 1:43;
    dataset_postfix = '_original_set';
    default_title = 'Select the "static_whole_MATLAB" or the original "Output_BM"(from grabmyo) folder';
else
    error('Invalid selection. Please run script again and type W, E, or O.');
end

% Select the input folder
fprintf('\nPlease select the folder containing the converted MAT files...\n');
base_input_folder = uigetdir(pwd, default_title);

if base_input_folder == 0
    error('No folder selected.');
end

% Constants
fs = 2048;              % Sampling frequency
NGESTURE = 16;          % Total number of gestures (Script loads 1:NGESTURE+1 for rest)
NTRIALS = 7;            % Total number of trials
NSESSION = 3;           % Number of sessions

% Define Output Folder with Postfix
output_dir = [pwd filesep 'Feature_Extracted_BM' dataset_postfix];
if ~exist(output_dir, 'dir')
    mkdir(output_dir);
    fprintf('Created output folder: %s\n', output_dir);
else
    fprintf('Output folder exists (%s). Overwriting content...\n', output_dir);
end

% =========================================================================
% STEP 2: LOAD AND FLATTEN DATA
% =========================================================================

for isession = 1:NSESSION
    CompleteSet = []; 
    current_session_folder = [base_input_folder filesep 'Session' num2str(isession)];

    if ~exist(current_session_folder, 'dir')
        warning(['Session folder not found: ' current_session_folder]);
        continue;
    end    

    fprintf('\nProcessing Session %d (%s)...\n', isession, dataset_postfix);   
    valid_sub_count = 0;
    
    for isub = sub_list
        fileName = ['session' num2str(isession) '_participant' num2str(isub) '.mat'];
        filePath = [current_session_folder filesep fileName];
        
        if ~exist(filePath, 'file')
            warning(['File missing: ' fileName]);
            continue;
        end
        
        temp_load = load(filePath, 'DATA_WRIST');
        datafile = temp_load.DATA_WRIST;
        a2 = []; 
        
        for igesture = 1:(NGESTURE + 1)
            a1 = []; 
            for itrial = 1:NTRIALS
                if isempty(datafile{itrial, igesture})
                    warning(['Empty data for Sub ' num2str(isub) ' Ges ' num2str(igesture)]);
                    continue;
                end
                a1 = [a1; datafile{itrial, igesture}];
            end
            a2 = [a2, {a1}];
        end
        
        CompleteSet = [CompleteSet; a2];
        valid_sub_count = valid_sub_count + 1;
        
        if mod(valid_sub_count, 10) == 0
            fprintf('Loaded %d subjects...\n', valid_sub_count);
        end
    end
    
    if isempty(CompleteSet)
        warning(['No data loaded for Session ' num2str(isession) '. Skipping.']);
        continue;
    end

    % =========================================================================
    % STEP 3: SEGMENTATION AND FEATURE EXTRACTION
    % =========================================================================
    
    fprintf('Extracting Features for Session %d...\n', isession);
    
    FeatSet = {};
    num_rows_processed = 0;
    
    for idx = 1:size(CompleteSet, 1)
        
        for igesture = 1:NGESTURE
            OneSet = CompleteSet{idx, igesture}'; 
            post_process = zeros(6, size(OneSet, 2));
            temp_6ch = OneSet(1:6, :); 
            common_avg = mean(temp_6ch, 1);
            for ich = 1:6
                post_process(ich, :) = OneSet(ich, :) - common_avg;
            end
            
            % --- SEGMENTATION ---
            % 0.2s window, 0.15s slide
            segData = segmentEMG(post_process', 0.2, 0.15, NTRIALS*5, fs, 1);
            
            % --- FEATURE EXTRACTION ---
            feat = featiDFTl(2048, 6, segData);
            FeatSet(idx, igesture) = {feat};
        end
        
        num_rows_processed = num_rows_processed + 1;
    end
    
    % Save Result with Postfix
    saveName = [output_dir filesep 'Wrist_Session' num2str(isession) dataset_postfix '.mat'];
    disp(['Saving: ' saveName]);
    save(saveName, 'FeatSet');
    
end

disp('Feature Extraction Complete.');