changeset 611:9994e96e9ade

analyze75: code clean to follow standards, simpler code, checks, more documentation, and move of common code to shared subfunctions
author carandraug
date Tue, 25 Sep 2012 17:21:39 +0000
parents 4c92bffbf4cc
children 7c1df1b5f058
files inst/analyze75info.m inst/analyze75read.m inst/private/analyze75filename.m
diffstat 3 files changed, 195 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/inst/analyze75info.m
+++ b/inst/analyze75info.m
@@ -1,4 +1,5 @@
 %% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com>
+%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com>
 %%
 %% This program is free software; you can redistribute it and/or modify
 %% it under the terms of the GNU General Public License as published by
@@ -14,182 +15,126 @@
 %% along with this program; If not, see <http://www.gnu.org/licenses/>.
 
 %% -*- texinfo -*-
-%% @deftypefn {Function File} {@var{header} = } analyze75info(@var{filename})
-%% Read the header of an Analyze file.
+%% @deftypefn {Function File} {@var{header} =} analyze75info (@var{filename})
+%% @deftypefnx {Function File} {@var{header} =} analyze75info (@var{filename}, "ByteOrder", @var{arch})
+%% Read header of an Analyze 7.5 file.
+%%
+%% @var{filename} must be the path for an Analyze 7.5 file or the path for a
+%% directory with a single .hdr file can be specified.
 %%
-%% FILENAME is a string (giving the filename).
+%% The optional argument @code{"ByteOrder"} reads the file with the specified
+%% @var{arch} ("ieee-be" or "ieee-le" for IEEE big endian or IEEE
+%% little endian respectively).
+%%
+%% @var{header} is a structure with the file information.
+%%
+%% @seealso{analyze75read}
 %% @end deftypefn
 
-function header = analyze75info(varargin);
-%--------------------------------------------------------------------------
-
-%--------------
-% Check filename
-%--------------
-
-filename = varargin{1};
-
-if exist('filename','var')==1 && exist(filename,'dir')==7
-  filelist = dir([filename,filesep,'*.hdr']);
-  if numel(filelist)==1
-    filename = [filename,filesep,filelist.name];
-  else
-    [filename,filepath] = uigetfile([filename,filesep,'*.hdr'],'Select the input file');
-    filename = [filepath,filename];
-  end
-elseif ( exist('filename','var')==1 && exist(filename,'file')==0 ) || exist('filename','var')==0
-  [filename,filepath] = uigetfile('*.hdr','Select the input file');
-  filename = [filepath,filename];
-end
-
-% Strip the filename of the extension
+function header = analyze75info (filename, varargin)
 
-fileextH = strfind(filename,'.hdr');
-fileextI = strfind(filename,'.img');
-if isempty(fileextH)==0
-  fileprefix = filename(1:fileextH-1);
-elseif isempty(fileextI)==0
-  fileprefix = filename(1:fileextI-1);
-else
-  fileprefix = filename;
-end
-
-%--------------
-% Check the byteorder
-%--------------
-
-byteorder = 'ieee-le';
-
-for loopN = 2:nargin-1
-  if ischar(varargin{loopN}) && strcmpi(varargin{loopN})=='ByteOrder'
-    if ischar(varargin{loopN+1}) && ( strcmpi(varargin{loopN+1})=='ieee-be' || strcmpi(varargin{loopN+1})=='b' )
-      byteorder = 'ieee-be';
-      disp('Code does not yet work for big-endian files.')
-    else
-      byteorder = 'ieee-le';
+  if (nargin ~= 1 && nargin ~= 3)
+    print_usage;
+  elseif (~ischar (filename))
+    error ('analyze75info: `filename'' must be a string');
+  elseif (nargin == 3)
+    %% Check the byteorder
+    if (strcmpi (varargin{1}, 'byteorder'))
+      error ('analyze75info: second argument must be string `ByteOrder''');
+    elseif (!all (strcmpi (varargin{3}, {'ieee-le', 'l', 'ieee-be', 'b'})))
+      error ('analyze75info: valid options for `ByteOrder'' are `ieee-le'' or `ieee-be''');
+    elseif (any (strcmpi (varargin{3}, {'ieee-be', 'b'})))
+      warning ('analyze75info: no support for big-endian. Please consider submitting a patch. Attempting to read as little-endian');
     end
   end
-end
+
+  fileprefix = analyze75filename (filename);
 
-%--------------
-% Read the file
-%--------------
+  %% finally start reading the actual file
+  hdrdirdata              = dir ([fileprefix, '.hdr']);
+  imgdirdata              = dir ([fileprefix, '.img']);
 
-header = READ_hdr(fileprefix);
-
+  header.ImgFileSize      = imgdirdata.bytes;
 
-end %function
-%--------------------------------------------------------------------------
-
+  header.Filename         = [fileprefix, '.hdr'];
+  header.FileModDate      = hdrdirdata.date;
+  header.Format           = 'Analyze';
+  header.FormatVersion    = '7.5';
+  header.ColorType        = 'grayscale';
+  header.ByteOrder        = 'ieee-le';
 
-%--------------------------------------------------------------------------
-function [header] = READ_hdr(fileprefix)
-
-%----------------------------
-% Gather the header info
-%----------------------------
-
-dirdata                 = dir([fileprefix,'.hdr']);
+  fidH                    = fopen ([fileprefix, '.hdr']);
 
-header.Filename         = [fileprefix,'.hdr'];
-header.FileModDate      = dirdata.date;
-header.Format           = 'Analyze';
-header.FormatVersion    = '7.5';
-header.ColorType        = 'grayscale';
-header.ByteOrder        = 'ieee-le';
-
-fidH                    = fopen([fileprefix,'.hdr']);
-
-header.HdrFileSize      = fread(fidH,1,'int32');
-header.HdrDataType      = char(fread(fidH,10,'char'))';
-header.DatabaseName     = char(fread(fidH,18,'char'))';
-header.Extents          = fread(fidH,1,'int32');
-header.SessionError     = fread(fidH,1,'int16');
-header.Regular          = char(fread(fidH,1,'char'));
-unused                  = char(fread(fidH,1,'char'));
-unused                  = fread(fidH,1,'int16');
-header.Dimensions       = zeros(size(1,4));
-header.Dimensions(1)    = fread(fidH,1,'int16');
-header.Dimensions(2)    = fread(fidH,1,'int16');
-header.Dimensions(3)    = fread(fidH,1,'int16');
-header.Dimensions(4)    = fread(fidH,1,'int16');
-unused                  = fread(fidH,3,'int16');
-header.VoxelUnits       = char(fread(fidH,4,'char'))';
-header.CalibrationUnits = char(fread(fidH,8,'char'))';
-unused                  = fread(fidH,1,'int16');
+  header.HdrFileSize      = fread (fidH, 1, 'int32');
+  header.HdrDataType      = char (fread (fidH, 10, 'char'))';
+  header.DatabaseName     = char (fread (fidH, 18, 'char'))';
+  header.Extents          = fread (fidH, 1, 'int32');
+  header.SessionError     = fread (fidH, 1, 'int16');
+  header.Regular          = char (fread (fidH, 1, 'char'));
+  unused                  = char (fread (fidH, 1, 'char'));
+  unused                  = fread (fidH, 1, 'int16');
+  header.Dimensions       = zeros (size (1, 4));
+  header.Dimensions(1)    = fread (fidH, 1, 'int16');
+  header.Dimensions(2)    = fread (fidH, 1, 'int16');
+  header.Dimensions(3)    = fread (fidH, 1, 'int16');
+  header.Dimensions(4)    = fread (fidH, 1, 'int16');
+  unused                  = fread (fidH, 3, 'int16');
+  header.VoxelUnits       = char (fread (fidH, 4, 'char'))';
+  header.CalibrationUnits = char (fread (fidH, 8, 'char'))';
+  unused                  = fread (fidH, 1, 'int16');
 
-datatype = fread(fidH,1,'int16');
-if datatype==0 
-  header.ImgDataType = 'DT_UNKNOWN';
-elseif datatype==1
-  header.ImgDataType = 'DT_BINARY';
-elseif datatype==2
-  header.ImgDataType = 'DT_UNSIGNED_CHAR';
-elseif datatype==4
-  header.ImgDataType = 'DT_SIGNED_SHORT';
-elseif datatype==8
-  header.ImgDataType = 'DT_SIGNED_INT';
-elseif datatype==16
-  header.ImgDataType = 'DT_FLOAT';
-elseif datatype==32
-  header.ImgDataType = 'DT_COMPLEX';
-elseif datatype==64
-  header.ImgDataType = 'DT_DOUBLE';
-elseif datatype==128
-  header.ImgDataType = 'DT_RGB';
-elseif datatype==255
-  header.ImgDataType = 'DT_ALL';
-end
+  datatype = fread (fidH, 1, 'int16');
+  switch datatype
+  case   0, header.ImgDataType = 'DT_UNKNOWN';
+  case   1, header.ImgDataType = 'DT_BINARY';
+  case   2, header.ImgDataType = 'DT_UNSIGNED_CHAR';
+  case   4, header.ImgDataType = 'DT_SIGNED_SHORT';
+  case   8, header.ImgDataType = 'DT_SIGNED_INT';
+  case  16, header.ImgDataType = 'DT_FLOAT';
+  case  32, header.ImgDataType = 'DT_COMPLEX';
+  case  64, header.ImgDataType = 'DT_DOUBLE';
+  case 128, header.ImgDataType = 'DT_RGB';
+  case 255, header.ImgDataType = 'DT_ALL';
+  otherwise, warning ('analyze75: unable to detect ImgDataType');
+  end
 
-header.BitDepth           = fread(fidH,1,'int16');
-unused                    = fread(fidH,1,'int16');
-unused                    = fread(fidH,1,'float');
-header.PixelDimensions    = zeros(1,3);
-header.PixelDimensions(1) = fread(fidH,1,'float');
-header.PixelDimensions(2) = fread(fidH,1,'float');
-header.PixelDimensions(3) = fread(fidH,1,'float');
-unused                    = fread(fidH,4,'float');
-header.VoxelOffset        = fread(fidH,1,'float');
-unused                    = fread(fidH,3,'float');
-header.CalibrationMax     = fread(fidH,1,'float');
-header.CalibrationMin     = fread(fidH,1,'float');
-header.Compressed         = fread(fidH,1,'float');
-header.Verified           = fread(fidH,1,'float');
-header.GlobalMax          = fread(fidH,1,'int32');
-header.GlobalMin          = fread(fidH,1,'int32');
-header.Descriptor         = char(fread(fidH,80,'char'))';
-header.AuxFile            = char(fread(fidH,24,'char'))';
-header.Orientation        = char(fread(fidH,1,'char'))';
-header.Originator         = char(fread(fidH,10,'char'))';
-header.Generated          = char(fread(fidH,10,'char'))';
-header.Scannumber         = char(fread(fidH,10,'char'))';
-header.PatientID          = char(fread(fidH,10,'char'))';
-header.ExposureDate       = char(fread(fidH,10,'char'))';
-header.ExposureTime       = char(fread(fidH,10,'char'))';
-unused                    = char(fread(fidH,3,'char'))';
-header.Views              = fread(fidH,1,'int32');
-header.VolumesAdded       = fread(fidH,1,'int32');
-header.StartField         = fread(fidH,1,'int32');
-header.FieldSkip          = fread(fidH,1,'int32');
-header.OMax               = fread(fidH,1,'int32');
-header.OMin               = fread(fidH,1,'int32');
-header.SMax               = fread(fidH,1,'int32');
-header.SMin               = fread(fidH,1,'int32');
+  header.BitDepth           = fread (fidH, 1, 'int16');
+  unused                    = fread (fidH, 1, 'int16');
+  unused                    = fread (fidH, 1, 'float');
+  header.PixelDimensions    = zeros (1, 3);
+  header.PixelDimensions(1) = fread (fidH, 1, 'float');
+  header.PixelDimensions(2) = fread (fidH, 1, 'float');
+  header.PixelDimensions(3) = fread (fidH, 1, 'float');
+  unused                    = fread (fidH, 4, 'float');
+  header.VoxelOffset        = fread (fidH, 1, 'float');
+  unused                    = fread (fidH, 3, 'float');
+  header.CalibrationMax     = fread (fidH, 1, 'float');
+  header.CalibrationMin     = fread (fidH, 1, 'float');
+  header.Compressed         = fread (fidH, 1, 'float');
+  header.Verified           = fread (fidH, 1, 'float');
+  header.GlobalMax          = fread (fidH, 1, 'int32');
+  header.GlobalMin          = fread (fidH, 1, 'int32');
+  header.Descriptor         = char (fread (fidH, 80, 'char'))';
+  header.AuxFile            = char (fread (fidH, 24, 'char'))';
+  header.Orientation        = char (fread (fidH, 1,  'char'))';
+  header.Originator         = char (fread (fidH, 10, 'char'))';
+  header.Generated          = char (fread (fidH, 10, 'char'))';
+  header.Scannumber         = char (fread (fidH, 10, 'char'))';
+  header.PatientID          = char (fread (fidH, 10, 'char'))';
+  header.ExposureDate       = char (fread (fidH, 10, 'char'))';
+  header.ExposureTime       = char (fread (fidH, 10, 'char'))';
+  unused                    = char (fread (fidH, 3,  'char'))';
+  header.Views              = fread (fidH, 1, 'int32');
+  header.VolumesAdded       = fread (fidH, 1, 'int32');
+  header.StartField         = fread (fidH, 1, 'int32');
+  header.FieldSkip          = fread (fidH, 1, 'int32');
+  header.OMax               = fread (fidH, 1, 'int32');
+  header.OMin               = fread (fidH, 1, 'int32');
+  header.SMax               = fread (fidH, 1, 'int32');
+  header.SMin               = fread (fidH, 1, 'int32');
 
-header.Width              = header.Dimensions(1);
-header.Height             = header.Dimensions(2);
-
-fclose(fidH);
-
-%----------------------------
-% Check the img filesize
-%----------------------------
+  header.Width              = header.Dimensions(1);
+  header.Height             = header.Dimensions(2);
 
-fidI = fopen([fileprefix,'.img']);
-fseek(fidI,0,1);
-header.ImgFileSize = ftell(fidI);
-fclose(fidI);
-
-end %function
-%--------------------------------------------------------------------------
-
+  fclose(fidH);
+end
--- a/inst/analyze75read.m
+++ b/inst/analyze75read.m
@@ -1,4 +1,5 @@
 %% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com>
+%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com>
 %%
 %% This program is free software; you can redistribute it and/or modify
 %% it under the terms of the GNU General Public License as published by
@@ -14,95 +15,55 @@
 %% along with this program; If not, see <http://www.gnu.org/licenses/>.
 
 %% -*- texinfo -*-
-%% @deftypefn {Function File} {@var{image} = } analyze75read(@var{filename})
-%% @deftypefnx {Function File} {@var{image} = } analyze75read(@var{structure})
-%% Read the image data contained in an Analyze file.
+%% @deftypefn {Function File} {@var{image} =} analyze75read (@var{filename})
+%% @deftypefnx {Function File} {@var{image} =} analyze75read (@var{header})
+%% Read image data of an Analyze 7.5 file.
 %%
-%% FILENAME is a string (giving the filename).
-%% Alternatively, STRUCTURE is a structure containing a field `Filename'
-%% (such as returned by `analyze75info').
+%% @var{filename} must be the path for an Analyze 7.5 file or the path for a
+%% directory with a single .hdr file can be specified. Alternatively, the file
+%% @var{header} can be specified as returned by @code{analyze75info}.
+%%
+%% @seealso{analyze75info}
 %% @end deftypefn
 
-function data = analyze75read(varargin);
-%--------------------------------------------------------------------------
-
-%--------------
-% Check filename
-%--------------
-
-filename = varargin{1};
+function data = analyze75read (filename);
 
-if isstruct(filename)==1 && isfield(filename,'Filename')==1
-  header   = filename;
-  filename = header.Filename;
-elseif exist('filename','var')==1 && exist(filename,'dir')==7
-  filelist = dir([filename,filesep,'*.hdr']);
-  if numel(filelist)==1
-    filename = [filename,filesep,filelist.name];
-  else
-    [filename,filepath] = uigetfile([filename,filesep,'*.hdr'],'Select the input file');
-    filename = [filepath,filename];
+  if (nargin ~= 1)
+    print_usage;
+  elseif (isstruct (filename))
+    if (~isfield (filename, 'Filename'))
+      error ('analyze75read: structure given does not have a `Filename'' field.');
+    else
+      header   = filename;
+      filename = filename.Filename;
+    end
+  elseif (~ischar (filename))
+    error ('analyze75read: `filename'' must be either a string or a structure.');
   end
-elseif ( exist('filename','var')==1 && exist(filename,'file')==0 ) || exist('filename','var')==0
-  [filename,filepath] = uigetfile('*.hdr','Select the input file');
-  filename = [filepath,filename];
-end
 
-% Strip the filename of the extension
+  fileprefix = analyze75filename (filename);
 
-fileextH = strfind(filename,'.hdr');
-fileextI = strfind(filename,'.img');
-if isempty(fileextH)==0
-  fileprefix = filename(1:fileextH-1);
-elseif isempty(fileextI)==0
-  fileprefix = filename(1:fileextI-1);
-else
-  fileprefix = filename;
-end
-
-%--------------
-% Read the file
-%--------------
+  if (~exist ('header', 'var'))
+    header = analyze75info ([fileprefix, '.hdr']);
+  end
 
-if exist('header','var')==0
-  header = analyze75info(filename);
-end
-
-data = READ_img(fileprefix,header);
-
-end %function
-%--------------------------------------------------------------------------
-
-
-%--------------------------------------------------------------------------
-function [data] = READ_img(fileprefix,header)
-
-%----------------------------
-% Read the .img file
-%----------------------------
-
-fidI = fopen([fileprefix,'.img']);
-
-fseek(fidI,0,-1);
+  %% finally start reading the actual file
+  [fidI, err] = fopen ([fileprefix, '.img']);
+  if (fidI < 0)
+    error ('analyze75read: unable to fopen `%s'': %s', [fileprefix, '.img'], err);
+  end
 
-if strcmp(header.ImgDataType,'DT_FLOAT')==1
-  datatype = 'single';
-else
-  datatype = 'double';
-end
-
-data    = zeros(header.Dimensions,datatype);
-data(:) = fread(fidI,datatype,header.ByteOrder);
-
-fclose(fidI);
+  if (strcmp (header.ImgDataType, 'DT_FLOAT'))
+    datatype = 'single';
+  else
+    datatype = 'double';
+  end
 
-%----------------------------
-% Rearrange the data
-%----------------------------
+  data    = zeros (header.Dimensions, datatype);
+  data(:) = fread (fidI, datatype, header.ByteOrder);
 
-data = permute(data,[2,1,3]);
+  fclose (fidI);
 
-end %function
-%--------------------------------------------------------------------------
-
-
+  %% Rearrange the data
+  data = permute (data, [2,1,3]);
+end
new file mode 100644
--- /dev/null
+++ b/inst/private/analyze75filename.m
@@ -0,0 +1,45 @@
+%% Copyright (C) 2012 Adam H Aitkenhead <adamaitkenhead@hotmail.com>
+%% Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com>
+%%
+%% This program is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published by
+%% the Free Software Foundation; either version 3 of the License, or
+%% (at your option) any later version.
+%%
+%% This program is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%% GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public License
+%% along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+%% private function with common code for the analyze75info and read functions
+
+function filename = analyze75check (filename)
+
+  %% Check filename
+  if (exist (filename, 'dir'))
+    filelist = dir ([filename, filesep, '*.hdr']);
+    if (numel (filelist) == 1)
+      filename = [filename, filesep, filelist.name];
+    elseif (numel (filelist) > 1)
+      error ('analyze75: `filename'' is a directory with multiple hdr files.')
+    else
+      error ('analyze75: `filename'' is a directory with no hdr files.')
+    end
+  elseif (~exist (filename,'file')
+      error ('analyze75info: no file `%s''', filename)
+  end
+
+  %% Strip the filename of the extension
+  fileextH = strfind (filename, '.hdr');
+  fileextI = strfind (filename, '.img');
+  if (~isempty (fileextH))
+    filename = filename(1:fileextH(end)-1);
+  elseif (~isempty (fileextI))
+    filename = filename(1:fileextI(end)-1);
+  else
+    filename = filename;
+  end
+end