spm_summarise.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. function [Y, xY] = spm_summarise(V,xY,fhandle,keepNaNs)
  2. % Summarise data within a Region of Interest
  3. % FORMAT [Y, xY] = spm_summarise(V,xY,fhandle)
  4. % V - [1 x n] vector of mapped image volumes to read (from spm_vol)
  5. % Or a char array of filenames
  6. % xY - VOI structure (from spm_ROI)
  7. % Or a VOI_*.mat (from spm_regions) or a mask image filename
  8. % Or the keyword 'all' to summarise all voxels in the images
  9. % Or a [3 x m] matrix of voxel coordinates {mm}
  10. % fhandle - function handle to be applied on image data within VOI
  11. % Must transform a [1 x m] array into a [1 x p] array
  12. % Default is Identity (returns raw data, vectorised into rows).
  13. % Can also use keyword 'litres' to compute the total volume,
  14. % within the region of interest, for a tissue segment image.
  15. %
  16. % Y - [n x p] data summary
  17. % xY - (updated) VOI structure
  18. %__________________________________________________________________________
  19. %
  20. % Example:
  21. % spm_summarise('beta_0001.nii',...
  22. % struct('def','sphere', 'spec',8, 'xyz',[10 20 30]'),...
  23. % @mean)
  24. %__________________________________________________________________________
  25. % Copyright (C) 2010-2015 Wellcome Trust Centre for Neuroimaging
  26. % Guillaume Flandin, Ged Ridgway
  27. % $Id: spm_summarise.m 7384 2018-07-31 13:36:15Z guillaume $
  28. %-Argument checks
  29. %--------------------------------------------------------------------------
  30. if nargin < 1 || isempty(V)
  31. [V, sts] = spm_select([1 Inf], 'image', 'Specify Images');
  32. if ~sts, error('Must select 1 or more images'), end
  33. end
  34. if iscellstr(V), V = char(V); end
  35. if ischar(V), V = spm_data_hdr_read(V); end
  36. spm_check_orientations(V);
  37. if nargin < 2 || isempty(xY), xY = struct; end
  38. if ischar(xY)
  39. if strcmpi(xY, 'all')
  40. xY = struct('def', 'all');
  41. elseif any(regexpi(xY, '\.mat$'))
  42. try
  43. load(xY,'xY'); % VOI_*.mat file. Warns if .mat has no xY ...
  44. xY = rmfield(xY,'XYZmm'); % ... error if .mat has no xY
  45. catch
  46. xY = struct; % GUI specification in spm_ROI
  47. end
  48. else % assume mask image filename
  49. xY = struct('def','mask', 'spec',xY);
  50. end
  51. elseif isnumeric(xY) && any(size(xY, 1) == [3 4])
  52. xY = struct('XYZmm', xY(1:3, :));
  53. elseif isstruct(xY) && isfield(xY,'fname')
  54. xY = struct('def','mask', 'spec',xY);
  55. elseif ~isstruct(xY)
  56. error('Incorrect xY specified')
  57. end
  58. if ~isfield(xY,'XYZmm'), [xY, xY.XYZmm] = spm_ROI(xY,V(1)); end
  59. if nargin < 3 || isempty(fhandle), fhandle = @(x) x; end
  60. if ischar(fhandle) && strcmp(fhandle, 'litres')
  61. vsz = abs(det(V(1).mat)); % voxel size in mm^3
  62. fhandle = @(x) sum(x) * vsz / 1e6;
  63. end
  64. if ischar(fhandle), fhandle = str2func(fhandle); end
  65. % Undocumented option in case anyone wants to keep (e.g. to check for) NaNs
  66. if nargin < 4, keepNaNs = false; end
  67. if keepNaNs
  68. dropNaNs = @(x) x;
  69. else
  70. dropNaNs = @(x) x(~isnan(x));
  71. end
  72. %-Summarise data
  73. %--------------------------------------------------------------------------
  74. XYZ = round(V(1).mat \ [xY.XYZmm; ones(1, size(xY.XYZmm, 2))]);
  75. % Run on first volume to determine p, and transpose if column vector
  76. Y = fhandle(dropNaNs(spm_data_read(V(1), 'xyz', XYZ)));
  77. if ndims(Y) > 2
  78. error('Function must return a [1 x p] array')
  79. elseif size(Y, 1) ~= 1
  80. if size(Y, 2) == 1
  81. Y = Y';
  82. else
  83. error('Function returned a [%d x %d] array instead of [1 x p]', ...
  84. size(Y, 1), size(Y, 2))
  85. end
  86. end
  87. % Preallocate space and then run on remaining volumes
  88. Y(2:numel(V), :) = 0;
  89. for i = 2:numel(V)
  90. Y(i, :) = fhandle(dropNaNs(spm_data_read(V(i), 'xyz', XYZ)));
  91. end