-
Nicola Vigano authored
Signed-off-by:
Nicola Vigano <nicola.vigano@esrf.fr>
Nicola Vigano authoredSigned-off-by:
Nicola Vigano <nicola.vigano@esrf.fr>
edf_info.m 5.27 KiB
function edf_header = edf_info(fname)
% EDF_INFO.M
% provides a structure containing all elements found in the header of the
% specified .edf file.
% Usage:
% edfheader = edf_info(filename)
% where filename is the name of the EDF file
%
% GJ May 2006
% modified July 2006 to force all parameters to lower case (PyHST generates
% a number of different variations!
%
% Modified by Nicola Vigano, 07/12/2011, nicola.vigano@esrf.fr
%%% Fields pattern
pattern = '(?<parameter>.*?)=(?<value>.*);';
edf_check(fname)
%%% Read the header
fid = fopen(fname, 'rt');
if (fid == -1)
error('EDF:file_not_found', ['Could not open ' fname]);
end
edf_header = [];
end_of_header = [];
edf_header.('headerlength') = 0;
while (isempty(end_of_header))
% Split lines
htxt = fgetl(fid);
% Check for inconsistencies in lines
if (isnumeric(htxt))
% Possible empty file! or at least malformed ;-)
% Close Resource
close(fid)
error('EDF:empty_line_in_header', 'Found an empty line in header.');
end
tmp = regexp(htxt, pattern, 'names');
if (~isempty(tmp))
field = sfCleanField(lower(strtrim(tmp.parameter)));
try
edf_header.(field) = strtrim(tmp.value);
catch mexc
gtPrintException(mexc)
warning('EDF:malformed_field', 'Didn''t understand this header');
disp(field);
end
end
% Look for end of header reached
end_of_header = find( htxt == '}' );
% Plus 1 is for the newline
edf_header.headerlength = edf_header.headerlength + length(htxt) +1;
end
% Count the bytes of the header, and check if it is a standard header
if (mod(edf_header.headerlength, 512) ~= 0)
warning('EDF:wrong_header_size', ...
'Header is not multiple of 512 bytes in %s (%d instead)!\n', ...
fname, edf_header.headerlength);
% disp('Setting correctly!')
% % XXX - may be cause of errors in edf_read. Check it!
% filePosition = round(filePosition/512) * 512;
end
% Release Resource
fclose(fid);
edf_header = sfCleanupHeaderInfo(edf_header);
end
function field_str = sfCleanField(field_str)
% if header field has weird characters (spaces, parentheses) - this removes
% them
field_str( find(field_str == ' ') ) = '_';
field_str( find(field_str == '-') ) = '_';
field_str( find(field_str == ',') ) = '_';
field_str( find(field_str == '(') ) = [];
field_str( find(field_str == ')') ) = [];
end
function edf_header = sfCleanupHeaderInfo(edf_header)
% convert to numbers any fields that I know should not be strings
numeric_fields = { ...
'dim_1', 'dim_2', 'dim_3', 'size', 'count_time', 'timestamp_ms', ...
'col_beg', 'col_end', 'row_beg', 'row_end', 'col_bin', 'row_bin', ...
'energy', 'optic_used', 'acq_frame_nb', 'point_no', 'scan_no', ...
'run', 'image' ...
};
for ii = 1:length(numeric_fields)
if isfield(edf_header, numeric_fields{ii})
value = edf_header.(numeric_fields{ii});
value = str2double(value);
edf_header.(numeric_fields{ii}) = value;
end
end
% convert all the motors and counters to individual fields
coupled_fields = { 'motor', 'counter' };
for ii = 1:length(coupled_fields)
field_pos = [coupled_fields{ii} '_pos'];
field_mne = [coupled_fields{ii} '_mne'];
if isfield(edf_header, field_pos)
field_tmp = [];
token_pos = textscan(edf_header.(field_pos), '%f');
token_name = textscan(edf_header.(field_mne), '%s');
for jj = 1:length(token_pos{1})
field_tmp.(token_name{1}{jj}) = token_pos{1}(jj);
end
edf_header.(coupled_fields{ii}) = field_tmp;
edf_header = rmfield(edf_header, {field_pos, field_mne} );
end
end
% convert endianness to standard representation
switch (edf_header.byteorder)
case 'HighByteFirst'
edf_header.byteorder = 'b';
case 'LowByteFirst'
edf_header.byteorder = 'l';
otherwise
disp('No endian-ness specified');
end
% convert datatype to matlab standard representation
switch lower(edf_header.datatype)
case {'doublevalue'}
edf_header.datatype = 'float64';
case {'float','floatvalue','real'}
edf_header.datatype = 'float32';
case {'unsigned64'}
edf_header.datatype = 'uint64';
case {'signed64'}
edf_header.datatype = 'int64';
case {'unsignedinteger','unsignedlong'}
edf_header.datatype = 'uint32';
case {'signedinteger','signedlong'}
edf_header.datatype = 'int32';
case {'unsignedshort'}
edf_header.datatype = 'uint16';
case {'signedshort'}
edf_header.datatype = 'int16';
case {'unsignedbyte'}
edf_header.datatype = 'uint8';
case {'signedbyte'}
edf_header.datatype = 'int8';
otherwise
edf_header.datatype = [];
warning('EDF:unknown_type', ...
'Type "%s" not known', edf_header.datatype);
end
end