function varargout=rdmat(varargin) % % [tm,signal,Fs,siginfo]=rdmat(recordName) % % Import a signal in physical units from a *.mat file generated by WFDB2MAT. % Required Parameters: % % recorName % String specifying the name of the *.mat file. % % Outputs are: % % tm % A Nx1 array of doubles specifying the time in seconds. % signal % A NxM matrix of doubles contain the signals in physical units. % Fs % A 1x1 integer specifying the sampling frequency in Hz for the entire record. %siginfo % A LxN cell array specifying the signal siginfo. Currently it is a % structure with the following fields: % % siginfo.Units % siginfo.Baseline % siginfo.Gain % siginfo.Description % % NOTE: % You can use the WFDB2MAT command in order to convert the record data into a *.mat file, % which can then be loaded into MATLAB/Octave's workspace using the LOAD command. % This sequence of procedures is quicker (by several orders of magnitude) than calling RDSAMP. % The LOAD command will load the signal data in raw units, use RDMAT to load the signal in physical units. % % KNOWN LIMITATIONS: % This function currently does support several of the features described % in the WFDB record format (such as multiresolution signals) : % http://www.physionet.org/physiotools/wag/header-5.htm % If you are not sure that the record (or database format) you are reading is % supported, you can do an integrity check by comparing the output with RDSAMP: % % [tm,signal,Fs,siginfo]=rdmat('200m'); % [tm2,signal2]=rdsamp('200m'); % if(sum(abs(signal-signal2)) !=0); % error('Record not compatible with RDMAT'); % end % % % Written by Ikaro Silva, 2014 % Last Modified: November 26, 2014 % Version 1.2 % % Since 0.9.7 % % %Example: % wfdb2mat('mitdb/200') %tic;[tm,signal,Fs,siginfo]=rdmat('200m');toc %tic;[signal2]=rdsamp('200m');toc % sum(abs(signal-signal2)) % % % See also RDSAMP, WFDB2MAT %endOfHelp %Set default pararameter values inputs={'recordName'}; defGain=200; %Default value for missing gains for n=1:nargin if(~isempty(varargin{n})) eval([inputs{n} '=varargin{n};']) end end outputs={'tm','val','Fs','siginfo'}; fid = fopen([recordName, '.hea'], 'rt'); if(fid==-1) error(['Could not open file: ' recordName '.hea !']) end %Following the documentation described in : %http://www.physionet.org/physiotools/wag/header-5.htm %to parse the header file %Skip any comment lines str=fgetl(fid); while(strcmp(str(1),'#')) str=fgetl(fid); end %Process Record Line Info info=textscan(str,'%s %d %f %d %s %s'); M=info{2}; %Number of signals present Fs=info{3}; %Process Signal Specification lines. Assumes no comments between lines. siginfo(M)=struct(); for m = 1:M str=fgetl(fid); info=textscan(str,'%s %s %s %d %d %f %d %d %s'); fmt=info{2}{:}; gain=info{3}{:}; %Get Signal Units if present ind=strfind(gain,'/'); if(~isempty(ind)) siginfo(m).Units=gain(ind+1:end); gain=gain(1:ind-1); end %Get Signal Baseline if present ind=strfind(gain,'('); if(~isempty(ind)) ind2=strfind(gain,')'); siginfo(m).Baseline=str2num(gain(ind+1:ind2-1)); gain=gain(1:ind-1); else %If Baseline is missing, set it equal to ADC Zero adc_zero=info{5}; if(~isempty(adc_zero)) siginfo(m).Baseline=double(adc_zero); else error('Could not obtain signal baseline'); end end %Get Signal Gain gain=str2num(gain); if(gain==0) %Set gain to default value in this case gain=defGain; end siginfo(m).Gain=double(gain); %Get Signal Descriptor siginfo(m).Description=info{9}{:}; % Store format for later siginfo(m).fmt=fmt(1:strfind(fmt,'+')-1); end fclose(fid); load([recordName '.mat']); for m = 1:M % Interpreting digital values of byte offset format 80 if strcmp(siginfo(m).fmt, '80') val(m,:)=val(m,:)-128; wfdbNaN=-128; elseif strcmp(siginfo(m).fmt, '16') wfdbNaN=-32768; else wfdbNaN=-2147483648; end % Fill in NaNs before subtracting and dividing. val(m, val(m,:)==wfdbNaN)=nan; %Convert from digital units to physical units. % Mapping should be similar to that of rdsamp.c: % http://www.physionet.org/physiotools/wfdb/app/rdsamp.c val(m, :) = (val(m, :) - siginfo(m).Baseline ) / siginfo(m).Gain; end %Reshape to the Toolbox's standard format val=val'; %Generate time vector N=size(val,1); tm =linspace(0,(N-1)/Fs,N); for n=1:nargout eval(['varargout{n}=' outputs{n} ';']) end end