function V = lyngby_getvolume(index);

% lyngby_getvolume     - Get a volume from a file
%
%	function V = lyngby_getvolume(index);
%
%	Input:	index	Index in the total number of scans, indexed
%	                from one.
%	
%	Output:	V	The volume as a row vector
%
%       Global: DATATYPE           Datatype, see fread
%               FILENAMEPATH       The 'Path' part of the filename
%               FILENAME_PATTERN   Pattern for file name containing a
%                                  '%d' part
%               FILE_READING_TYPE  [ analyze | analyze4d | sdt |
%                                  vapet4d | 1 | 2 | 3 ] The filetype 
%               NUM_VOXELS         Number of voxels
%               ORDERING           Ordering between dimensions, eg,
%                                  whether y is before x
%               ORIENTATION        Mirroring, e.g., whether left or
%                                  right is first in the volume
%
%       This function reads a volume in one of several
%       fileformats. The volume read and how it is interpret is
%       determined from global variables. 
% 
%	If FILE_READING_TYPE is 2 the function looks
%	for a matlab function named 'data_readdata' that the user 
%	should provide. This function should be defined as:
%		V = data_readdata(index);
%	
%	If FILE_READING_TYPE is 1 it will be assumed
%	that the filetype is ANALYZE of VAPET, and the orientation
%	and ordering is: 
%		[left-to-right back-to-front bottom-to-top] 
%
%	See also LYNGBY, LYNGBY_READ_VOLUME, LYNGBY_GETINFO,
%	         LYNGBY_GLOBAL, LYNGBY_READ_ANALYZE,
%	         LYNGBY_READ_ANA4D, LYNGBY_READ_SDT,
%	         LYNGBY_READ_VAPET4D.
%
% $Id: lyngby_getvolume.m,v 1.10 2002/05/19 22:26:28 fnielsen Exp $


    lyngby_global;

    if isstr(FILE_READING_TYPE) 
      if strcmp('analyze', lower(FILE_READING_TYPE))
	filename = [FILENAME_PATH FILENAME_PATTERN];
	V = lyngby_read_analyze(filename, ...
	    'size', NUM_VOXELS, ...
	    'Datatype', DATATYPE, ...
	    'Ordering', ORDERING, ...
	    'Orientation', ORIENTATION, ...
	    'FilenameIndex', index);
      elseif strcmp('analyze4d', lower(FILE_READING_TYPE))
	filename = [FILENAME_PATH FILENAME_PATTERN];
	V = lyngby_read_ana4d(filename, ...
	    'size', NUM_VOXELS, ...
	    'scans', NUM_SCANS, ...
	    'Datatype', DATATYPE, ...
	    'Ordering', ORDERING, ...
	    'Orientation', ORIENTATION, ...
	    'VolumeIndex', index);
      elseif strcmp('sdt', lower(FILE_READING_TYPE))
	filename = [FILENAME_PATH FILENAME_PATTERN];
	V = lyngby_read_sdt(filename, ...
	    'size', NUM_VOXELS, ...
	    'scans', NUM_SCANS, ...
	    'Datatype', DATATYPE, ...
	    'Ordering', ORDERING, ...
	    'Orientation', ORIENTATION, ...
	    'VolumeIndex', index);
      elseif strcmp('vapet4d', lower(FILE_READING_TYPE))
	filename = [FILENAME_PATH FILENAME_PATTERN];
	V = lyngby_read_vapet4d(filename, ...
	    'size', NUM_VOXELS, ...
	    'scans', NUM_SCANS, ...
	    'Datatype', DATATYPE, ...
	    'Ordering', ORDERING, ...
	    'Orientation', ORIENTATION, ...
	    'VolumeIndex', index);
      else
	error(sprintf('Unknown fileformat: %s', FILE_READING_TYPE));
      end
      
    else
    
      if FILE_READING_TYPE == 1,
	% Analyze/VAPET format
	name = [FILENAME_PATH ...
	      sprintf(FILENAME_PATTERN, index+FILENAME_STARTINDEX-1)];
	V = lyngby_read_volume(name);
      elseif FILE_READING_TYPE == 2,
	% Custom format
	if exist('data_readdata')
	  eval('V = data_readdata(index);')
	  if isempty(V)
	    error('data_readdata function did not return anything');
	  elseif isempty('NUM_VOXELS')  
	    error([ ...
		  'NUM_VOXELS (dimension of volume) is not set. ' ...
		  ]);
	  elseif ~all(prod(size(V)) == prod(NUM_VOXELS))
	    error(sprintf([...
		  'data_readdata function did not return a volume ', ...
		  'with the same size as specified by NUM_VOXELS\n', ...
		  '    Volume: %d \n    NUM_VOXELS: %d %d %d = %d'], ...
		length(V), NUM_VOXELS, prod(NUM_VOXELS)));
	  elseif size(V,1) > size(V,2)
	    % The user has a transposed volume.
	    V = V';
	  end
	else
	  error('The user should provide a ''data_readdata'' funct.');
	end
      elseif FILE_READING_TYPE == 3,
	% RAW format
	name = [FILENAME_PATH ...
	      sprintf(FILENAME_PATTERN, index+FILENAME_STARTINDEX-1)];
	f = fopen(name, 'rb');
	if f<0, 
	  error(sprintf(['Could not open file: %s'], ...
	      name));
	end
	
	% Calculate the word byte-size of the datatype
	switch (lower(DATATYPE))
	 case {'int8','uint8', 'byte', 'uchar', 'schar'}
	  wordlength = 1;
	 case {'int16','uint16','short'}
	  wordlength = 2;
	 case {'int32','uint32', 'single', 'float', 'uint', 'int', ...
	       'float32', 'int', 'long', 'ulong'}
	  wordlength = 4;
	 case {'int64','uint64', 'double', 'float64'}
	  wordlength = 8;
	 otherwise
	  wordlength = 2; % Default value
	end
	newpos = (index-1)*prod(NUM_VOXELS)*wordlength;  % Calc increment
	fseek(f,newpos,-1);                              % Reposition pointer
	V = fread(f, prod(NUM_VOXELS), lower(DATATYPE));
	if length(V) ~= prod(NUM_VOXELS)
	  error(sprintf(['The size of the file does not fit with '...
		'NUM_VOXELS and DATATYPE\n ' ...
		'File: %d, NUM_VOXELS: %d'], length(V), prod(NUM_VOXELS)));
	end

	% if size(V,1) > size(V,2)
	%  V = V';
	% end

        % New code to allow orientation and byte-order specification
    	orientation = ORIENTATION;
    	if isstr(ORDERING) & length(ORDERING) == 3 & ...
	      findstr('x', ORDERING) & ...
	      findstr('y', ORDERING) & ...
	      findstr('z', ORDERING)
    	  ordering = ORDERING;
    	else
    	  error(['The ''Ordering'' global variable should be ' ...
    		'a string with length 3 and consist of x, y and z.']); 
    	end
    
    	if isstr(ORIENTATION) & length(ORIENTATION) == 6 & ...
	      ( length(findstr('lr', ORIENTATION)) | ...
	      length(findstr('rl', ORIENTATION)) ) & ...
	      ( length(findstr('ap', ORIENTATION)) | ...
	      length(findstr('pa', ORIENTATION)) ) & ...
    	      ( length(findstr('is', ORIENTATION)) | ...
	      length(findstr('si', ORIENTATION)) ) 
    	  orientation = ORIENTATION;
    	else
    	  error(['The ''Orientation'' global variable should be ' ...
    		'a string with length 6 and consist of x, y and z.']); 
    	end
    
    	V = reshape(V, NUM_VOXELS);
    	if ~strcmp('xyz', ordering)
    	  x = findstr('x', ordering);
    	  y = findstr('y', ordering);
    	  z = findstr('z', ordering);
    	  V = permute(V, [x y z]);
    	end
    	if strcmp('rl', orientation(1:2))
    	  V = flipdim(V, 1);
    	end
    	if strcmp('ap', orientation(3:4))
    	  V = flipdim(V, 2);
    	end
    	if strcmp('si', orientation(5:6))
    	  V = flipdim(V, 3);
    	end
	
	V = reshape(V, [1 prod(NUM_VOXELS)]);
	% End new code
	
      elseif ~exist('FILE_READING_TYPE') | FILE_READING_TYPE == []
	error('The global variable FILE_READING_TYPE is not defined')
      else
	error('Invalid FILE_READING_TYPE');
      end
    end













