%% BR Literature Review Analyses
% BRReviewAnalyses runs the analyses, as specified in Section S1-D of the
% supplementary material.
%
%               BRReviewAnalyses
%
%	Inputs:
%		BRReviewScreeningResults.xlsx
%       BRReviewMethodologiesData.xlsx
%
%	Outputs:
%       The results are provided as variables in the workspace, and a
%       Matlab figure.
%
%   Running this script:
%       To run this script use the command:
%           [screen_results, arts_results] = BRReviewAnalyses;
%       You wil be asked to select the folder containing the supplementary
%       xlsx files (listed above as inputs).
%           
%   Further Information:
%       This is provided to facilitate reproduction of the analyses performed in:
%           Charlton P.H. et al. Breathing Rate Estimation from the
%           Electrocardiogram and Photoplethysmogram: A Review
%           - IEEE Reviews in Biomedical Engineering
%
%   Version:
%       v.2 - added images on 6th April 2020 by Peter H. Charlton
%
%   Licence:
%       Available under the GNU general public license. For details see:
%           http://www.gnu.org/
%

function [screen_results, arts_results] = BRReviewAnalyses

% Provide licence details
provide_licence_details

% setup univeral parameters (mostly file paths)
up = setup_up;

% perform analyses for the screening
screen_results = screening_analysis(up);
fprintf('\n\n The results provided in the structure "screen_results" were used to describe the screening process.')

% generate plots for blog post
blog_post_plots(screen_results, up);

% perform analyses of individual articles
arts_results = articles_analysis(up);
fprintf('\n\n The results provided in the structure "arts_results" were used to describe the BR algorithm assessment methodologies.\n\n')

end

function provide_licence_details

% note that this function has been sourced from:
%    setup_universal_params.m ,
% which is available as part of the RRest toolbox at:
%    http://peterhcharlton.github.io/RRest/ ,
% and is covered by the GNU public license.
% The filename and licence details in the output text have been adjusted.

licence_details = ['\n\n BRReviewAnalyses  Copyright (C) 2017  King''s College London',...
    '\n This program comes with ABSOLUTELY NO WARRANTY', ... 
    '\n and is available under the GNU public license.', ...
    '\n For details see http://www.gnu.org/ .\n\n'];

fprintf(licence_details)

end

function up = setup_up

% setup universal parameters

%%%%%%%  Identify location of xls files  %%%%%%%%%%%%%%%%%%%%%%%%%
fprintf(['------------------------------------\n' ...
    'Please select the folder containing:\n' ...
    '-  BRReviewScreeningResults.xlsx\n' ...
    '-  BRReviewMethodologiesData.xlsx\n' ...
    '------------------------------------\n']);
foldername = uigetdir('*.xlsx');   % this is used to identify the location of the xlsx input files.
up.slash_direction = filesep;     % adjust according to operating system
up.root_folder = [foldername, filesep];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

close all

% filename
up.screening_filename = 'BRReviewScreeningResults.xlsx';
up.methodologies_filename = 'BRReviewMethodologiesData.xlsx';

% setup file paths
up.screening_filepath = [up.root_folder, up.screening_filename];
up.methodologies_filepath = [up.root_folder, up.methodologies_filename];
up.savefolder = [up.root_folder, 'results', up.slash_direction];

% specify whether or not to create figures in .eps format as well as other formats
up.eps_figs = false;
up.save_fig = false;
if ~up.save_fig
    fprintf('\n    NB: The figures are not currently being saved. Please adjust the value of ''up.save_fig'' within the ''setup_up'' function of this script to save them.')
end

end

function res = screening_analysis(up)

%% Load and prepare data

% Load data from the excel spreadsheet
sheet = 'screening';
[~,~,raw] = xlsread(up.screening_filepath, sheet); clear sheet

% eliminate any empty rows from the raw data
headers = raw(2,:);
temp_data = raw(3:end,:); clear raw
for el = 1 : length(temp_data)
    if isnumeric(temp_data{el,1}) && isnan(temp_data{el,1})
        last_row = el-1;
        break
    else last_row = el;
    end
end
data.raw = temp_data(1:last_row,:); clear last_row el temp_data

%% Details of identified and included articles

% How many articles were there?
res.n_found = length(data.raw);   % no articles

% How many articles were included?
rel_col = strcmp(headers, 'Include?');
res.n_included = sum(strcmp(data.raw(:,rel_col),'Y'));

% Why were the others excluded?
exc_reasons = {'Irrelevant Title?', 'Other language?', 'Couldn''t find text?', 'Report of another paper?', 'Exclude as patent?', 'Exclude on not using ECG or PPG?', 'Exclude on estimating BR?'};
for exc_reason = exc_reasons
    rel_col = strcmp(headers, exc_reason{1,1});
    exc_txt = strrep(strrep(strrep(exc_reason{1,1}, '?', ''), ' ', '_'), '''', '');
    eval(['res.n_exc_' exc_txt ' = sum(strcmp(data.raw(:,rel_col), ''Y'') | strcmp(data.raw(:,rel_col), ''Y (emailed)''));']);
end

%% Search engines analysis

search_engines = {'My search', 'My second search', 'Google', 'IEEE', 'Pubmed', 'Scopus', 'Science Direct'};

% How many articles were found by each search method?
for search_engine = search_engines
    rel_col = strcmp(headers, search_engine{1});
    eval(['res.n_found_' strrep(lower(search_engine{1}), ' ', '_') ' = sum(strcmp(data.raw(:,rel_col), ''Y''));'])
end

% find out how many times each publication was found by search engines
rel_col = strcmp(headers, 'Include?');
inc_log = strcmp(data.raw(:,rel_col),'Y'); clear rel_col
no_search_engines = zeros(length(inc_log),1);
for search_engine = search_engines
    rel_col = strcmp(headers, search_engine{1});
    se_log = strcmp(data.raw(:,rel_col), 'Y') | strcmp(data.raw(:,rel_col), 'Y (emailed)');
    no_search_engines = no_search_engines + se_log;
end

% evaluate utility of search engines (using several statistics)
for search_engine = search_engines
    rel_col = strcmp(headers, search_engine{1});
    se_log = strcmp(data.raw(:,rel_col), 'Y');
    % sensitivity
    eval(['res.perf_' strrep(lower(search_engine{1}), ' ', '_') '_sen = 100*sum(se_log & inc_log)/sum(inc_log);'])
%    % specificity
%    eval(['res.perf_' strrep(lower(search_engine{1}), ' ', '_') '_spec = 100*sum(~se_log & ~inc_log)/(sum(~se_log & ~inc_log) +sum(se_log & ~inc_log));'])
    % PPV
    eval(['res.perf_' strrep(lower(search_engine{1}), ' ', '_') '_ppv = 100*sum(se_log & inc_log)/sum(se_log);'])
    % No included
    eval(['res.perf_' strrep(lower(search_engine{1}), ' ', '_') '_n_inc = sum(se_log & inc_log);'])
    % No included and unique to this search method
    eval(['res.perf_' strrep(lower(search_engine{1}), ' ', '_') '_n_inc_and_uniq = sum(se_log & inc_log & no_search_engines == 1);'])
end

% How many articles would have been found when using 1, 2, 3, 4 or 5 search engines?

% - one search engine (Scopus)
search_engine = 'Scopus';
rel_col = strcmp(headers, search_engine);
se_log = strcmp(data.raw(:,rel_col), 'Y');
res.how_many.one = sum(se_log & inc_log);
% - two search engines (Scopus and Google) - this seemed to be the best combination
search_engine = 'Google';
rel_col2 = strcmp(headers, search_engine);
se_log2 = strcmp(data.raw(:,rel_col2), 'Y');
res.how_many.two = sum((se_log | se_log2) & inc_log);
% - three search engines (Scopus, Google and IEEE) - this seemed to be the best combination (joint with exchanging IEEE for Science Direct)
search_engine = 'IEEE';
rel_col2 = strcmp(headers, search_engine);
se_log3 = strcmp(data.raw(:,rel_col2), 'Y');
res.how_many.three = sum((se_log | se_log2 | se_log3) & inc_log);
% - four search engines (Scopus, Google, IEEE and Science Direct) - this seemed to be the best combination
search_engine = 'Science Direct';
rel_col2 = strcmp(headers, search_engine);
se_log4 = strcmp(data.raw(:,rel_col2), 'Y');
res.how_many.four = sum((se_log | se_log2 | se_log3 | se_log4) & inc_log);
% - five search engines (all)
search_engine = 'Pubmed';
rel_col2 = strcmp(headers, search_engine);
se_log5 = strcmp(data.raw(:,rel_col2), 'Y');
res.how_many.five = sum((se_log | se_log2 | se_log3 | se_log4 | se_log5) & inc_log);

end


function res = articles_analysis(up)

%% Load and extract raw data

% Load data from "Included Papers" worksheet
sheet = 'included papers';
[~,~,raw] = xlsread(up.methodologies_filename, sheet); clear sheet filepath

% extract raw data
headers = raw(2,:);
data = raw(3:end,:); clear raw

%% Tidy up data for use in Matlab

% Replace unknown years of publication with NaNs
rel_col = strcmp(headers, 'Year');
unk_rows = strcmp(data(:,rel_col), 'unk'); 
data{unk_rows,rel_col} = nan;
ind_article_data = data;


%% Individual articles analysis

% publication type
rel_col = find(strcmp(headers, 'Type'));
ind_art.pub_type = ind_article_data(:, rel_col); clear rel_col
pub_types = unique(ind_art.pub_type)';
for pub_type = pub_types
    eval(['res.pub_type.n_' pub_type{1,1} ' = sum(strcmp(ind_art.pub_type, pub_type{1,1}));'])
    eval(['res.pub_type.perc_' pub_type{1,1} ' = 100*sum(strcmp(ind_art.pub_type, pub_type{1,1}))/length(ind_art.pub_type);'])
end
clear pub_types pub_type

% no first authors
rel_col = find(strcmp(headers, 'First Author'));
ind_art.first_author = unique(ind_article_data(:, rel_col)); clear rel_col
res.first_author.n = length(ind_art.first_author);

% year
rel_col = find(strcmp(headers, 'Year'));
ind_art.yr = cell2mat(ind_article_data(:, rel_col));
int = 1;
res.yr.bar_years = min(ind_art.yr):int:max(ind_art.yr);
res.yr.overall_bar_counts = nan(length(res.yr.bar_years),1);
res.yr.art_bar_counts = nan(length(res.yr.bar_years),1);
res.yr.conf_bar_counts = nan(length(res.yr.bar_years),1);
conf_log = strcmp(ind_art.pub_type, 'Conference');
art_log = strcmp(ind_art.pub_type, 'Journal');
for yr_no = 1 : length(res.yr.bar_years)
    curr_yr = res.yr.bar_years(yr_no);
    res.yr.overall_bar_counts(yr_no) = sum(ind_art.yr >= curr_yr & ind_art.yr < (curr_yr+int))/int;
    res.yr.art_bar_counts(yr_no) = sum(ind_art.yr >= curr_yr & ind_art.yr < (curr_yr+int) & art_log)/int;
    res.yr.conf_bar_counts(yr_no) = sum(ind_art.yr >= curr_yr & ind_art.yr < (curr_yr+int) & conf_log)/int;
end

% Type of breathing
rel_col = find(strcmp(headers, 'Type of breathing'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.breath_type = find_cat_res(rel_data); clear rel_data

% Subject age
rel_col = find(strcmp(headers, 'Age(s)'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.age = find_cat_res(rel_data); clear rel_data

% Illness level
rel_col = find(strcmp(headers, 'Level of illness'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.illness = find_cat_res(rel_data); clear rel_data

% Ambulatory
rel_col = find(strcmp(headers, 'Ambulatory data?'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.ambulatory = find_cat_res(rel_data); clear rel_data

% Input signal
rel_col = find(strcmp(headers, 'Input signal(s)'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.input = find_cat_res(rel_data); clear rel_data

%Reference BR
rel_col = find(strcmp(headers, 'Reference BR'));
rel_data = ind_article_data(:, rel_col); clear rel_col
rel_data = strrep(rel_data, 'belt', 'unk');
rel_data = strrep(rel_data, 'thermistor', 'airpressflow');
rel_data = strrep(rel_data, 'ventilator', 'airpressflow');
rel_data = strrep(rel_data, 'airpressure', 'airpressflow');
rel_data = strrep(rel_data, 'capnometry', 'airpressflow');
rel_data = strrep(rel_data, 'airflow', 'airpressflow');
rel_data = strrep(rel_data, 'spirometry', 'airpressflow');
rel_data = strrep(rel_data, 'manual', 'other');
rel_data = strrep(rel_data, 'button', 'other');
rel_data = strrep(rel_data, 'none', 'other');
rel_data = strrep(rel_data, 'body plethysmography', 'other');
rel_data = strrep(rel_data, 'displacement', 'other');
rel_data = strrep(rel_data, 'gating signal', 'other');
rel_data = strrep(rel_data, 'chest pressure', 'other');
rel_data = strrep(rel_data, 'simulated', 'other');
res.ref = find_cat_res(rel_data);
clear rel_data

% Stats
rel_col = find(strcmp(headers, 'Statistical measure(s)'));
rel_data = ind_article_data(:, rel_col); clear rel_col
rel_data = strrep(rel_data, 'SpearmanCC', 'cc');
rel_data = strrep(rel_data, 'LinsCC', 'cc');
rel_data = strrep(rel_data, 'Accuracy', 'ind_breaths');
rel_data = strrep(rel_data, 'FNR', 'ind_breaths');
rel_data = strrep(rel_data, 'FN', 'ind_breaths');
rel_data = strrep(rel_data, 'FPR', 'ind_breaths');
rel_data = strrep(rel_data, 'FP', 'ind_breaths');
rel_data = strrep(rel_data, 'Error rate', 'ind_breaths');
rel_data = strrep(rel_data, 'PPV', 'ind_breaths');
rel_data = strrep(rel_data, 'Se', 'ind_breaths');
rel_data = strrep(rel_data, 'Sp', 'ind_breaths');
rel_data = strrep(rel_data, 'error', 'error_stat');
rel_data = strrep(rel_data, 'Error', 'error_stat');
rel_data = strrep(rel_data, 'NMSE', 'error_stat');
rel_data = strrep(rel_data, 'RMSE', 'error_stat');
rel_data = strrep(rel_data, 'RMSNE', 'error_stat');
rel_data = strrep(rel_data, 'MSE', 'error_stat');
rel_data = strrep(rel_data, 'ME', 'error_stat');
rel_data = strrep(rel_data, 'MAE', 'error_stat');
rel_data = strrep(rel_data, 'MAPE', 'error_stat');
rel_data = strrep(rel_data, 'PE', 'error_stat');
rel_data = strrep(rel_data, 'concCC', 'cc');
rel_data = strrep(rel_data, 'PearsonsCC', 'cc');
rel_data = strrep(rel_data, 'CC', 'cc');
rel_data = strrep(rel_data, 'perc_CP', 'CP');
res.stats = find_cat_res(rel_data); clear rel_data

% Conflict of Interest
rel_col = find(strcmp(headers, 'Conflict of Interest?'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.conf = find_cat_res(rel_data); clear rel_data

% No. algorithms
rel_col = find(strcmp(headers, 'No algs'));
rel_data = ind_article_data(:, rel_col); clear rel_col
rel_data = cell2mat(rel_data);
res.algs.n_1 = sum(rel_data == 1);
res.algs.n_2 = sum(rel_data>=2 & rel_data<=5);
res.algs.n_6 = sum(rel_data>=6 & rel_data<=10);
res.algs.n_11 = sum(rel_data>=11 & rel_data<=15);
res.algs.n_16 = sum(rel_data>=16);
res.algs.perc_1 = 100*res.algs.n_1/length(rel_data);
res.algs.perc_2 = 100*res.algs.n_2/length(rel_data);
res.algs.perc_6 = 100*res.algs.n_6/length(rel_data);
res.algs.perc_11 = 100*res.algs.n_11/length(rel_data);
res.algs.perc_16 = 100*res.algs.n_16/length(rel_data);
clear rel_data

% Window Duration
rel_col = find(strcmp(headers, 'Window length [s]'));
rel_data = ind_article_data(:, rel_col); clear rel_col
no_pubs = length(rel_data);
no_unk = sum(strcmp(rel_data, 'unk'));
% eliminate "beats" from data (making the assumption that 1 beat ~= 1 sec)
for s = 1 : length(rel_data)
    if ~isnumeric(rel_data{s}) && ~isempty(strfind(rel_data{s}, 'beats'))
        rel_data{s} = strrep(rel_data{s}, ' beats', '');
    end
end
% make sure all entries are in numerical format where possible
for s = 1 : length(rel_data)
    if ~isnumeric(rel_data{s}) && isempty(strfind(rel_data{s}, ';')) && ~strcmp(rel_data{s}, 'unk') && ~strcmp(rel_data{s}, 'none')
        rel_data{s} = str2double(rel_data{s});
    end
end
    
int = 1;
res.win_durn = find_num_res(rel_data, int); clear rel_data
res.win_durn.len_sub_30_n = sum(res.win_durn.overall_bar_counts(res.win_durn.bar < 30));
res.win_durn.len_sub_30_perc = 100*res.win_durn.len_sub_30_n/no_pubs;
res.win_durn.len_30_to_59_n = sum(res.win_durn.overall_bar_counts(res.win_durn.bar >= 30 & res.win_durn.bar < 60));
res.win_durn.len_30_to_59_perc = 100*res.win_durn.len_30_to_59_n/no_pubs;
res.win_durn.len_60_to_89_n = sum(res.win_durn.overall_bar_counts(res.win_durn.bar >= 60 & res.win_durn.bar < 90));
res.win_durn.len_60_to_89_perc = 100*res.win_durn.len_60_to_89_n/no_pubs;
res.win_durn.len_90_plus_n = sum(res.win_durn.overall_bar_counts(res.win_durn.bar >= 90));
res.win_durn.len_90_plus_perc = 100*res.win_durn.len_90_plus_n/no_pubs;
res.win_durn.unk_n = no_unk;
res.win_durn.unk_perc = 100*res.win_durn.unk_n/no_pubs;

% No subjs
rel_col = find(strcmp(headers, 'No subjs'));
rel_data = ind_article_data(:, rel_col); clear rel_col
int = 5;
res.no_subjs = find_num_res(rel_data, int); clear rel_data

% Dataset
rel_col = find(strcmp(headers, 'Dataset'));
rel_data = ind_article_data(:, rel_col); clear rel_col
res.dataset = find_cat_res(rel_data); 
for s = 1 : length(rel_data)
    no(s) = length(strfind(rel_data{s}, ';'));
end
res.dataset.n_1_dataset = sum(no == 0);
res.dataset.perc_1_dataset = 100*res.dataset.n_1_dataset/length(no);
res.dataset.n_2_dataset = sum(no == 1);
res.dataset.perc_2_dataset = 100*res.dataset.n_2_dataset/length(no);
res.dataset.n_3_dataset = sum(no == 2);
res.dataset.perc_3_dataset = 100*res.dataset.n_3_dataset/length(no);
res.dataset.n_4_dataset = sum(no == 3);
res.dataset.perc_4_dataset = 100*res.dataset.n_4_dataset/length(no);

% Rec time
rel_col = find(strcmp(headers, 'Recording time [mins]'));
rel_data = ind_article_data(:, rel_col); clear rel_col
rel_data(strcmp(rel_data, 'unk')) = {nan};
rel_data = cell2mat(rel_data);
res.rec_time.n_1 = sum(rel_data<=10);
res.rec_time.n_11 = sum(rel_data>= 11 & rel_data<=20);
res.rec_time.n_21 = sum(rel_data>= 21 & rel_data<=59);
res.rec_time.n_60 = sum(rel_data>=60);
res.rec_time.n_unk = sum(isnan(rel_data));
res.rec_time.perc_1 = 100*res.rec_time.n_1/length(rel_data);
res.rec_time.perc_11 = 100*res.rec_time.n_11/length(rel_data);
res.rec_time.perc_21 = 100*res.rec_time.n_21/length(rel_data);
res.rec_time.perc_60 = 100*res.rec_time.n_60/length(rel_data);
res.rec_time.perc_unk = 100*res.rec_time.n_unk/length(rel_data);
clear rel_data s

%% Plots

% Plot pubs per year histogram
a = res.yr.bar_years;
inc_els = res.yr.bar_years >= 1991 & res.yr.bar_years < 2017;
for s = 1 : length(a)
    labs{s} = num2str(a(s)); labs{s} = labs{s}(3:end);
end
paper_size = [8,3.5];
figure('Position', [200,100,paper_size(1)*100,paper_size(2)*100]), ftsize = 16; lwidth = 2; set(gcf,'color','w')
subplot('Position', [0.22,0.19,0.76,0.79]), bar(res.yr.bar_years(inc_els), res.yr.overall_bar_counts(inc_els)),
ylim([0 25])
set(gca, 'FontSize', ftsize), xlabel('Year', 'FontSize', ftsize),
ylab = ylabel({'Publications', 'per year'}, 'FontSize', ftsize, 'Rotation', 0);
set(ylab, 'Units', 'Normalized', 'Position', [-0.17, 0.45, 0]);
xlim([min(res.yr.bar_years(inc_els))-1, max(res.yr.bar_years(inc_els))+1])
set(gca,'TickDir','out')
box off

if up.save_fig
    savepath = [up.savefolder, 'rr_pubs_bar'];
    PrintFigs(gcf, paper_size, savepath, up)
end

end

function PrintFigs(h, paper_size, savepath, up)
set(h,'PaperUnits','centimeters');
set(h,'PaperSize', [paper_size(1), paper_size(2)]./0.3);
set(h,'PaperPosition',[0 0 paper_size(1) paper_size(2)]./0.3);
print(h,'-dpng',savepath)

if up.eps_figs
    export_fig_dir_path = 'C:\Documents\Google Drive\Work\Projects\PhD\Github\phd\Tools\Other Scripts\export_fig\altmany-export_fig-76bd7fa\';
    addpath(genpath(export_fig_dir_path))
    addpath(genpath('C:\Program Files\Xpdf\'))
    export_fig(savepath, '-eps')
end
close all
end

function res = find_cat_res(rel_data)
rel_data = strrep(rel_data, '; ', ';');
rel_data = strrep(rel_data, ' ', '_');
rel_data = strrep(rel_data, '-', '_');
rel_data = strrep(rel_data, '&', 'and');
cats = unique(rel_data)';
new_cats = cell(0);
for cat_no = 1 : length(cats)
    curr_cat = cats{cat_no};
    colon_els = strfind(curr_cat, ';'); colon_els = [0, colon_els, length(curr_cat)+1];
    temp = cell(0);
    for s = 1 : length(colon_els)-1
        temp{s} = curr_cat(colon_els(s)+1:colon_els(s+1)-1);
    end
    curr_cat = temp; clear temp s
    new_cats(length(new_cats)+1:length(new_cats)+length(curr_cat)) = curr_cat; clear curr_cat
end
cats = unique(new_cats); clear new_cats
for cat = cats
    eval(['res.n_' cat{1,1} ' = sum(~cellfun(@isempty, strfind(rel_data, cat{1,1})));'])
    eval(['res.perc_' cat{1,1} ' = 100*sum(~cellfun(@isempty, strfind(rel_data, cat{1,1})))/length(rel_data);'])
end
clear cats cat rel_data
end

function res = find_num_res(rel_data, int)

% Prepare data (eliminating unknowns and nones)
rel_els = find(strcmp(rel_data, 'unk'));
for s = 1 : length(rel_els)
    rel_data{rel_els(s)} = nan;
end
rel_els = find(strcmp(rel_data, 'none'));
for s = 1 : length(rel_els)
    rel_data{rel_els(s)} = nan;
end
rel_els = find(strcmp(rel_data, 'not applicable'));
for s = 1 : length(rel_els)
    rel_data{rel_els(s)} = nan;
end

% separate data from rows with multiple entries
for s = 1 : length(rel_data)
    if ~isnumeric(rel_data{s})
        if strfind(rel_data{s}, ';')
            rel_els = strfind(rel_data{s}, ';');
            rel_els = [0, rel_els, length(rel_data{s})+1];
            for el_no = 1 : length(rel_els)-1
                curr_str = rel_data{s}(rel_els(el_no)+1:rel_els(el_no+1)-1);
                rel_data{end+1} = str2double(curr_str);
            end
            rel_data{s} = 9999;
        end
    end
end


% convert to mat
rel_data = cell2mat(rel_data);

% eliminate the nonsensical rows created by the separation process
rel_data = rel_data(rel_data~= 9999);

% create histogram data
res.bar = min(rel_data):int:max(rel_data);
res.overall_bar_counts = nan(length(res.bar),1);
for bar_no = 1 : length(res.bar)
    curr_bar = res.bar(bar_no);
    res.overall_bar_counts(bar_no) = sum(rel_data >= curr_bar & rel_data < (curr_bar+int));
end

end

function blog_post_plots(screen_results, up)

%% Coverage

% Proportion of included articles
% - input data
search_engines = {'G. Scholar', 'IEEE Xplore', 'Pubmed', 'Scopus', 'Sci. Direct'};
data = 100*[screen_results.perf_google_n_inc, screen_results.perf_ieee_n_inc, screen_results.perf_pubmed_n_inc, screen_results.perf_scopus_n_inc, screen_results.perf_science_direct_n_inc]./screen_results.n_included;
% - sort
[data, order] = sort(data, 'descend');
search_engines = search_engines(order); clear order
% - plot
paper_size = [800,400];
figure('Position', [20,20,paper_size])
ftsize = 19;
cats = categorical(search_engines);
cats = reordercats(cats,search_engines);
bar(cats, data)
ylab = ylabel('Percentage of included publications');
set(ylab, 'position', get(ylab,'position')-[0.3,0,0]);
set(gca, 'FontSize', ftsize)
xtickangle(30)
box off
% - save
filepath = [up.root_folder, 'prop_inc_articles'];
if up.save_fig
    print(filepath, '-dpng')
end

%% PPV

% Number needed to screen to find one relevant publication
% - input data
search_engines = {'G. Scholar', 'IEEE Xplore', 'Pubmed', 'Scopus', 'Sci. Direct'};
data = 1./(([screen_results.perf_google_ppv, screen_results.perf_ieee_ppv, screen_results.perf_pubmed_ppv, screen_results.perf_scopus_ppv, screen_results.perf_science_direct_ppv])/100);
% - sort
[data, order] = sort(data, 'ascend');
search_engines = search_engines(order); clear order
% - plot
paper_size = [800,400];
figure('Position', [20,20,paper_size])
ftsize = 20;
cats = categorical(search_engines);
cats = reordercats(cats,search_engines);
bar(cats, data)
ylab = ylabel({'Number screened', 'for each relevant result'});
set(ylab, 'position', get(ylab,'position')-[0.3,0,0]);
set(gca, 'FontSize', ftsize, 'YGrid', 'on')
xtickangle(30)
box off
% - save
filepath = [up.root_folder, 'number_screened'];
if up.save_fig
    print(filepath, '-dpng')
end

%% How many search engines?

% - input data
% search_engines = {'G. Scholar', 'IEEE Xplore', 'Pubmed', 'Scopus', 'Sci. Direct'};
data = [screen_results.how_many.one, screen_results.how_many.two, screen_results.how_many.three, screen_results.how_many.four, screen_results.how_many.five];
% - plot
paper_size = [800,400];
figure('Position', [20,20,paper_size])
ftsize = 20;
cats = categorical(search_engines);
cats = reordercats(cats,search_engines);
plot(1:5, data, 'o--b', 'LineWidth', 2, 'MarkerSize', 10, 'MarkerFaceColor', 'b')
xlabel('Number of search engines used');
ylab = ylabel({'Number of relevant results'});
set(ylab, 'position', get(ylab,'position')-[0.8,0,0]);
xlim([0.5 5.5])
ylim([floor((screen_results.how_many.one-1)/10)*10, ceil((screen_results.how_many.five+1)/10)*10])
set(gca, 'FontSize', ftsize, 'YGrid', 'on', 'XTick', 1:5)
box off
% - save
filepath = [up.root_folder, 'number_search_engines'];
if up.save_fig
    print(filepath, '-dpng')
end

end