function challenge(recordName)
%
% challenge(recordName)
%
% Octave-compatible code for the 2014 PhysioNet/CinC Challenge
%
% This function takes only one input argument:
%
% recordName
%       String specifying the name of the record to process.  Do not include
%       the '.dat' or '.hea' suffix in recordName.
%
% This function has no output arguments, but it writes an annotation file
% named "recordName.qrs" in the current directory, containing a annotation
% for each detected beat in the record.
%
% Dependencies:
%
%       1) This function requires the WFDB Toolbox for MATLAB and Octave.
%          For information on how to install the toolbox, please see:
%              http://www.physionet.org/physiotools/matlab/wfdb-app-matlab/
%
%       2) The Toolbox is supported only on 64-bit MATLAB 2013a and 2013b
%          and on GNU Octave 3.6.4 and later, on Linux, Mac OS X, and Windows.
%
% This file was written as part of a sample entry for the 2014 Challenge;  for
% the complete sample entry including all other required components, see
%    http://physionet.org/challenge/2014/octave/
% For a description of the Challenge and how to participate in it, see
%    http://physionet.org/challenge/2014/
%
% Version 0.91
%
% Written by Ikaro Silva, December 10, 2013.
% Last Modified: February 14, 2014

% Using the WFDB Toolbox's wfdbloadlib function, initialize the Toolbox
% configuration to the default values.  (This is required for Octave.)
[~,config] = wfdbloadlib;
% For more information, run 'help wfdbloadlib'.

annName = 'qrs'; % This annotator name is required by the Challenge rules.

% Although the code in this example does not directly access the raw samples
% of the record, they can be loaded into an array for processing using the
% WFDB Toolbox's rdsamp function, like this:
%   [tm,signal] = rdsamp(recordName);
% For more information, run 'help rdsamp'.

% The Toolbox's wfdbdesc function reads metadata for the record, including
% the names of the signals.
siginfo = wfdbdesc(recordName);
description = squeeze(struct2cell(siginfo));
description = description(5,:);
% For more information, run 'help wfdbdesc'.

% Using the helper function defined below, find the ECG and blood pressure
% signals available in the record.
ecg_ind = get_index(description,'ECG');
bp_ind = get_index(description,'BP');

% Using the Toolbox's gqrs function, annotate the first ECG signal to generate
% an annotation file (recordName.qrs), using default values for gqrs's N, N0,
% and threshold parameters.
N = [];
N0 = [];
threshold = [];
gqrs(recordName,N,N0,ecg_ind(1),threshold,annName);
% For more information, run 'help gqrs'.

% If there is a blood pressure signal, there is more processing to do.
if (~isempty(bp_ind)) 
   % Using the Toolbox's wabp function, annotate the first ABP, ART or BP signal
   % with wabp to generate a second annotation file (recordName.wabp). (wabp
   % finds this signal itself -- we don't need to tell it which signal to use.)
   wabp(recordName);
   % For more information, run 'help wabp'.
   
   % Using the Toolbox's ann2rr function, read the BP annotations from wabp, and
   % fill an array with the inter-beat (RR) intervals.
   [rr_abp,~] = ann2rr(recordName,'wabp');
   % For more information, run 'help ann2rr'.

   % Fill another array with the RR intervals from the ECG annotations.
   [rr_ecg,~] = ann2rr(recordName,'qrs');

   % Compare the variances of the BP- and ECG-based RR intervals, and assume
   % that the RR series with the lower variance is best.
   [~,best] = min([var(rr_abp) var(rr_ecg)]);
   
   % If the BP-based RR intervals are best, overwrite recordName.qrs
   if(best == 1)
     % This example assumes, naively, that the delay from the QRS annotations
     % to the BP annotations is always 200 ms.  We need to determine the
     % number of sample intervals corresponding to 200 ms (which is the
     % sampling frequency divided by 5).
     sampfreq = siginfo(bp_ind).SamplingFrequency;
     delta_t = round(250/5);

     % Using the Toolbox's rdann function, read the BP annotations into a
     % set of vectors.
     [sample_number,type,subtype,chan,num] = rdann(recordName,'wabp');

     % For more information, run 'help rdann'.

     % Adjust the annotation times (sample numbers) by -200 ms.
     sample_number = sample_number - delta_t; 

     % Using the Toolbox's wrann function, write the time-shifted BP annotations
     % into recordName.qrs (replacing the original ECG annotations).
          delete ([recordName,'.qrs'])
     delete ([recordName,'.wabp'])

     wrann(recordName,annName,sample_number,type,subtype,chan,num);
     % For more information, run 'help wrann'.
   end

   % If the ECG-based RR intervals are best, recordName.qrs does not need to
   % be changed.
end

%%%%%%%%%%%% Helper Function get_index %%%%%%%%%%%%%%%%%%%%%
% Inputs:
%   description  strings containing signal descriptions from wfdbdesc
%   pattern      a string to be found in the descriptions
% Output:
%   ind          indices of the descriptions that contain the pattern

function ind = get_index(description,pattern)
M = length(description);
tmp_ind = strfind(description,pattern);
ind = [];
for m = 1:M
    if(~isempty(tmp_ind{m}))
        ind(end+1) = m;
    end
end
