matRad_gammaIndex

Purpose ^

gamma index calculation

Synopsis ^

function [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,localglobal,cst)

Description ^

 gamma index calculation 
 according to http://www.ncbi.nlm.nih.gov/pubmed/9608475
 
 call
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,cst)
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,cst)
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,n,cst)
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,localglobal,cst)
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,cst)
               ...
   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,localglobal,cst)

 input
   cube1:         dose cube as an M x N x O array
   cube2:         dose cube as an M x N x O array
   resolution:    resolution of the cubes [mm/voxel]
   criteria:      [1x2] vector specifying the distance to agreement
                  criterion; first element is percentage difference,
                  second element is distance [mm]
   slice:         (optional) slice in cube1/2 that will be visualized 
   n:             (optional) number of interpolations. there will be 2^n-1 
                  interpolation points. The maximum suggested value is 3.
   localglobal:   (optional) parameter to choose between 'global' and 'local' 
                  normalization 
   cst:           list of interessing volumes inside the patient

 output 

   gammaCube:          result of gamma index calculation
   gammaPassRateCell:  rate of voxels passing the specified gamma criterion 
                  evaluated for every structure listed in 'cst'.
                  note that only voxels exceeding the dose threshold are
                  considered.

 References
   [1]  http://www.ncbi.nlm.nih.gov/pubmed/9608475

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 Copyright 2015 the matRad development team. 
 
 This file is part of the matRad project. It is subject to the license 
 terms in the LICENSE file found in the top-level directory of this 
 distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part 
 of the matRad project, including this file, may be copied, modified, 
 propagated, or distributed except according to the terms contained in the 
 LICENSE file.

 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Cross-reference information ^

This function calls: This function is called by:

Source code ^

0001 function [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,localglobal,cst)
0002 % gamma index calculation
0003 % according to http://www.ncbi.nlm.nih.gov/pubmed/9608475
0004 %
0005 % call
0006 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,cst)
0007 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,cst)
0008 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,n,cst)
0009 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,localglobal,cst)
0010 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,cst)
0011 %               ...
0012 %   [gammaCube,gammaPassRateCell] = matRad_gammaIndex(cube1,cube2,resolution,criteria,slice,n,localglobal,cst)
0013 %
0014 % input
0015 %   cube1:         dose cube as an M x N x O array
0016 %   cube2:         dose cube as an M x N x O array
0017 %   resolution:    resolution of the cubes [mm/voxel]
0018 %   criteria:      [1x2] vector specifying the distance to agreement
0019 %                  criterion; first element is percentage difference,
0020 %                  second element is distance [mm]
0021 %   slice:         (optional) slice in cube1/2 that will be visualized
0022 %   n:             (optional) number of interpolations. there will be 2^n-1
0023 %                  interpolation points. The maximum suggested value is 3.
0024 %   localglobal:   (optional) parameter to choose between 'global' and 'local'
0025 %                  normalization
0026 %   cst:           list of interessing volumes inside the patient
0027 %
0028 % output
0029 %
0030 %   gammaCube:          result of gamma index calculation
0031 %   gammaPassRateCell:  rate of voxels passing the specified gamma criterion
0032 %                  evaluated for every structure listed in 'cst'.
0033 %                  note that only voxels exceeding the dose threshold are
0034 %                  considered.
0035 %
0036 % References
0037 %   [1]  http://www.ncbi.nlm.nih.gov/pubmed/9608475
0038 %
0039 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0040 %
0041 % Copyright 2015 the matRad development team.
0042 %
0043 % This file is part of the matRad project. It is subject to the license
0044 % terms in the LICENSE file found in the top-level directory of this
0045 % distribution and at https://github.com/e0404/matRad/LICENSES.txt. No part
0046 % of the matRad project, including this file, may be copied, modified,
0047 % propagated, or distributed except according to the terms contained in the
0048 % LICENSE file.
0049 %
0050 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0051 
0052 [env, ~] = matRad_getEnvironment();
0053 
0054 % set parameters for gamma index calculation
0055 if exist('criteria','var')
0056     relDoseThreshold = criteria(1); % in [%]
0057     dist2AgreeMm     = criteria(2); % in [mm]
0058 else
0059     dist2AgreeMm     = 3; % in [mm]
0060     relDoseThreshold = 3; % in [%]
0061 end
0062 
0063 % set parameters for gamma index calculation
0064 if ~exist('n','var')
0065     n = 0;
0066 end
0067 
0068 % set global or local gamma evaluation
0069 if ~exist('localglobal','var')
0070     localglobal = 'global';
0071 end
0072 
0073 % check if cubes consistent
0074 if ~isequal(size(cube1),size(cube2))
0075    error('dose cubes must be the same size\n'); 
0076 end
0077 
0078 % define search nighborhood and resolution
0079 if round(n) ~= n
0080     error('n must be an integer value');
0081 else
0082     resolution = resolution./(2.^n);
0083 end
0084 
0085 neighborhood = 1.5* dist2AgreeMm; % [mm]
0086 searchX = ceil(neighborhood./resolution(1));
0087 searchY = ceil(neighborhood./resolution(2));
0088 searchZ = ceil(neighborhood./resolution(3));
0089 
0090 % init cube
0091 % cut all the zeros surrounding the interesting part
0092 cut1 = any(any(cube1,2),3);
0093 cut2 = any(any(cube1,1),3);
0094 cut3 = any(any(cube1,1),2);
0095 
0096 % avoids that "zero-slides" are deleted between two interest regions
0097 k = find(cut1); cut1(k(1):k(end)) = 1;
0098 k = find(cut2); cut2(k(1):k(end)) = 1;
0099 k = find(cut2); cut2(k(1):k(end)) = 1;
0100 
0101 % copy cubes
0102 cubex1c = cube1;
0103 cubex2c = cube2;
0104 
0105 % cut cubes
0106 cubex1c( ~cut1, :, :) = []; % rows
0107 cubex1c( :, ~cut2, :) = []; % columns
0108 cubex1c( :, :, ~cut3) = []; % slices
0109 cubex2c( ~cut1, :, :) = []; % rows
0110 cubex2c( :, ~cut2, :) = []; % columns
0111 cubex2c( :, :, ~cut3) = []; % slices
0112 
0113 % pad cubes
0114 cubex2 = zeros([size(cubex2c,1)+2*searchX size(cubex2c,2)+2*searchY size(cubex2c,3)+2*searchZ]);
0115 cubex2((1+searchX):(end-searchX), ...
0116        (1+searchY):(end-searchY), ...
0117        (1+searchZ):(end-searchZ)) = cubex2c;
0118    
0119 % interpolate if necessary
0120 if n > 0
0121     switch env
0122         case 'MATLAB'
0123             cubex2 = interp3(cubex2,n,'cubic');
0124         case 'OCTAVE'
0125             cubex2 = interp3(cubex2,n,'linear');
0126     end
0127 end
0128 
0129 % set up temporary cubes required for calculation
0130 gammaCubeSq = inf*ones(size(cubex1c));
0131 
0132 % adjust dose threshold
0133 if strcmp(localglobal,'local')
0134     doseThreshold = cubex1c .* relDoseThreshold/100;                
0135 elseif strcmp(localglobal,'global')
0136     doseThreshold = relDoseThreshold/100 * max(cube1(:));
0137 end
0138 
0139 % search for min
0140 for i = -searchX:searchX
0141     for j = -searchY:searchY
0142         for k = -searchZ:searchZ
0143             
0144             delta_sq = ((i*resolution(1))^2 + ...
0145                         (j*resolution(2))^2 + ...
0146                         (k*resolution(3))^2) / dist2AgreeMm^2;                 
0147             
0148             tmpCube = cubex1c - cubex2((1+((2^n)*searchX)+i) : 2^n : (end-((2^n)*searchX)+i), ...
0149                                        (1+((2^n)*searchY)+j) : 2^n : (end-((2^n)*searchY)+j), ...
0150                                        (1+((2^n)*searchZ)+k) : 2^n : (end-((2^n)*searchZ)+k));
0151                     
0152             tmpCube = tmpCube.^2 ./ doseThreshold.^2 + delta_sq;
0153             
0154             gammaCubeSq = min(gammaCubeSq,tmpCube);
0155             
0156             
0157         end
0158     end
0159     
0160 %     display '.';
0161     
0162 end
0163 
0164 % evaluate gamma cube and set to zero all the voxel that contain an
0165 % infinite value
0166 gammaCubeSqx                 = zeros(size(cube1));
0167 gammaCubeSqx(cut1,cut2,cut3) = gammaCubeSq;
0168 gammaCube                    = sqrt(gammaCubeSqx);
0169 
0170 % set values where we did not compute gamma keeping inf in the cube to zero
0171 gammaCube(cube1<=0 & cube2<=0) = 0;
0172   
0173 % compute gamma pass rate
0174 doseIx          = cube1 > relDoseThreshold/100*max(cube1(:)) | cube2 > relDoseThreshold/100*max(cube2(:));
0175 numOfPassGamma  = sum(gammaCube(doseIx) < 1);
0176 gammaPassRate   = 100 * numOfPassGamma / sum(doseIx(:));
0177 
0178 % compute stats for all segmented sturtures
0179 if exist('cst','var')
0180     gammaPassRateCell = cell(1,2);
0181     gammaPassRateCell{1,1} = 'Whole CT';
0182     gammaPassRateCell{1,2} = gammaPassRate;
0183 
0184     for i = 1:size(cst, 1)
0185         volume = cst{i,4}{1,1}; % indices of voxels of the interesting volume
0186         doseIxVol = false(size(doseIx)); 
0187         doseIxVol(volume) = doseIx(volume); 
0188         numOfPassGammaVol  = sum(gammaCube(doseIxVol) < 1);
0189         gammaPassRateVol   = 100 * numOfPassGammaVol / sum(doseIxVol(:));
0190         if isnan(gammaPassRateVol) % remove organs not receiving any dose (resulting in NaN)
0191             continue;
0192         end
0193         gammaPassRateCell{end+1, 1} = cst{i,2};
0194         gammaPassRateCell{end, 2} = gammaPassRateVol;
0195 
0196     end
0197 end
0198 
0199 % visualize if applicable
0200 if exist('slice','var') && ~isempty(slice)
0201     figure
0202     set(gcf,'Color',[1 1 1]);
0203     imagesc(gammaCube(:,:,slice),[0 2])
0204     myColormap = matRad_getColormap('gammaIndex');
0205 
0206     colormap(gca,myColormap);
0207     colorbar
0208 
0209     title({[num2str(gammaPassRate,5) '% of points > ' num2str(relDoseThreshold) ...
0210             '% pass gamma criterion (' num2str(relDoseThreshold) '% / ' ...
0211             num2str(dist2AgreeMm) 'mm)']; ['with ' num2str(2^n-1) ' interpolation points']});
0212 end

| Generated by m2html © 2005