%% Clear + Global Data 
clear, close all, clc;

nSamples = 300;
lead = 1;
use_pod = false;



%% Create all data matlab files if not exist 

for i=100:234
    actual_path = strcat('C:\Users\mitch\AppData\Roaming\MathWorks\MATLAB Add-Ons\Toolboxes\physionet\database\mitdb\', num2str(i), '.dat');
    full_path = strcat('data\final_data\mitdb_', num2str(i), '_beats.mat');

    if ~exist(actual_path, 'file')
        fprintf("%s --> No Exist\n", num2str(i));
        continue;
    end   

    if ~exist(full_path, 'file')
        fprintf("In here\n");
        read_and_parse_beats(num2str(i), nSamples);
    end

end

%% Read in the beat data and split into leads

for i=100:234
    actual_path = strcat('C:\Users\mitch\AppData\Roaming\MathWorks\MATLAB Add-Ons\Toolboxes\physionet\database\mitdb\', num2str(i), '.dat');
    full_path = strcat('data\final_data\mitdb_', num2str(i), '_beats.mat');

    if ~exist(full_path, 'file')
        continue;
    end

    tmp_beats = load(full_path);
    tmp_lead_beats = beats_to_leads(tmp_beats.beats);

    if i ~= 100
        beats = [beats; squeeze(tmp_lead_beats(1,:,:))];
        beat_type = [beat_type; cell2mat(tmp_beats.beats(:,2))];
        rate = [rate; cell2mat(tmp_beats.beats(:,4))];
        beat_patient = [beat_patient; ones(size(tmp_beats.beats, 1), 1)*i];         
    else
        beat_patient = ones(size(tmp_beats.beats, 1), 1)*i;
        beats = squeeze(tmp_lead_beats(1,:,:));
        beat_type = cell2mat(tmp_beats.beats(:,2));
        rate = cell2mat(tmp_beats.beats(:,4));
    end

    clear tmp_beats;
    clear tmp_lead_beats;

end

save('data\total_data\original.mat', 'beats');
save('data\total_data\meta_data.mat', 'beat_type', 'rate', 'beat_patient');


%% Filter beats

beats = filter_beats(beats);
save('data\total_data\filtered.mat', 'beats');

%% Condition the beats
[beats, condition_variable] = condition_beats(beats, use_pod);
save('data\total_data\conditioned.mat', 'beats');
condvar.shiftVec = condition_variable.shiftVec;
condvar.normVec = condition_variable.normVec;
condvar.negOffset = condition_variable.negOffset;
condvar.threshVal = condition_variable.theshVal;
condvar.meanBeat = condition_variable.meanBeat;
save('data\total_data\condition_variable.mat', 'condvar');
clear condition_variable;

%% Plot Ensemble of 1000 beats
rand_beats = randperm(size(beats,1), 1000);
plt_ensemble(beats(rand_beats, :)');

%% Tailored Sensing on 1000 random 

do_parallel = true;

beats_to_cs = beats(rand_beats, :);
beats_to_cs = beats;

percent_training = 0.5;
compression_ratio = 50;

meanBeat = mean(beats_to_cs, 1);

tic
t_sense_1 = tailored_sensing(beats_to_cs', percent_training, compression_ratio, meanBeat, use_pod, do_parallel);
toc

%% PRD 


t = linspace(1, length(t_sense_1.test_idx), length(t_sense_1.test_idx));

prd_dat = [t_sense_1.eval_stats.prd];
prd1_dat = [t_sense_1.eval_stats.prd1];

subplot(1,2,1), scatter(t, [t_sense_1.eval_stats.rmse]);
subplot(1,2,2), scatter(t, [t_sense_1.eval_stats.rsnr]);

fprintf("CR: [%d] Mean/Min/Max PRD:  [%f] [%f] [%f]\n", compression_ratio, mean(prd_dat), min(prd_dat), max(prd_dat));
fprintf("CR: [%d] Mean/Min/Max PRD1: [%f] [%f] [%f]\n", compression_ratio, mean(prd1_dat), min(prd1_dat), max(prd1_dat));

beat_label = beat_type(t_sense_1.test_idx);
unique_beat_label = unique(beat_label);

for i=1:size(unique_beat_label,1)
    beat_lab = unique_beat_label(i);
    
    index_of_beat = beat_label == beat_lab;

    prd_vals = prd_dat(beat_label == beat_lab);

    fprintf("PRD for [%40s] [%d beats] --> Mean/Min/Max PRD: [%f] [%f] [%f]\n", get_beat_type(beat_lab), length(prd_vals), mean(prd_vals), min(prd_vals), max(prd_vals));
end

%% 

plot(t_sense_1.recon_beats(301,:));
hold on;
plot(beats_to_cs(t_sense_1.test_idx(301),:));
legend('Recovered', 'Original');
hold off;

%% Per Beat Final Data

load('data\total_data\filtered.mat');
load('data\total_data\meta_data.mat');

%%

unq_beat = unique(beat_type);
for i=1:length(unq_beat)
    cur_beat = unq_beat(i);
    abbvr = cellfun(@(c) lower(c(1)), strsplit(get_beat_type(cur_beat)));

    dir_path = strcat('data\total_data\per_beat\', abbvr);
    if ~exist(dir_path, 'dir')
        mkdir(dir_path);
    end

    filt_beats = beats(beat_type == cur_beat, :);
    [filt_beats, condition_variable] = condition_beats(filt_beats, use_pod);
    save(strcat(dir_path, '\conditioned.mat'), 'filt_beats');

    condvar.shiftVec = condition_variable.shiftVec;
    condvar.normVec = condition_variable.normVec;
    condvar.negOffset = condition_variable.negOffset;
    condvar.threshVal = condition_variable.theshVal;
    condvar.meanBeat = condition_variable.meanBeat;
    save(strcat(dir_path, '\condition_variable.mat'), 'condvar');

    clear condition_variable;
    clear filt_beats;

    beat_map(i).type = cur_beat;
    beat_map(i).path = dir_path;
end

save('data\total_data\per_beat\beat_map.mat', 'beat_map');

%% Tailored Per Beat

load('data\total_data\per_beat\beat_map.mat');

for i=1:length(beat_map)

    tmp_beats = load(strcat(beat_map(i).path, '\conditioned.mat'));
    tmp_beats = tmp_beats.filt_beats;
    percent_training = 0.5;
    compression_ratio = 50;
    
    meanBeat = mean(tmp_beats, 1);
    
    tic
    t_sense_1 = tailored_sensing(tmp_beats', percent_training, compression_ratio, meanBeat, use_pod, do_parallel);
    toc

    t = linspace(1, length(t_sense_1.test_idx), length(t_sense_1.test_idx));

    prd_dat = [t_sense_1.eval_stats.prd];
    prd1_dat = [t_sense_1.eval_stats.prd1];

    fprintf("Results for [%s]\n", get_beat_type(beat_map(i).type));
    
    fprintf("    CR: [%d] Mean/Min/Max PRD:  [%f] [%f] [%f]\n", compression_ratio, mean(prd_dat), min(prd_dat), max(prd_dat));
    fprintf("    CR: [%d] Mean/Min/Max PRD1: [%f] [%f] [%f]\n", compression_ratio, mean(prd1_dat), min(prd1_dat), max(prd1_dat));

    clear tmp_beats;
    clear t_sense_1;

end






