clear, close all, clc;

%% Not Always Needed --> Send patient data to beat log

% read_and_parse_beats('118', 300);
% read_and_parse_beats('100', 300);
% read_and_parse_beats('228', 300);


% NOT USING ANYMORE

% pat_path = 'cdb/08730_01';
% [signal, Fs, tm] = rdsamp(pat_path);
% gqrs(pat_path);
% [RR] = ann2rr(pat_path, 'qrs');

%% Global Data:

nSamples = 300;


%% Read in the beat data and split into leads

for i=100:234
    full_path = strcat('data\final_data\mitdb_', num2str(i), '_beats.mat');

    if ~exist(full_path, 'file')
        read_and_parse_beats(num2str(i), nSamples);
    end

    tmp_beats = load(full_path);
    beats = [beats; tmp_beats.beats];
    clear tmp_beats;

end

% Read in data
beats_118 = load('data\final_data\mitdb_118_beats.mat');
beats_100 = load('data\final_data\mitdb_100_beats.mat');
beats_228 = load('data\final_data\mitdb_228_beats.mat');
beats = [beats_118.beats; beats_100.beats; beats_228.beats];
og_beats = beats;
clear beats_118;
clear beats_100;
clear beats_228;

% Split by lead and get into an array
lead_beats = beats_to_leads(beats);

nLeads = size(lead_beats,1);

use_pod = false;    % Proper Orthogonal Decompisition --> Removing the meanface



%% Filter, Condition and Plot

% Filter the beats
for i=1:nLeads
    lead_beats(i,:,:) = filter_beats(squeeze(lead_beats(i,:,:)));
end

% Condition the beats
for i=1:nLeads
    [lead_beats(i,:,:), cvar] = condition_beats(squeeze(lead_beats(i,:,:)), use_pod);
    c_vars(i) = cvar;
    clear cvar;
end

% Plot how they have changed
figure;
subplot(2,3,1), plt_ensemble(squeeze(c_vars(1).plt_out(1,:,:))'), title('Orignal');
subplot(2,3,2), plt_ensemble(squeeze(c_vars(1).plt_out(2,:,:))'), title('Vertically Zeroed');
subplot(2,3,3), plt_ensemble(squeeze(c_vars(1).plt_out(3,:,:))'), title('Normalized');
subplot(2,3,4), plt_ensemble(squeeze(c_vars(1).plt_out(4,:,:))'), title('Forced Positive');
subplot(2,3,5), plt_ensemble(squeeze(c_vars(1).plt_out(5,:,:))'), title('Thesholded');
subplot(2,3,6), plt_ensemble(squeeze(c_vars(1).plt_out(6,:,:))'), title('Mean Removed - Not Using');

% Clear plots
clear c_vars(1).plt_out;
clear c_vars(2).plt_out;

%% TAILORED SENSING --> Perform Tailored Sensing

percent_training = 0.5;
compression_ratio = 50;

lead_to_use = 1;
beats_to_cs = squeeze(lead_beats(lead_to_use,:,:));
meanBeat = mean(beats_to_cs, 1);

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

%% TAILORED SENSING --> Plot the Sensing Locations

sensors = t_sense_1.pivot(1:t_sense_1.r);
mask = zeros(300,1);
mask(sensors) = meanBeat(sensors);
mask(mask==0) = nan;
plot(meanBeat), hold on, plot(mask, "rx", "LineWidth", 4),  title('Sampled Signal'), hold off;

%% TAILORED SENSING --> Evaluate Performance (scatter of PRD/PRD1, mean/min/max PRD/PRD1, PRD/PRD1 comparison by beat type)

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 = cell2mat(beats(:,2));
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(t_sense_1.test_idx) == beat_lab);

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

end



%% TAILORED SENSING --> Plot a bad case

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% TAILORED SENSING --> Tailored Sensing per Beat Type

beat_label = cell2mat(og_beats(:,2));
unique_beat_label = unique(beat_label);

og_lead_beats = beats_to_leads(og_beats);
lead_1_beats = squeeze(og_lead_beats(1,:,:));

compression_ratio = 20;
percent_training = 0.5;

figure;
title('Beat Type Comparison - Mean Beat');
hold on;

for i=1:size(unique_beat_label,1)

    % (a) Extract the beat data
    beat_lab = unique_beat_label(i);
    beat_dat = squeeze(lead_1_beats(beat_label == beat_lab, :));

    % (b) Filter the beat data
    beat_dat = filter_beats(beat_dat);

    % (c) Condition the beat data
    [beat_dat, cvar] = condition_beats(beat_dat, use_pod);

    % (d) Plot the mean beat
    mean_beat_dat = mean(beat_dat, 1);
    plot(mean_beat_dat);

    % (e) Ensure we have enough beats to build a dictionary
    if size(beat_dat,1) < compression_ratio
        fprintf("Too few beats for [%s] --> [%d]\n", beat_type(beat_lab), size(beat_dat,1));
        continue;
    end   

    % (f) Perform CS and evaluate
    temp = tailored_sensing(beat_dat', percent_training, compression_ratio, mean_beat_dat, use_pod);
    fprintf("CR: [%d] Mean/Min/Max PRD: [%f] [%f] [%f] --> [%s]\n", compression_ratio, mean([temp.eval_stats.prd]), min([temp.eval_stats.prd]), max([temp.eval_stats.prd]), beat_type(beat_lab));

end
legend(arrayfun(@beat_type, unique_beat_label));
hold off;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% COMPRESSED SENSING --> Perform CS using a DDBD & Generic Dictionary
beats_to_cs = squeeze(lead_beats(1,:,:));
beats_to_test = beats_to_cs;

compression_ratio = 20;
mean_beat = mean(beats_to_test,1);

% new_cs_out = compressed_sensing(beats_to_test, compression_ratio, mean_beat, 'bernoulli', 'dct', 'irls');
new_cs_out_2 = compressed_sensing(beats_to_test, compression_ratio, mean_beat, 'gauss', 'dct', 'bp');

%% COMPRESSED SENSING --> Plot the PRD information

t = linspace(1, size(beats_to_test,1), size(beats_to_test,1));
t = linspace(1, 1000, 1000);
figure;
subplot(1,2,1), scatter(t, [new_cs_out_2.eval_stats.prd]), hold on, subplot(1,2,2), scatter(t, [new_cs_out_2.eval_stats.prd1]), hold off;
figure;
time_out = [new_cs_out_2.solve_time];
scatter(t, time_out(1:1000,1));
fprintf("CR: [%d] Mean PRD:  [%f]\n", compression_ratio, mean([new_cs_out_2.eval_stats.prd]));
fprintf("CR: [%d] Mean PRD1: [%f]\n", compression_ratio, mean([new_cs_out_2.eval_stats.prd1]));

%% Power Plots

c = dctmtx(300);
for cr=1:100
    pwr_dbbd(cr) = power_consumption(300, cr, ddbd_c(300, ceil(300/cr), cr));
    pwr(cr) = power_consumption(300, cr, c);
end
plot([pwr(:).tx_pwr]+[pwr(:).smp_pwr]);
hold on;
plot([pwr_dbbd(:).tx_pwr]+[pwr_dbbd(:).smp_pwr]);
hold off;
legend('DCT', 'DBBD');
xlabel('Compression Ratio');
ylabel('Power Consumption (Joules)');

%% COMPRESSED SENSING --> Plot the PRD information

t = linspace(1, size(beats_to_test,1), size(beats_to_test,1));
subplot(1,2,1), scatter(t, [new_cs_out.eval_stats.prd]), hold on, subplot(1,2,2), scatter(t, [new_cs_out_2.eval_stats.prd]), hold off;

fprintf("CR: [%d] Mean PRD:  [%f]\n", compression_ratio, mean([new_cs_out.eval_stats.prd]));
fprintf("CR: [%d] Mean PRD1: [%f]\n", compression_ratio, mean([new_cs_out.eval_stats.prd1]));
fprintf("CR: [%d] Mean PRD:  [%f]\n", compression_ratio, mean([new_cs_out_2.eval_stats.prd]));
fprintf("CR: [%d] Mean PRD1: [%f]\n", compression_ratio, mean([new_cs_out_2.eval_stats.prd1]));

%% COMPRESSED SENSING --> Plot a bad case

plot(new_cs_out_2.recon_beats(647,:));
hold on;
plot(beats_to_test(647,:));
legend('Recovered', 'Original');
hold off;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function c = ddbd_c(N, M, CR)
    c = zeros(M,N);
    for i = 1:M
        offset = (i-1)*CR + 1;
        c(i, offset:offset+CR-1) = ones(1,CR);
    end
end







