Home > bioelectromagnetism > avw_hdr_write.m

avw_hdr_write

PURPOSE ^

AVW_HDR_WRITE - Write Analyze header file (*.hdr)

SYNOPSIS ^

function avw_hdr_write(avw, fileprefix, machine, verbose)

DESCRIPTION ^

 AVW_HDR_WRITE - Write Analyze header file (*.hdr)
 
 avw_hdr_write(avw,[fileprefix],[machine],[verbose])
 
 eg, avw_hdr_write(avw,'test');
 
 avw        - a struct with .hdr field, which itself is a struct,
              containing all fields of an Analyze header.
              For details, see avw_hdr_read.m
 
 fileprefix - a string, the filename without the .hdr extension.
              If empty, may use avw.fileprefix
 
 machine    - a string, see machineformat in fread for details.
              The default here is 'ieee-le'.
 
 verbose - the default is to output processing information to the command
           window.  If verbose = 0, this will not happen.

 See also, AVW_HDR_READ AVW_HDR_MAKE
           AVW_IMG_READ AVW_IMG_WRITE

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function avw_hdr_write(avw, fileprefix, machine, verbose)
0002 
0003 % AVW_HDR_WRITE - Write Analyze header file (*.hdr)
0004 %
0005 % avw_hdr_write(avw,[fileprefix],[machine],[verbose])
0006 %
0007 % eg, avw_hdr_write(avw,'test');
0008 %
0009 % avw        - a struct with .hdr field, which itself is a struct,
0010 %              containing all fields of an Analyze header.
0011 %              For details, see avw_hdr_read.m
0012 %
0013 % fileprefix - a string, the filename without the .hdr extension.
0014 %              If empty, may use avw.fileprefix
0015 %
0016 % machine    - a string, see machineformat in fread for details.
0017 %              The default here is 'ieee-le'.
0018 %
0019 % verbose - the default is to output processing information to the command
0020 %           window.  If verbose = 0, this will not happen.
0021 %
0022 % See also, AVW_HDR_READ AVW_HDR_MAKE
0023 %           AVW_IMG_READ AVW_IMG_WRITE
0024 %
0025 
0026 % $Revision: 1.1 $ $Date: 2004/11/12 01:30:25 $
0027 
0028 % Licence:  GNU GPL, no express or implied warranties
0029 % History:  05/2002, Darren.Weber@flinders.edu.au
0030 %           02/2003, Bennett.Landman@ieee.org
0031 %                    - more specific data history var sizes
0032 %                    - 02/2003 confirmed, Darren
0033 %
0034 %                    The Analyze format and c code below is copyright
0035 %                    (c) Copyright, 1986-1995
0036 %                    Biomedical Imaging Resource, Mayo Foundation
0037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0038 
0039 if ~exist('verbose','var'), verbose = 1; end
0040 if ~exist('machine','var'), machine = 'ieee-le'; end
0041 
0042 if verbose,
0043     version = '[$Revision: 1.1 $]';
0044     fprintf('AVW_HDR_WRITE [v%s]\n',version(12:16));  tic;
0045 end
0046 
0047 %----------------------------------------------------------------------------
0048 % Check inputs
0049 
0050 if ~exist('avw','var'),
0051     warning('...no input avw - calling avw_hdr_make\n');
0052     avw = avw_hdr_make;
0053 elseif isempty(avw),
0054     warning('...empty input avw - calling avw_hdr_make\n');
0055     avw = avw_hdr_make;
0056 elseif ~isfield(avw,'hdr'),
0057     warning('...empty input avw.hdr - calling avw_hdr_make\n');
0058     avw = avw_hdr_make;
0059 end
0060 if ~isequal(avw.hdr.hk.sizeof_hdr,348),
0061     msg = sprintf('...avw.hdr.hk.sizeof_hdr must be 348!\n');
0062     error(msg);
0063 end
0064 
0065 quit = 0;
0066 if ~exist('fileprefix','var'),
0067     if isfield(avw,'fileprefix'),
0068         if ~isempty(avw.fileprefix),
0069             fileprefix = avw.fileprefix;
0070         else,
0071             quit = 1;
0072         end
0073     else
0074         quit = 1;
0075     end
0076     if quit,
0077         helpwin avw_hdr_write;
0078         error('...no input fileprefix - see help avw_hdr_write\n\n');
0079         return;
0080     end
0081 end
0082 
0083 if findstr('.hdr',fileprefix),
0084 %    fprintf('AVW_HDR_WRITE: Removing .hdr extension from ''%s''\n',fileprefix);
0085     fileprefix = strrep(fileprefix,'.hdr','');
0086 end
0087 
0088 
0089 
0090 %----------------------------------------------------------------------------
0091 % MAIN
0092 
0093 if verbose, tic; end
0094 
0095 
0096 % % force volume to 4D if necessary; conforms to AVW standard.  i lifted this
0097 % % code from mri_toolbox/avw_hdr_read.m and modified it just a little bit
0098 % % (using minDim = 4; etc)
0099 % minDim = 4;
0100 % currDim = double(avw.hdr.dime.dim(1));
0101 % if ( currDim < minDim )
0102 %    % fprintf( 'Warning %s: Forcing %d dimensions in avw.hdr.dime.dim\n', ...
0103 %    %    mfilename, minDim );
0104 %    avw.hdr.dime.dim(1) = int16(minDim);
0105 %    avw.hdr.dime.dim(currDim+2:minDim+1) = int16(1);
0106 %    avw.hdr.dime.pixdim(1) = int16(minDim);
0107 %    avw.hdr.dime.pixdim(currDim+2:minDim+1) = int16(1);
0108 % end;
0109 
0110 
0111 fid = fopen(sprintf('%s.hdr',fileprefix),'w',machine);
0112 if fid < 0,
0113     msg = sprintf('Cannot write to file %s.hdr\n',fileprefix);
0114     error(msg);
0115 else
0116     if verbose, fprintf('...writing %s Analyze header.\n',machine); end
0117     write_header(fid,avw,verbose);
0118 end
0119 
0120 if verbose, t=toc; fprintf('...done (%5.2f sec).\n\n',t); end
0121 
0122 return
0123 
0124 
0125 
0126 
0127 
0128 %----------------------------------------------------------------------------
0129 
0130 function write_header(fid,avw,verbose)
0131     
0132     header_key(fid,avw.hdr.hk);
0133     image_dimension(fid,avw.hdr.dime);
0134     data_history(fid,avw.hdr.hist);
0135     
0136     % check the file size is 348 bytes
0137     fbytes = ftell(fid);
0138     fclose(fid);
0139     if ~isequal(fbytes,348),
0140         msg = sprintf('...file size is not 348 bytes!\n');
0141         warning(msg);
0142     end
0143     
0144 return
0145 
0146 %----------------------------------------------------------------------------
0147 
0148 function header_key(fid,hk)
0149     
0150     % Original header structures - ANALYZE 7.5
0151     % struct header_key                      /* header key      */
0152     %       {                                /* off + size      */
0153     %       int sizeof_hdr                   /*  0 +  4         */
0154     %       char data_type[10];              /*  4 + 10         */
0155     %       char db_name[18];                /* 14 + 18         */
0156     %       int extents;                     /* 32 +  4         */
0157     %       short int session_error;         /* 36 +  2         */
0158     %       char regular;                    /* 38 +  1         */
0159     %       char hkey_un0;                   /* 39 +  1         */
0160     %       };                               /* total=40 bytes  */
0161     
0162     fseek(fid,0,'bof');
0163     
0164     fwrite(fid, hk.sizeof_hdr(1),   'int32');  % must be 348!
0165     
0166     data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars
0167     fwrite(fid, hk.data_type(1:10), 'uchar');
0168     
0169     db_name   = sprintf('%-18s',hk.db_name);   % ensure it is 18 chars
0170     fwrite(fid, db_name(1:18),      'uchar');
0171     
0172     fwrite(fid, hk.extents(1),      'int32');
0173     fwrite(fid, hk.session_error(1),'int16');
0174     
0175     regular   = sprintf('%1s',hk.regular);     % ensure it is 1 char
0176     fwrite(fid, regular(1),         'uchar');  % might be uint8
0177     
0178     %hkey_un0  = sprintf('%1s',hk.hkey_un0);    % ensure it is 1 char
0179     %fwrite(fid, hkey_un0(1),        'uchar');
0180     fwrite(fid, hk.hkey_un0(1),     'uint8');
0181     
0182     %    >Would you set hkey_un0 as char or uint8?
0183     %   Really doesn't make any difference.  As far as anyone here can remember,
0184     %   this was just to pad to an even byte boundary for that structure.  I guess
0185     %   I'd suggest setting it to a uint8 value of 0 (i.e, truly zero-valued) so
0186     %   that it doesn't look like anything important!
0187     %   Denny <hanson.dennis2@mayo.edu>
0188     
0189 return
0190 
0191 %----------------------------------------------------------------------------
0192 
0193 function image_dimension(fid,dime)
0194     
0195     %struct image_dimension
0196     %       {                                /* off + size      */
0197     %       short int dim[8];                /* 0 + 16          */
0198     %       char vox_units[4];               /* 16 + 4          */
0199     %       char cal_units[8];               /* 20 + 8          */
0200     %       short int unused1;               /* 28 + 2          */
0201     %       short int datatype;              /* 30 + 2          */
0202     %       short int bitpix;                /* 32 + 2          */
0203     %       short int dim_un0;               /* 34 + 2          */
0204     %       float pixdim[8];                 /* 36 + 32         */
0205     %            /*
0206     %                pixdim[] specifies the voxel dimensions:
0207     %                pixdim[1] - voxel width
0208     %                pixdim[2] - voxel height
0209     %                pixdim[3] - interslice distance
0210     %                    ..etc
0211     %            */
0212     %       float vox_offset;                /* 68 + 4          */
0213     %       float roi_scale;                 /* 72 + 4          */
0214     %       float funused1;                  /* 76 + 4          */
0215     %       float funused2;                  /* 80 + 4          */
0216     %       float cal_max;                   /* 84 + 4          */
0217     %       float cal_min;                   /* 88 + 4          */
0218     %       int compressed;                  /* 92 + 4          */
0219     %       int verified;                    /* 96 + 4          */
0220     %       int glmax;                       /* 100 + 4         */
0221     %       int glmin;                       /* 104 + 4         */
0222     %       };                               /* total=108 bytes */
0223     
0224     fwrite(fid, dime.dim(1:8),      'int16');
0225     fwrite(fid, dime.vox_units(1:4),'uchar');
0226     fwrite(fid, dime.cal_units(1:8),'uchar');
0227     fwrite(fid, dime.unused1(1),    'int16');
0228     fwrite(fid, dime.datatype(1),   'int16');
0229     fwrite(fid, dime.bitpix(1),     'int16');
0230     fwrite(fid, dime.dim_un0(1),    'int16');
0231     fwrite(fid, dime.pixdim(1:8),   'float32');
0232     fwrite(fid, dime.vox_offset(1), 'float32');
0233     
0234     % Ensure compatibility with SPM (according to MRIcro)
0235     if dime.roi_scale == 0, dime.roi_scale = 0.00392157; end
0236     fwrite(fid, dime.roi_scale(1),  'float32');
0237     
0238     fwrite(fid, dime.funused1(1),   'float32');
0239     fwrite(fid, dime.funused2(1),   'float32');
0240     fwrite(fid, dime.cal_max(1),    'float32');
0241     fwrite(fid, dime.cal_min(1),    'float32');
0242     fwrite(fid, dime.compressed(1), 'int32');
0243     fwrite(fid, dime.verified(1),   'int32');
0244     fwrite(fid, dime.glmax(1),      'int32');
0245     fwrite(fid, dime.glmin(1),      'int32');
0246     
0247 return
0248 
0249 %----------------------------------------------------------------------------
0250 
0251 function data_history(fid,hist)
0252     
0253     % Original header structures - ANALYZE 7.5
0254     %struct data_history
0255     %       {                                /* off + size      */
0256     %       char descrip[80];                /* 0 + 80          */
0257     %       char aux_file[24];               /* 80 + 24         */
0258     %       char orient;                     /* 104 + 1         */
0259     %       char originator[10];             /* 105 + 10        */
0260     %       char generated[10];              /* 115 + 10        */
0261     %       char scannum[10];                /* 125 + 10        */
0262     %       char patient_id[10];             /* 135 + 10        */
0263     %       char exp_date[10];               /* 145 + 10        */
0264     %       char exp_time[10];               /* 155 + 10        */
0265     %       char hist_un0[3];                /* 165 + 3         */
0266     %       int views                        /* 168 + 4         */
0267     %       int vols_added;                  /* 172 + 4         */
0268     %       int start_field;                 /* 176 + 4         */
0269     %       int field_skip;                  /* 180 + 4         */
0270     %       int omax;                        /* 184 + 4         */
0271     %       int omin;                        /* 188 + 4         */
0272     %       int smax;                        /* 192 + 4         */
0273     %       int smin;                        /* 196 + 4         */
0274     %       };                               /* total=200 bytes */
0275     
0276     descrip     = sprintf('%-80s', hist.descrip);       % 80 chars
0277     aux_file    = sprintf('%-24s', hist.aux_file);      % 24 chars
0278     originator  = sprintf('%-10s', hist.originator);    % 10 chars
0279     generated   = sprintf('%-10s', hist.generated);     % 10 chars
0280     scannum     = sprintf('%-10s', hist.scannum);       % 10 chars
0281     patient_id  = sprintf('%-10s', hist.patient_id);    % 10 chars
0282     exp_date    = sprintf('%-10s', hist.exp_date);      % 10 chars
0283     exp_time    = sprintf('%-10s', hist.exp_time);      % 10 chars
0284     hist_un0    = sprintf( '%-3s', hist.hist_un0);      %  3 chars
0285     
0286     % ---
0287     % The following should not be necessary, but I actually
0288     % found one instance where it was, so this totally anal
0289     % retentive approach became necessary, despite the
0290     % apparently elegant solution above to ensuring that variables
0291     % are the right length.
0292     
0293     if length(descrip) < 80,
0294       paddingN = 80-length(descrip);
0295       padding = char(repmat(double(' '),1,paddingN));
0296       descrip = [descrip,padding];
0297     end
0298     if length(aux_file) < 24,
0299       paddingN = 24-length(aux_file);
0300       padding = char(repmat(double(' '),1,paddingN));
0301       aux_file = [aux_file,padding];
0302     end
0303     if length(originator) < 10,
0304       paddingN = 10-length(originator);
0305       padding = char(repmat(double(' '),1,paddingN));
0306       originator = [originator, padding];
0307     end
0308     if length(generated) < 10,
0309       paddingN = 10-length(generated);
0310       padding = char(repmat(double(' '),1,paddingN));
0311       generated = [generated, padding];
0312     end
0313     if length(scannum) < 10,
0314       paddingN = 10-length(scannum);
0315       padding = char(repmat(double(' '),1,paddingN));
0316       scannum = [scannum, padding];
0317     end
0318     if length(patient_id) < 10,
0319       paddingN = 10-length(patient_id);
0320       padding = char(repmat(double(' '),1,paddingN));
0321       patient_id = [patient_id, padding];
0322     end
0323     if length(exp_date) < 10,
0324       paddingN = 10-length(exp_date);
0325       padding = char(repmat(double(' '),1,paddingN));
0326       exp_date = [exp_date, padding];
0327     end
0328     if length(exp_time) < 10,
0329       paddingN = 10-length(exp_time);
0330       padding = char(repmat(double(' '),1,paddingN));
0331       exp_time = [exp_time, padding];
0332     end
0333     if length(hist_un0) < 10,
0334       paddingN = 10-length(hist_un0);
0335       padding = char(repmat(double(' '),1,paddingN));
0336       hist_un0 = [hist_un0, padding];
0337     end
0338     
0339     % -- if you thought that was anal, try this;
0340     % -- lets check for unusual ASCII char values!
0341     
0342     if find(double(descrip)>128),
0343       indexStrangeChar = find(double(descrip)>128);
0344       descrip(indexStrangeChar) = ' ';
0345     end
0346     if find(double(aux_file)>128),
0347       indexStrangeChar = find(double(aux_file)>128);
0348       aux_file(indexStrangeChar) = ' ';
0349     end
0350     if find(double(originator)>128),
0351       indexStrangeChar = find(double(originator)>128);
0352       originator(indexStrangeChar) = ' ';
0353     end
0354     if find(double(generated)>128),
0355       indexStrangeChar = find(double(generated)>128);
0356       generated(indexStrangeChar) = ' ';
0357     end
0358     if find(double(scannum)>128),
0359       indexStrangeChar = find(double(scannum)>128);
0360       scannum(indexStrangeChar) = ' ';
0361     end
0362     if find(double(patient_id)>128),
0363       indexStrangeChar = find(double(patient_id)>128);
0364       patient_id(indexStrangeChar) = ' ';
0365     end
0366     if find(double(exp_date)>128),
0367       indexStrangeChar = find(double(exp_date)>128);
0368       exp_date(indexStrangeChar) = ' ';
0369     end
0370     if find(double(exp_time)>128),
0371       indexStrangeChar = find(double(exp_time)>128);
0372       exp_time(indexStrangeChar) = ' ';
0373     end
0374     if find(double(hist_un0)>128),
0375       indexStrangeChar = find(double(hist_un0)>128);
0376       hist_un0(indexStrangeChar) = ' ';
0377     end
0378     
0379     
0380     % --- finally, we write the fields
0381     
0382     fwrite(fid, descrip(1:80),    'uchar');
0383     fwrite(fid, aux_file(1:24),   'uchar');
0384     
0385     
0386     %orient      = sprintf(  '%1s', hist.orient);        %  1 char
0387     %fwrite(fid, orient(1),        'uchar');
0388     fwrite(fid, hist.orient(1),   'uint8');     % see note below on char
0389     
0390     fwrite(fid, originator(1:10), 'uchar');
0391     fwrite(fid, generated(1:10),  'uchar');
0392     fwrite(fid, scannum(1:10),    'uchar');
0393     fwrite(fid, patient_id(1:10), 'uchar');
0394     fwrite(fid, exp_date(1:10),   'uchar');
0395     fwrite(fid, exp_time(1:10),   'uchar');
0396     fwrite(fid, hist_un0(1:3),    'uchar');
0397     
0398     fwrite(fid, hist.views(1),      'int32');
0399     fwrite(fid, hist.vols_added(1), 'int32');
0400     fwrite(fid, hist.start_field(1),'int32');
0401     fwrite(fid, hist.field_skip(1), 'int32');
0402     fwrite(fid, hist.omax(1),       'int32');
0403     fwrite(fid, hist.omin(1),       'int32');
0404     fwrite(fid, hist.smax(1),       'int32');
0405     fwrite(fid, hist.smin(1),       'int32');
0406     
0407 return
0408 
0409 
0410 
0411 % Note on using char:
0412 % The 'char orient' field in the header is intended to
0413 % hold simply an 8-bit unsigned integer value, not the ASCII representation
0414 % of the character for that value.  A single 'char' byte is often used to
0415 % represent an integer value in Analyze if the known value range doesn't
0416 % go beyond 0-255 - saves a byte over a short int, which may not mean
0417 % much in today's computing environments, but given that this format
0418 % has been around since the early 1980's, saving bytes here and there on
0419 % older systems was important!  In this case, 'char' simply provides the
0420 % byte of storage - not an indicator of the format for what is stored in
0421 % this byte.  Generally speaking, anytime a single 'char' is used, it is
0422 % probably meant to hold an 8-bit integer value, whereas if this has
0423 % been dimensioned as an array, then it is intended to hold an ASCII
0424 % character string, even if that was only a single character.
0425 % Denny  <hanson.dennis2@mayo.edu>
0426 
0427 % See other notes in avw_hdr_read

Generated on Mon 15-Aug-2005 15:36:19 by m2html © 2003