diff --git a/func/utils/FitFieldsGetSusceptibilityMaps.m b/func/utils/FitFieldsGetSusceptibilityMaps.m deleted file mode 100644 index b02bdaf..0000000 --- a/func/utils/FitFieldsGetSusceptibilityMaps.m +++ /dev/null @@ -1,158 +0,0 @@ -function [FittedSuscep, FittedField]=FitFieldsGetSusceptibilityMaps(Field,SegmentationModel,ExtraModulation, B0dir,voxel_size,shimm,varargin) -% [FittedSuscep, FittedField]=FitFieldsGetSuisceptibilityMaps(Field,SegmentationModel,ExtraModulation, B0dir,voxel_size,shimm) -% FieldSegmentationModel -% ExtraModulation can be left empty or be a 4D volume with R1, R2*, T1w, MT and blabla -% B0dir of this model -% voxel_size -% shim, can be 0 or 1 meaning that other than the field it fits a second -% order polynominal -% if nargin = 7 structure with tissue with stepwise smooth assumptions (modulation is not used ) -% and no stepwosesmooth assumption (Only the modulation models are used there) -% TissueModelsNoStepWiseSmooth= varargin{1}.ModulationOnly; -% TissueModelsWithStepWiseSmooth= varargin{1}.StepWiseSmooth; - -if isempty(ExtraModulation) - models=SegmentationModel; -else - models=SegmentationModel; - for k=1:size(ExtraModulation,4) - models=cat(4, models, bsxfun(@times,SegmentationModel,ExtraModulation(:,:,:,k))); - end; -end; - - -%% - -if nargin == 7 - NModulations = size(ExtraModulation,4); - NTissues = size(SegmentationModel,4); - SusceptibilitySources=size(models,4); - - if isfield(varargin{1},'ModulationOnly') - TissueModelsNotStepWiseSmooth= varargin{1}.ModulationOnly; - else - TissueModelsNotStepWiseSmooth= [] - end; - - if isfield(varargin{1},'StepWiseSmooth') - temp= varargin{1}.StepWiseSmooth; - TissueModelsStepWiseSmooth=[]; - for k=1:NModulations - TissueModelsStepWiseSmooth = cat(2,TissueModelsStepWiseSmooth, NTissues+temp); - end - else - TissueModelsStepWiseSmooth= [] - end; - SusceptibilitySources=size(models,4); - Models2keep = setdiff(1:SusceptibilitySources,TissueModelsNotStepWiseSmooth); - - Models2keep = setdiff(Models2keep,TissueModelsStepWiseSmooth); - - models=models(:,:,:,Models2keep); - -else - - - -end; - -SusceptibilitySources=size(models,4); - -N=size(Field); - - -mask=Field~=0; -Indices=find(mask); - - - -%% -D = create_dipole_kernel(B0dir, voxel_size,N, 1); - -modelfields=models; -clear modelfieldvector -for k=1:size(models,4) - temp=ifftn(fftn(modelfields(:,:,:,k)).*D); - modelfields(:,:,:,k)=temp; - modelfieldvector(:,k)=temp(Indices); -end -if shimm==0 - modelfields(:,:,:,end+1)=1; - modelfieldvector(:,end+1)=1; -else - - [x1,y1,z1]=ndgrid((1:N(1))-(N(1)+1)/2,(1:N(2))-(N(2)+1)/2,(1:N(3))-(N(3)+1)/2); - - modelfields(:,:,:,end+1)=1; - modelfieldvector(:,end+1)=1; - modelfields(:,:,:,end+1)=x1; - modelfieldvector(:,end+1)=x1(Indices); - modelfields(:,:,:,end+1)=y1; - modelfieldvector(:,end+1)=y1(Indices); - modelfields(:,:,:,end+1)=z1; - modelfieldvector(:,end+1)=z1(Indices); - modelfields(:,:,:,end+1)=x1.^2; - modelfieldvector(:,end+1)=x1(Indices).^2; - modelfields(:,:,:,end+1)=y1.^2; - modelfieldvector(:,end+1)=y1(Indices).^2; - modelfields(:,:,:,end+1)=z1.^2; - modelfieldvector(:,end+1)=z1(Indices).^2; - modelfields(:,:,:,end+1)=x1.*y1; - modelfieldvector(:,end+1)=x1(Indices).*y1(Indices); - modelfields(:,:,:,end+1)=y1.*z1; - modelfieldvector(:,end+1)=y1(Indices).*z1(Indices); - modelfields(:,:,:,end+1)=z1.*x1; - modelfieldvector(:,end+1)=z1(Indices).*x1(Indices); - - -end; - -% try -% MultFact=Field(Indices)'*pinv(modelfieldvector'); -% catch - -% if nargin<7 -MultFact=lsqr(modelfieldvector,Field(Indices),1e-6,1000); -% else -% in this case we put an weighting factor on the fit -% MultFact=lsqr(modelfieldvector,varargin{1}.*Field(Indices),1e-4,100); -% -% % end - -FittedField=real(sum(bsxfun(@times,reshape(MultFact,[1 1 1 length(MultFact)]),modelfields),4)); -FittedSuscep=real(sum(bsxfun(@times,reshape(MultFact(1:(SusceptibilitySources+1)),[1 1 1 SusceptibilitySources+1]),cat(4,models,ones(N))),4)); -% fv(real(FittedSuscep)) -% fv(real(FittedField)) - -ShowResults=1; -if ShowResults==1 - dims=size(Field) - pos=round(dims/2)+[+8 5 -9]; - figure() -% subplot(321) - subplot1(3,2,'Gap',[0.02 0.02]) - subplot1(1) - Orthoview(FittedSuscep,pos) - title('Susceptibility map ') -% subplot(322) - subplot1(2) - - % Orthoview(-FittedSuscep,pos,[ 50 600]) -temp=FittedSuscep(Field~=0)-mean(FittedSuscep((Field~=0))); - Orthoview(FittedSuscep-mean(FittedSuscep((Field~=0))),pos, prctile(temp(:),[4 96])); - title('Susceptibility map zoomed') -% subplot(323) - subplot1(3) - - Orthoview(Field,pos,[-200 40]); - title('Data to fit') - subplot1(4) -% subplot(324) - Orthoview(FittedField.*single(Field~=0),pos,[-200 40]); - title('fitted field') -% subplot(325) - subplot1(5) - Orthoview(Field-FittedField.*single(Field~=0),pos,[-200 40]); - title('residuals of fit') -end; - diff --git a/func/utils/Fitwith.m b/func/utils/Fitwith.m deleted file mode 100644 index 82b6641..0000000 --- a/func/utils/Fitwith.m +++ /dev/null @@ -1,57 +0,0 @@ -function [FIT3D, b,Residuals]=Fitwith(Volume,Mask,varargin) -% function [FIT3D, b,Residuals]=Fitwith(Volumenii,Mask,varargin) - -dim=size(Volume); -size(varargin); -Indices=find(Mask(:,:,:)); -[x1,y1,z1]=ind2sub(size(Volume(:,:,:)),Indices); -R=Volume(Indices); - - -model(1:length(Indices),1)=1; -for k=1:length(varargin) - model(1:length(Indices),k+1)=varargin{k}(Indices); -end; - -% b=model\R; - b=pinv(model)*R; - -% Fit=model*b; -% clear model -% FIT3D=Volumenii; -% FIT3D.img=zeros(size(Volumenii.img(:,:,:))); -% for pos=1:length(x1) -% FIT3D.img(x1(pos),y1(pos),z1(pos))=Fit(pos); -% end; -% clear Fit -% FIT3D.img(isnan(FIT3D.img))=0; -% Residuals=FIT3D; -% Residuals.img=(Volumenii.img-FIT3D.img).*Mask.img; -% -% - - - - - - -model(1:(prod(size(Mask))),1)=1; -for k=1:length(varargin) - model(1:(prod(size(Mask))),k+1)=varargin{k}(:); -end; - -Fit=model*b; -clear model -FIT3D=Volume; -% FIT3D.img=zeros(size(Volumenii.img(:,:,:))); - FIT3D=reshape(Fit,size(Mask)); -clear Fit -FIT3D(isnan(FIT3D))=0; -Residuals=FIT3D; -Residuals=(Volume-FIT3D).*Mask; - - - - -Residuals=(Volume-FIT3D); - diff --git a/func/utils/Orthoview.m b/func/utils/Orthoview.m deleted file mode 100644 index 565ed78..0000000 --- a/func/utils/Orthoview.m +++ /dev/null @@ -1,96 +0,0 @@ - -function [ output mosaic ] = Orthoview( volume ,varargin) -%[ output_args ] = Orthoview( volume ,varargin) -% varargin{1} is the position of the slices -% varargin{2} is the range of the colorbar -% varargin{3} is the type of image 'normal','mip',proj - - -dims=size(volume); -if nargin>=2 - if isempty(varargin{1}) - xyz=round(dims/2); - else - xyz=varargin{1}; - end; - -else - xyz=round(dims/2); -end -if nargin>=4 - if isempty(varargin{3}) - showim='normal'; - else - showim=varargin{3}; - end; - -else - showim='normal'; -end - -if nargin>=3 - if isempty(varargin{2}) - if strcmp(showim,'normal') - scale=[prctile(volume(:),2) prctile(volume(:),98)]; - end; - if or(strcmp(showim,'mip'),strcmp(showim,'MIP')) - - scale=[0 max(volume(:))]; - end; - if or(strcmp(showim,'proj'),strcmp(showim,'PROJ')) - temp1=abs(sum(volume,1)); - temp2=abs(sum(volume,2)); - temp3=abs(sum(volume,3)); - maxi=max([max(temp1(:)), max(temp2(:)),max(temp3(:))]); - scale=[0 maxi]; - end; - else - - scale=varargin{2}; - end; -else - - scale=[prctile(volume(:),2) prctile(volume(:),98)]; -end - -% simulation=0; -mosaic=zeros([max(dims(2:3)) 2*dims(1)+dims(2)]); -temp1=zeros([size(mosaic,1),dims(2)]); -temp2=zeros([size(mosaic,1),dims(1)]); -temp3=zeros([size(mosaic,1),dims(1)]); -if strcmp(showim,'normal') - temp1a=permute(volume(xyz(1),:,:),[3,2,1]); - temp2a=permute(volume(:,xyz(2),:),[3,1,2]); - temp3a=permute(volume(:,:,xyz(3)),[2,1,3]); -else - if or(strcmp(showim,'mip'),strcmp(showim,'MIP')) - temp1a=max(permute(volume(:,:,:),[3,2,1]),[],3); - temp2a=max(permute(volume(:,:,:),[3,1,2]),[],3); - temp3a=max(permute(volume(:,:,:),[2,1,3]),[],3); - end; - if or(strcmp(showim,'proj'),strcmp(showim,'PROJ')) - temp1a=abs(sum(permute(volume(:,:,:),[3,2,1]),3)); - temp2a=abs(sum(permute(volume(:,:,:),[3,1,2]),3)); - temp3a=abs(sum(permute(volume(:,:,:),[2,1,3]),3)); - end; - -end; - - -% temp1a=permute(volume(xyz(1),:,:),[2,3,1]); -% temp2a=permute(volume(:,xyz(2),:),[3,1,2]); -% temp3a=permute(volume(:,:,xyz(3)),[1,2,3]); - -% keyboard -temp1(round((size(temp1,1)-size(temp1a,1))/2)+(1:size(temp1a,1)),:)=temp1a; -temp2(round((size(temp2,1)-size(temp2a,1))/2)+(1:size(temp2a,1)),:)=temp2a; -temp3(round((size(temp3,1)-size(temp3a,1))/2)+(1:size(temp3a,1)),:)=temp3a; -mosaic=cat(2,temp1,temp2,temp3); -% subplot(111) -imagesc(flipdim(mosaic,1),scale); -axis equal tight off -colormap(gray) -output=1; - -end - diff --git a/func/utils/PolyFitShimLike.m b/func/utils/PolyFitShimLike.m deleted file mode 100644 index 379d822..0000000 --- a/func/utils/PolyFitShimLike.m +++ /dev/null @@ -1,111 +0,0 @@ -function [FIT3D,Residuals,b]=PolyFitShimLike(Volumenii,Mask,order); - -dim=Volumenii.hdr.dime.dim(2:4); - - - -%% for volume fitting - - -Indices=find(Mask.img(:,:,:)); -[x1,y1,z1]=ind2sub(size(Volumenii.img(:,:,:)),Indices); -R=Volumenii.img(Indices); -% keyboard -if length(Indices)>(3*order)^2 - - model=Create_model(x1,y1,z1,dim,order); -% keyboard - % b=model\R; - b=pinv(model)*R; -% temp=R-model*b; - clear model - clear R -% [FIT3D,Residuals,b1,model1]=PolyFitNifti(Volumenii,Mask,order); -% Residuals=Volumenii; -% Residuals.img=Residuals.img*0; -% Residuals.img(Indices)=temp; -% subplot(121);Orthoview (Residuals.img) -% subplot(122);Orthoview (Volumenii.img.*Mask.img) - Indices = find(ones(dim)); - [x1,y1,z1]=ind2sub(size(Volumenii.img(:,:,:)),Indices); - model=Create_model(x1,y1,z1,dim,order); -% for k=1:10,subplot(5,2,k),plot(model(:,k)),end - Fit=model*b; - clear model - FIT3D=Volumenii; - FIT3D.img=reshape(Fit,dim); - Residuals=FIT3D; - Residuals.img=(Volumenii.img-FIT3D.img); -else - FIT3D=Volumenii; - FIT3D.img=zeros(size(Volumenii.img(:,:,:))); - Residuals=FIT3D; - Residuals.img=(Volumenii.img-FIT3D.img).*Mask.img; -end; - -% % figure -% % keyboard -% % -% % imagesc(FIT3D());colorbar -function model = Create_model(x1,y1,z1,dim,order); -Nsize=[1 4 10 20 35]; -N=Nsize(order+1); -model=double(zeros(length(x1),N)); -%zeroth order -if order>=0 - model(1:length(x1),1)=1; -end -%first order -if order>=1 - model(:,2)=reshape(x1-dim(1)/2,length(x1),1);%x -siemens - model(:,3)=reshape(y1-dim(2)/2,length(x1),1);%y -siemens - model(:,4)=reshape(z1-dim(3)/2,length(x1),1);%z -siemens -end -%second order -if order>=2 - -% model(:,5) =model(:,2).*model(:,2);%x^2y^0z^0 -% model(:,6) =model(:,2).*model(:,3);%x^1y^1z^0 -siemens xy -% model(:,7) =model(:,3).*model(:,3);%x^0y^2z^0 -% model(:,8) =model(:,3).*model(:,4);%x^0y^1z^1 -siemens yz -% model(:,9) =model(:,4).*model(:,4);%x^0y^0z^2 -siemens -% model(:,10)=model(:,4).*model(:,2);%x^1y^0z^1 -siemens xz - model(:,5) = model(:,2).*model(:,2) ... - - model(:,3).*model(:,3);% siemens x^2-y^2 - model(:,6) = model(:,2).*model(:,3);%x^1y^1z^0 -siemens xy - model(:,7) = 2 * model(:,4).*model(:,4) ... - - model(:,3).*model(:,3)... - - model(:,2).*model(:,2); % 2 z^2 - x^2 - y^2 - model(:,8) =model(:,3).*model(:,4);%x^0y^1z^1 -siemens yz - model(:,9)=model(:,4).*model(:,2);%x^1y^0z^1 -siemens xz -end -%%third order -%if order>=3 -% model(:,11) =model(:,5).*model(:,2); %x^3y^0z^0 -% model(:,14) =model(:,7).*model(:,3); %x^0y^3z^0 -% model(:,18) =model(:,9).*model(:,4); %x^0y^0z^3 -% model(:,15) =model(:,8).*model(:,2); %x^1y^1z^1 -% model(:,12) =model(:,6).*model(:,2); %x^2y^1z^0 -% model(:,13) =model(:,7).*model(:,2); %x^1y^2z^0 -% model(:,16) =model(:,9).*model(:,2); %x^1y^0z^2 -% model(:,17) =model(:,10).*model(:,2);%x^2y^0z^1 -% model(:,19) =model(:,9).*model(:,3); %x^0y^1z^2 -% model(:,20) =model(:,8).*model(:,3); %x^0y^2z^1 -%end -%if order>=4 -% model(:,21) =model(:,11).*model(:,2); %x^4y^0z^0 -% model(:,22) =model(:,14).*model(:,3); %x^0y^4z^0 -% model(:,23) =model(:,18).*model(:,4); %x^0y^0z^4 -% model(:,24) =model(:,11).*model(:,3); %x^3y^1z^0 -% model(:,25) =model(:,11).*model(:,4); %x^3y^0z^1 -% model(:,26) =model(:,5).*model(:,7); %x^2y^2z^0 -% model(:,27) =model(:,5).*model(:,9); %x^2y^0z^2 -% model(:,28) =model(:,17).*model(:,3);%x^2y^1z^1 -% model(:,29) =model(:,14).*model(:,4); %x^0y^3z^1 -% model(:,30) =model(:,14).*model(:,2); %x^1y^3z^0 -% model(:,31) =model(:,13).*model(:,4); %x^1y^2z^1 -% model(:,32) =model(:,20).*model(:,4); %x^0y^2z^2 -% model(:,33) =model(:,18).*model(:,3); %x^0y^1z^3 -% model(:,34) =model(:,18).*model(:,2); %x^1y^0z^3 -% model(:,35) =model(:,15).*model(:,4); %x^1y^1z^2 -%end diff --git a/func/utils/WaveletDenoising/Wavedec3Denoising.m b/func/utils/WaveletDenoising/Wavedec3Denoising.m deleted file mode 100644 index 6b7f139..0000000 --- a/func/utils/WaveletDenoising/Wavedec3Denoising.m +++ /dev/null @@ -1,105 +0,0 @@ -function outmat=Wavedec3Denoising(inmat,threshold,L,h,method,varargin); -% function outmat=Wavedec3Denoising(inmat,threshold,L,h,method,varargin); -% varargin{1} is a mask -% varargin{2} is noise weighting term - - -if nargin>6 - if ~isempty(varargin{2}) - [y_r] = wavedec3(inmat.*varargin{2},L,h); - else - [y_r] = wavedec3(inmat,L,h); - - end -else - [y_r] = wavedec3(inmat,L,h); - -end - - -if nargin>5 - if ~isempty(varargin{1}) - mask1=varargin{1}; - [y_mask] = wavedec3(mask1,L,h); - [y_all] = wavedec3(ones(size(mask1)),L,h); - - for k=1:length(y_mask.dec) - w_mask.dec{k}=0*y_all.dec{k}; - w_mask.dec{k}(abs(y_all.dec{k})>1.1*abs(y_mask.dec{k}))=0; - w_mask.dec{k}(abs(y_all.dec{k})<=1.1*abs(y_mask.dec{k}))=1; - w_mask.dec{k}(abs(y_mask.dec{k})<0.01)=1; - w_mask.dec{k}=reshape(w_mask.dec{k},size(y_mask.dec{k})); - end; - else - for k=1:length(y_r.dec) - w_mask.dec{k}=ones(size(y_r.dec{k})); - end; - end; -else - for k=1:length(y_r.dec) - w_mask.dec{k}=ones(size(y_r.dec{k})); - end; - % indexes_mask=1:prod(size(inmat)); - -end -% keyboard -% size(w_mask.dec{1}); -for k=1:length(y_r.dec) -% size(w_mask.dec{k}); - indexes_dn2.dec{k}=find(and(abs(y_r.dec{k})<3*threshold,w_mask.dec{k})); - indexes_dn.dec{k} =find(and(abs(y_r.dec{k})< threshold,w_mask.dec{k})); - indexes.dec{k}=find(~and(abs(y_r.dec{k})=threshold)); - -if strcmp(method,'hard') - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - end; - - -elseif strcmp(method,'soft') - - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - % regions that were not truncatedget the phase they had - % before but a constant amplitude (threshold) subtracted from it - y_r.dec{k}(indexes.dec{k})=y_r.dec{k}(indexes.dec{k})-exp(1i*angle(y_r.dec{k}(indexes.dec{k})))*threshold; - end; - - - - -elseif strcmp(method,'verysoft') - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - y_r.dec{k}(indexes.dec{k})=max(abs(y_r.dec{k}(:)))/(max(abs(y_r.dec{k}(:)))-threshold).*(y_r.dec{k}(indexes.dec{k})-exp(1i*angle(y_r.dec{k}(indexes.dec{k})))*threshold); - end; - - -elseif strcmp(method,'verysoft2') - % it only applies the very soft threshold from threshold to 3*threshold - % and the rest of the values remain unchanged - for k=1:length(y_r.dec) - maximum=3*threshold; - y_r.dec{k}(indexes_dn2.dec{k})=maximum/(maximum-threshold).*(y_r.dec{k}(indexes_dn2.dec{k})-exp(1i*angle(y_r.dec{k}(indexes_dn2.dec{k})))*threshold); - y_r.dec{k}(indexes_dn.dec{k})=0; - end; - - - -end; - -[outmat] = (waverec3(y_r)); -if nargin>6 - if ~isempty(varargin{2}) - outmat= outmat./varargin{2}; - end -end - diff --git a/func/utils/WaveletDenoising/WaveletDenoising2D.m b/func/utils/WaveletDenoising/WaveletDenoising2D.m deleted file mode 100644 index f4d0587..0000000 --- a/func/utils/WaveletDenoising/WaveletDenoising2D.m +++ /dev/null @@ -1,73 +0,0 @@ -function outmat=WaveletDenoising2D(inmat,threshold,L,h,method,varargin); - - - [y_r,L2D] = wavedec2(inmat,L,h); -% [y_r,L2D] = wavedec2(real(inmat),L,h); -% [y_i,L2D] = wavedec2(imag(inmat),L,h); -% y_r=y_r+1i*y_i; - - -if nargin>5 - if ~isempty(varargin{1}) - mask1=varargin{1}; - [y_mask,L2D] = wavedec2(mask1,L,h); - [y_all,L2D] = wavedec2(ones(size(mask1)),L,h); -% clear y_r3 -% subplot(121) -% hold off -% plot(y_r) -% hold on -% plot(y_r2) -% plot(y_r2,'r') - w_mask(abs(y_all)>1.1*abs(y_mask))=0; - w_mask(abs(y_all)<=1.1*abs(y_mask))=1; - w_mask(abs(y_mask)<0.01)=1; -% plot(w_mask,'g') -% [outmat] = waverec2(w_mask,L2D,h); -% subplot(122) -% imagesc(abs(outmat)) - -% indexes_mask=find(abs(y_r)=threshold)); - - -if strcmp(method,'hard') - - y_r(indexes_dn)=0; - - -elseif strcmp(method,'soft') - - - y_r(indexes_dn)=0; - y_r(indexes)=y_r(indexes)-exp(1i*angle(y_r(indexes)))*threshold; - - - - -elseif strcmp(method,'verysoft') - - y_r(indexes_dn)=0; - y_r(indexes)=max(abs(y_r(:)))/(max(abs(y_r(:)))-threshold).*(y_r(indexes)-exp(1i*angle(y_r(indexes)))*threshold); - - - -end; - - [outmat] = conj(waverec2(y_r,L2D,h)); -% [outmat] = (waverec2(real(y_r),L2D,h))+1i*(waverec2(imag(y_r),L2D,h)); diff --git a/func/utils/WaveletDenoising/WaveletDenoising3D.m b/func/utils/WaveletDenoising/WaveletDenoising3D.m deleted file mode 100644 index 48a2fae..0000000 --- a/func/utils/WaveletDenoising/WaveletDenoising3D.m +++ /dev/null @@ -1,72 +0,0 @@ -function outmat=WaveletDenoising3D(inmat,threshold,L,h,method,varargin); - - [y_r,L3D] = mdwt_complex_3D(inmat,h,L); -% [y_r] = wavedec3(inmat,L,h); - - -if nargin>5 - if ~isempty(varargin{1}) - mask1=varargin{1}; - [y_mask,L2D] = mdwt_complex_3D(mask1,h,L); - [y_all,L2D] = mdwt_complex_3D(ones(size(mask1)),h,L); -% [y_mask,L3D] = wavedec3(mask1,L,h); -% [y_all,L3D] = wavedec3(ones(size(mask1)),L,h); -% clear y_r3 -% subplot(121) -% hold off -% plot(y_r) -% hold on -% plot(y_r2) -% plot(y_r2,'r') - w_mask(abs(y_all)>1.1*abs(y_mask))=0; - w_mask(abs(y_all)<=1.1*abs(y_mask))=1; - w_mask(abs(y_mask)<0.01)=1; - w_mask=reshape(w_mask,size(y_r)); -% plot(w_mask,'g') -% [outmat] = waverec2(w_mask,L2D,h); -% subplot(122) -% imagesc(abs(outmat)) - -% indexes_mask=find(abs(y_r)=threshold)); - -if strcmp(method,'hard') - - y_r(indexes_dn)=0; - - -elseif strcmp(method,'soft') - - - y_r(indexes_dn)=0; - y_r(indexes)=y_r(indexes)-exp(1i*angle(y_r(indexes)))*threshold; - - - - -elseif strcmp(method,'verysoft') - - y_r(indexes_dn)=0; - y_r(indexes)=max(abs(y_r(:)))/(max(abs(y_r(:)))-threshold).*(y_r(indexes)-exp(1i*angle(y_r(indexes)))*threshold); - - - -end; - -% [outmat] = conj(waverec3(y_r,L3D,h)); - [outmat] = conj(midwt_complex_3D(y_r,h,L3D)); diff --git a/func/utils/WaveletDenoising/gradient_3D_waveletDN b/func/utils/WaveletDenoising/gradient_3D_waveletDN deleted file mode 100644 index c39973a..0000000 --- a/func/utils/WaveletDenoising/gradient_3D_waveletDN +++ /dev/null @@ -1,73 +0,0 @@ -function [dx, dy, dz] = gradient_3D_waveDN -function outmat=Wavedec3Denoising(inmat,threshold,L,h,method,varargin); - -[y_r] = wavedec3(inmat,L,h); - - -if nargin>5 - if ~isempty(varargin{1}) - mask1=varargin{1}; - [y_mask] = wavedec3(mask1,L,h); - [y_all] = wavedec3(ones(size(mask1)),L,h); - - for k=1:length(y_r.dec) - w_mask.dec{k}=0*y_all.dec{k}; - w_mask.dec{k}(abs(y_all.dec{k})>1.1*abs(y_mask.dec{k}))=0; - w_mask.dec{k}(abs(y_all.dec{k})<=1.1*abs(y_mask.dec{k}))=1; - w_mask.dec{k}(abs(y_mask.dec{k})<0.01)=1; - w_mask.dec{k}=reshape(w_mask.dec{k},size(y_r.dec{k})); - end; - else - for k=1:length(y_r.dec) - w_mask.dec{k}=ones(size(y_r.dec{k})); - end; - end; -else - for k=1:length(y_r.dec) - w_mask.dec{k}=ones(size(y_r.dec{k})); - end; - % indexes_mask=1:prod(size(inmat)); - -end -% keyboard -% size(w_mask.dec{1}); -for k=1:length(y_r.dec) -% size(w_mask.dec{k}); - indexes_dn.dec{k}=find(and(abs(y_r.dec{k})=threshold)); - -if strcmp(method,'hard') - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - end; - - -elseif strcmp(method,'soft') - - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - y_r.dec{k}(indexes.dec{k})=y_r.dec{k}(indexes.dec{k})-exp(1i*angle(y_r.dec{k}(indexes.dec{k})))*threshold; - end; - - - - -elseif strcmp(method,'verysoft') - - for k=1:length(y_r.dec) - y_r.dec{k}(indexes_dn.dec{k})=0; - y_r.dec{k}(indexes.dec{k})=max(abs(y_r.dec{k}(:)))/(max(abs(y_r.dec{k}(:)))-threshold).*(y_r.dec{k}(indexes.dec{k})-exp(1i*angle(y_r.dec{k}(indexes.dec{k})))*threshold); - end; - - - -end; - -[outmat] = (waverec3(y_r)); diff --git a/func/utils/WaveletDenoising/gradient_3D_waveletDN.m b/func/utils/WaveletDenoising/gradient_3D_waveletDN.m deleted file mode 100644 index 29528da..0000000 --- a/func/utils/WaveletDenoising/gradient_3D_waveletDN.m +++ /dev/null @@ -1,59 +0,0 @@ -function [dx, dy, dz] = gradient_3D_waveletDN(I,varargin) -%[dx, dy, dz] = gradient_3D_waveletDN(I,varargin) -%[dx, dy, dz] = gradient_3D_waveletDN(I,res,method,noiselevel,L,wname,) -% varargin{1} is the resolution -% varargin{2} corresponds to the gradientmethod, the default is 0 which corresponds -% to the mid gradient definition -% varargin{3} is the noise level -% varargin{4} is number of decomposition levels -% varargin{5} is the wavelet name -% varargin{6} is the mask - - -if nargin==1 - res=[1,1,1]; -else - if isempty(varargin{1}) - res=[1,1,1]; -else - res=varargin{1}; - end; -end - -if nargin>=3 - gradientmethod = varargin{2}; -else - gradientmethod = 0; -end; - -if nargin>=4 - threshold = varargin{3}; -else - threshold = 1; -end; - -if nargin>=5 - L= varargin{4}; -else - L = 4; -end; -if nargin>=6 - h= varargin{5}; -else - h = 'sym4'; - h = 'bior6.8'; -end; -if nargin>=7 - mask= varargin{6}; -else - mask=[]; -end; - -outmat=Wavedec3Denoising(I,threshold,L,h,mask); -[dx, dy, dz] = gradient_3D(outmat,res,method); - -dthreshold=threshold*(1./res)*sqrt(2); -dx=Wavedec3Denoising(dx,dthreshold,L,h,mask); -dy=Wavedec3Denoising(dy,dthreshold,L,h,mask); -dz=Wavedec3Denoising(dz,dthreshold,L,h,mask); - UNFINISHED UNTESTED CODE \ No newline at end of file diff --git a/func/utils/centerofmass.m b/func/utils/centerofmass.m deleted file mode 100644 index cfa081d..0000000 --- a/func/utils/centerofmass.m +++ /dev/null @@ -1,14 +0,0 @@ -function [coord , width]=centerofmass(data); - -data=abs(data); -dims=size(data); - -for k=1:length(dims) - % datatemp=permute(data,[k ]); - dimsvect=ones([1, length(dims)]); - dimsvect(k)=dims(k); - temp=bsxfun(@times,(data),reshape(1:dims(k),dimsvect)); - coord(k)=sum(temp(:))./sum(data(:)); - temp=bsxfun(@times,(data),(reshape(1:dims(k),dimsvect)-coord(k)).^2); - width(k)=sqrt(sum(temp(:))./sum(data(:))); -end; diff --git a/func/utils/compute_rmse.m b/func/utils/compute_rmse.m deleted file mode 100644 index 18ce35a..0000000 --- a/func/utils/compute_rmse.m +++ /dev/null @@ -1,8 +0,0 @@ -function [ rmse ] = compute_rmse( chi_recon, chi_true ) - - -rmse = 100 * norm( chi_recon(:) - chi_true(:) ) / norm(chi_true(:)); - - -end - diff --git a/func/utils/create_dipole_kernel.m b/func/utils/create_dipole_kernel.m deleted file mode 100644 index f5666b1..0000000 --- a/func/utils/create_dipole_kernel.m +++ /dev/null @@ -1,32 +0,0 @@ -function D = create_dipole_kernel(B0_dir, voxel_size, N, createInKspace) - -if createInKspace - disp('Dipole kernel created directly in k-space - it does support rotations') - [ky,kx,kz] = meshgrid(-N(2)/2:N(2)/2-1, -N(1)/2:N(1)/2-1, -N(3)/2:N(3)/2-1); - - kx = (kx / max(abs(kx(:)))) / (2*voxel_size(1)); - ky = (ky / max(abs(ky(:)))) / (2*voxel_size(2)); - kz = (kz / max(abs(kz(:)))) / (2*voxel_size(3)); - - k2 = kx.^2 + ky.^2 + kz.^2; - -% R_tot = eye(3); -% R_tot (3,1:3)=B0_dir; - D = fftshift( 1/3 - (kx * B0_dir(1) + ky * B0_dir(2) + kz * B0_dir(3)).^2 ./ (k2 + eps) ); -else - disp('Dipole kernel created in the object domain') - % dipole kernel: (3*cos(theta)^2 - 1) / (4*pi*r^3) - - [Y,X,Z] = meshgrid(-N(2)/2:(N(2)/2-1),... - -N(1)/2:(N(1)/2-1),... - -N(3)/2:(N(3)/2-1)); - - X = X * voxel_size(1); - Y = Y * voxel_size(2); - Z = Z * voxel_size(3); - - d = prod(voxel_size) * ( 3 * (X*B0_dir(1) + Y*B0_dir(2) + Z*B0_dir(3)).^2 - X.^2 - Y.^2 - Z.^2 ) ./ (4 * pi * (X.^2 + Y.^2 + Z.^2).^2.5); - - d(isnan(d)) = 0; - D = fftn(fftshift(d)); -end \ No newline at end of file diff --git a/func/utils/crop.m b/func/utils/crop.m deleted file mode 100644 index 3505462..0000000 --- a/func/utils/crop.m +++ /dev/null @@ -1,66 +0,0 @@ -function res = crop(x,sx,sy,sz,st) -% res = crop(x,sx,sy) -% crops a 2D matrix around its center. -% -% -% res = crop(x,sx,sy,sz,st) -% crops a 4D matrix around its center -% -% -% res = crop(x,[sx,sy,sz,st]) -% same as the previous example -% -% -% -% -% (c) Michael Lustig 2007 - -if nargin < 2 - error('must have a target size') -end - -if nargin == 2 - s = sx; -end - -if nargin == 3 - s = [sx,sy]; -end - -if nargin == 4 - s = [sx,sy,sz]; -end - -if nargin == 5 - s = [sx,sy,sz,st]; -end - - m = size(x); - if length(s) < length(m) - s = [s, ones(1,length(m)-length(s))]; - end - - if sum(m==s)==length(m) - res = x; - return; - end - - - for n=1:length(s) - idx{n} = floor(m(n)/2)+1+ceil(-s(n)/2) : floor(m(n)/2)+ceil(s(n)/2); - floor(m(n)/2)+1+ceil(-s(n)/2) - floor(m(n)/2)+ceil(s(n)/2) - end - - % this is a dirty ugly trick - cmd = 'res = x(idx{1}'; - for n=2:length(s) - cmd = sprintf('%s,idx{%d}',cmd,n); - end - cmd = sprintf('%s);',cmd); - eval(cmd); - - - - - diff --git a/func/utils/fft3s.m b/func/utils/fft3s.m deleted file mode 100644 index b330264..0000000 --- a/func/utils/fft3s.m +++ /dev/null @@ -1,6 +0,0 @@ -function out = fft3s(data) -% function out = fft3s(data) -% -% Do 3D FFT on each slice of data and fftshift - -out = fftshift(fftshift(fftshift(fft(fft(fft(ifftshift(ifftshift(ifftshift(data,1),2),3),[],1),[],2),[],3),1),2),3); diff --git a/func/utils/figureJ.m b/func/utils/figureJ.m deleted file mode 100644 index 89ae1cb..0000000 --- a/func/utils/figureJ.m +++ /dev/null @@ -1,9 +0,0 @@ -function figureJ(varargin); -if nargin==0 - gcf=figure; -else -gcf=figure(varargin{1}); -end; -set(gcf,'Color',[1 1 1]); - - diff --git a/func/utils/fontScale.m b/func/utils/fontScale.m deleted file mode 100644 index 058f12e..0000000 --- a/func/utils/fontScale.m +++ /dev/null @@ -1,18 +0,0 @@ -function fontScale(scale) -% function fontScale(scale) - -H = gcf; -allText = findall(H, 'type', 'text'); -allAxes = findall(H, 'type', 'axes'); -allFont = [allText; allAxes]; -fontSize = get(allFont,'FontSize'); - -newFontSize = LocalScale(fontSize, scale, 2); -set(allFont,{'FontSize'},newFontSize); - -function newArray = LocalScale(inArray, scale, minValue) -n = length(inArray); -newArray = cell(n,1); -for k=1:n - newArray{k} = max(minValue,scale*inArray{k}(1)); -end \ No newline at end of file diff --git a/func/utils/gradient_3D.m b/func/utils/gradient_3D.m deleted file mode 100644 index 245227d..0000000 --- a/func/utils/gradient_3D.m +++ /dev/null @@ -1,88 +0,0 @@ -function [dx, dy, dz] = gradient_3D(I,varargin) -% varargin{2} corresponds to the gradientmethod, the default is 0 which corresponds -% to the mid gradient definition -%defined based on div_op by Gilles Puy -if nargin==1 - res=[1,1,1]; -else - if isempty(varargin{1}) - res=[1,1,1]; -else - res=varargin{1}; - end; -end - -if nargin>=3 - gradientmethod = varargin{2}; -else - gradientmethod = 0; -end; - - -gradientmethod; - -switch gradientmethod - case 1 -%defined based on gradient_op by Gilles Puy - it is a forward differential -dx = cat(1, I(2:end,:,:)-I(1:end-1,:,:) , zeros(1, size(I, 2), size(I, 3))) ; -dy = cat(2, I(:,2:end,:)-I(:,1:end-1,:) , zeros(size(I, 1), 1, size(I, 3))) ; -dz = cat(3, I(:,:,2:end)-I(:,:,1:end-1) , zeros(size(I, 1), size(I, 2), 1)); - case 0 -%defined based on my favorite way - midpoint differenttial -dx = cat(1, I(2,:,:)-I(1,:,:) , 0.5*(I(3:end,:,:)-I(1:end-2,:,:)) ,I(end,:,:)-I(end-1,:,:)) ; -dy = cat(2, I(:,2,:)-I(:,1,:) , 0.5*(I(:,3:end,:)-I(:,1:end-2,:)) ,I(:,end,:)-I(:,end-1,:)) ; -dz = cat(3, I(:,:,2)-I(:,:,1) , 0.5*(I(:,:,3:end)-I(:,:,1:end-2)) ,I(:,:,end)-I(:,:,end-1)); - case -1 -%defined based on gradient_op by Gilles Puy - it is a backwards differential -dx = cat(1, zeros(1, size(I, 2), size(I, 3)), I(2:end,:,:)-I(1:end-1,:,:) ) ; -dy = cat(2, zeros(size(I, 1), 1, size(I, 3)), I(:,2:end,:)-I(:,1:end-1,:) ) ; -dz = cat(3, zeros(size(I, 1), size(I, 2), 1), I(:,:,2:end)-I(:,:,1:end-1) ); - case 2 -% keyboard -%defined based on my favorite way - but very large midpoint differenttial -dx = cat(1, I(2:3,:,:)-I(1:2,:,:) , 0.25*(I(5:end,:,:)-I(1:end-4,:,:)) ,I((end-1):(end),:,:)-I((end-2):(end-1),:,:)) ; -dy = cat(2, I(:,2:3,:)-I(:,1:2,:) , 0.25*(I(:,5:end,:)-I(:,1:end-4,:)) ,I(:,(end-1):(end),:)-I(:,(end-2):(end-1),:)) ; -dz = cat(3, I(:,:,2:3)-I(:,:,1:2) , 0.25*(I(:,:,5:end)-I(:,:,1:end-4)) ,I(:,:,(end-1):(end))-I(:,:,(end-2):(end-1))); - - otherwise - disp('gradient is not performed'); -end - dx = dx /res(1); - dy = dy /res(2); - dz = dz /res(3); - -end -% %testing code -% [X,Y,Z]=meshgrid([-5:1:5],[-5:1:5],[-5:1:5]); -% [gy, gx, gz]=gradient(X,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(X,res(1),res(2)*10,res(3)); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Y,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Y,res(1),res(2)*10,res(3)); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Z,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Z,res(1),res(2)*10,res(3)); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% -% [X,Y,Z]=meshgrid([-5:1:5],[-5:1:5],[-5:1:5]); -% [gy, gx, gz]=gradient(X,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(X,res(1),res(2)*10,res(3),-1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Y,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Y,res(1),res(2)*10,res(3),-1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Z,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Z,res(1),res(2)*10,res(3),-1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% -% [X,Y,Z]=meshgrid([-5:1:5],[-5:1:5],[-5:1:5]); -% [gy, gx, gz]=gradient(X,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(X,res(1),res(2)*10,res(3),1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Y,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Y,res(1),res(2)*10,res(3),1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) -% [gy, gx, gz]=gradient(Z,res(2)*10,res(1),res(3)); -% [dx, dy, dz]=gradient_3D(Z,res(1),res(2)*10,res(3),1); -% image_view3(cat(4,gx,dx,gy,dy,gz,dz)) - diff --git a/func/utils/ifft3s.m b/func/utils/ifft3s.m deleted file mode 100644 index 7f43e88..0000000 --- a/func/utils/ifft3s.m +++ /dev/null @@ -1,6 +0,0 @@ -function out = ifft3s(data) -% function out = ifft3s(data) -% -% Do 3D FFT on each slice of data and fftshift - -out = ifftshift(ifftshift(ifftshift(ifft(ifft(ifft(fftshift(fftshift(fftshift(data,1),2),3),[],1),[],2),[],3),1),2),3); diff --git a/func/utils/imab.m b/func/utils/imab.m deleted file mode 100644 index adc10cc..0000000 --- a/func/utils/imab.m +++ /dev/null @@ -1,258 +0,0 @@ -function handle = imab(data, clims, bSep, noCols) -% function handle = imab(data, clims, bSep, noCols) -% -% Just show the 2D, 3D or 4D data as quickly as possible -% -% Concatenates the slice dimension from left to right, and the time -% dimension from top to bottom. -% -% When Mosaiced, lowest slice is in bottom-left corner. -% -% bSep is boolean option to separate each image from its neighbours rather -% than making one big image (when Mosaicing) -% -% noCols is no. of columns to use in Mosaic (only used for single volume) -% -% January 2010 -% daniel.gallichan@uniklinik-freiburg.de -% -% subfunction 'makemosaic' borrowed from Jaemin Shin's implementation. - - -if nargin < 4; noCols =[]; end -if nargin < 3; bSep = 0; end -if nargin < 2 - clims = []; -end - -if size(data,3)==1 - data = squeeze(data); -end - -if size(data,4) > 20 - disp('Dataset more than 20 time points, could be difficult to see what''s going on...!') -end - -data = permute(data,[2 1 3 4]); -if ~isreal(data) - data = abs(data); - disp('Data were complex - absolute values are shown') -end - - - -if bSep && size(data,3)>1 - figure - dims = size(data); - - if isempty(clims) -% clims = [min(data(:)) max(data(:))]; - clims = [prctile(data(:),2) prctile(data(:),98)] - end - - if size(data,4)==1 - if isempty(noCols) - noCols = min(5,ceil(dims(3)/2)); - end - noRows = ceil(dims(3)/noCols); - iPlots = reshape(noCols*noRows:-1:1,[noCols noRows]).'; - iPlots = iPlots(:,end:-1:1); - - - - subplot1(noRows,noCols) - for iR = 1:noRows - for iC = 1:noCols - if (noRows==1), - subplot1(iC) - else - subplot1([iR iC]) - end - if iPlots(iR,iC) > dims(3) - set(gca,'visible','off') - else - hndl=imagesc(data(:,:,iPlots(iR,iC)),clims);axis equal tight;set(gca,'Xtick',[],'YTick',[]); - end - end - end - - - else - - noRows = size(data,4); noCols = size(data,3); - subplot1(noRows,noCols) - for iR = 1:noRows - for iC = 1:noCols - if (noRows==1), - subplot1(iC) - else - subplot1([iR iC]) - end - hndl=imagesc(data(:,:,iC,iR),clims);axis equal tight;set(gca,'Xtick',[],'YTick',[]); - end - end - - end - -else - %%%% Normal behaviour:- - if size(data,4)==1 - if size(data,3)>1 - if isempty(noCols) - noCols = min(5,ceil(size(data,3)/2)); - end - outIm = makemosaic(data,noCols); - else - outIm = data; - end - if isempty(clims) - hndl=imagesc(outIm);axis equal tight;set(gca,'Xtick',[],'YTick',[]); - else - hndl=imagesc(outIm,clims);axis equal tight;set(gca,'Xtick',[],'YTick',[]); - end - else - if isempty(clims) - hndl=imagesc(imcat(imcat(data,2,3),1,4,0));axis equal tight;set(gca,'Xtick',[],'YTick',[]); - else - hndl=imagesc(imcat(imcat(data,2,3),1,4,0),clims);axis equal tight;set(gca,'Xtick',[],'YTick',[]); - end - end - -end - -set(gca,'YDir','normal'); - -if nargout - handle=hndl; -end - - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function imall=makemosaic(im,MaxN); -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% function imall=makemosaic(im,MaxN); -% Make a mosaic image for display the image with "show.m" -% i.e., the 3D image [im] transforms to a mosaic 2D image [imall] -% If [im] is 4D, [im(:,:,:,1)] will be used -% NOTE : First, singleton dimensions will be removed; 64x64x1x20 -> 3D -% Input : -% [im] : 3D or 4D image -% [MaxN](option): The number of colons, Default is 5 -% Output : -% [imall]: mosaic 2D image -% Usages, -% imall=makemosaic(im,MaxN); -% imall=makemosaic(im); -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Examples, -% let [im] is a matrix of 64x64x20 -% imall=makemosaic(im,10); -% [imall] is a 2x10 image of 64x64, size(imall)= 128 x 640 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Copyright (c) Jaemin Shin -% jaemins@gatech.edu -% 01/30/06 -% updated -% 02/28/06 : bug fixed - -if exist('MaxN','var') == 0 - MaxN = 5; -end -im = squeeze(im); -dim = size(im); -if length(dim) < 2; - error('Input is 1D or 2D signal') -elseif length(dim) ==4 - im = squeeze(im(:,:,:,1)); - disp('4D : TimePoint 1 was used') -elseif length(dim) > 4 - error('5D or Higher dimension does not support') -end -Nrow = ceil(dim(3)/MaxN); -Rcol = mod(MaxN - mod(dim(3),MaxN),MaxN); - -if dim(3) <= MaxN - imall = reshape(im,[dim(1) dim(2)*dim(3)]); - imall = [imall,zeros(dim(1),dim(2)*Rcol)]; -else - imall = reshape(im(:,:,1:MaxN),[dim(1) dim(2)*MaxN]); - for ii=2:Nrow-1 % bug fixed - temp = reshape(im(:,:,(ii-1)*MaxN+1:ii*MaxN),[dim(1) dim(2)*MaxN]); - imall = cat(1,imall,temp); - end - temp = reshape(im(:,:,(Nrow-1)*MaxN+1:end),[dim(1) dim(2)*(MaxN-Rcol)]); - temp = [temp,zeros(dim(1),dim(2)*Rcol)]; - imall = cat(1,imall,temp); -end - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function out = imcat(data, outdim, indim, updown) -% function out = imcat(data, outdim, indim, updown) -% concatenate data along indim dimension and add it to dimension outdim - -if nargin < 4 updown = 1; end -if nargin < 3 indim = 3; end - -if updown - switch indim - case 3 - temp = data(:,:,1,:); - if size(data,3)> 1 - for i = 2:size(data,3) - temp = cat(outdim,temp, data(:,:,i,:)); - end - end - - case 4 - temp = data(:,:,:,1); - if size(data,4)> 1 - for i = 2:size(data,4) - temp = cat(outdim,temp,data(:,:,:,i)); - end - end - - case 5 - temp = data(:,:,:,:,1); - if size(data,5)> 1 - for i = 2:size(data,5) - temp = cat(outdim,temp,data(:,:,:,:,i)); - end - end - - end - -else - switch indim - case 3 - temp = data(:,:,end,:); - if size(data,3)> 1 - for i = size(data,3)-1:-1:1 - temp = cat(outdim,temp, data(:,:,i,:)); - end - end - - case 4 - temp = data(:,:,:,end); - if size(data,4)> 1 - for i = size(data,4)-1:-1:1 - temp = cat(outdim,temp,data(:,:,:,i)); - end - end - - case 5 - temp = data(:,:,:,:,end); - if size(data,5)> 1 - for i = size(data,5)-1:-1:1 - temp = cat(outdim,temp,data(:,:,:,:,i)); - end - end - - end -end - -axis off -set(gca,'box','off') -out = temp; \ No newline at end of file diff --git a/func/utils/nii/FAQ.pdf b/func/utils/nii/FAQ.pdf deleted file mode 100644 index b04456b..0000000 Binary files a/func/utils/nii/FAQ.pdf and /dev/null differ diff --git a/func/utils/nii/NIfTI_tools.pdf b/func/utils/nii/NIfTI_tools.pdf deleted file mode 100644 index 592c807..0000000 Binary files a/func/utils/nii/NIfTI_tools.pdf and /dev/null differ diff --git a/func/utils/nii/UseANALYZE.pdf b/func/utils/nii/UseANALYZE.pdf deleted file mode 100644 index 4bcdf21..0000000 Binary files a/func/utils/nii/UseANALYZE.pdf and /dev/null differ diff --git a/func/utils/nii/affine.m b/func/utils/nii/affine.m deleted file mode 100644 index c494c63..0000000 --- a/func/utils/nii/affine.m +++ /dev/null @@ -1,554 +0,0 @@ -% Using 2D or 3D affine matrix to rotate, translate, scale, reflect and -% shear a 2D image or 3D volume. 2D image is represented by a 2D matrix, -% 3D volume is represented by a 3D matrix, and data type can be real -% integer or floating-point. -% -% You may notice that MATLAB has a function called 'imtransform.m' for -% 2D spatial transformation. However, keep in mind that 'imtransform.m' -% assumes y for the 1st dimension, and x for the 2nd dimension. They are -% equivalent otherwise. -% -% In addition, if you adjust the 'new_elem_size' parameter, this 'affine.m' -% is equivalent to 'interp2.m' for 2D image, and equivalent to 'interp3.m' -% for 3D volume. -% -% Usage: [new_img new_M] = ... -% affine(old_img, old_M, [new_elem_size], [verbose], [bg], [method]); -% -% old_img - original 2D image or 3D volume. We assume x for the 1st -% dimension, y for the 2nd dimension, and z for the 3rd -% dimension. -% -% old_M - a 3x3 2D affine matrix for 2D image, or a 4x4 3D affine -% matrix for 3D volume. We assume x for the 1st dimension, -% y for the 2nd dimension, and z for the 3rd dimension. -% -% new_elem_size (optional) - size of voxel along x y z direction for -% a transformed 3D volume, or size of pixel along x y for -% a transformed 2D image. We assume x for the 1st dimension -% y for the 2nd dimension, and z for the 3rd dimension. -% 'new_elem_size' is 1 if it is default or empty. -% -% You can increase its value to decrease the resampling rate, -% and make the 2D image or 3D volume more coarse. It works -% just like 'interp3'. -% -% verbose (optional) - 1, 0 -% 1: show transforming progress in percentage -% 2: progress will not be displayed -% 'verbose' is 1 if it is default or empty. -% -% bg (optional) - background voxel intensity in any extra corner that -% is caused by the interpolation. 0 in most cases. If it is -% default or empty, 'bg' will be the average of two corner -% voxel intensities in original data. -% -% method (optional) - 1, 2, or 3 -% 1: for Trilinear interpolation -% 2: for Nearest Neighbor interpolation -% 3: for Fischer's Bresenham interpolation -% 'method' is 1 if it is default or empty. -% -% new_img - transformed 2D image or 3D volume -% -% new_M - transformed affine matrix -% -% Example 1 (3D rotation): -% load mri.mat; old_img = double(squeeze(D)); -% old_M = [0.88 0.5 3 -90; -0.5 0.88 3 -126; 0 0 2 -72; 0 0 0 1]; -% new_img = affine(old_img, old_M, 2); -% [x y z] = meshgrid(1:128,1:128,1:27); -% sz = size(new_img); -% [x1 y1 z1] = meshgrid(1:sz(2),1:sz(1),1:sz(3)); -% figure; slice(x, y, z, old_img, 64, 64, 13.5); -% shading flat; colormap(map); view(-66, 66); -% figure; slice(x1, y1, z1, new_img, sz(1)/2, sz(2)/2, sz(3)/2); -% shading flat; colormap(map); view(-66, 66); -% -% Example 2 (2D interpolation): -% load mri.mat; old_img=D(:,:,1,13)'; -% old_M = [1 0 0; 0 1 0; 0 0 1]; -% new_img = affine(old_img, old_M, [.2 .4]); -% figure; image(old_img); colormap(map); -% figure; image(new_img); colormap(map); -% -% This program is inspired by: -% SPM5 Software from Wellcome Trust Centre for Neuroimaging -% http://www.fil.ion.ucl.ac.uk/spm/software -% Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid -% Transformations to Volume Data, WSCG2004 Conference. -% http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function [new_img, new_M] = affine(old_img, old_M, new_elem_size, verbose, bg, method) - - if ~exist('old_img','var') | ~exist('old_M','var') - error('Usage: [new_img new_M] = affine(old_img, old_M, [new_elem_size], [verbose], [bg], [method]);'); - end - - if ndims(old_img) == 3 - if ~isequal(size(old_M),[4 4]) - error('old_M should be a 4x4 affine matrix for 3D volume.'); - end - elseif ndims(old_img) == 2 - if ~isequal(size(old_M),[3 3]) - error('old_M should be a 3x3 affine matrix for 2D image.'); - end - else - error('old_img should be either 2D image or 3D volume.'); - end - - if ~exist('new_elem_size','var') | isempty(new_elem_size) - new_elem_size = [1 1 1]; - elseif length(new_elem_size) < 2 - new_elem_size = new_elem_size(1)*ones(1,3); - elseif length(new_elem_size) < 3 - new_elem_size = [new_elem_size(:); 1]'; - end - - if ~exist('method','var') | isempty(method) - method = 1; - elseif ~exist('bresenham_line3d.m','file') & method == 3 - error([char(10) char(10) 'Please download 3D Bresenham''s line generation program from:' char(10) char(10) 'http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21057' char(10) char(10) 'to test Fischer''s Bresenham interpolation method.' char(10) char(10)]); - end - - % Make compatible to MATLAB earlier than version 7 (R14), which - % can only perform arithmetic on double data type - % - old_img = double(old_img); - old_dim = size(old_img); - - if ~exist('bg','var') | isempty(bg) - bg = mean([old_img(1) old_img(end)]); - end - - if ~exist('verbose','var') | isempty(verbose) - verbose = 1; - end - - if ndims(old_img) == 2 - old_dim(3) = 1; - old_M = old_M(:, [1 2 3 3]); - old_M = old_M([1 2 3 3], :); - old_M(3,:) = [0 0 1 0]; - old_M(:,3) = [0 0 1 0]'; - end - - % Vertices of img in voxel - % - XYZvox = [ 1 1 1 - 1 1 old_dim(3) - 1 old_dim(2) 1 - 1 old_dim(2) old_dim(3) - old_dim(1) 1 1 - old_dim(1) 1 old_dim(3) - old_dim(1) old_dim(2) 1 - old_dim(1) old_dim(2) old_dim(3) ]'; - - old_R = old_M(1:3,1:3); - old_T = old_M(1:3,4); - - % Vertices of img in millimeter - % - XYZmm = old_R*(XYZvox-1) + repmat(old_T, [1, 8]); - - % Make scale of new_M according to new_elem_size - % - new_M = diag([new_elem_size 1]); - - % Make translation so minimum vertex is moved to [1,1,1] - % - new_M(1:3,4) = round( min(XYZmm,[],2) ); - - % New dimensions will be the maximum vertices in XYZ direction (dim_vox) - % i.e. compute dim_vox via dim_mm = R*(dim_vox-1)+T - % where, dim_mm = round(max(XYZmm,[],2)); - % - new_dim = ceil(new_M(1:3,1:3) \ ( round(max(XYZmm,[],2))-new_M(1:3,4) )+1)'; - - % Initialize new_img with new_dim - % - new_img = zeros(new_dim(1:3)); - - % Mask out any changes from Z axis of transformed volume, since we - % will traverse it voxel by voxel below. We will only apply unit - % increment of mask_Z(3,4) to simulate the cursor movement - % - % i.e. we will use mask_Z * new_XYZvox to replace new_XYZvox - % - mask_Z = diag(ones(1,4)); - mask_Z(3,3) = 0; - - % It will be easier to do the interpolation if we invert the process - % by not traversing the original volume. Instead, we traverse the - % transformed volume, and backproject each voxel in the transformed - % volume back into the original volume. If the backprojected voxel - % in original volume is within its boundary, the intensity of that - % voxel can be used by the cursor location in the transformed volume. - % - % First, we traverse along Z axis of transformed volume voxel by voxel - % - for z = 1:new_dim(3) - - if verbose & ~mod(z,10) - fprintf('%.2f percent is done.\n', 100*z/new_dim(3)); - end - - % We need to find out the mapping from voxel in the transformed - % volume (new_XYZvox) to voxel in the original volume (old_XYZvox) - % - % The following equation works, because they all equal to XYZmm: - % new_R*(new_XYZvox-1) + new_T == old_R*(old_XYZvox-1) + old_T - % - % We can use modified new_M1 & old_M1 to substitute new_M & old_M - % new_M1 * new_XYZvox == old_M1 * old_XYZvox - % - % where: M1 = M; M1(:,4) = M(:,4) - sum(M(:,1:3),2); - % and: M(:,4) == [T; 1] == sum(M1,2) - % - % Therefore: old_XYZvox = old_M1 \ new_M1 * new_XYZvox; - % - % Since we are traverse Z axis, and new_XYZvox is replaced - % by mask_Z * new_XYZvox, the above formula can be rewritten - % as: old_XYZvox = old_M1 \ new_M1 * mask_Z * new_XYZvox; - % - % i.e. we find the mapping from new_XYZvox to old_XYZvox: - % M = old_M1 \ new_M1 * mask_Z; - % - % First, compute modified old_M1 & new_M1 - % - old_M1 = old_M; old_M1(:,4) = old_M(:,4) - sum(old_M(:,1:3),2); - new_M1 = new_M; new_M1(:,4) = new_M(:,4) - sum(new_M(:,1:3),2); - - % Then, apply unit increment of mask_Z(3,4) to simulate the - % cursor movement - % - mask_Z(3,4) = z; - - % Here is the mapping from new_XYZvox to old_XYZvox - % - M = old_M1 \ new_M1 * mask_Z; - - switch method - case 1 - new_img(:,:,z) = trilinear(old_img, new_dim, old_dim, M, bg); - case 2 - new_img(:,:,z) = nearest_neighbor(old_img, new_dim, old_dim, M, bg); - case 3 - new_img(:,:,z) = bresenham(old_img, new_dim, old_dim, M, bg); - end - - end; % for z - - if ndims(old_img) == 2 - new_M(3,:) = []; - new_M(:,3) = []; - end - - return; % affine - - -%-------------------------------------------------------------------- -function img_slice = trilinear(img, dim1, dim2, M, bg) - - img_slice = zeros(dim1(1:2)); - TINY = 5e-2; % tolerance - - % Dimension of transformed 3D volume - % - xdim1 = dim1(1); - ydim1 = dim1(2); - - % Dimension of original 3D volume - % - xdim2 = dim2(1); - ydim2 = dim2(2); - zdim2 = dim2(3); - - % initialize new_Y accumulation - % - Y2X = 0; - Y2Y = 0; - Y2Z = 0; - - for y = 1:ydim1 - - % increment of new_Y accumulation - % - Y2X = Y2X + M(1,2); % new_Y to old_X - Y2Y = Y2Y + M(2,2); % new_Y to old_Y - Y2Z = Y2Z + M(3,2); % new_Y to old_Z - - % backproject new_Y accumulation and translation to old_XYZ - % - old_X = Y2X + M(1,4); - old_Y = Y2Y + M(2,4); - old_Z = Y2Z + M(3,4); - - for x = 1:xdim1 - - % accumulate the increment of new_X, and apply it - % to the backprojected old_XYZ - % - old_X = M(1,1) + old_X ; - old_Y = M(2,1) + old_Y ; - old_Z = M(3,1) + old_Z ; - - % within boundary of original image - % - if ( old_X > 1-TINY & old_X < xdim2+TINY & ... - old_Y > 1-TINY & old_Y < ydim2+TINY & ... - old_Z > 1-TINY & old_Z < zdim2+TINY ) - - % Calculate distance of old_XYZ to its neighbors for - % weighted intensity average - % - dx = old_X - floor(old_X); - dy = old_Y - floor(old_Y); - dz = old_Z - floor(old_Z); - - x000 = floor(old_X); - x100 = x000 + 1; - - if floor(old_X) < 1 - x000 = 1; - x100 = x000; - elseif floor(old_X) > xdim2-1 - x000 = xdim2; - x100 = x000; - end - - x010 = x000; - x001 = x000; - x011 = x000; - - x110 = x100; - x101 = x100; - x111 = x100; - - y000 = floor(old_Y); - y010 = y000 + 1; - - if floor(old_Y) < 1 - y000 = 1; - y100 = y000; - elseif floor(old_Y) > ydim2-1 - y000 = ydim2; - y010 = y000; - end - - y100 = y000; - y001 = y000; - y101 = y000; - - y110 = y010; - y011 = y010; - y111 = y010; - - z000 = floor(old_Z); - z001 = z000 + 1; - - if floor(old_Z) < 1 - z000 = 1; - z001 = z000; - elseif floor(old_Z) > zdim2-1 - z000 = zdim2; - z001 = z000; - end - - z100 = z000; - z010 = z000; - z110 = z000; - - z101 = z001; - z011 = z001; - z111 = z001; - - x010 = x000; - x001 = x000; - x011 = x000; - - x110 = x100; - x101 = x100; - x111 = x100; - - v000 = double(img(x000, y000, z000)); - v010 = double(img(x010, y010, z010)); - v001 = double(img(x001, y001, z001)); - v011 = double(img(x011, y011, z011)); - - v100 = double(img(x100, y100, z100)); - v110 = double(img(x110, y110, z110)); - v101 = double(img(x101, y101, z101)); - v111 = double(img(x111, y111, z111)); - - img_slice(x,y) = v000*(1-dx)*(1-dy)*(1-dz) + ... - v010*(1-dx)*dy*(1-dz) + ... - v001*(1-dx)*(1-dy)*dz + ... - v011*(1-dx)*dy*dz + ... - v100*dx*(1-dy)*(1-dz) + ... - v110*dx*dy*(1-dz) + ... - v101*dx*(1-dy)*dz + ... - v111*dx*dy*dz; - - else - img_slice(x,y) = bg; - - end % if boundary - - end % for x - end % for y - - return; % trilinear - - -%-------------------------------------------------------------------- -function img_slice = nearest_neighbor(img, dim1, dim2, M, bg) - - img_slice = zeros(dim1(1:2)); - - % Dimension of transformed 3D volume - % - xdim1 = dim1(1); - ydim1 = dim1(2); - - % Dimension of original 3D volume - % - xdim2 = dim2(1); - ydim2 = dim2(2); - zdim2 = dim2(3); - - % initialize new_Y accumulation - % - Y2X = 0; - Y2Y = 0; - Y2Z = 0; - - for y = 1:ydim1 - - % increment of new_Y accumulation - % - Y2X = Y2X + M(1,2); % new_Y to old_X - Y2Y = Y2Y + M(2,2); % new_Y to old_Y - Y2Z = Y2Z + M(3,2); % new_Y to old_Z - - % backproject new_Y accumulation and translation to old_XYZ - % - old_X = Y2X + M(1,4); - old_Y = Y2Y + M(2,4); - old_Z = Y2Z + M(3,4); - - for x = 1:xdim1 - - % accumulate the increment of new_X and apply it - % to the backprojected old_XYZ - % - old_X = M(1,1) + old_X ; - old_Y = M(2,1) + old_Y ; - old_Z = M(3,1) + old_Z ; - - xi = round(old_X); - yi = round(old_Y); - zi = round(old_Z); - - % within boundary of original image - % - if ( xi >= 1 & xi <= xdim2 & ... - yi >= 1 & yi <= ydim2 & ... - zi >= 1 & zi <= zdim2 ) - - img_slice(x,y) = img(xi,yi,zi); - - else - img_slice(x,y) = bg; - - end % if boundary - - end % for x - end % for y - - return; % nearest_neighbor - - -%-------------------------------------------------------------------- -function img_slice = bresenham(img, dim1, dim2, M, bg) - - img_slice = zeros(dim1(1:2)); - - % Dimension of transformed 3D volume - % - xdim1 = dim1(1); - ydim1 = dim1(2); - - % Dimension of original 3D volume - % - xdim2 = dim2(1); - ydim2 = dim2(2); - zdim2 = dim2(3); - - for y = 1:ydim1 - - start_old_XYZ = round(M*[0 y 0 1]'); - end_old_XYZ = round(M*[xdim1 y 0 1]'); - - [X Y Z] = bresenham_line3d(start_old_XYZ, end_old_XYZ); - - % line error correction - % -% del = end_old_XYZ - start_old_XYZ; - % del_dom = max(del); - % idx_dom = find(del==del_dom); - % idx_dom = idx_dom(1); - % idx_other = [1 2 3]; - % idx_other(idx_dom) = []; - %del_x1 = del(idx_other(1)); -% del_x2 = del(idx_other(2)); - % line_slope = sqrt((del_x1/del_dom)^2 + (del_x2/del_dom)^2 + 1); - % line_error = line_slope - 1; -% line error correction removed because it is too slow - - for x = 1:xdim1 - - % rescale ratio - % - i = round(x * length(X) / xdim1); - - if i < 1 - i = 1; - elseif i > length(X) - i = length(X); - end - - xi = X(i); - yi = Y(i); - zi = Z(i); - - % within boundary of the old XYZ space - % - if ( xi >= 1 & xi <= xdim2 & ... - yi >= 1 & yi <= ydim2 & ... - zi >= 1 & zi <= zdim2 ) - - img_slice(x,y) = img(xi,yi,zi); - -% if line_error > 1 - % x = x + 1; - -% if x <= xdim1 - % img_slice(x,y) = img(xi,yi,zi); - % line_error = line_slope - 1; - % end - % end % if line_error -% line error correction removed because it is too slow - - else - img_slice(x,y) = bg; - - end % if boundary - - end % for x - end % for y - - return; % bresenham - diff --git a/func/utils/nii/bipolar.m b/func/utils/nii/bipolar.m deleted file mode 100644 index 02cd30b..0000000 --- a/func/utils/nii/bipolar.m +++ /dev/null @@ -1,94 +0,0 @@ -%BIPOLAR returns an M-by-3 matrix containing a blue-red colormap, in -% in which red stands for positive, blue stands for negative, -% and white stands for 0. -% -% Usage: cmap = bipolar(M, lo, hi, contrast); or cmap = bipolar; -% -% cmap: output M-by-3 matrix for BIPOLAR colormap. -% M: number of shades in the colormap. By default, it is the -% same length as the current colormap. -% lo: the lowest value to represent. -% hi: the highest value to represent. -% -% Inspired from the LORETA PASCAL program: -% http://www.unizh.ch/keyinst/NewLORETA -% -% jimmy@rotman-baycrest.on.ca -% -%---------------------------------------------------------------- -function cmap = bipolar(M, lo, hi, contrast) - - if ~exist('contrast','var') - contrast = 128; - end - - if ~exist('lo','var') - lo = -1; - end - - if ~exist('hi','var') - hi = 1; - end - - if ~exist('M','var') - cmap = colormap; - M = size(cmap,1); - end - - steepness = 10 ^ (1 - (contrast-1)/127); - pos_infs = 1e-99; - neg_infs = -1e-99; - - doubleredc = []; - doublebluec = []; - - if lo >= 0 % all positive - - if lo == 0 - lo = pos_infs; - end - - for i=linspace(hi/M, hi, M) - t = exp(log(i/hi)*steepness); - doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; - end - - cmap = doubleredc; - - elseif hi <= 0 % all negative - - if hi == 0 - hi = neg_infs; - end - - for i=linspace(abs(lo)/M, abs(lo), M) - t = exp(log(i/abs(lo))*steepness); - doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; - end - - cmap = flipud(doublebluec); - - else - - if hi > abs(lo) - maxc = hi; - else - maxc = abs(lo); - end - - for i=linspace(maxc/M, hi, round(M*hi/(hi-lo))) - t = exp(log(i/maxc)*steepness); - doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; - end - - for i=linspace(maxc/M, abs(lo), round(M*abs(lo)/(hi-lo))) - t = exp(log(i/maxc)*steepness); - doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; - end - - cmap = [flipud(doublebluec); doubleredc]; - - end - - return; % bipolar - diff --git a/func/utils/nii/bresenham_line3d.m b/func/utils/nii/bresenham_line3d.m deleted file mode 100644 index e1e9dc7..0000000 --- a/func/utils/nii/bresenham_line3d.m +++ /dev/null @@ -1,189 +0,0 @@ -% Generate X Y Z coordinates of a 3D Bresenham's line between -% two given points. -% -% A very useful application of this algorithm can be found in the -% implementation of Fischer's Bresenham interpolation method in my -% another program that can rotate three dimensional image volume -% with an affine matrix: -% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21080 -% -% Usage: [X Y Z] = bresenham_line3d(P1, P2, [precision]); -% -% P1 - vector for Point1, where P1 = [x1 y1 z1] -% -% P2 - vector for Point2, where P2 = [x2 y2 z2] -% -% precision (optional) - Although according to Bresenham's line -% algorithm, point coordinates x1 y1 z1 and x2 y2 z2 should -% be integer numbers, this program extends its limit to all -% real numbers. If any of them are floating numbers, you -% should specify how many digits of decimal that you would -% like to preserve. Be aware that the length of output X Y -% Z coordinates will increase in 10 times for each decimal -% digit that you want to preserve. By default, the precision -% is 0, which means that they will be rounded to the nearest -% integer. -% -% X - a set of x coordinates on Bresenham's line -% -% Y - a set of y coordinates on Bresenham's line -% -% Z - a set of z coordinates on Bresenham's line -% -% Therefore, all points in XYZ set (i.e. P(i) = [X(i) Y(i) Z(i)]) -% will constitute the Bresenham's line between P1 and P1. -% -% Example: -% P1 = [12 37 6]; P2 = [46 3 35]; -% [X Y Z] = bresenham_line3d(P1, P2); -% figure; plot3(X,Y,Z,'s','markerface','b'); -% -% This program is ported to MATLAB from: -% -% B.Pendleton. line3d - 3D Bresenham's (a 3D line drawing algorithm) -% ftp://ftp.isc.org/pub/usenet/comp.sources.unix/volume26/line3d, 1992 -% -% Which is also referenced by: -% -% Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid -% Transformations to Volume Data, WSCG2004 Conference. -% http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function [X,Y,Z] = bresenham_line3d(P1, P2, precision) - - if ~exist('precision','var') | isempty(precision) | round(precision) == 0 - precision = 0; - P1 = round(P1); - P2 = round(P2); - else - precision = round(precision); - P1 = round(P1*(10^precision)); - P2 = round(P2*(10^precision)); - end - - d = max(abs(P2-P1)+1); - X = zeros(1, d); - Y = zeros(1, d); - Z = zeros(1, d); - - x1 = P1(1); - y1 = P1(2); - z1 = P1(3); - - x2 = P2(1); - y2 = P2(2); - z2 = P2(3); - - dx = x2 - x1; - dy = y2 - y1; - dz = z2 - z1; - - ax = abs(dx)*2; - ay = abs(dy)*2; - az = abs(dz)*2; - - sx = sign(dx); - sy = sign(dy); - sz = sign(dz); - - x = x1; - y = y1; - z = z1; - idx = 1; - - if(ax>=max(ay,az)) % x dominant - yd = ay - ax/2; - zd = az - ax/2; - - while(1) - X(idx) = x; - Y(idx) = y; - Z(idx) = z; - idx = idx + 1; - - if(x == x2) % end - break; - end - - if(yd >= 0) % move along y - y = y + sy; - yd = yd - ax; - end - - if(zd >= 0) % move along z - z = z + sz; - zd = zd - ax; - end - - x = x + sx; % move along x - yd = yd + ay; - zd = zd + az; - end - elseif(ay>=max(ax,az)) % y dominant - xd = ax - ay/2; - zd = az - ay/2; - - while(1) - X(idx) = x; - Y(idx) = y; - Z(idx) = z; - idx = idx + 1; - - if(y == y2) % end - break; - end - - if(xd >= 0) % move along x - x = x + sx; - xd = xd - ay; - end - - if(zd >= 0) % move along z - z = z + sz; - zd = zd - ay; - end - - y = y + sy; % move along y - xd = xd + ax; - zd = zd + az; - end - elseif(az>=max(ax,ay)) % z dominant - xd = ax - az/2; - yd = ay - az/2; - - while(1) - X(idx) = x; - Y(idx) = y; - Z(idx) = z; - idx = idx + 1; - - if(z == z2) % end - break; - end - - if(xd >= 0) % move along x - x = x + sx; - xd = xd - az; - end - - if(yd >= 0) % move along y - y = y + sy; - yd = yd - az; - end - - z = z + sz; % move along z - xd = xd + ax; - yd = yd + ay; - end - end - - if precision ~= 0 - X = X/(10^precision); - Y = Y/(10^precision); - Z = Z/(10^precision); - end - - return; % bresenham_line3d - diff --git a/func/utils/nii/clip_nii.m b/func/utils/nii/clip_nii.m deleted file mode 100644 index 126524e..0000000 --- a/func/utils/nii/clip_nii.m +++ /dev/null @@ -1,115 +0,0 @@ -% CLIP_NII: Clip the NIfTI volume from any of the 6 sides -% -% Usage: nii = clip_nii(nii, [option]) -% -% Inputs: -% -% nii - NIfTI volume. -% -% option - struct instructing how many voxel to be cut from which side. -% -% option.cut_from_L = ( number of voxel ) -% option.cut_from_R = ( number of voxel ) -% option.cut_from_P = ( number of voxel ) -% option.cut_from_A = ( number of voxel ) -% option.cut_from_I = ( number of voxel ) -% option.cut_from_S = ( number of voxel ) -% -% Options description in detail: -% ============================== -% -% cut_from_L: Number of voxels from Left side will be clipped. -% -% cut_from_R: Number of voxels from Right side will be clipped. -% -% cut_from_P: Number of voxels from Posterior side will be clipped. -% -% cut_from_A: Number of voxels from Anterior side will be clipped. -% -% cut_from_I: Number of voxels from Inferior side will be clipped. -% -% cut_from_S: Number of voxels from Superior side will be clipped. -% -% NIfTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function nii = clip_nii(nii, opt) - - dims = abs(nii.hdr.dime.dim(2:4)); - origin = abs(nii.hdr.hist.originator(1:3)); - - if isempty(origin) | all(origin == 0) % according to SPM - origin = round((dims+1)/2); - end - - cut_from_L = 0; - cut_from_R = 0; - cut_from_P = 0; - cut_from_A = 0; - cut_from_I = 0; - cut_from_S = 0; - - if nargin > 1 & ~isempty(opt) - if ~isstruct(opt) - error('option argument should be a struct'); - end - - if isfield(opt,'cut_from_L') - cut_from_L = round(opt.cut_from_L); - - if cut_from_L >= origin(1) | cut_from_L < 0 - error('cut_from_L cannot be negative or cut beyond originator'); - end - end - - if isfield(opt,'cut_from_P') - cut_from_P = round(opt.cut_from_P); - - if cut_from_P >= origin(2) | cut_from_P < 0 - error('cut_from_P cannot be negative or cut beyond originator'); - end - end - - if isfield(opt,'cut_from_I') - cut_from_I = round(opt.cut_from_I); - - if cut_from_I >= origin(3) | cut_from_I < 0 - error('cut_from_I cannot be negative or cut beyond originator'); - end - end - - if isfield(opt,'cut_from_R') - cut_from_R = round(opt.cut_from_R); - - if cut_from_R > dims(1)-origin(1) | cut_from_R < 0 - error('cut_from_R cannot be negative or cut beyond originator'); - end - end - - if isfield(opt,'cut_from_A') - cut_from_A = round(opt.cut_from_A); - - if cut_from_A > dims(2)-origin(2) | cut_from_A < 0 - error('cut_from_A cannot be negative or cut beyond originator'); - end - end - - if isfield(opt,'cut_from_S') - cut_from_S = round(opt.cut_from_S); - - if cut_from_S > dims(3)-origin(3) | cut_from_S < 0 - error('cut_from_S cannot be negative or cut beyond originator'); - end - end - end - - nii = make_nii(nii.img( (cut_from_L+1) : (dims(1)-cut_from_R), ... - (cut_from_P+1) : (dims(2)-cut_from_A), ... - (cut_from_I+1) : (dims(3)-cut_from_S), ... - :,:,:,:,:), nii.hdr.dime.pixdim(2:4), ... - [origin(1)-cut_from_L origin(2)-cut_from_P origin(3)-cut_from_I], ... - nii.hdr.dime.datatype, nii.hdr.hist.descrip); - - return; - diff --git a/func/utils/nii/collapse_nii_scan.m b/func/utils/nii/collapse_nii_scan.m deleted file mode 100644 index 14f1bc6..0000000 --- a/func/utils/nii/collapse_nii_scan.m +++ /dev/null @@ -1,260 +0,0 @@ -% Collapse multiple single-scan NIFTI files into a multiple-scan NIFTI file -% -% Usage: collapse_nii_scan(scan_file_pattern, [collapsed_fileprefix], [scan_file_folder]) -% -% Here, scan_file_pattern should look like: 'myscan_0*.img' -% If collapsed_fileprefix is omit, 'multi_scan' will be used -% If scan_file_folder is omit, current file folder will be used -% -% The order of volumes in the collapsed file will be the order of -% corresponding filenames for those selected scan files. -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function collapse_nii_scan(scan_pattern, fileprefix, scan_path) - - if ~exist('fileprefix','var') - fileprefix = 'multi_scan'; - else - [tmp fileprefix] = fileparts(fileprefix); - end - - if ~exist('scan_path','var'), scan_path = pwd; end - pnfn = fullfile(scan_path, scan_pattern); - - file_lst = dir(pnfn); - flist = {file_lst.name}; - flist = flist(:); - filename = flist{1}; - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - else - gzFile = 1; - end - else - if ~strcmp(filename(end-3:end), '.img') & ... - ~strcmp(filename(end-3:end), '.hdr') & ... - ~strcmp(filename(end-3:end), '.nii') - - error('Please check filename.'); - end - end - - nii = load_untouch_nii(fullfile(scan_path,filename)); - nii.hdr.dime.dim(5) = length(flist); - - if nii.hdr.dime.dim(1) < 4 - nii.hdr.dime.dim(1) = 4; - end - - hdr = nii.hdr; - filetype = nii.filetype; - - if isfield(nii,'ext') & ~isempty(nii.ext) - ext = nii.ext; - [ext, esize_total] = verify_nii_ext(ext); - else - ext = []; - end - - switch double(hdr.dime.datatype), - case 1, - hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; - case 2, - hdr.dime.bitpix = int16(8 ); precision = 'uint8'; - case 4, - hdr.dime.bitpix = int16(16); precision = 'int16'; - case 8, - hdr.dime.bitpix = int16(32); precision = 'int32'; - case 16, - hdr.dime.bitpix = int16(32); precision = 'float32'; - case 32, - hdr.dime.bitpix = int16(64); precision = 'float32'; - case 64, - hdr.dime.bitpix = int16(64); precision = 'float64'; - case 128, - hdr.dime.bitpix = int16(24); precision = 'uint8'; - case 256 - hdr.dime.bitpix = int16(8 ); precision = 'int8'; - case 512 - hdr.dime.bitpix = int16(16); precision = 'uint16'; - case 768 - hdr.dime.bitpix = int16(32); precision = 'uint32'; - case 1024 - hdr.dime.bitpix = int16(64); precision = 'int64'; - case 1280 - hdr.dime.bitpix = int16(64); precision = 'uint64'; - case 1792, - hdr.dime.bitpix = int16(128); precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - - if filetype == 2 - fid = fopen(sprintf('%s.nii',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.nii.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 352; - - if ~isempty(ext) - hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; - end - - hdr.hist.magic = 'n+1'; - save_untouch_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - elseif filetype == 1 - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 0; - hdr.hist.magic = 'ni1'; - save_untouch_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - - fclose(fid); - fid = fopen(sprintf('%s.img',fileprefix),'w'); - else - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - save_untouch0_nii_hdr(hdr, fid); - - fclose(fid); - fid = fopen(sprintf('%s.img',fileprefix),'w'); - end - - if filetype == 2 & isempty(ext) - skip_bytes = double(hdr.dime.vox_offset) - 348; - else - skip_bytes = 0; - end - - if skip_bytes - fwrite(fid, zeros(1,skip_bytes), 'uint8'); - end - - glmax = -inf; - glmin = inf; - - for i = 1:length(flist) - nii = load_untouch_nii(fullfile(scan_path,flist{i})); - - if double(hdr.dime.datatype) == 128 - - % RGB planes are expected to be in the 4th dimension of nii.img - % - if(size(nii.img,4)~=3) - error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); - end - - nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); - end - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - real_img = real(nii.img(:))'; - nii.img = imag(nii.img(:))'; - nii.img = [real_img; nii.img]; - end - - if nii.hdr.dime.glmax > glmax - glmax = nii.hdr.dime.glmax; - end - - if nii.hdr.dime.glmin < glmin - glmin = nii.hdr.dime.glmin; - end - - fwrite(fid, nii.img, precision); - end - - hdr.dime.glmax = round(glmax); - hdr.dime.glmin = round(glmin); - - if filetype == 2 - fseek(fid, 140, 'bof'); - fwrite(fid, hdr.dime.glmax, 'int32'); - fwrite(fid, hdr.dime.glmin, 'int32'); - elseif filetype == 1 - fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid2 < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - save_untouch_nii_hdr(hdr, fid2); - - if ~isempty(ext) - save_nii_ext(ext, fid2); - end - - fclose(fid2); - else - fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid2 < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - save_untouch0_nii_hdr(hdr, fid2); - - fclose(fid2); - end - - fclose(fid); - - % gzip output file if requested - % - if exist('gzFile', 'var') - if filetype == 1 - gzip([fileprefix, '.img']); - delete([fileprefix, '.img']); - gzip([fileprefix, '.hdr']); - delete([fileprefix, '.hdr']); - elseif filetype == 2 - gzip([fileprefix, '.nii']); - delete([fileprefix, '.nii']); - end; - end; - - return; % collapse_nii_scan - diff --git a/func/utils/nii/examples.txt b/func/utils/nii/examples.txt deleted file mode 100644 index 1111650..0000000 --- a/func/utils/nii/examples.txt +++ /dev/null @@ -1,130 +0,0 @@ - -- Examples to load, make and save a nii struct: - - To load Analyze data or NIFTI data to a structure: - - nii = load_nii(NIFTI_file_name, [img_idx], [old_RGB24]); - - img_idx is a numerical array of image indices along the temporal - axis, which is only available in NIFTI data. After you specify - img_idx, only those images indexed by img_idx will be loaded. If - there is no img_idx or img_idx is empty, all available images - will be loaded. - - For RGB image, most people use RGB triple sequentially for each - voxel, like [R1 G1 B1 R2 G2 B2 ...]. However, some program like - Analyze 6.0 developed by AnalyzeDirect uses old RGB24, in a way - like [R1 R2 ... G1 G2 ... B1 B2 ...] for each slices. In this - case, you can set old_RGB24 flag to 1 and load data correctly: - - nii = load_nii(NIFTI_file_name, [], 1); - - To get a total number of images along the temporal axis: - - num_scan = get_nii_frame(NIFTI_file_name); - - You can also load the header extension if it exists: - - nii.ext = load_nii_ext(NIFTI_file_name); - - You can just load the Analyze or NIFTI header: - (header contains: hk, dime, and hist) - - hdr = load_nii_hdr(NIFTI_file_name); - - You can also save the structure to a new file: - (header extension will be saved if there is nii.ext structure) - - save_nii(nii, NIFTI_file_name); - - To make the structure from any 3D (or 4D) data: - - img = rand(91,109,91); or - img = rand(64,64,21,18); - nii = make_nii(img [, voxel_size, origin, datatype] ); - - Use "help load_nii", "help save_nii", "help make_nii" etc. - to get more detail information. - - -- Examples to plot a nii struct: - (More detail descriptions are available on top of "view_nii.m") - - Simple way to plot a nii struct: - - view_nii(nii); - - The default colormap will use the Gray if all data values are - non-negative; otherwise, the default colormap will use BiPolar. - You can choose other colormap, including customized colormap - from panel. - - To imbed the plot into your existing figure: - - h = gcf; - opt.command = 'init'; - opt.setarea = [0.3 0.1 0.6 0.8]; - view_nii(h, nii, opt); - - To add a colorbar: - - opt.usecolorbar = 1; - view_nii(gcf, opt); - - Here, opt.command is implicitly set to 'update'. - - To display in real aspect ratio: - - opt.usestretch = 0; - view_nii(gcf, opt); - - If you want the data value to be directly used as the index - of colormap, instead of scale to the whole colormap: - - opt.useimagesc = 0; - view_nii(gcf, opt); - - If you modified the data value without changing the dimension, - voxel_size, and origin, you can update the display by: - - opt.command = 'updateimg'; - view_nii(gcf, nii.img, opt); - - If the data is completely different, display can be updated by: - - opt.command = 'updatenii'; - view_nii(gcf, nii, opt); - - This is an example to plot EEG source imaging on top of T1 background: - 1. download overlay.zip and unzip it from: - http://www.rotman-baycrest.on.ca/~jimmy/NIFTI/overlay.zip - 2. T1 = load_nii('T1.nii'); - 3. EEG = load_nii('EEG.nii'); - 4. option.setvalue.idx = find(EEG.img); - 5. option.setvalue.val = EEG.img(option.setvalue.idx); - 6. option.useinterp = 1; - 7. option.setviewpoint = [62 48 46]; - 8. view_nii(T1, option); - - -- Contrast and Brightness are available under Gray and Bipolar colormap: - - Increase contrast in Gray colormap will make high end values - more distinguishable by sacrificing the low end values; The - minimum contrast (default) will display the whole range. - - Increase or decrease contrast in BiPolar colormap will shift - the distinguishable position for both positive and negative - values. - - Increase or decrease brightness in Gray colormap will shift - the distinguishable position. - - Increase or decrease brightness in BiPolar colormap will make - both positive and negative values more distinguishable. - - -- Required files: - - All files in this package. - diff --git a/func/utils/nii/expand_nii_scan.m b/func/utils/nii/expand_nii_scan.m deleted file mode 100644 index c2e4063..0000000 --- a/func/utils/nii/expand_nii_scan.m +++ /dev/null @@ -1,48 +0,0 @@ -% Expand a multiple-scan NIFTI file into multiple single-scan NIFTI files -% -% Usage: expand_nii_scan(multi_scan_filename, [img_idx], [path_to_save]) -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function expand_nii_scan(filename, img_idx, newpath) - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - else - gzFile = 1; - end - end - - if ~exist('newpath','var') | isempty(newpath), newpath = pwd; end - if ~exist('img_idx','var') | isempty(img_idx), img_idx = 1:get_nii_frame(filename); end - - for i=img_idx - nii_i = load_untouch_nii(filename, i); - - fn = [nii_i.fileprefix '_' sprintf('%04d',i)]; - pnfn = fullfile(newpath, fn); - - if exist('gzFile', 'var') - pnfn = [pnfn '.nii.gz']; - end - - save_untouch_nii(nii_i, pnfn); - end - - return; % expand_nii_scan - diff --git a/func/utils/nii/extra_nii_hdr.m b/func/utils/nii/extra_nii_hdr.m deleted file mode 100644 index a2b5291..0000000 --- a/func/utils/nii/extra_nii_hdr.m +++ /dev/null @@ -1,255 +0,0 @@ -% Decode extra NIFTI header information into hdr.extra -% -% Usage: hdr = extra_nii_hdr(hdr) -% -% hdr can be obtained from load_nii_hdr -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function hdr = extra_nii_hdr(hdr) - - switch hdr.dime.datatype - case 1 - extra.NIFTI_DATATYPES = 'DT_BINARY'; - case 2 - extra.NIFTI_DATATYPES = 'DT_UINT8'; - case 4 - extra.NIFTI_DATATYPES = 'DT_INT16'; - case 8 - extra.NIFTI_DATATYPES = 'DT_INT32'; - case 16 - extra.NIFTI_DATATYPES = 'DT_FLOAT32'; - case 32 - extra.NIFTI_DATATYPES = 'DT_COMPLEX64'; - case 64 - extra.NIFTI_DATATYPES = 'DT_FLOAT64'; - case 128 - extra.NIFTI_DATATYPES = 'DT_RGB24'; - case 256 - extra.NIFTI_DATATYPES = 'DT_INT8'; - case 512 - extra.NIFTI_DATATYPES = 'DT_UINT16'; - case 768 - extra.NIFTI_DATATYPES = 'DT_UINT32'; - case 1024 - extra.NIFTI_DATATYPES = 'DT_INT64'; - case 1280 - extra.NIFTI_DATATYPES = 'DT_UINT64'; - case 1536 - extra.NIFTI_DATATYPES = 'DT_FLOAT128'; - case 1792 - extra.NIFTI_DATATYPES = 'DT_COMPLEX128'; - case 2048 - extra.NIFTI_DATATYPES = 'DT_COMPLEX256'; - otherwise - extra.NIFTI_DATATYPES = 'DT_UNKNOWN'; - end - - switch hdr.dime.intent_code - case 2 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CORREL'; - case 3 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST'; - case 4 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST'; - case 5 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ZSCORE'; - case 6 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ'; - case 7 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BETA'; - case 8 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_BINOM'; - case 9 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GAMMA'; - case 10 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POISSON'; - case 11 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NORMAL'; - case 12 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_FTEST_NONC'; - case 13 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHISQ_NONC'; - case 14 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGISTIC'; - case 15 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LAPLACE'; - case 16 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_UNIFORM'; - case 17 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TTEST_NONC'; - case 18 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_WEIBULL'; - case 19 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_CHI'; - case 20 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_INVGAUSS'; - case 21 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_EXTVAL'; - case 22 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_PVAL'; - case 23 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOGPVAL'; - case 24 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LOG10PVAL'; - case 1001 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_ESTIMATE'; - case 1002 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_LABEL'; - case 1003 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NEURONAME'; - case 1004 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_GENMATRIX'; - case 1005 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_SYMMATRIX'; - case 1006 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DISPVECT'; - case 1007 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_VECTOR'; - case 1008 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_POINTSET'; - case 1009 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_TRIANGLE'; - case 1010 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_QUATERNION'; - case 1011 - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_DIMLESS'; - otherwise - extra.NIFTI_INTENT_CODES = 'NIFTI_INTENT_NONE'; - end - - extra.NIFTI_INTENT_NAMES = hdr.hist.intent_name; - - if hdr.hist.sform_code > 0 - switch hdr.hist.sform_code - case 1 - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT'; - case 2 - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT'; - case 3 - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_TALAIRACH'; - case 4 - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_MNI_152'; - otherwise - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - end - - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - elseif hdr.hist.qform_code > 0 - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - - switch hdr.hist.qform_code - case 1 - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_SCANNER_ANAT'; - case 2 - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_ALIGNED_ANAT'; - case 3 - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_TALAIRACH'; - case 4 - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_MNI_152'; - otherwise - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - end - else - extra.NIFTI_SFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - extra.NIFTI_QFORM_CODES = 'NIFTI_XFORM_UNKNOWN'; - end - - switch bitand(hdr.dime.xyzt_units, 7) % mask with 0x07 - case 1 - extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_METER'; - case 2 - extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MM'; % millimeter - case 3 - extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_MICRO'; - otherwise - extra.NIFTI_SPACE_UNIT = 'NIFTI_UNITS_UNKNOWN'; - end - - switch bitand(hdr.dime.xyzt_units, 56) % mask with 0x38 - case 8 - extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_SEC'; - case 16 - extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_MSEC'; - case 24 - extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_USEC'; % microsecond - otherwise - extra.NIFTI_TIME_UNIT = 'NIFTI_UNITS_UNKNOWN'; - end - - switch hdr.dime.xyzt_units - case 32 - extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_HZ'; - case 40 - extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_PPM'; % part per million - case 48 - extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_RADS'; % radians per second - otherwise - extra.NIFTI_SPECTRAL_UNIT = 'NIFTI_UNITS_UNKNOWN'; - end - - % MRI-specific spatial and temporal information - % - dim_info = hdr.hk.dim_info; - extra.NIFTI_FREQ_DIM = bitand(dim_info, 3); - extra.NIFTI_PHASE_DIM = bitand(bitshift(dim_info, -2), 3); - extra.NIFTI_SLICE_DIM = bitand(bitshift(dim_info, -4), 3); - - % Check slice code - % - switch hdr.dime.slice_code - case 1 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_INC'; % sequential increasing - case 2 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_SEQ_DEC'; % sequential decreasing - case 3 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC'; % alternating increasing - case 4 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC'; % alternating decreasing - case 5 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_INC2'; % ALT_INC # 2 - case 6 - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_ALT_DEC2'; % ALT_DEC # 2 - otherwise - extra.NIFTI_SLICE_ORDER = 'NIFTI_SLICE_UNKNOWN'; - end - - % Check NIFTI version - % - if ~isempty(hdr.hist.magic) & strcmp(hdr.hist.magic(1),'n') & ... - ( strcmp(hdr.hist.magic(2),'i') | strcmp(hdr.hist.magic(2),'+') ) & ... - str2num(hdr.hist.magic(3)) >= 1 & str2num(hdr.hist.magic(3)) <= 9 - - extra.NIFTI_VERSION = str2num(hdr.hist.magic(3)); - else - extra.NIFTI_VERSION = 0; - end - - % Check if data stored in the same file (*.nii) or separate - % files (*.hdr/*.img) - % - if isempty(hdr.hist.magic) - extra.NIFTI_ONEFILE = 0; - else - extra.NIFTI_ONEFILE = strcmp(hdr.hist.magic(2), '+'); - end - - % Swap has been taken care of by checking whether sizeof_hdr is - % 348 (machine is 'ieee-le' or 'ieee-be' etc) - % - % extra.NIFTI_NEEDS_SWAP = (hdr.dime.dim(1) < 0 | hdr.dime.dim(1) > 7); - - % Check NIFTI header struct contains a 5th (vector) dimension - % - if hdr.dime.dim(1) > 4 & hdr.dime.dim(6) > 1 - extra.NIFTI_5TH_DIM = hdr.dime.dim(6); - else - extra.NIFTI_5TH_DIM = 0; - end - - hdr.extra = extra; - - return; % extra_nii_hdr - diff --git a/func/utils/nii/flip_lr.m b/func/utils/nii/flip_lr.m deleted file mode 100644 index fc78e78..0000000 --- a/func/utils/nii/flip_lr.m +++ /dev/null @@ -1,84 +0,0 @@ -% When you load any ANALYZE or NIfTI file with 'load_nii.m', and view -% it with 'view_nii.m', you may find that the image is L-R flipped. -% This is because of the confusion of radiological and neurological -% convention in the medical image before NIfTI format is adopted. You -% can find more details from: -% -% http://www.rotman-baycrest.on.ca/~jimmy/UseANALYZE.htm -% -% Sometime, people even want to convert RAS (standard orientation) back -% to LAS orientation to satisfy the legend programs or processes. This -% program is only written for those purpose. So PLEASE BE VERY CAUTIOUS -% WHEN USING THIS 'FLIP_LR.M' PROGRAM. -% -% With 'flip_lr.m', you can convert any ANALYZE or NIfTI (no matter -% 3D or 4D) file to a flipped NIfTI file. This is implemented simply -% by flipping the affine matrix in the NIfTI header. Since the L-R -% orientation is determined there, so the image will be flipped. -% -% Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance],[preferredForm]) -% -% original_fn - filename of the original ANALYZE or NIfTI (3D or 4D) file -% -% flipped_fn - filename of the L-R flipped NIfTI file -% -% old_RGB (optional) - a scale number to tell difference of new RGB24 -% from old RGB24. New RGB24 uses RGB triple sequentially for each -% voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect -% uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for -% each slices. If the image that you view is garbled, try to set -% old_RGB variable to 1 and try again, because it could be in -% old RGB24. It will be set to 0, if it is default or empty. -% -% tolerance (optional) - distortion allowed for non-orthogonal rotation -% or shearing in NIfTI affine matrix. It will be set to 0.1 (10%), -% if it is default or empty. -% -% preferredForm (optional) - selects which transformation from voxels -% to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate -% "prefer sform or qform, but use others if preferred not present". -% Upper case indicate the program is forced to use the specificied -% tranform or fail loading. 'preferredForm' will be 's', if it is -% default or empty. - Jeff Gunter -% -% Example: flip_lr('avg152T1_LR_nifti.nii', 'flipped_lr.nii'); -% flip_lr('avg152T1_RL_nifti.nii', 'flipped_rl.nii'); -% -% You will find that 'avg152T1_LR_nifti.nii' and 'avg152T1_RL_nifti.nii' -% are the same, and 'flipped_lr.nii' and 'flipped_rl.nii' are also the -% the same, but they are L-R flipped from 'avg152T1_*'. -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function flip_lr(original_fn, flipped_fn, old_RGB, tolerance, preferredForm) - - if ~exist('original_fn','var') | ~exist('flipped_fn','var') - error('Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance])'); - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - if ~exist('tolerance','var') | isempty(tolerance) - tolerance = 0.1; - end - - if ~exist('preferredForm','var') | isempty(preferredForm) - preferredForm= 's'; % Jeff - end - - nii = load_nii(original_fn, [], [], [], [], old_RGB, tolerance, preferredForm); - M = diag(nii.hdr.dime.pixdim(2:5)); - M(1:3,4) = -M(1:3,1:3)*(nii.hdr.hist.originator(1:3)-1)'; - M(1,:) = -1*M(1,:); - nii.hdr.hist.sform_code = 1; - nii.hdr.hist.srow_x = M(1,:); - nii.hdr.hist.srow_y = M(2,:); - nii.hdr.hist.srow_z = M(3,:); - save_nii(nii, flipped_fn); - - return; % flip_lr - diff --git a/func/utils/nii/get_nii_frame.m b/func/utils/nii/get_nii_frame.m deleted file mode 100644 index 9ebdc82..0000000 --- a/func/utils/nii/get_nii_frame.m +++ /dev/null @@ -1,164 +0,0 @@ -% Return time frame of a NIFTI dataset. Support both *.nii and -% *.hdr/*.img file extension. If file extension is not provided, -% *.hdr/*.img will be used as default. -% -% It is a lightweighted "load_nii_hdr", and is equivalent to -% hdr.dime.dim(5) -% -% Usage: [ total_scan ] = get_nii_frame(filename) -% -% filename - NIFTI file name. -% -% Returned values: -% -% total_scan - total number of image scans for the time frame -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function [ total_scan ] = get_nii_frame(filename) - - if ~exist('filename','var'), - error('Usage: [ total_scan ] = get_nii_frame(filename)'); - end - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - fileprefix = filename; - machine = 'ieee-le'; - new_ext = 0; - - if findstr('.nii',fileprefix) & strcmp(fileprefix(end-3:end), '.nii') - new_ext = 1; - fileprefix(end-3:end)=''; - end - - if findstr('.hdr',fileprefix) & strcmp(fileprefix(end-3:end), '.hdr') - fileprefix(end-3:end)=''; - end - - if findstr('.img',fileprefix) & strcmp(fileprefix(end-3:end), '.img') - fileprefix(end-3:end)=''; - end - - if new_ext - fn = sprintf('%s.nii',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.nii".', fileprefix); - error(msg); - end - else - fn = sprintf('%s.hdr',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.hdr".', fileprefix); - error(msg); - end - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - hdr = read_header(fid); - fclose(fid); - end - - if hdr.sizeof_hdr ~= 348 - % first try reading the opposite endian to 'machine' - switch machine, - case 'ieee-le', machine = 'ieee-be'; - case 'ieee-be', machine = 'ieee-le'; - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - hdr = read_header(fid); - fclose(fid); - end - end - - if hdr.sizeof_hdr ~= 348 - % Now throw an error - msg = sprintf('File "%s" is corrupted.',fn); - error(msg); - end - - total_scan = hdr.dim(5); - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - rmdir(tmpDir,'s'); - end - - return; % get_nii_frame - - -%--------------------------------------------------------------------- -function [ dsr ] = read_header(fid) - - fseek(fid,0,'bof'); - dsr.sizeof_hdr = fread(fid,1,'int32')'; % should be 348! - - fseek(fid,40,'bof'); - dsr.dim = fread(fid,8,'int16')'; - - return; % read_header - diff --git a/func/utils/nii/license.txt b/func/utils/nii/license.txt deleted file mode 100644 index 5a2d7f8..0000000 --- a/func/utils/nii/license.txt +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2014, Jimmy Shen -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/func/utils/nii/load_nii.m b/func/utils/nii/load_nii.m deleted file mode 100644 index d8515d4..0000000 --- a/func/utils/nii/load_nii.m +++ /dev/null @@ -1,198 +0,0 @@ -% Load NIFTI or ANALYZE dataset. Support both *.nii and *.hdr/*.img -% file extension. If file extension is not provided, *.hdr/*.img will -% be used as default. -% -% A subset of NIFTI transform is included. For non-orthogonal rotation, -% shearing etc., please use 'reslice_nii.m' to reslice the NIFTI file. -% It will not cause negative effect, as long as you remember not to do -% slice time correction after reslicing the NIFTI file. Output variable -% nii will be in RAS orientation, i.e. X axis from Left to Right, -% Y axis from Posterior to Anterior, and Z axis from Inferior to -% Superior. -% -% Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... -% [dim7_idx], [old_RGB], [tolerance], [preferredForm]) -% -% filename - NIFTI or ANALYZE file name. -% -% img_idx (optional) - a numerical array of 4th dimension indices, -% which is the indices of image scan volume. The number of images -% scan volumes can be obtained from get_nii_frame.m, or simply -% hdr.dime.dim(5). Only the specified volumes will be loaded. -% All available image volumes will be loaded, if it is default or -% empty. -% -% dim5_idx (optional) - a numerical array of 5th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% dim6_idx (optional) - a numerical array of 6th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% dim7_idx (optional) - a numerical array of 7th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% old_RGB (optional) - a scale number to tell difference of new RGB24 -% from old RGB24. New RGB24 uses RGB triple sequentially for each -% voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect -% uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for -% each slices. If the image that you view is garbled, try to set -% old_RGB variable to 1 and try again, because it could be in -% old RGB24. It will be set to 0, if it is default or empty. -% -% tolerance (optional) - distortion allowed in the loaded image for any -% non-orthogonal rotation or shearing of NIfTI affine matrix. If -% you set 'tolerance' to 0, it means that you do not allow any -% distortion. If you set 'tolerance' to 1, it means that you do -% not care any distortion. The image will fail to be loaded if it -% can not be tolerated. The tolerance will be set to 0.1 (10%), if -% it is default or empty. -% -% preferredForm (optional) - selects which transformation from voxels -% to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate -% "prefer sform or qform, but use others if preferred not present". -% Upper case indicate the program is forced to use the specificied -% tranform or fail loading. 'preferredForm' will be 's', if it is -% default or empty. - Jeff Gunter -% -% Returned values: -% -% nii structure: -% -% hdr - struct with NIFTI header fields. -% -% filetype - Analyze format .hdr/.img (0); -% NIFTI .hdr/.img (1); -% NIFTI .nii (2) -% -% fileprefix - NIFTI filename without extension. -% -% machine - machine string variable. -% -% img - 3D (or 4D) matrix of NIFTI data. -% -% original - the original header before any affine transform. -% -% Part of this file is copied and modified from: -% http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function nii = load_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... - old_RGB, tolerance, preferredForm) - - if ~exist('filename','var') - error('Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [tolerance], [preferredForm])'); - end - - if ~exist('img_idx','var') | isempty(img_idx) - img_idx = []; - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) - dim5_idx = []; - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) - dim6_idx = []; - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) - dim7_idx = []; - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - if ~exist('tolerance','var') | isempty(tolerance) - tolerance = 0.1; % 10 percent - end - - if ~exist('preferredForm','var') | isempty(preferredForm) - preferredForm= 's'; % Jeff - end - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - % Read the dataset header - % - [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); - - % Read the header extension - % -% nii.ext = load_nii_ext(filename); - - % Read the dataset body - % - [nii.img,nii.hdr] = load_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... - nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB); - - % Perform some of sform/qform transform - % - nii = xform_nii(nii, tolerance, preferredForm); - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - - % fix fileprefix so it doesn't point to temp location - % - nii.fileprefix = gzFileName(1:end-7); - rmdir(tmpDir,'s'); - end - - return % load_nii - diff --git a/func/utils/nii/load_nii_ext.m b/func/utils/nii/load_nii_ext.m deleted file mode 100644 index 193ee11..0000000 --- a/func/utils/nii/load_nii_ext.m +++ /dev/null @@ -1,207 +0,0 @@ -% Load NIFTI header extension after its header is loaded using load_nii_hdr. -% -% Usage: ext = load_nii_ext(filename) -% -% filename - NIFTI file name. -% -% Returned values: -% -% ext - Structure of NIFTI header extension, which includes num_ext, -% and all the extended header sections in the header extension. -% Each extended header section will have its esize, ecode, and -% edata, where edata can be plain text, xml, or any raw data -% that was saved in the extended header section. -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function ext = load_nii_ext(filename) - - if ~exist('filename','var'), - error('Usage: ext = load_nii_ext(filename)'); - end - - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - machine = 'ieee-le'; - new_ext = 0; - - if findstr('.nii',filename) & strcmp(filename(end-3:end), '.nii') - new_ext = 1; - filename(end-3:end)=''; - end - - if findstr('.hdr',filename) & strcmp(filename(end-3:end), '.hdr') - filename(end-3:end)=''; - end - - if findstr('.img',filename) & strcmp(filename(end-3:end), '.img') - filename(end-3:end)=''; - end - - if new_ext - fn = sprintf('%s.nii',filename); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.nii".', filename); - error(msg); - end - else - fn = sprintf('%s.hdr',filename); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.hdr".', filename); - error(msg); - end - end - - fid = fopen(fn,'r',machine); - vox_offset = 0; - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - - if fread(fid,1,'int32') == 348 - if new_ext - fseek(fid,108,'bof'); - vox_offset = fread(fid,1,'float32'); - end - - ext = read_extension(fid, vox_offset); - fclose(fid); - else - fclose(fid); - - % first try reading the opposite endian to 'machine' - % - switch machine, - case 'ieee-le', machine = 'ieee-be'; - case 'ieee-be', machine = 'ieee-le'; - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - - if fread(fid,1,'int32') ~= 348 - - % Now throw an error - % - msg = sprintf('File "%s" is corrupted.',fn); - error(msg); - end - - if new_ext - fseek(fid,108,'bof'); - vox_offset = fread(fid,1,'float32'); - end - - ext = read_extension(fid, vox_offset); - fclose(fid); - end - end - end - - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - rmdir(tmpDir,'s'); - end - - - return % load_nii_ext - - -%--------------------------------------------------------------------- -function ext = read_extension(fid, vox_offset) - - ext = []; - - if vox_offset - end_of_ext = vox_offset; - else - fseek(fid, 0, 'eof'); - end_of_ext = ftell(fid); - end - - if end_of_ext > 352 - fseek(fid, 348, 'bof'); - ext.extension = fread(fid,4)'; - end - - if isempty(ext) | ext.extension(1) == 0 - ext = []; - return; - end - - i = 1; - - while(ftell(fid) < end_of_ext) - ext.section(i).esize = fread(fid,1,'int32'); - ext.section(i).ecode = fread(fid,1,'int32'); - ext.section(i).edata = char(fread(fid,ext.section(i).esize-8)'); - i = i + 1; - end - - ext.num_ext = length(ext.section); - - return % read_extension - diff --git a/func/utils/nii/load_nii_hdr.m b/func/utils/nii/load_nii_hdr.m deleted file mode 100644 index fcfd479..0000000 --- a/func/utils/nii/load_nii_hdr.m +++ /dev/null @@ -1,280 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function [hdr, filetype, fileprefix, machine] = load_nii_hdr(fileprefix) - - if ~exist('fileprefix','var'), - error('Usage: [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename)'); - end - - machine = 'ieee-le'; - new_ext = 0; - - if findstr('.nii',fileprefix) & strcmp(fileprefix(end-3:end), '.nii') - new_ext = 1; - fileprefix(end-3:end)=''; - end - - if findstr('.hdr',fileprefix) & strcmp(fileprefix(end-3:end), '.hdr') - fileprefix(end-3:end)=''; - end - - if findstr('.img',fileprefix) & strcmp(fileprefix(end-3:end), '.img') - fileprefix(end-3:end)=''; - end - - if new_ext - fn = sprintf('%s.nii',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.nii".', fileprefix); - error(msg); - end - else - fn = sprintf('%s.hdr',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.hdr".', fileprefix); - error(msg); - end - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - - if fread(fid,1,'int32') == 348 - hdr = read_header(fid); - fclose(fid); - else - fclose(fid); - - % first try reading the opposite endian to 'machine' - % - switch machine, - case 'ieee-le', machine = 'ieee-be'; - case 'ieee-be', machine = 'ieee-le'; - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - - if fread(fid,1,'int32') ~= 348 - - % Now throw an error - % - msg = sprintf('File "%s" is corrupted.',fn); - error(msg); - end - - hdr = read_header(fid); - fclose(fid); - end - end - end - - if strcmp(hdr.hist.magic, 'n+1') - filetype = 2; - elseif strcmp(hdr.hist.magic, 'ni1') - filetype = 1; - else - filetype = 0; - end - - return % load_nii_hdr - - -%--------------------------------------------------------------------- -function [ dsr ] = read_header(fid) - - % Original header structures - % struct dsr - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - dsr.hk = header_key(fid); - dsr.dime = image_dimension(fid); - dsr.hist = data_history(fid); - - % For Analyze data format - % - if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1') - dsr.hist.qform_code = 0; - dsr.hist.sform_code = 0; - end - - return % read_header - - -%--------------------------------------------------------------------- -function [ hk ] = header_key(fid) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char dim_info; % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - % - % int sizeof_header Should be 348. - % char regular Must be 'r' to indicate that all images and - % volumes are the same size. - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! - hk.data_type = deblank(fread(fid,10,directchar)'); - hk.db_name = deblank(fread(fid,18,directchar)'); - hk.extents = fread(fid, 1,'int32')'; - hk.session_error = fread(fid, 1,'int16')'; - hk.regular = fread(fid, 1,directchar)'; - hk.dim_info = fread(fid, 1,'uchar')'; - - return % header_key - - -%--------------------------------------------------------------------- -function [ dime ] = image_dimension(fid) - - % Original header structures - % struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % /* - % dim[0] Number of dimensions in database; usually 4. - % dim[1] Image X dimension; number of *pixels* in an image row. - % dim[2] Image Y dimension; number of *pixel rows* in slice. - % dim[3] Volume Z dimension; number of *slices* in a volume. - % dim[4] Time points; number of volumes in database - % */ - % float intent_p1; % char vox_units[4]; /* 16 + 4 */ - % float intent_p2; % char cal_units[8]; /* 20 + 4 */ - % float intent_p3; % char cal_units[8]; /* 24 + 4 */ - % short int intent_code; % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int slice_start; % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width, mm - % pixdim[2] - voxel height, mm - % pixdim[3] - slice thickness, mm - % pixdim[4] - volume timing, in msec - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float scl_slope; % float roi_scale; /* 72 + 4 */ - % float scl_inter; % float funused1; /* 76 + 4 */ - % short slice_end; % float funused2; /* 80 + 2 */ - % char slice_code; % float funused2; /* 82 + 1 */ - % char xyzt_units; % float funused2; /* 83 + 1 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % float slice_duration; % int compressed; /* 92 + 4 */ - % float toffset; % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - dime.dim = fread(fid,8,'int16')'; - dime.intent_p1 = fread(fid,1,'float32')'; - dime.intent_p2 = fread(fid,1,'float32')'; - dime.intent_p3 = fread(fid,1,'float32')'; - dime.intent_code = fread(fid,1,'int16')'; - dime.datatype = fread(fid,1,'int16')'; - dime.bitpix = fread(fid,1,'int16')'; - dime.slice_start = fread(fid,1,'int16')'; - dime.pixdim = fread(fid,8,'float32')'; - dime.vox_offset = fread(fid,1,'float32')'; - dime.scl_slope = fread(fid,1,'float32')'; - dime.scl_inter = fread(fid,1,'float32')'; - dime.slice_end = fread(fid,1,'int16')'; - dime.slice_code = fread(fid,1,'uchar')'; - dime.xyzt_units = fread(fid,1,'uchar')'; - dime.cal_max = fread(fid,1,'float32')'; - dime.cal_min = fread(fid,1,'float32')'; - dime.slice_duration = fread(fid,1,'float32')'; - dime.toffset = fread(fid,1,'float32')'; - dime.glmax = fread(fid,1,'int32')'; - dime.glmin = fread(fid,1,'int32')'; - - return % image_dimension - - -%--------------------------------------------------------------------- -function [ hist ] = data_history(fid) - - % Original header structures - % struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % short int qform_code; /* 104 + 2 */ - % short int sform_code; /* 106 + 2 */ - % float quatern_b; /* 108 + 4 */ - % float quatern_c; /* 112 + 4 */ - % float quatern_d; /* 116 + 4 */ - % float qoffset_x; /* 120 + 4 */ - % float qoffset_y; /* 124 + 4 */ - % float qoffset_z; /* 128 + 4 */ - % float srow_x[4]; /* 132 + 16 */ - % float srow_y[4]; /* 148 + 16 */ - % float srow_z[4]; /* 164 + 16 */ - % char intent_name[16]; /* 180 + 16 */ - % char magic[4]; % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hist.descrip = deblank(fread(fid,80,directchar)'); - hist.aux_file = deblank(fread(fid,24,directchar)'); - hist.qform_code = fread(fid,1,'int16')'; - hist.sform_code = fread(fid,1,'int16')'; - hist.quatern_b = fread(fid,1,'float32')'; - hist.quatern_c = fread(fid,1,'float32')'; - hist.quatern_d = fread(fid,1,'float32')'; - hist.qoffset_x = fread(fid,1,'float32')'; - hist.qoffset_y = fread(fid,1,'float32')'; - hist.qoffset_z = fread(fid,1,'float32')'; - hist.srow_x = fread(fid,4,'float32')'; - hist.srow_y = fread(fid,4,'float32')'; - hist.srow_z = fread(fid,4,'float32')'; - hist.intent_name = deblank(fread(fid,16,directchar)'); - hist.magic = deblank(fread(fid,4,directchar)'); - - fseek(fid,253,'bof'); - hist.originator = fread(fid, 5,'int16')'; - - return % data_history - diff --git a/func/utils/nii/load_nii_img.m b/func/utils/nii/load_nii_img.m deleted file mode 100644 index f0768d6..0000000 --- a/func/utils/nii/load_nii_img.m +++ /dev/null @@ -1,400 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function [img,hdr] = load_nii_img(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB) - - if ~exist('hdr','var') | ~exist('filetype','var') | ~exist('fileprefix','var') | ~exist('machine','var') - error('Usage: [img,hdr] = load_nii_img(hdr,filetype,fileprefix,machine,[img_idx],[dim5_idx],[dim6_idx],[dim7_idx],[old_RGB]);'); - end - - if ~exist('img_idx','var') | isempty(img_idx) | hdr.dime.dim(5)<1 - img_idx = []; - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) | hdr.dime.dim(6)<1 - dim5_idx = []; - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) | hdr.dime.dim(7)<1 - dim6_idx = []; - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) | hdr.dime.dim(8)<1 - dim7_idx = []; - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - % check img_idx - % - if ~isempty(img_idx) & ~isnumeric(img_idx) - error('"img_idx" should be a numerical array.'); - end - - if length(unique(img_idx)) ~= length(img_idx) - error('Duplicate image index in "img_idx"'); - end - - if ~isempty(img_idx) & (min(img_idx) < 1 | max(img_idx) > hdr.dime.dim(5)) - max_range = hdr.dime.dim(5); - - if max_range == 1 - error(['"img_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"img_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim5_idx - % - if ~isempty(dim5_idx) & ~isnumeric(dim5_idx) - error('"dim5_idx" should be a numerical array.'); - end - - if length(unique(dim5_idx)) ~= length(dim5_idx) - error('Duplicate index in "dim5_idx"'); - end - - if ~isempty(dim5_idx) & (min(dim5_idx) < 1 | max(dim5_idx) > hdr.dime.dim(6)) - max_range = hdr.dime.dim(6); - - if max_range == 1 - error(['"dim5_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim5_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim6_idx - % - if ~isempty(dim6_idx) & ~isnumeric(dim6_idx) - error('"dim6_idx" should be a numerical array.'); - end - - if length(unique(dim6_idx)) ~= length(dim6_idx) - error('Duplicate index in "dim6_idx"'); - end - - if ~isempty(dim6_idx) & (min(dim6_idx) < 1 | max(dim6_idx) > hdr.dime.dim(7)) - max_range = hdr.dime.dim(7); - - if max_range == 1 - error(['"dim6_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim6_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim7_idx - % - if ~isempty(dim7_idx) & ~isnumeric(dim7_idx) - error('"dim7_idx" should be a numerical array.'); - end - - if length(unique(dim7_idx)) ~= length(dim7_idx) - error('Duplicate index in "dim7_idx"'); - end - - if ~isempty(dim7_idx) & (min(dim7_idx) < 1 | max(dim7_idx) > hdr.dime.dim(8)) - max_range = hdr.dime.dim(8); - - if max_range == 1 - error(['"dim7_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim7_idx" should be an integer within the range of [' range '].']); - end - end - - [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB); - - return % load_nii_img - - -%--------------------------------------------------------------------- -function [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB) - - switch filetype - case {0, 1} - fn = [fileprefix '.img']; - case 2 - fn = [fileprefix '.nii']; - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - end - - % Set bitpix according to datatype - % - % /*Acceptable values for datatype are*/ - % - % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN - % 1 Binary (ubit1, bitpix=1) % DT_BINARY - % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 - % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 - % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 - % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 - % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 - % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 - % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 - % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 - % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 - % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 - % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 - % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 - % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 - % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 - % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % - switch hdr.dime.datatype - case 1, - hdr.dime.bitpix = 1; precision = 'ubit1'; - case 2, - hdr.dime.bitpix = 8; precision = 'uint8'; - case 4, - hdr.dime.bitpix = 16; precision = 'int16'; - case 8, - hdr.dime.bitpix = 32; precision = 'int32'; - case 16, - hdr.dime.bitpix = 32; precision = 'float32'; - case 32, - hdr.dime.bitpix = 64; precision = 'float32'; - case 64, - hdr.dime.bitpix = 64; precision = 'float64'; - case 128, - hdr.dime.bitpix = 24; precision = 'uint8'; - case 256 - hdr.dime.bitpix = 8; precision = 'int8'; - case 511 - hdr.dime.bitpix = 96; precision = 'float32'; - case 512 - hdr.dime.bitpix = 16; precision = 'uint16'; - case 768 - hdr.dime.bitpix = 32; precision = 'uint32'; - case 1024 - hdr.dime.bitpix = 64; precision = 'int64'; - case 1280 - hdr.dime.bitpix = 64; precision = 'uint64'; - case 1792, - hdr.dime.bitpix = 128; precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - - hdr.dime.dim(find(hdr.dime.dim < 1)) = 1; - - % move pointer to the start of image block - % - switch filetype - case {0, 1} - fseek(fid, 0, 'bof'); - case 2 - fseek(fid, hdr.dime.vox_offset, 'bof'); - end - - % Load whole image block for old Analyze format or binary image; - % otherwise, load images that are specified in img_idx, dim5_idx, - % dim6_idx, and dim7_idx - % - % For binary image, we have to read all because pos can not be - % seeked in bit and can not be calculated the way below. - % - if hdr.dime.datatype == 1 | isequal(hdr.dime.dim(5:8),ones(1,4)) | ... - (isempty(img_idx) & isempty(dim5_idx) & isempty(dim6_idx) & isempty(dim7_idx)) - - % For each frame, precision of value will be read - % in img_siz times, where img_siz is only the - % dimension size of an image, not the byte storage - % size of an image. - % - img_siz = prod(hdr.dime.dim(2:8)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - - img = fread(fid, img_siz, sprintf('*%s',precision)); - - d1 = hdr.dime.dim(2); - d2 = hdr.dime.dim(3); - d3 = hdr.dime.dim(4); - d4 = hdr.dime.dim(5); - d5 = hdr.dime.dim(6); - d6 = hdr.dime.dim(7); - d7 = hdr.dime.dim(8); - - if isempty(img_idx) - img_idx = 1:d4; - end - - if isempty(dim5_idx) - dim5_idx = 1:d5; - end - - if isempty(dim6_idx) - dim6_idx = 1:d6; - end - - if isempty(dim7_idx) - dim7_idx = 1:d7; - end - else - - d1 = hdr.dime.dim(2); - d2 = hdr.dime.dim(3); - d3 = hdr.dime.dim(4); - d4 = hdr.dime.dim(5); - d5 = hdr.dime.dim(6); - d6 = hdr.dime.dim(7); - d7 = hdr.dime.dim(8); - - if isempty(img_idx) - img_idx = 1:d4; - end - - if isempty(dim5_idx) - dim5_idx = 1:d5; - end - - if isempty(dim6_idx) - dim6_idx = 1:d6; - end - - if isempty(dim7_idx) - dim7_idx = 1:d7; - end - - % compute size of one image - % - img_siz = prod(hdr.dime.dim(2:4)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - - % preallocate img - img = zeros(img_siz, length(img_idx)*length(dim5_idx)*length(dim6_idx)*length(dim7_idx) ); - currentIndex = 1; - - for i7=1:length(dim7_idx) - for i6=1:length(dim6_idx) - for i5=1:length(dim5_idx) - for t=1:length(img_idx) - - % Position is seeked in bytes. To convert dimension size - % to byte storage size, hdr.dime.bitpix/8 will be - % applied. - % - pos = sub2ind([d1 d2 d3 d4 d5 d6 d7], 1, 1, 1, ... - img_idx(t), dim5_idx(i5),dim6_idx(i6),dim7_idx(i7)) -1; - pos = pos * hdr.dime.bitpix/8; - - if filetype == 2 - fseek(fid, pos + hdr.dime.vox_offset, 'bof'); - else - fseek(fid, pos, 'bof'); - end - - % For each frame, fread will read precision of value - % in img_siz times - % - img(:,currentIndex) = fread(fid, img_siz, sprintf('*%s',precision)); - currentIndex = currentIndex +1; - - end - end - end - end - end - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img = reshape(img, [2, length(img)/2]); - img = complex(img(1,:)', img(2,:)'); - end - - fclose(fid); - - % Update the global min and max values - % - hdr.dime.glmax = double(max(img(:))); - hdr.dime.glmin = double(min(img(:))); - - % old_RGB treat RGB slice by slice, now it is treated voxel by voxel - % - if old_RGB & hdr.dime.datatype == 128 & hdr.dime.bitpix == 24 - % remove squeeze - img = (reshape(img, [hdr.dime.dim(2:3) 3 hdr.dime.dim(4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [1 2 4 3 5 6 7 8]); - elseif hdr.dime.datatype == 128 & hdr.dime.bitpix == 24 - % remove squeeze - img = (reshape(img, [3 hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [2 3 4 1 5 6 7 8]); - elseif hdr.dime.datatype == 511 & hdr.dime.bitpix == 96 - img = double(img(:)); - img = single((img - min(img))/(max(img) - min(img))); - % remove squeeze - img = (reshape(img, [3 hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [2 3 4 1 5 6 7 8]); - else - % remove squeeze - - % keyboard - try - img = (reshape(img, [hdr.dime.dim(2:4) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - catch - img = (reshape(img, [hdr.dime.dim(2:4) 1 length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - - end; - - end - - if ~isempty(img_idx) - hdr.dime.dim(5) = length(img_idx); - end - - if ~isempty(dim5_idx) - hdr.dime.dim(6) = length(dim5_idx); - end - - if ~isempty(dim6_idx) - hdr.dime.dim(7) = length(dim6_idx); - end - - if ~isempty(dim7_idx) - hdr.dime.dim(8) = length(dim7_idx); - end - - return % read_image - diff --git a/func/utils/nii/load_untouch0_nii_hdr.m b/func/utils/nii/load_untouch0_nii_hdr.m deleted file mode 100644 index 20335cb..0000000 --- a/func/utils/nii/load_untouch0_nii_hdr.m +++ /dev/null @@ -1,200 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function hdr = load_nii_hdr(fileprefix, machine) - - fn = sprintf('%s.hdr',fileprefix); - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - hdr = read_header(fid); - fclose(fid); - end - - return % load_nii_hdr - - -%--------------------------------------------------------------------- -function [ dsr ] = read_header(fid) - - % Original header structures - % struct dsr - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - dsr.hk = header_key(fid); - dsr.dime = image_dimension(fid); - dsr.hist = data_history(fid); - - return % read_header - - -%--------------------------------------------------------------------- -function [ hk ] = header_key(fid) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - % - % int sizeof_header Should be 348. - % char regular Must be 'r' to indicate that all images and - % volumes are the same size. - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! - hk.data_type = deblank(fread(fid,10,directchar)'); - hk.db_name = deblank(fread(fid,18,directchar)'); - hk.extents = fread(fid, 1,'int32')'; - hk.session_error = fread(fid, 1,'int16')'; - hk.regular = fread(fid, 1,directchar)'; - hk.hkey_un0 = fread(fid, 1,directchar)'; - - return % header_key - - -%--------------------------------------------------------------------- -function [ dime ] = image_dimension(fid) - - %struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % /* - % dim[0] Number of dimensions in database; usually 4. - % dim[1] Image X dimension; number of *pixels* in an image row. - % dim[2] Image Y dimension; number of *pixel rows* in slice. - % dim[3] Volume Z dimension; number of *slices* in a volume. - % dim[4] Time points; number of volumes in database - % */ - % char vox_units[4]; /* 16 + 4 */ - % char cal_units[8]; /* 20 + 8 */ - % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width, mm - % pixdim[2] - voxel height, mm - % pixdim[3] - slice thickness, mm - % pixdim[4] - volume timing, in msec - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float roi_scale; /* 72 + 4 */ - % float funused1; /* 76 + 4 */ - % float funused2; /* 80 + 4 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % int compressed; /* 92 + 4 */ - % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - dime.dim = fread(fid,8,'int16')'; - dime.vox_units = deblank(fread(fid,4,directchar)'); - dime.cal_units = deblank(fread(fid,8,directchar)'); - dime.unused1 = fread(fid,1,'int16')'; - dime.datatype = fread(fid,1,'int16')'; - dime.bitpix = fread(fid,1,'int16')'; - dime.dim_un0 = fread(fid,1,'int16')'; - dime.pixdim = fread(fid,8,'float32')'; - dime.vox_offset = fread(fid,1,'float32')'; - dime.roi_scale = fread(fid,1,'float32')'; - dime.funused1 = fread(fid,1,'float32')'; - dime.funused2 = fread(fid,1,'float32')'; - dime.cal_max = fread(fid,1,'float32')'; - dime.cal_min = fread(fid,1,'float32')'; - dime.compressed = fread(fid,1,'int32')'; - dime.verified = fread(fid,1,'int32')'; - dime.glmax = fread(fid,1,'int32')'; - dime.glmin = fread(fid,1,'int32')'; - - return % image_dimension - - -%--------------------------------------------------------------------- -function [ hist ] = data_history(fid) - - %struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % char orient; /* 104 + 1 */ - % char originator[10]; /* 105 + 10 */ - % char generated[10]; /* 115 + 10 */ - % char scannum[10]; /* 125 + 10 */ - % char patient_id[10]; /* 135 + 10 */ - % char exp_date[10]; /* 145 + 10 */ - % char exp_time[10]; /* 155 + 10 */ - % char hist_un0[3]; /* 165 + 3 */ - % int views /* 168 + 4 */ - % int vols_added; /* 172 + 4 */ - % int start_field; /* 176 + 4 */ - % int field_skip; /* 180 + 4 */ - % int omax; /* 184 + 4 */ - % int omin; /* 188 + 4 */ - % int smax; /* 192 + 4 */ - % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hist.descrip = deblank(fread(fid,80,directchar)'); - hist.aux_file = deblank(fread(fid,24,directchar)'); - hist.orient = fread(fid, 1,'char')'; - hist.originator = fread(fid, 5,'int16')'; - hist.generated = deblank(fread(fid,10,directchar)'); - hist.scannum = deblank(fread(fid,10,directchar)'); - hist.patient_id = deblank(fread(fid,10,directchar)'); - hist.exp_date = deblank(fread(fid,10,directchar)'); - hist.exp_time = deblank(fread(fid,10,directchar)'); - hist.hist_un0 = deblank(fread(fid, 3,directchar)'); - hist.views = fread(fid, 1,'int32')'; - hist.vols_added = fread(fid, 1,'int32')'; - hist.start_field = fread(fid, 1,'int32')'; - hist.field_skip = fread(fid, 1,'int32')'; - hist.omax = fread(fid, 1,'int32')'; - hist.omin = fread(fid, 1,'int32')'; - hist.smax = fread(fid, 1,'int32')'; - hist.smin = fread(fid, 1,'int32')'; - - return % data_history - diff --git a/func/utils/nii/load_untouch_header_only.m b/func/utils/nii/load_untouch_header_only.m deleted file mode 100644 index 3231db0..0000000 --- a/func/utils/nii/load_untouch_header_only.m +++ /dev/null @@ -1,187 +0,0 @@ -% Load NIfTI / Analyze header without applying any appropriate affine -% geometric transform or voxel intensity scaling. It is equivalent to -% hdr field when using load_untouch_nii to load dataset. Support both -% *.nii and *.hdr file extension. If file extension is not provided, -% *.hdr will be used as default. -% -% Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename) -% -% filename - NIfTI / Analyze file name. -% -% Returned values: -% -% header - struct with NIfTI / Analyze header fields. -% -% ext - NIfTI extension if it is not empty. -% -% filetype - 0 for Analyze format (*.hdr/*.img); -% 1 for NIFTI format in 2 files (*.hdr/*.img); -% 2 for NIFTI format in 1 file (*.nii). -% -% machine - a string, see below for details. The default here is 'ieee-le'. -% -% 'native' or 'n' - local machine format - the default -% 'ieee-le' or 'l' - IEEE floating point with little-endian -% byte ordering -% 'ieee-be' or 'b' - IEEE floating point with big-endian -% byte ordering -% 'vaxd' or 'd' - VAX D floating point and VAX ordering -% 'vaxg' or 'g' - VAX G floating point and VAX ordering -% 'cray' or 'c' - Cray floating point with big-endian -% byte ordering -% 'ieee-le.l64' or 'a' - IEEE floating point with little-endian -% byte ordering and 64 bit long data type -% 'ieee-be.l64' or 's' - IEEE floating point with big-endian byte -% ordering and 64 bit long data type. -% -% Part of this file is copied and modified from: -% http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function [hdr, ext, filetype, machine] = load_untouch_header_only(filename) - - if ~exist('filename','var') - error('Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename)'); - end - - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - % Read the dataset header - % - [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename); - - if filetype == 0 - hdr = load_untouch0_nii_hdr(fileprefix, machine); - ext = []; - else - hdr = load_untouch_nii_hdr(fileprefix, machine, filetype); - - % Read the header extension - % - ext = load_nii_ext(filename); - end - - % Set bitpix according to datatype - % - % /*Acceptable values for datatype are*/ - % - % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN - % 1 Binary (ubit1, bitpix=1) % DT_BINARY - % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 - % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 - % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 - % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 - % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 - % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 - % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 - % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 - % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 - % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 - % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 - % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 - % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 - % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 - % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % - switch hdr.dime.datatype - case 1, - hdr.dime.bitpix = 1; precision = 'ubit1'; - case 2, - hdr.dime.bitpix = 8; precision = 'uint8'; - case 4, - hdr.dime.bitpix = 16; precision = 'int16'; - case 8, - hdr.dime.bitpix = 32; precision = 'int32'; - case 16, - hdr.dime.bitpix = 32; precision = 'float32'; - case 32, - hdr.dime.bitpix = 64; precision = 'float32'; - case 64, - hdr.dime.bitpix = 64; precision = 'float64'; - case 128, - hdr.dime.bitpix = 24; precision = 'uint8'; - case 256 - hdr.dime.bitpix = 8; precision = 'int8'; - case 511 - hdr.dime.bitpix = 96; precision = 'float32'; - case 512 - hdr.dime.bitpix = 16; precision = 'uint16'; - case 768 - hdr.dime.bitpix = 32; precision = 'uint32'; - case 1024 - hdr.dime.bitpix = 64; precision = 'int64'; - case 1280 - hdr.dime.bitpix = 64; precision = 'uint64'; - case 1792, - hdr.dime.bitpix = 128; precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - - tmp = hdr.dime.dim(2:end); - tmp(find(tmp < 1)) = 1; - hdr.dime.dim(2:end) = tmp; - - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - rmdir(tmpDir,'s'); - end - - - return % load_untouch_header_only - diff --git a/func/utils/nii/load_untouch_nii.m b/func/utils/nii/load_untouch_nii.m deleted file mode 100644 index 42fa763..0000000 --- a/func/utils/nii/load_untouch_nii.m +++ /dev/null @@ -1,191 +0,0 @@ -% Load NIFTI or ANALYZE dataset, but not applying any appropriate affine -% geometric transform or voxel intensity scaling. -% -% Although according to NIFTI website, all those header information are -% supposed to be applied to the loaded NIFTI image, there are some -% situations that people do want to leave the original NIFTI header and -% data untouched. They will probably just use MATLAB to do certain image -% processing regardless of image orientation, and to save data back with -% the same NIfTI header. -% -% Since this program is only served for those situations, please use it -% together with "save_untouch_nii.m", and do not use "save_nii.m" or -% "view_nii.m" for the data that is loaded by "load_untouch_nii.m". For -% normal situation, you should use "load_nii.m" instead. -% -% Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... -% [dim7_idx], [old_RGB], [slice_idx]) -% -% filename - NIFTI or ANALYZE file name. -% -% img_idx (optional) - a numerical array of image volume indices. -% Only the specified volumes will be loaded. All available image -% volumes will be loaded, if it is default or empty. -% -% The number of images scans can be obtained from get_nii_frame.m, -% or simply: hdr.dime.dim(5). -% -% dim5_idx (optional) - a numerical array of 5th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% dim6_idx (optional) - a numerical array of 6th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% dim7_idx (optional) - a numerical array of 7th dimension indices. -% Only the specified range will be loaded. All available range -% will be loaded, if it is default or empty. -% -% old_RGB (optional) - a scale number to tell difference of new RGB24 -% from old RGB24. New RGB24 uses RGB triple sequentially for each -% voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect -% uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for -% each slices. If the image that you view is garbled, try to set -% old_RGB variable to 1 and try again, because it could be in -% old RGB24. It will be set to 0, if it is default or empty. -% -% slice_idx (optional) - a numerical array of image slice indices. -% Only the specified slices will be loaded. All available image -% slices will be loaded, if it is default or empty. -% -% Returned values: -% -% nii structure: -% -% hdr - struct with NIFTI header fields. -% -% filetype - Analyze format .hdr/.img (0); -% NIFTI .hdr/.img (1); -% NIFTI .nii (2) -% -% fileprefix - NIFTI filename without extension. -% -% machine - machine string variable. -% -% img - 3D (or 4D) matrix of NIFTI data. -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function nii = load_untouch_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... - old_RGB, slice_idx) - - if ~exist('filename','var') - error('Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [slice_idx])'); - end - - if ~exist('img_idx','var') | isempty(img_idx) - img_idx = []; - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) - dim5_idx = []; - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) - dim6_idx = []; - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) - dim7_idx = []; - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - if ~exist('slice_idx','var') | isempty(slice_idx) - slice_idx = []; - end - - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - % Read the dataset header - % - [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); - - if nii.filetype == 0 - nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine); - nii.ext = []; - else - nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype); - - % Read the header extension - % - nii.ext = load_nii_ext(filename); - end - - % Read the dataset body - % - [nii.img,nii.hdr] = load_untouch_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... - nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx); - - % Perform some of sform/qform transform - % -% nii = xform_nii(nii, tolerance, preferredForm); - - nii.untouch = 1; - - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - - % fix fileprefix so it doesn't point to temp location - % - nii.fileprefix = gzFileName(1:end-7); - rmdir(tmpDir,'s'); - end - - - return % load_untouch_nii - diff --git a/func/utils/nii/load_untouch_nii_hdr.m b/func/utils/nii/load_untouch_nii_hdr.m deleted file mode 100644 index ee91caf..0000000 --- a/func/utils/nii/load_untouch_nii_hdr.m +++ /dev/null @@ -1,217 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function hdr = load_nii_hdr(fileprefix, machine, filetype) - - if filetype == 2 - fn = sprintf('%s.nii',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.nii".', fileprefix); - error(msg); - end - else - fn = sprintf('%s.hdr',fileprefix); - - if ~exist(fn) - msg = sprintf('Cannot find file "%s.hdr".', fileprefix); - error(msg); - end - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - else - fseek(fid,0,'bof'); - hdr = read_header(fid); - fclose(fid); - end - - return % load_nii_hdr - - -%--------------------------------------------------------------------- -function [ dsr ] = read_header(fid) - - % Original header structures - % struct dsr - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - dsr.hk = header_key(fid); - dsr.dime = image_dimension(fid); - dsr.hist = data_history(fid); - - % For Analyze data format - % - if ~strcmp(dsr.hist.magic, 'n+1') & ~strcmp(dsr.hist.magic, 'ni1') - dsr.hist.qform_code = 0; - dsr.hist.sform_code = 0; - end - - return % read_header - - -%--------------------------------------------------------------------- -function [ hk ] = header_key(fid) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char dim_info; % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - % - % int sizeof_header Should be 348. - % char regular Must be 'r' to indicate that all images and - % volumes are the same size. - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hk.sizeof_hdr = fread(fid, 1,'int32')'; % should be 348! - hk.data_type = deblank(fread(fid,10,directchar)'); - hk.db_name = deblank(fread(fid,18,directchar)'); - hk.extents = fread(fid, 1,'int32')'; - hk.session_error = fread(fid, 1,'int16')'; - hk.regular = fread(fid, 1,directchar)'; - hk.dim_info = fread(fid, 1,'uchar')'; - - return % header_key - - -%--------------------------------------------------------------------- -function [ dime ] = image_dimension(fid) - - % Original header structures - % struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % /* - % dim[0] Number of dimensions in database; usually 4. - % dim[1] Image X dimension; number of *pixels* in an image row. - % dim[2] Image Y dimension; number of *pixel rows* in slice. - % dim[3] Volume Z dimension; number of *slices* in a volume. - % dim[4] Time points; number of volumes in database - % */ - % float intent_p1; % char vox_units[4]; /* 16 + 4 */ - % float intent_p2; % char cal_units[8]; /* 20 + 4 */ - % float intent_p3; % char cal_units[8]; /* 24 + 4 */ - % short int intent_code; % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int slice_start; % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width, mm - % pixdim[2] - voxel height, mm - % pixdim[3] - slice thickness, mm - % pixdim[4] - volume timing, in msec - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float scl_slope; % float roi_scale; /* 72 + 4 */ - % float scl_inter; % float funused1; /* 76 + 4 */ - % short slice_end; % float funused2; /* 80 + 2 */ - % char slice_code; % float funused2; /* 82 + 1 */ - % char xyzt_units; % float funused2; /* 83 + 1 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % float slice_duration; % int compressed; /* 92 + 4 */ - % float toffset; % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - dime.dim = fread(fid,8,'int16')'; - dime.intent_p1 = fread(fid,1,'float32')'; - dime.intent_p2 = fread(fid,1,'float32')'; - dime.intent_p3 = fread(fid,1,'float32')'; - dime.intent_code = fread(fid,1,'int16')'; - dime.datatype = fread(fid,1,'int16')'; - dime.bitpix = fread(fid,1,'int16')'; - dime.slice_start = fread(fid,1,'int16')'; - dime.pixdim = fread(fid,8,'float32')'; - dime.vox_offset = fread(fid,1,'float32')'; - dime.scl_slope = fread(fid,1,'float32')'; - dime.scl_inter = fread(fid,1,'float32')'; - dime.slice_end = fread(fid,1,'int16')'; - dime.slice_code = fread(fid,1,'uchar')'; - dime.xyzt_units = fread(fid,1,'uchar')'; - dime.cal_max = fread(fid,1,'float32')'; - dime.cal_min = fread(fid,1,'float32')'; - dime.slice_duration = fread(fid,1,'float32')'; - dime.toffset = fread(fid,1,'float32')'; - dime.glmax = fread(fid,1,'int32')'; - dime.glmin = fread(fid,1,'int32')'; - - return % image_dimension - - -%--------------------------------------------------------------------- -function [ hist ] = data_history(fid) - - % Original header structures - % struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % short int qform_code; /* 104 + 2 */ - % short int sform_code; /* 106 + 2 */ - % float quatern_b; /* 108 + 4 */ - % float quatern_c; /* 112 + 4 */ - % float quatern_d; /* 116 + 4 */ - % float qoffset_x; /* 120 + 4 */ - % float qoffset_y; /* 124 + 4 */ - % float qoffset_z; /* 128 + 4 */ - % float srow_x[4]; /* 132 + 16 */ - % float srow_y[4]; /* 148 + 16 */ - % float srow_z[4]; /* 164 + 16 */ - % char intent_name[16]; /* 180 + 16 */ - % char magic[4]; % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - v6 = version; - if str2num(v6(1))<6 - directchar = '*char'; - else - directchar = 'uchar=>char'; - end - - hist.descrip = deblank(fread(fid,80,directchar)'); - hist.aux_file = deblank(fread(fid,24,directchar)'); - hist.qform_code = fread(fid,1,'int16')'; - hist.sform_code = fread(fid,1,'int16')'; - hist.quatern_b = fread(fid,1,'float32')'; - hist.quatern_c = fread(fid,1,'float32')'; - hist.quatern_d = fread(fid,1,'float32')'; - hist.qoffset_x = fread(fid,1,'float32')'; - hist.qoffset_y = fread(fid,1,'float32')'; - hist.qoffset_z = fread(fid,1,'float32')'; - hist.srow_x = fread(fid,4,'float32')'; - hist.srow_y = fread(fid,4,'float32')'; - hist.srow_z = fread(fid,4,'float32')'; - hist.intent_name = deblank(fread(fid,16,directchar)'); - hist.magic = deblank(fread(fid,4,directchar)'); - - return % data_history - diff --git a/func/utils/nii/load_untouch_nii_img.m b/func/utils/nii/load_untouch_nii_img.m deleted file mode 100644 index fc48306..0000000 --- a/func/utils/nii/load_untouch_nii_img.m +++ /dev/null @@ -1,475 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function [img,hdr] = load_untouch_nii_img(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx) - - if ~exist('hdr','var') | ~exist('filetype','var') | ~exist('fileprefix','var') | ~exist('machine','var') - error('Usage: [img,hdr] = load_nii_img(hdr,filetype,fileprefix,machine,[img_idx],[dim5_idx],[dim6_idx],[dim7_idx],[old_RGB],[slice_idx]);'); - end - - if ~exist('img_idx','var') | isempty(img_idx) | hdr.dime.dim(5)<1 - img_idx = []; - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) | hdr.dime.dim(6)<1 - dim5_idx = []; - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) | hdr.dime.dim(7)<1 - dim6_idx = []; - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) | hdr.dime.dim(8)<1 - dim7_idx = []; - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - if ~exist('slice_idx','var') | isempty(slice_idx) | hdr.dime.dim(4)<1 - slice_idx = []; - end - - % check img_idx - % - if ~isempty(img_idx) & ~isnumeric(img_idx) - error('"img_idx" should be a numerical array.'); - end - - if length(unique(img_idx)) ~= length(img_idx) - error('Duplicate image index in "img_idx"'); - end - - if ~isempty(img_idx) & (min(img_idx) < 1 | max(img_idx) > hdr.dime.dim(5)) - max_range = hdr.dime.dim(5); - - if max_range == 1 - error(['"img_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"img_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim5_idx - % - if ~isempty(dim5_idx) & ~isnumeric(dim5_idx) - error('"dim5_idx" should be a numerical array.'); - end - - if length(unique(dim5_idx)) ~= length(dim5_idx) - error('Duplicate index in "dim5_idx"'); - end - - if ~isempty(dim5_idx) & (min(dim5_idx) < 1 | max(dim5_idx) > hdr.dime.dim(6)) - max_range = hdr.dime.dim(6); - - if max_range == 1 - error(['"dim5_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim5_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim6_idx - % - if ~isempty(dim6_idx) & ~isnumeric(dim6_idx) - error('"dim6_idx" should be a numerical array.'); - end - - if length(unique(dim6_idx)) ~= length(dim6_idx) - error('Duplicate index in "dim6_idx"'); - end - - if ~isempty(dim6_idx) & (min(dim6_idx) < 1 | max(dim6_idx) > hdr.dime.dim(7)) - max_range = hdr.dime.dim(7); - - if max_range == 1 - error(['"dim6_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim6_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim7_idx - % - if ~isempty(dim7_idx) & ~isnumeric(dim7_idx) - error('"dim7_idx" should be a numerical array.'); - end - - if length(unique(dim7_idx)) ~= length(dim7_idx) - error('Duplicate index in "dim7_idx"'); - end - - if ~isempty(dim7_idx) & (min(dim7_idx) < 1 | max(dim7_idx) > hdr.dime.dim(8)) - max_range = hdr.dime.dim(8); - - if max_range == 1 - error(['"dim7_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim7_idx" should be an integer within the range of [' range '].']); - end - end - - % check slice_idx - % - if ~isempty(slice_idx) & ~isnumeric(slice_idx) - error('"slice_idx" should be a numerical array.'); - end - - if length(unique(slice_idx)) ~= length(slice_idx) - error('Duplicate index in "slice_idx"'); - end - - if ~isempty(slice_idx) & (min(slice_idx) < 1 | max(slice_idx) > hdr.dime.dim(4)) - max_range = hdr.dime.dim(4); - - if max_range == 1 - error(['"slice_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"slice_idx" should be an integer within the range of [' range '].']); - end - end - - [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx); - - return % load_nii_img - - -%--------------------------------------------------------------------- -function [img,hdr] = read_image(hdr,filetype,fileprefix,machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx) - - switch filetype - case {0, 1} - fn = [fileprefix '.img']; - case 2 - fn = [fileprefix '.nii']; - end - - fid = fopen(fn,'r',machine); - - if fid < 0, - msg = sprintf('Cannot open file %s.',fn); - error(msg); - end - - % Set bitpix according to datatype - % - % /*Acceptable values for datatype are*/ - % - % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN - % 1 Binary (ubit1, bitpix=1) % DT_BINARY - % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 - % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 - % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 - % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 - % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 - % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 - % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 - % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 - % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 - % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 - % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 - % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 - % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 - % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 - % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % - switch hdr.dime.datatype - case 1, - hdr.dime.bitpix = 1; precision = 'ubit1'; - case 2, - hdr.dime.bitpix = 8; precision = 'uint8'; - case 4, - hdr.dime.bitpix = 16; precision = 'int16'; - case 8, - hdr.dime.bitpix = 32; precision = 'int32'; - case 16, - hdr.dime.bitpix = 32; precision = 'float32'; - case 32, - hdr.dime.bitpix = 64; precision = 'float32'; - case 64, - hdr.dime.bitpix = 64; precision = 'float64'; - case 128, - hdr.dime.bitpix = 24; precision = 'uint8'; - case 256 - hdr.dime.bitpix = 8; precision = 'int8'; - case 511 - hdr.dime.bitpix = 96; precision = 'float32'; - case 512 - hdr.dime.bitpix = 16; precision = 'uint16'; - case 768 - hdr.dime.bitpix = 32; precision = 'uint32'; - case 1024 - hdr.dime.bitpix = 64; precision = 'int64'; - case 1280 - hdr.dime.bitpix = 64; precision = 'uint64'; - case 1792, - hdr.dime.bitpix = 128; precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - - tmp = hdr.dime.dim(2:end); - tmp(find(tmp < 1)) = 1; - hdr.dime.dim(2:end) = tmp; - - % move pointer to the start of image block - % - switch filetype - case {0, 1} - fseek(fid, 0, 'bof'); - case 2 - fseek(fid, hdr.dime.vox_offset, 'bof'); - end - - % Load whole image block for old Analyze format or binary image; - % otherwise, load images that are specified in img_idx, dim5_idx, - % dim6_idx, and dim7_idx - % - % For binary image, we have to read all because pos can not be - % seeked in bit and can not be calculated the way below. - % - if hdr.dime.datatype == 1 | isequal(hdr.dime.dim(4:8),ones(1,5)) | ... - (isempty(img_idx) & isempty(dim5_idx) & isempty(dim6_idx) & isempty(dim7_idx) & isempty(slice_idx)) - - % For each frame, precision of value will be read - % in img_siz times, where img_siz is only the - % dimension size of an image, not the byte storage - % size of an image. - % - img_siz = prod(hdr.dime.dim(2:8)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - - img = fread(fid, img_siz, sprintf('*%s',precision)); - - d1 = hdr.dime.dim(2); - d2 = hdr.dime.dim(3); - d3 = hdr.dime.dim(4); - d4 = hdr.dime.dim(5); - d5 = hdr.dime.dim(6); - d6 = hdr.dime.dim(7); - d7 = hdr.dime.dim(8); - - if isempty(slice_idx) - slice_idx = 1:d3; - end - - if isempty(img_idx) - img_idx = 1:d4; - end - - if isempty(dim5_idx) - dim5_idx = 1:d5; - end - - if isempty(dim6_idx) - dim6_idx = 1:d6; - end - - if isempty(dim7_idx) - dim7_idx = 1:d7; - end - else - - d1 = hdr.dime.dim(2); - d2 = hdr.dime.dim(3); - d3 = hdr.dime.dim(4); - d4 = hdr.dime.dim(5); - d5 = hdr.dime.dim(6); - d6 = hdr.dime.dim(7); - d7 = hdr.dime.dim(8); - - if isempty(slice_idx) - slice_idx = 1:d3; - end - - if isempty(img_idx) - img_idx = 1:d4; - end - - if isempty(dim5_idx) - dim5_idx = 1:d5; - end - - if isempty(dim6_idx) - dim6_idx = 1:d6; - end - - if isempty(dim7_idx) - dim7_idx = 1:d7; - end - - %ROMAN: begin - roman = 1; - if(roman) - - % compute size of one slice - % - img_siz = prod(hdr.dime.dim(2:3)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - - % preallocate img - img = zeros(img_siz, length(slice_idx)*length(img_idx)*length(dim5_idx)*length(dim6_idx)*length(dim7_idx) ); - currentIndex = 1; - else - img = []; - end; %if(roman) - % ROMAN: end - - for i7=1:length(dim7_idx) - for i6=1:length(dim6_idx) - for i5=1:length(dim5_idx) - for t=1:length(img_idx) - for s=1:length(slice_idx) - - % Position is seeked in bytes. To convert dimension size - % to byte storage size, hdr.dime.bitpix/8 will be - % applied. - % - pos = sub2ind([d1 d2 d3 d4 d5 d6 d7], 1, 1, slice_idx(s), ... - img_idx(t), dim5_idx(i5),dim6_idx(i6),dim7_idx(i7)) -1; - pos = pos * hdr.dime.bitpix/8; - - % ROMAN: begin - if(roman) - % do nothing - else - img_siz = prod(hdr.dime.dim(2:3)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - end; % if (roman) - % ROMAN: end - - if filetype == 2 - fseek(fid, pos + hdr.dime.vox_offset, 'bof'); - else - fseek(fid, pos, 'bof'); - end - - % For each frame, fread will read precision of value - % in img_siz times - % - % ROMAN: begin - if(roman) - img(:,currentIndex) = fread(fid, img_siz, sprintf('*%s',precision)); - currentIndex = currentIndex +1; - else - img = [img fread(fid, img_siz, sprintf('*%s',precision))]; - end; %if(roman) - % ROMAN: end - - end - end - end - end - end - end - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img = reshape(img, [2, length(img)/2]); - img = complex(img(1,:)', img(2,:)'); - end - - fclose(fid); - - % Update the global min and max values - % - hdr.dime.glmax = double(max(img(:))); - hdr.dime.glmin = double(min(img(:))); - - % old_RGB treat RGB slice by slice, now it is treated voxel by voxel - % - if old_RGB & hdr.dime.datatype == 128 & hdr.dime.bitpix == 24 - % remove squeeze - img = (reshape(img, [hdr.dime.dim(2:3) 3 length(slice_idx) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [1 2 4 3 5 6 7 8]); - elseif hdr.dime.datatype == 128 & hdr.dime.bitpix == 24 - % remove squeeze - img = (reshape(img, [3 hdr.dime.dim(2:3) length(slice_idx) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [2 3 4 1 5 6 7 8]); - elseif hdr.dime.datatype == 511 & hdr.dime.bitpix == 96 - img = double(img(:)); - img = single((img - min(img))/(max(img) - min(img))); - % remove squeeze - img = (reshape(img, [3 hdr.dime.dim(2:3) length(slice_idx) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - img = permute(img, [2 3 4 1 5 6 7 8]); - else - % remove squeeze -% keyboard - try - img = (reshape(img, [hdr.dime.dim(2:3) length(slice_idx) length(img_idx) length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - catch - img = (reshape(img, [hdr.dime.dim(2:3) length(slice_idx) 1 length(dim5_idx) length(dim6_idx) length(dim7_idx)])); - - end; - - end - - if ~isempty(slice_idx) - hdr.dime.dim(4) = length(slice_idx); - end - - if ~isempty(img_idx) - hdr.dime.dim(5) = length(img_idx); - end - - if ~isempty(dim5_idx) - hdr.dime.dim(6) = length(dim5_idx); - end - - if ~isempty(dim6_idx) - hdr.dime.dim(7) = length(dim6_idx); - end - - if ~isempty(dim7_idx) - hdr.dime.dim(8) = length(dim7_idx); - end - - return % read_image - diff --git a/func/utils/nii/make_ana.m b/func/utils/nii/make_ana.m deleted file mode 100644 index 3febf85..0000000 --- a/func/utils/nii/make_ana.m +++ /dev/null @@ -1,210 +0,0 @@ -% Make ANALYZE 7.5 data structure specified by a 3D or 4D matrix. -% Optional parameters can also be included, such as: voxel_size, -% origin, datatype, and description. -% -% Once the ANALYZE structure is made, it can be saved into ANALYZE 7.5 -% format data file using "save_untouch_nii" command (for more detail, -% type: help save_untouch_nii). -% -% Usage: ana = make_ana(img, [voxel_size], [origin], [datatype], [description]) -% -% Where: -% -% img: a 3D matrix [x y z], or a 4D matrix with time -% series [x y z t]. When image is in RGB format, -% make sure that the size of 4th dimension is -% always 3 (i.e. [R G B]). In that case, make -% sure that you must specify RGB datatype to 128. -% -% voxel_size (optional): Voxel size in millimeter for each -% dimension. Default is [1 1 1]. -% -% origin (optional): The AC origin. Default is [0 0 0]. -% -% datatype (optional): Storage data type: -% 2 - uint8, 4 - int16, 8 - int32, 16 - float32, -% 64 - float64, 128 - RGB24 -% Default will use the data type of 'img' matrix -% For RGB image, you must specify it to 128. -% -% description (optional): Description of data. Default is ''. -% -% e.g.: -% origin = [33 44 13]; datatype = 64; -% ana = make_ana(img, [], origin, datatype); % default voxel_size -% -% ANALYZE 7.5 format: http://www.rotman-baycrest.on.ca/~jimmy/ANALYZE75.pdf -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function ana = make_ana(varargin) - - ana.img = varargin{1}; - dims = size(ana.img); - dims = [4 dims ones(1,8)]; - dims = dims(1:8); - - voxel_size = [0 ones(1,3) zeros(1,4)]; - origin = zeros(1,5); - descrip = ''; - - switch class(ana.img) - case 'uint8' - datatype = 2; - case 'int16' - datatype = 4; - case 'int32' - datatype = 8; - case 'single' - datatype = 16; - case 'double' - datatype = 64; - otherwise - error('Datatype is not supported by make_ana.'); - end - - if nargin > 1 & ~isempty(varargin{2}) - voxel_size(2:4) = double(varargin{2}); - end - - if nargin > 2 & ~isempty(varargin{3}) - origin(1:3) = double(varargin{3}); - end - - if nargin > 3 & ~isempty(varargin{4}) - datatype = double(varargin{4}); - - if datatype == 128 | datatype == 511 - dims(5) = []; - dims = [dims 1]; - end - end - - if nargin > 4 & ~isempty(varargin{5}) - descrip = varargin{5}; - end - - if ndims(ana.img) > 4 - error('NIfTI only allows a maximum of 4 Dimension matrix.'); - end - - maxval = round(double(max(ana.img(:)))); - minval = round(double(min(ana.img(:)))); - - ana.hdr = make_header(dims, voxel_size, origin, datatype, ... - descrip, maxval, minval); - ana.filetype = 0; - ana.ext = []; - ana.untouch = 1; - - switch ana.hdr.dime.datatype - case 2 - ana.img = uint8(ana.img); - case 4 - ana.img = int16(ana.img); - case 8 - ana.img = int32(ana.img); - case 16 - ana.img = single(ana.img); - case 64 - ana.img = double(ana.img); - case 128 - ana.img = uint8(ana.img); - otherwise - error('Datatype is not supported by make_ana.'); - end - - return; % make_ana - - -%--------------------------------------------------------------------- -function hdr = make_header(dims, voxel_size, origin, datatype, ... - descrip, maxval, minval) - - hdr.hk = header_key; - hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); - hdr.hist = data_history(origin, descrip); - - return; % make_header - - -%--------------------------------------------------------------------- -function hk = header_key - - hk.sizeof_hdr = 348; % must be 348! - hk.data_type = ''; - hk.db_name = ''; - hk.extents = 0; - hk.session_error = 0; - hk.regular = 'r'; - hk.hkey_un0 = '0'; - - return; % header_key - - -%--------------------------------------------------------------------- -function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) - - dime.dim = dims; - dime.vox_units = 'mm'; - dime.cal_units = ''; - dime.unused1 = 0; - dime.datatype = datatype; - - switch dime.datatype - case 2, - dime.bitpix = 8; precision = 'uint8'; - case 4, - dime.bitpix = 16; precision = 'int16'; - case 8, - dime.bitpix = 32; precision = 'int32'; - case 16, - dime.bitpix = 32; precision = 'float32'; - case 64, - dime.bitpix = 64; precision = 'float64'; - case 128 - dime.bitpix = 24; precision = 'uint8'; - otherwise - error('Datatype is not supported by make_ana.'); - end - - dime.dim_un0 = 0; - dime.pixdim = voxel_size; - dime.vox_offset = 0; - dime.roi_scale = 1; - dime.funused1 = 0; - dime.funused2 = 0; - dime.cal_max = 0; - dime.cal_min = 0; - dime.compressed = 0; - dime.verified = 0; - dime.glmax = maxval; - dime.glmin = minval; - - return; % image_dimension - - -%--------------------------------------------------------------------- -function hist = data_history(origin, descrip) - - hist.descrip = descrip; - hist.aux_file = 'none'; - hist.orient = 0; - hist.originator = origin; - hist.generated = ''; - hist.scannum = ''; - hist.patient_id = ''; - hist.exp_date = ''; - hist.exp_time = ''; - hist.hist_un0 = ''; - hist.views = 0; - hist.vols_added = 0; - hist.start_field = 0; - hist.field_skip = 0; - hist.omax = 0; - hist.omin = 0; - hist.smax = 0; - hist.smin = 0; - - return; % data_history - diff --git a/func/utils/nii/make_nii.m b/func/utils/nii/make_nii.m deleted file mode 100644 index af31952..0000000 --- a/func/utils/nii/make_nii.m +++ /dev/null @@ -1,256 +0,0 @@ -% Make NIfTI structure specified by an N-D matrix. Usually, N is 3 for -% 3D matrix [x y z], or 4 for 4D matrix with time series [x y z t]. -% Optional parameters can also be included, such as: voxel_size, -% origin, datatype, and description. -% -% Once the NIfTI structure is made, it can be saved into NIfTI file -% using "save_nii" command (for more detail, type: help save_nii). -% -% Usage: nii = make_nii(img, [voxel_size], [origin], [datatype], [description]) -% -% Where: -% -% img: Usually, img is a 3D matrix [x y z], or a 4D -% matrix with time series [x y z t]. However, -% NIfTI allows a maximum of 7D matrix. When the -% image is in RGB format, make sure that the size -% of 4th dimension is always 3 (i.e. [R G B]). In -% that case, make sure that you must specify RGB -% datatype, which is either 128 or 511. -% -% voxel_size (optional): Voxel size in millimeter for each -% dimension. Default is [1 1 1]. -% -% origin (optional): The AC origin. Default is [0 0 0]. -% -% datatype (optional): Storage data type: -% 2 - uint8, 4 - int16, 8 - int32, 16 - float32, -% 32 - complex64, 64 - float64, 128 - RGB24, -% 256 - int8, 511 - RGB96, 512 - uint16, -% 768 - uint32, 1792 - complex128 -% Default will use the data type of 'img' matrix -% For RGB image, you must specify it to either 128 -% or 511. -% -% description (optional): Description of data. Default is ''. -% -% e.g.: -% origin = [33 44 13]; datatype = 64; -% nii = make_nii(img, [], origin, datatype); % default voxel_size -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function nii = make_nii(varargin) - - nii.img = varargin{1}; - dims = size(nii.img); - dims = [length(dims) dims ones(1,8)]; - dims = dims(1:8); - - voxel_size = [0 ones(1,7)]; - origin = zeros(1,5); - descrip = ''; - - switch class(nii.img) - case 'uint8' - datatype = 2; - case 'int16' - datatype = 4; - case 'int32' - datatype = 8; - case 'single' - if isreal(nii.img) - datatype = 16; - else - datatype = 32; - end - case 'double' - if isreal(nii.img) - datatype = 64; - else - datatype = 1792; - end - case 'int8' - datatype = 256; - case 'uint16' - datatype = 512; - case 'uint32' - datatype = 768; - otherwise - error('Datatype is not supported by make_nii.'); - end - - if nargin > 1 & ~isempty(varargin{2}) - voxel_size(2:4) = double(varargin{2}); - end - - if nargin > 2 & ~isempty(varargin{3}) - origin(1:3) = double(varargin{3}); - end - - if nargin > 3 & ~isempty(varargin{4}) - datatype = double(varargin{4}); - - if datatype == 128 | datatype == 511 - dims(5) = []; - dims(1) = dims(1) - 1; - dims = [dims 1]; - end - end - - if nargin > 4 & ~isempty(varargin{5}) - descrip = varargin{5}; - end - - if ndims(nii.img) > 7 - error('NIfTI only allows a maximum of 7 Dimension matrix.'); - end - - maxval = round(double(max(nii.img(:)))); - minval = round(double(min(nii.img(:)))); - - nii.hdr = make_header(dims, voxel_size, origin, datatype, ... - descrip, maxval, minval); - - switch nii.hdr.dime.datatype - case 2 - nii.img = uint8(nii.img); - case 4 - nii.img = int16(nii.img); - case 8 - nii.img = int32(nii.img); - case 16 - nii.img = single(nii.img); - case 32 - nii.img = single(nii.img); - case 64 - nii.img = double(nii.img); - case 128 - nii.img = uint8(nii.img); - case 256 - nii.img = int8(nii.img); - case 511 - img = double(nii.img(:)); - img = single((img - min(img))/(max(img) - min(img))); - nii.img = reshape(img, size(nii.img)); - nii.hdr.dime.glmax = double(max(img)); - nii.hdr.dime.glmin = double(min(img)); - case 512 - nii.img = uint16(nii.img); - case 768 - nii.img = uint32(nii.img); - case 1792 - nii.img = double(nii.img); - otherwise - error('Datatype is not supported by make_nii.'); - end - - return; % make_nii - - -%--------------------------------------------------------------------- -function hdr = make_header(dims, voxel_size, origin, datatype, ... - descrip, maxval, minval) - - hdr.hk = header_key; - hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); - hdr.hist = data_history(origin, descrip); - - return; % make_header - - -%--------------------------------------------------------------------- -function hk = header_key - - hk.sizeof_hdr = 348; % must be 348! - hk.data_type = ''; - hk.db_name = ''; - hk.extents = 0; - hk.session_error = 0; - hk.regular = 'r'; - hk.dim_info = 0; - - return; % header_key - - -%--------------------------------------------------------------------- -function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) - - dime.dim = dims; - dime.intent_p1 = 0; - dime.intent_p2 = 0; - dime.intent_p3 = 0; - dime.intent_code = 0; - dime.datatype = datatype; - - switch dime.datatype - case 2, - dime.bitpix = 8; precision = 'uint8'; - case 4, - dime.bitpix = 16; precision = 'int16'; - case 8, - dime.bitpix = 32; precision = 'int32'; - case 16, - dime.bitpix = 32; precision = 'float32'; - case 32, - dime.bitpix = 64; precision = 'float32'; - case 64, - dime.bitpix = 64; precision = 'float64'; - case 128 - dime.bitpix = 24; precision = 'uint8'; - case 256 - dime.bitpix = 8; precision = 'int8'; - case 511 - dime.bitpix = 96; precision = 'float32'; - case 512 - dime.bitpix = 16; precision = 'uint16'; - case 768 - dime.bitpix = 32; precision = 'uint32'; - case 1792, - dime.bitpix = 128; precision = 'float64'; - otherwise - error('Datatype is not supported by make_nii.'); - end - - dime.slice_start = 0; - dime.pixdim = voxel_size; - dime.vox_offset = 0; - dime.scl_slope = 0; - dime.scl_inter = 0; - dime.slice_end = 0; - dime.slice_code = 0; - dime.xyzt_units = 0; - dime.cal_max = 0; - dime.cal_min = 0; - dime.slice_duration = 0; - dime.toffset = 0; - dime.glmax = maxval; - dime.glmin = minval; - - return; % image_dimension - - -%--------------------------------------------------------------------- -function hist = data_history(origin, descrip) - - hist.descrip = descrip; - hist.aux_file = 'none'; - hist.qform_code = 0; - hist.sform_code = 0; - hist.quatern_b = 0; - hist.quatern_c = 0; - hist.quatern_d = 0; - hist.qoffset_x = 0; - hist.qoffset_y = 0; - hist.qoffset_z = 0; - hist.srow_x = zeros(1,4); - hist.srow_y = zeros(1,4); - hist.srow_z = zeros(1,4); - hist.intent_name = ''; - hist.magic = ''; - hist.originator = origin; - - return; % data_history - diff --git a/func/utils/nii/mat_into_hdr.m b/func/utils/nii/mat_into_hdr.m deleted file mode 100644 index 1584306..0000000 --- a/func/utils/nii/mat_into_hdr.m +++ /dev/null @@ -1,83 +0,0 @@ -%MAT_INTO_HDR The old versions of SPM (any version before SPM5) store -% an affine matrix of the SPM Reoriented image into a matlab file -% (.mat extension). The file name of this SPM matlab file is the -% same as the SPM Reoriented image file (.img/.hdr extension). -% -% This program will convert the ANALYZE 7.5 SPM Reoriented image -% file into NIfTI format, and integrate the affine matrix in the -% SPM matlab file into its header file (.hdr extension). -% -% WARNING: Before you run this program, please save the header -% file (.hdr extension) into another file name or into another -% folder location, because all header files (.hdr extension) -% will be overwritten after they are converted into NIfTI -% format. -% -% Usage: mat_into_hdr(filename); -% -% filename: file name(s) with .hdr or .mat file extension, like: -% '*.hdr', or '*.mat', or a single .hdr or .mat file. -% e.g. mat_into_hdr('T1.hdr') -% mat_into_hdr('*.mat') -% - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -%------------------------------------------------------------------------- -function mat_into_hdr(files) - - pn = fileparts(files); - file_lst = dir(files); - file_lst = {file_lst.name}; - file1 = file_lst{1}; - [p n e]= fileparts(file1); - - for i=1:length(file_lst) - [p n e]= fileparts(file_lst{i}); - disp(['working on file ', num2str(i) ,' of ', num2str(length(file_lst)), ': ', n,e]); - process=1; - - if isequal(e,'.hdr') - mat=fullfile(pn, [n,'.mat']); - hdr=fullfile(pn, file_lst{i}); - - if ~exist(mat,'file') - warning(['Cannot find file "',mat , '". File "', n, e, '" will not be processed.']); - process=0; - end - elseif isequal(e,'.mat') - hdr=fullfile(pn, [n,'.hdr']); - mat=fullfile(pn, file_lst{i}); - - if ~exist(hdr,'file') - warning(['Can not find file "',hdr , '". File "', n, e, '" will not be processed.']); - process=0; - end - else - warning(['Input file must have .mat or .hdr extension. File "', n, e, '" will not be processed.']); - process=0; - end - - if process - load(mat); - R=M(1:3,1:3); - T=M(1:3,4); - T=R*ones(3,1)+T; - M(1:3,4)=T; - - [h filetype fileprefix machine]=load_nii_hdr(hdr); - h.hist.qform_code=0; - h.hist.sform_code=1; - h.hist.srow_x=M(1,:); - h.hist.srow_y=M(2,:); - h.hist.srow_z=M(3,:); - h.hist.magic='ni1'; - - fid = fopen(hdr,'w',machine); - save_nii_hdr(h,fid); - fclose(fid); - end - end - - return; % mat_into_hdr - diff --git a/func/utils/nii/pad_nii.m b/func/utils/nii/pad_nii.m deleted file mode 100644 index e6284f1..0000000 --- a/func/utils/nii/pad_nii.m +++ /dev/null @@ -1,142 +0,0 @@ -% PAD_NII: Pad the NIfTI volume from any of the 6 sides -% -% Usage: nii = pad_nii(nii, [option]) -% -% Inputs: -% -% nii - NIfTI volume. -% -% option - struct instructing how many voxel to be padded from which side. -% -% option.pad_from_L = ( number of voxel ) -% option.pad_from_R = ( number of voxel ) -% option.pad_from_P = ( number of voxel ) -% option.pad_from_A = ( number of voxel ) -% option.pad_from_I = ( number of voxel ) -% option.pad_from_S = ( number of voxel ) -% option.bg = [0] -% -% Options description in detail: -% ============================== -% -% pad_from_L: Number of voxels from Left side will be padded. -% -% pad_from_R: Number of voxels from Right side will be padded. -% -% pad_from_P: Number of voxels from Posterior side will be padded. -% -% pad_from_A: Number of voxels from Anterior side will be padded. -% -% pad_from_I: Number of voxels from Inferior side will be padded. -% -% pad_from_S: Number of voxels from Superior side will be padded. -% -% bg: Background intensity, which is 0 by default. -% -% NIfTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jshen@research.baycrest.org) -% -function nii = pad_nii(nii, opt) - - dims = abs(nii.hdr.dime.dim(2:4)); - origin = abs(nii.hdr.hist.originator(1:3)); - - if isempty(origin) | all(origin == 0) % according to SPM - origin = round((dims+1)/2); - end - - pad_from_L = 0; - pad_from_R = 0; - pad_from_P = 0; - pad_from_A = 0; - pad_from_I = 0; - pad_from_S = 0; - bg = 0; - - if nargin > 1 & ~isempty(opt) - if ~isstruct(opt) - error('option argument should be a struct'); - end - - if isfield(opt,'pad_from_L') - pad_from_L = round(opt.pad_from_L); - - if pad_from_L >= origin(1) | pad_from_L < 0 - error('pad_from_L cannot be negative'); - end - end - - if isfield(opt,'pad_from_P') - pad_from_P = round(opt.pad_from_P); - - if pad_from_P >= origin(2) | pad_from_P < 0 - error('pad_from_P cannot be negative'); - end - end - - if isfield(opt,'pad_from_I') - pad_from_I = round(opt.pad_from_I); - - if pad_from_I >= origin(3) | pad_from_I < 0 - error('pad_from_I cannot be negative'); - end - end - - if isfield(opt,'pad_from_R') - pad_from_R = round(opt.pad_from_R); - - if pad_from_R > dims(1)-origin(1) | pad_from_R < 0 - error('pad_from_R cannot be negative'); - end - end - - if isfield(opt,'pad_from_A') - pad_from_A = round(opt.pad_from_A); - - if pad_from_A > dims(2)-origin(2) | pad_from_A < 0 - error('pad_from_A cannot be negative'); - end - end - - if isfield(opt,'pad_from_S') - pad_from_S = round(opt.pad_from_S); - - if pad_from_S > dims(3)-origin(3) | pad_from_S < 0 - error('pad_from_S cannot be negative'); - end - end - - if isfield(opt,'bg') - bg = opt.bg; - end - end - - blk = bg * ones( pad_from_L, dims(2), dims(3) ); - nii.img = cat(1, blk, nii.img); - - blk = bg * ones( pad_from_R, dims(2), dims(3) ); - nii.img = cat(1, nii.img, blk); - - dims = size(nii.img); - - blk = bg * ones( dims(1), pad_from_P, dims(3) ); - nii.img = cat(2, blk, nii.img); - - blk = bg * ones( dims(1), pad_from_A, dims(3) ); - nii.img = cat(2, nii.img, blk); - - dims = size(nii.img); - - blk = bg * ones( dims(1), dims(2), pad_from_I ); - nii.img = cat(3, blk, nii.img); - - blk = bg * ones( dims(1), dims(2), pad_from_S ); - nii.img = cat(3, nii.img, blk); - - nii = make_nii(nii.img, nii.hdr.dime.pixdim(2:4), ... - [origin(1)+pad_from_L origin(2)+pad_from_P origin(3)+pad_from_I], ... - nii.hdr.dime.datatype, nii.hdr.hist.descrip); - - return; - diff --git a/func/utils/nii/reslice_nii.m b/func/utils/nii/reslice_nii.m deleted file mode 100644 index a764d1a..0000000 --- a/func/utils/nii/reslice_nii.m +++ /dev/null @@ -1,321 +0,0 @@ -% The basic application of the 'reslice_nii.m' program is to perform -% any 3D affine transform defined by a NIfTI format image. -% -% In addition, the 'reslice_nii.m' program can also be applied to -% generate an isotropic image from either a NIfTI format image or -% an ANALYZE format image. -% -% The resliced NIfTI file will always be in RAS orientation. -% -% This program only supports real integer or floating-point data type. -% For other data type, the program will exit with an error message -% "Transform of this NIFTI data is not supported by the program". -% -% Usage: reslice_nii(old_fn, new_fn, [voxel_size], [verbose], [bg], ... -% [method], [img_idx], [preferredForm]); -% -% old_fn - filename for original NIfTI file -% -% new_fn - filename for resliced NIfTI file -% -% voxel_size (optional) - size of a voxel in millimeter along x y z -% direction for resliced NIfTI file. 'voxel_size' will use -% the minimum voxel_size in original NIfTI header, -% if it is default or empty. -% -% verbose (optional) - 1, 0 -% 1: show transforming progress in percentage -% 2: progress will not be displayed -% 'verbose' is 1 if it is default or empty. -% -% bg (optional) - background voxel intensity in any extra corner that -% is caused by 3D interpolation. 0 in most cases. 'bg' -% will be the average of two corner voxel intensities -% in original image volume, if it is default or empty. -% -% method (optional) - 1, 2, or 3 -% 1: for Trilinear interpolation -% 2: for Nearest Neighbor interpolation -% 3: for Fischer's Bresenham interpolation -% 'method' is 1 if it is default or empty. -% -% img_idx (optional) - a numerical array of image volume indices. Only -% the specified volumes will be loaded. All available image -% volumes will be loaded, if it is default or empty. -% -% The number of images scans can be obtained from get_nii_frame.m, -% or simply: hdr.dime.dim(5). -% -% preferredForm (optional) - selects which transformation from voxels -% to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate -% "prefer sform or qform, but use others if preferred not present". -% Upper case indicate the program is forced to use the specificied -% tranform or fail loading. 'preferredForm' will be 's', if it is -% default or empty. - Jeff Gunter -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jshen@research.baycrest.org) -% -function reslice_nii(old_fn, new_fn, voxel_size, verbose, bg, method, img_idx, preferredForm) - - if ~exist('old_fn','var') | ~exist('new_fn','var') - error('Usage: reslice_nii(old_fn, new_fn, [voxel_size], [verbose], [bg], [method], [img_idx])'); - end - - if ~exist('method','var') | isempty(method) - method = 1; - end - - if ~exist('img_idx','var') | isempty(img_idx) - img_idx = []; - end - - if ~exist('verbose','var') | isempty(verbose) - verbose = 1; - end - - if ~exist('preferredForm','var') | isempty(preferredForm) - preferredForm= 's'; % Jeff - end - - nii = load_nii_no_xform(old_fn, img_idx, 0, preferredForm); - - if ~ismember(nii.hdr.dime.datatype, [2,4,8,16,64,256,512,768]) - error('Transform of this NIFTI data is not supported by the program.'); - end - - if ~exist('voxel_size','var') | isempty(voxel_size) - voxel_size = abs(min(nii.hdr.dime.pixdim(2:4)))*ones(1,3); - elseif length(voxel_size) < 3 - voxel_size = abs(voxel_size(1))*ones(1,3); - end - - if ~exist('bg','var') | isempty(bg) - bg = mean([nii.img(1) nii.img(end)]); - end - - old_M = nii.hdr.hist.old_affine; - - if nii.hdr.dime.dim(5) > 1 - for i = 1:nii.hdr.dime.dim(5) - if verbose - fprintf('Reslicing %d of %d volumes.\n', i, nii.hdr.dime.dim(5)); - end - - [img(:,:,:,i) M] = ... - affine(nii.img(:,:,:,i), old_M, voxel_size, verbose, bg, method); - end - else - [img M] = affine(nii.img, old_M, voxel_size, verbose, bg, method); - end - - new_dim = size(img); - nii.img = img; - nii.hdr.dime.dim(2:4) = new_dim(1:3); - nii.hdr.dime.datatype = 16; - nii.hdr.dime.bitpix = 32; - nii.hdr.dime.pixdim(2:4) = voxel_size(:)'; - nii.hdr.dime.glmax = max(img(:)); - nii.hdr.dime.glmin = min(img(:)); - nii.hdr.hist.qform_code = 0; - nii.hdr.hist.sform_code = 1; - nii.hdr.hist.srow_x = M(1,:); - nii.hdr.hist.srow_y = M(2,:); - nii.hdr.hist.srow_z = M(3,:); - nii.hdr.hist.new_affine = M; - - save_nii(nii, new_fn); - - return; % reslice_nii - - -%-------------------------------------------------------------------- -function [nii] = load_nii_no_xform(filename, img_idx, old_RGB, preferredForm) - - if ~exist('filename','var'), - error('Usage: [nii] = load_nii(filename, [img_idx], [old_RGB])'); - end - - if ~exist('img_idx','var'), img_idx = []; end - if ~exist('old_RGB','var'), old_RGB = 0; end - if ~exist('preferredForm','var'), preferredForm= 's'; end % Jeff - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - % Read the dataset header - % - [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); - - % Read the header extension - % -% nii.ext = load_nii_ext(filename); - - % Read the dataset body - % - [nii.img,nii.hdr] = ... - load_nii_img(nii.hdr,nii.filetype,nii.fileprefix,nii.machine,img_idx,'','','',old_RGB); - - % Perform some of sform/qform transform - % -% nii = xform_nii(nii, preferredForm); - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - - % fix fileprefix so it doesn't point to temp location - % - nii.fileprefix = gzFileName(1:end-7); - rmdir(tmpDir,'s'); - end - - - hdr = nii.hdr; - - % NIFTI can have both sform and qform transform. This program - % will check sform_code prior to qform_code by default. - % - % If user specifys "preferredForm", user can then choose the - % priority. - Jeff - % - useForm=[]; % Jeff - - if isequal(preferredForm,'S') - if isequal(hdr.hist.sform_code,0) - error('User requires sform, sform not set in header'); - else - useForm='s'; - end - end % Jeff - - if isequal(preferredForm,'Q') - if isequal(hdr.hist.qform_code,0) - error('User requires sform, sform not set in header'); - else - useForm='q'; - end - end % Jeff - - if isequal(preferredForm,'s') - if hdr.hist.sform_code > 0 - useForm='s'; - elseif hdr.hist.qform_code > 0 - useForm='q'; - end - end % Jeff - - if isequal(preferredForm,'q') - if hdr.hist.qform_code > 0 - useForm='q'; - elseif hdr.hist.sform_code > 0 - useForm='s'; - end - end % Jeff - - if isequal(useForm,'s') - R = [hdr.hist.srow_x(1:3) - hdr.hist.srow_y(1:3) - hdr.hist.srow_z(1:3)]; - - T = [hdr.hist.srow_x(4) - hdr.hist.srow_y(4) - hdr.hist.srow_z(4)]; - - nii.hdr.hist.old_affine = [ [R;[0 0 0]] [T;1] ]; - - elseif isequal(useForm,'q') - b = hdr.hist.quatern_b; - c = hdr.hist.quatern_c; - d = hdr.hist.quatern_d; - - if 1.0-(b*b+c*c+d*d) < 0 - if abs(1.0-(b*b+c*c+d*d)) < 1e-5 - a = 0; - else - error('Incorrect quaternion values in this NIFTI data.'); - end - else - a = sqrt(1.0-(b*b+c*c+d*d)); - end - - qfac = hdr.dime.pixdim(1); - i = hdr.dime.pixdim(2); - j = hdr.dime.pixdim(3); - k = qfac * hdr.dime.pixdim(4); - - R = [a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c - 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b - 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b]; - - T = [hdr.hist.qoffset_x - hdr.hist.qoffset_y - hdr.hist.qoffset_z]; - - nii.hdr.hist.old_affine = [ [R * diag([i j k]);[0 0 0]] [T;1] ]; - - elseif nii.filetype == 0 & exist([nii.fileprefix '.mat'],'file') - load([nii.fileprefix '.mat']); % old SPM affine matrix - R=M(1:3,1:3); - T=M(1:3,4); - T=R*ones(3,1)+T; - M(1:3,4)=T; - nii.hdr.hist.old_affine = M; - - else - M = diag(hdr.dime.pixdim(2:5)); - M(1:3,4) = -M(1:3,1:3)*(hdr.hist.originator(1:3)-1)'; - M(4,4) = 1; - nii.hdr.hist.old_affine = M; - end - - return % load_nii_no_xform - diff --git a/func/utils/nii/rri_file_menu.m b/func/utils/nii/rri_file_menu.m deleted file mode 100644 index cf0f701..0000000 --- a/func/utils/nii/rri_file_menu.m +++ /dev/null @@ -1,179 +0,0 @@ -% Imbed a file menu to any figure. If file menu exist, it will append -% to the existing file menu. This file menu includes: Copy to clipboard, -% print, save, close etc. -% -% Usage: rri_file_menu(fig); -% -% rri_file_menu(fig,0) means no 'Close' menu. -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -%-------------------------------------------------------------------- - -function rri_file_menu(action, varargin) - - if isnumeric(action) - fig = action; - action = 'init'; - end - - % clear the message line, - % - h = findobj(gcf,'Tag','MessageLine'); - set(h,'String',''); - - if ~strcmp(action, 'init') - set(gcbf, 'InvertHardcopy','off'); -% set(gcbf, 'PaperPositionMode','auto'); - end - - switch action - case {'init'} - if nargin > 1 - init(fig, 1); % no 'close' menu - else - init(fig, 0); - end - case {'print_fig'} - printdlg(gcbf); - case {'copy_fig'} - copy_fig; - case {'export_fig'} - export_fig; - end - - return % rri_file_menu - - -%------------------------------------------------ -% -% Create (or append) File menu -% -function init(fig, no_close) - - % search for file menu - % - h_file = []; - menuitems = findobj(fig, 'type', 'uimenu'); - - for i=1:length(menuitems) - filelabel = get(menuitems(i),'label'); - - if strcmpi(strrep(filelabel, '&', ''), 'file') - h_file = menuitems(i); - break; - end - end - - set(fig, 'menubar', 'none'); - - if isempty(h_file) - if isempty(menuitems) - h_file = uimenu('parent', fig, 'label', 'File'); - else - h_file = uimenu('parent', fig, 'label', 'Copy Figure'); - end - - h1 = uimenu('parent', h_file, ... - 'callback','rri_file_menu(''copy_fig'');', ... - 'label','Copy to Clipboard'); - else - h1 = uimenu('parent', h_file, ... - 'callback','rri_file_menu(''copy_fig'');', ... - 'separator','on', ... - 'label','Copy to Clipboard'); - end - - h2 = uimenu(h_file, ... - 'callback','pagesetupdlg(gcbf);', ... - 'label','Page Setup...'); - - h2 = uimenu(h_file, ... - 'callback','printpreview(gcbf);', ... - 'label','Print Preview...'); - - h2 = uimenu('parent', h_file, ... - 'callback','printdlg(gcbf);', ... - 'label','Print Figure ...'); - - h2 = uimenu('parent', h_file, ... - 'callback','rri_file_menu(''export_fig'');', ... - 'label','Save Figure ...'); - - arch = computer; - if ~strcmpi(arch(1:2),'PC') - set(h1, 'enable', 'off'); - end - - if ~no_close - h1 = uimenu('parent', h_file, ... - 'callback','close(gcbf);', ... - 'separator','on', ... - 'label','Close'); - end - - return; % init - - -%------------------------------------------------ -% -% Copy to clipboard -% -function copy_fig - - arch = computer; - if(~strcmpi(arch(1:2),'PC')) - error('copy to clipboard can only be used under MS Windows'); - return; - end - - print -noui -dbitmap; - - return % copy_fig - - -%------------------------------------------------ -% -% Save as an image file -% -function export_fig - - curr = pwd; - if isempty(curr) - curr = filesep; - end - - [selected_file, selected_path] = rri_select_file(curr,'Save As'); - - if isempty(selected_file) | isempty(selected_path) - return; - end - - filename = [selected_path selected_file]; - - if(exist(filename,'file')==2) % file exist - - dlg_title = 'Confirm File Overwrite'; - msg = ['File ',filename,' exist. Are you sure you want to overwrite it?']; - response = questdlg(msg,dlg_title,'Yes','No','Yes'); - - if(strcmp(response,'No')) - return; - end - - end - - old_pointer = get(gcbf,'pointer'); - set(gcbf,'pointer','watch'); - - try - saveas(gcbf,filename); - catch - msg = 'ERROR: Cannot save file'; - set(findobj(gcf,'Tag','MessageLine'),'String',msg); - end - - set(gcbf,'pointer',old_pointer); - - return; % export_fig - diff --git a/func/utils/nii/rri_orient.m b/func/utils/nii/rri_orient.m deleted file mode 100644 index b497c74..0000000 --- a/func/utils/nii/rri_orient.m +++ /dev/null @@ -1,106 +0,0 @@ -% Convert image of different orientations to standard Analyze orientation -% -% Usage: nii = rri_orient(nii); - -% Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 -%___________________________________________________________________ - -function [nii, orient, pattern] = rri_orient(nii, varargin) - - if nargin > 1 - pattern = varargin{1}; - else - pattern = []; - end - - if(nargin > 2) - orient = varargin{2}; - if(length(find(orient>6)) || length(find(orient<1))) %value checking - orient=[1 2 3]; %set to default if bogus values set - end - else - orient = [1 2 3]; - end - - - dim = double(nii.hdr.dime.dim([2:4])); - - if ~isempty(pattern) & ~isequal(length(pattern), prod(dim)) - return; - end - - % get orient of the current image - % - if isequal(orient, [1 2 3]) - orient = rri_orient_ui; - pause(.1); - end - - % no need for conversion - % - if isequal(orient, [1 2 3]) - return; - end - - if isempty(pattern) - pattern = 1:prod(dim); - end - - pattern = reshape(pattern, dim); - img = nii.img; - - % calculate after flip orient - % - rot_orient = mod(orient + 2, 3) + 1; - - % do flip: - % - flip_orient = orient - rot_orient; - - for i = 1:3 - if flip_orient(i) - pattern = flipdim(pattern, i); - img = flipdim(img, i); - end - end - - % get index of orient (do inverse) - % - [tmp rot_orient] = sort(rot_orient); - - % do rotation: - % - pattern = permute(pattern, rot_orient); - img = permute(img, [rot_orient 4 5 6]); - - % rotate resolution, or 'dim' - % - new_dim = nii.hdr.dime.dim([2:4]); - new_dim = new_dim(rot_orient); - nii.hdr.dime.dim([2:4]) = new_dim; - - % rotate voxel_size, or 'pixdim' - % - tmp = nii.hdr.dime.pixdim([2:4]); - tmp = tmp(rot_orient); - nii.hdr.dime.pixdim([2:4]) = tmp; - - % re-calculate originator - % - tmp = nii.hdr.hist.originator([1:3]); - tmp = tmp(rot_orient); - flip_orient = flip_orient(rot_orient); - - for i = 1:3 - if flip_orient(i) & ~isequal(double(tmp(i)), 0) - tmp(i) = int16(double(new_dim(i)) - double(tmp(i)) + 1); - end - end - - nii.hdr.hist.originator([1:3]) = tmp; - - nii.img = img; - pattern = pattern(:); - - return; % rri_orient - diff --git a/func/utils/nii/rri_orient_ui.m b/func/utils/nii/rri_orient_ui.m deleted file mode 100644 index 8f0c922..0000000 --- a/func/utils/nii/rri_orient_ui.m +++ /dev/null @@ -1,251 +0,0 @@ -% Return orientation of the current image: -% orient is orientation 1x3 matrix, in that: -% Three elements represent: [x y z] -% Element value: 1 - Left to Right; 2 - Posterior to Anterior; -% 3 - Inferior to Superior; 4 - Right to Left; -% 5 - Anterior to Posterior; 6 - Superior to Inferior; -% e.g.: -% Standard RAS Orientation: [1 2 3] -% Standard RHOS Orientation: [2 4 3] - -% Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 -% -function orient = rri_orient_ui(varargin) - - if nargin == 0 - init; - orient_ui_fig = gcf; - uiwait; % wait for user finish - - orient = getappdata(gcf, 'orient'); - - if isempty(orient) - orient = [1 2 3]; - end - - if ishandle(orient_ui_fig) - close(gcf); - end - - return; - end - - action = varargin{1}; - - if strcmp(action, 'done') - click_done; - elseif strcmp(action, 'cancel') - uiresume; - end - - return; % rri_orient_ui - - -%---------------------------------------------------------------------- -function init - - save_setting_status = 'on'; - rri_orient_pos = []; - - try - load('pls_profile'); - catch - end - - try - load('rri_pos_profile'); - catch - end - - if ~isempty(rri_orient_pos) & strcmp(save_setting_status,'on') - - pos = rri_orient_pos; - - else - - w = 0.35; - h = 0.4; - x = (1-w)/2; - y = (1-h)/2; - - pos = [x y w h]; - - end - - handles.figure = figure('Color',[0.8 0.8 0.8], ... - 'Units','normal', ... - 'Name', 'Convert to standard RAS orientation', ... - 'NumberTitle','off', ... - 'MenuBar','none', ... - 'Position',pos, ... - 'WindowStyle', 'normal', ... - 'ToolBar','none'); - - h0 = handles.figure; - Font.FontUnits = 'point'; - Font.FontSize = 12; - - margin = .1; - line_num = 6; - line_ht = (1 - margin*2) / line_num; - - x = margin; - y = 1 - margin - line_ht; - w = 1 - margin * 2; - h = line_ht * .7; - - pos = [x y w h]; - - handles.Ttit = uicontrol('parent', h0, ... - 'style','text', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'background', [0.8 0.8 0.8], ... - 'string', 'Please input orientation of the current image:'); - - y = y - line_ht; - w = .2; - - pos = [x y w h]; - - handles.Tx_orient = uicontrol('parent', h0, ... - 'style','text', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'background', [0.8 0.8 0.8], ... - 'string', 'X Axes:'); - - y = y - line_ht; - - pos = [x y w h]; - - handles.Ty_orient = uicontrol('parent', h0, ... - 'style','text', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'background', [0.8 0.8 0.8], ... - 'string', 'Y Axes:'); - - y = y - line_ht; - - pos = [x y w h]; - - handles.Tz_orient = uicontrol('parent', h0, ... - 'style','text', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'background', [0.8 0.8 0.8], ... - 'string', 'Z Axes:'); - - choice = { 'From Left to Right', 'From Posterior to Anterior', ... - 'From Inferior to Superior', 'From Right to Left', ... - 'From Anterior to Posterior', 'From Superior to Inferior' }; - - y = 1 - margin - line_ht; - y = y - line_ht; - w = 1 - margin - x - w; - x = 1 - margin - w; - - pos = [x y w h]; - - handles.x_orient = uicontrol('parent', h0, ... - 'style','popupmenu', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'string', choice, ... - 'value', 1, ... - 'background', [1 1 1]); - - y = y - line_ht; - - pos = [x y w h]; - - handles.y_orient = uicontrol('parent', h0, ... - 'style','popupmenu', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'string', choice, ... - 'value', 2, ... - 'background', [1 1 1]); - - y = y - line_ht; - - pos = [x y w h]; - - handles.z_orient = uicontrol('parent', h0, ... - 'style','popupmenu', ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','left',... - 'string', choice, ... - 'value', 3, ... - 'background', [1 1 1]); - - x = margin; - y = y - line_ht * 1.5; - w = .3; - - pos = [x y w h]; - - handles.done = uicontrol('parent', h0, ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','center',... - 'callback', 'rri_orient_ui(''done'');', ... - 'string', 'Done'); - - x = 1 - margin - w; - - pos = [x y w h]; - - handles.cancel = uicontrol('parent', h0, ... - 'unit', 'normal', ... - Font, ... - 'Position',pos, ... - 'HorizontalAlignment','center',... - 'callback', 'rri_orient_ui(''cancel'');', ... - 'string', 'Cancel'); - - setappdata(h0, 'handles', handles); - setappdata(h0, 'orient', [1 2 3]); - - return; % init - - -%---------------------------------------------------------------------- -function click_done - - handles = getappdata(gcf, 'handles'); - - x_orient = get(handles.x_orient, 'value'); - y_orient = get(handles.y_orient, 'value'); - z_orient = get(handles.z_orient, 'value'); - - orient = [x_orient y_orient z_orient]; - test_orient = [orient, orient + 3]; - test_orient = mod(test_orient, 3); - - if length(unique(test_orient)) ~= 3 - msgbox('Please don''t choose same or opposite direction','Error','modal'); - return; - end - - setappdata(gcf, 'orient', [x_orient y_orient z_orient]); - uiresume; - - return; % click_done - diff --git a/func/utils/nii/rri_select_file.m b/func/utils/nii/rri_select_file.m deleted file mode 100644 index 7e462c4..0000000 --- a/func/utils/nii/rri_select_file.m +++ /dev/null @@ -1,636 +0,0 @@ -function [selected_file, selected_path] = rri_select_file(varargin) -% -% USAGE: [selected_file, selected_path] = ... -% rri_select_file(dir_name, fig_title) -% -% Allow user to select a file from a list of Matlab competible -% file format -% -% Example: -% -% [selected_file, selected_path] = ... -% rri_select_file('/usr','Select Data File'); -% -% See Also RRI_GETFILES - -% -- Created June 2001 by Wilkin Chau, Rotman Research Institute -% -% use rri_select_file to open & save Matlab recognized format -% -- Modified Dec 2002 by Jimmy Shen, Rotman Research Institute -% - - if nargin == 0 | ischar(varargin{1}) % create rri_select_file figure - - dir_name = ''; - fig_title = 'Select a File'; - - if nargin > 0 - dir_name = varargin{1}; - end - - if nargin > 1 - fig_title = varargin{2}; - end - - Init(fig_title,dir_name); - uiwait; % wait for user finish - - selected_path = getappdata(gcf,'SelectedDirectory'); - selected_file = getappdata(gcf,'SelectedFile'); - - cd (getappdata(gcf,'StartDirectory')); - close(gcf); - return; - end; - - % clear the message line, - % - h = findobj(gcf,'Tag','MessageLine'); - set(h,'String',''); - - action = varargin{1}{1}; - - % change 'File format': - % update 'Files' & 'File selection' based on file pattern - % - if strcmp(action,'EditFilter'), - EditFilter; - - % run delete_fig when figure is closing - % - elseif strcmp(action,'delete_fig'), - delete_fig; - - % select 'Directories': - % go into the selected dir - % update 'Files' & 'File selection' based on file pattern - % - elseif strcmp(action,'select_dir'), - select_dir; - - % select 'Files': - % update 'File selection' - % - elseif strcmp(action,'select_file'), - select_file; - - % change 'File selection': - % if it is a file, select that, - % if it is more than a file (*), select those, - % if it is a directory, select based on file pattern - % - elseif strcmp(action,'EditSelection'), - EditSelection; - - % clicked 'Select' - % - elseif strcmp(action,'DONE_BUTTON_PRESSED'), - h = findobj(gcf,'Tag','SelectionEdit'); - [filepath,filename,fileext] = fileparts(get(h,'String')); - - if isempty(filepath) | isempty(filename) | isempty(fileext) - setappdata(gcf,'SelectedDirectory',[]); - setappdata(gcf,'SelectedFile',[]); - else - if ~strcmp(filepath(end),filesep) % not end with filesep - filepath = [filepath filesep]; % add a filesep to filepath - end - - setappdata(gcf,'SelectedDirectory',filepath); - setappdata(gcf,'SelectedFile',[filename fileext]); - end - - if getappdata(gcf,'ready') % ready to exit - uiresume; - end - - % clicked 'cancel' - % - elseif strcmp(action,'CANCEL_BUTTON_PRESSED'), - setappdata(gcf,'SelectedDirectory',[]); - setappdata(gcf,'SelectedFile',[]); - set(findobj(gcf,'Tag','FileList'),'String',''); - uiresume; - end; - - return; - - -% -------------------------------------------------------------------- -function Init(fig_title,dir_name), - - StartDirectory = pwd; - if isempty(StartDirectory), - StartDirectory = filesep; - end; - - filter_disp = {'JPEG image (*.jpg)', ... - 'TIFF image, compressed (*.tif)', ... - 'EPS Level 1 (*.eps)', ... - 'Adobe Illustrator 88 (*.ai)', ... - 'Enhanced metafile (*.emf)', ... - 'Matlab Figure (*.fig)', ... - 'Matlab M-file (*.m)', ... - 'Portable bitmap (*.pbm)', ... - 'Paintbrush 24-bit (*.pcx)', ... - 'Portable Graymap (*.pgm)', ... - 'Portable Network Graphics (*.png)', ... - 'Portable Pixmap (*.ppm)', ... - }; - - filter_string = {'*.jpg', ... - '*.tif', ... - '*.eps', ... - '*.ai', ... - '*.emf', ... - '*.fig', ... - '*.m', ... - '*.pbm', ... - '*.pcx', ... - '*.pgm', ... - '*.png', ... - '*.ppm', ... - }; - -% filter_disp = char(filter_disp); - filter_string = char(filter_string); - - margine = 0.05; - line_height = 0.07; - char_height = line_height*0.8; - - save_setting_status = 'on'; - rri_select_file_pos = []; - - try - load('pls_profile'); - catch - end - - if ~isempty(rri_select_file_pos) & strcmp(save_setting_status,'on') - - pos = rri_select_file_pos; - - else - - w = 0.4; - h = 0.6; - x = (1-w)/2; - y = (1-h)/2; - - pos = [x y w h]; - - end - - h0 = figure('parent',0, 'Color',[0.8 0.8 0.8], ... - 'Units','normal', ... - 'Name',fig_title, ... - 'NumberTitle','off', ... - 'MenuBar','none', ... - 'Position', pos, ... - 'deleteFcn','rri_select_file({''delete_fig''});', ... - 'WindowStyle', 'modal', ... - 'Tag','GetFilesFigure', ... - 'ToolBar','none'); - - x = margine; - y = 1 - 1*line_height - margine; - w = 1-2*x; - h = char_height; - - pos = [x y w h]; - - h1 = uicontrol('Parent',h0, ... % Filter Label - 'Style','text', ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'Position', pos, ... - 'String','Choose one of the file format:', ... - 'Tag','FilterLabel'); - - y = 1 - 2*line_height - margine + line_height*0.2; - w = 1-2*x; - - pos = [x y w h]; - - h_filter = uicontrol('Parent',h0, ... % Filter list - 'Style','popupmenu', ... - 'Units','normal', ... - 'BackgroundColor',[1 1 1], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'Position', pos, ... - 'String', filter_disp, ... - 'user', filter_string, ... - 'value', 1, ... - 'Callback','rri_select_file({''EditFilter''});', ... - 'Tag','FilterEdit'); - - y = 1 - 3*line_height - margine; - w = 0.5 - x - margine/2; - - pos = [x y w h]; - - h1 = uicontrol('Parent',h0, ... % Directory Label - 'Style','text', ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'ListboxTop',0, ... - 'Position', pos, ... - 'String','Directories', ... - 'Tag','DirectoryLabel'); - - x = 0.5; - y = 1 - 3*line_height - margine; - w = 0.5 - margine; - - pos = [x y w h]; - - h1 = uicontrol('Parent',h0, ... % File Label - 'Style','text', ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'ListboxTop',0, ... - 'Position', pos, ... - 'String','Files', ... - 'Tag','FileLabel'); - - x = margine; - y = 4*line_height + margine; - w = 0.5 - x - margine/2; - h = 1 - 7*line_height - 2*margine; - - pos = [x y w h]; - - h_dir = uicontrol('Parent',h0, ... % Directory Listbox - 'Style','listbox', ... - 'Units','normal', ... - 'fontunit','normal', ... - 'FontSize',0.08, ... - 'HorizontalAlignment','left', ... - 'Interruptible', 'off', ... - 'ListboxTop',1, ... - 'Position', pos, ... - 'String', '', ... - 'Callback','rri_select_file({''select_dir''});', ... - 'Tag','DirectoryList'); - - x = 0.5; - y = 4*line_height + margine; - w = 0.5 - margine; - h = 1 - 7*line_height - 2*margine; - - pos = [x y w h]; - - h_file = uicontrol('Parent',h0, ... % File Listbox - 'Style','listbox', ... - 'Units','normal', ... - 'fontunit','normal', ... - 'FontSize',0.08, ... - 'HorizontalAlignment','left', ... - 'ListboxTop',1, ... - 'Position', pos, ... - 'String', '', ... - 'Callback','rri_select_file({''select_file''});', ... - 'Tag','FileList'); - - x = margine; - y = 3*line_height + margine - line_height*0.2; - w = 1-2*x; - h = char_height; - - pos = [x y w h]; - - h1 = uicontrol('Parent',h0, ... % Selection Label - 'Style','text', ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'Position', pos, ... - 'String','File you selected:', ... - 'Tag','SelectionLabel'); - - y = 2*line_height + margine; - w = 1-2*x; - - pos = [x y w h]; - - h_select = uicontrol('Parent',h0, ... % Selection Edit - 'Style','edit', ... - 'Units','normal', ... - 'BackgroundColor',[1 1 1], ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'HorizontalAlignment','left', ... - 'Position', pos, ... - 'String', '', ... - 'Callback','rri_select_file({''EditSelection''});', ... - 'Tag','SelectionEdit'); - - x = 2*margine; - y = line_height/2 + margine; - w = 0.2; - h = line_height; - - pos = [x y w h]; - - h_done = uicontrol('Parent',h0, ... % DONE - 'Units','normal', ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'ListboxTop',0, ... - 'Position', pos, ... - 'HorizontalAlignment','center', ... - 'String','Save', ... % 'Select', ... - 'Callback','rri_select_file({''DONE_BUTTON_PRESSED''});', ... - 'Tag','DONEButton'); - - x = 1 - x - w; - - pos = [x y w h]; - - h_cancel = uicontrol('Parent',h0, ... % CANCEL - 'Units','normal', ... - 'fontunit','normal', ... - 'FontSize',0.5, ... - 'ListboxTop',0, ... - 'Position', pos, ... - 'HorizontalAlignment','center', ... - 'String','Cancel', ... - 'Callback','rri_select_file({''CANCEL_BUTTON_PRESSED''});', ... - 'Tag','CANCELButton'); - - if isempty(dir_name) - dir_name = StartDirectory; - end - - set(h_select,'string',dir_name); - - filter_select = get(h_filter,'value'); - filter_pattern = filter_string(filter_select,:); - - setappdata(gcf,'FilterPattern',deblank(filter_pattern)); - setappdata(gcf,'filter_string',filter_string); - - setappdata(gcf,'h_filter', h_filter); - setappdata(gcf,'h_dir', h_dir); - setappdata(gcf,'h_file', h_file); - setappdata(gcf,'h_select', h_select); - setappdata(gcf,'h_done', h_done); - setappdata(gcf,'h_cancel', h_cancel); - setappdata(gcf,'StartDirectory',StartDirectory); - - EditSelection; - - h_file = getappdata(gcf,'h_file'); - if isempty(get(h_file,'string')) - setappdata(gcf,'ready',0); - else - setappdata(gcf,'ready',1); - end - - return; % Init - - -% called by all the actions, to update 'Directories' or 'Files' -% based on filter_pattern. Select first file in filelist. -% -% -------------------------------------------------------------------- - -function update_dirlist; - - filter_path = getappdata(gcf,'curr_dir'); - filter_pattern = getappdata(gcf,'FilterPattern'); - - if exist(filter_pattern) == 2 % user input specific filename - is_single_file = 1; % need manually take path out later - else - is_single_file = 0; - end - - % take the file path out from filter_pattern - % - [fpath fname fext] = fileparts(filter_pattern); - filter_pattern = [fname fext]; - - dir_struct = dir(filter_path); - if isempty(dir_struct) - msg = 'ERROR: Directory not found!'; - uiwait(msgbox(msg,'File Selection Error','modal')); - return; - end; - - old_pointer = get(gcf,'Pointer'); - set(gcf,'Pointer','watch'); - - dir_list = dir_struct(find([dir_struct.isdir] == 1)); - [sorted_dir_names,sorted_dir_index] = sortrows({dir_list.name}'); - - dir_struct = dir([filter_path filesep filter_pattern]); - if isempty(dir_struct) - sorted_file_names = []; - else - file_list = dir_struct(find([dir_struct.isdir] == 0)); - - if is_single_file % take out path - tmp = file_list.name; - [fpath fname fext] = fileparts(tmp); - file_list.name = [fname fext]; - end - - [sorted_file_names,sorted_file_index] = sortrows({file_list.name}'); - end; - - disp_dir_names = []; % if need full path, use this - % instead of sorted_dir_names - for i=1:length(sorted_dir_names) - tmp = [filter_path filesep sorted_dir_names{i}]; - disp_dir_names = [disp_dir_names {tmp}]; - end - - h = findobj(gcf,'Tag','DirectoryList'); - set(h,'String',sorted_dir_names,'Value',1); - - h = findobj(gcf,'Tag','FileList'); - set(h,'String',sorted_file_names,'value',1); - - h_select = getappdata(gcf,'h_select'); - if strcmp(filter_path(end),filesep) % filepath end with filesep - filter_path = filter_path(1:end-1); % take filesep out - end - - if isempty(sorted_file_names) - set(h_select,'string',[filter_path filesep]); - else - set(h_select,'string',[filter_path filesep sorted_file_names{1}]); - end - - set(gcf,'Pointer',old_pointer); - - return; % update_dirlist - - -% change 'File format': -% update 'Files' & 'File selection' based on file pattern -% -% -------------------------------------------------------------------- - -function EditFilter() - - filter_select = get(gcbo,'value'); - filter_string = getappdata(gcf,'filter_string'); - filter_pattern = filter_string(filter_select,:); - filter_path = getappdata(gcf,'curr_dir'); - - % update filter_pattern - setappdata(gcf,'FilterPattern',deblank(filter_pattern)); - - if isempty(filter_path), - filter_path = filesep; - end; - - update_dirlist; - - h_file = getappdata(gcf,'h_file'); - if isempty(get(h_file,'string')) - setappdata(gcf,'ready',0); - else - setappdata(gcf,'ready',1); - end - - return; % EditFilter - - -% select 'Directories': -% go into the selected dir -% update 'Files' & 'File selection' based on file pattern -% -% -------------------------------------------------------------------- - -function select_dir() - - listed_dir = get(gcbo,'String'); - selected_dir_idx = get(gcbo,'Value'); - selected_dir = listed_dir{selected_dir_idx}; - curr_dir = getappdata(gcf,'curr_dir'); - - % update the selection box - % - try - cd ([curr_dir filesep selected_dir]); - catch - msg = 'ERROR: Cannot access directory'; - uiwait(msgbox(msg,'File Selection Error','modal')); - return; - end; - - if isempty(pwd) - curr_dir = filesep; - else - curr_dir = pwd; - end; - - setappdata(gcf,'curr_dir',curr_dir); - update_dirlist; - - h_file = getappdata(gcf,'h_file'); - if isempty(get(h_file,'string')) - setappdata(gcf,'ready',0); - else - setappdata(gcf,'ready',1); - end - - return; % select_dir - - -% select 'Files': -% update 'File selection' -% -% -------------------------------------------------------------------- - -function select_file() - - setappdata(gcf,'ready',1); - listed_file = get(gcbo,'String'); - selected_file_idx = get(gcbo,'Value'); - selected_file = listed_file{selected_file_idx}; - curr_dir = getappdata(gcf,'curr_dir'); - - if strcmp(curr_dir(end),filesep) % filepath end with filesep - curr_dir = curr_dir(1:end-1); % take filesep out - end - - h_select = getappdata(gcf,'h_select'); - set(h_select,'string',[curr_dir filesep selected_file]); - - return; % select_file - - -% change 'File selection': -% if it is a file, select that, -% if it is more than a file (*), select those, -% if it is a directory, select based on file pattern -% -% -------------------------------------------------------------------- - -function EditSelection() - - filter_string = getappdata(gcf,'filter_string'); - h_select = getappdata(gcf,'h_select'); - selected_file = get(h_select,'string'); - - if exist(selected_file) == 7 % if user enter a dir - setappdata(gcf,'ready',0); - setappdata(gcf,'curr_dir',selected_file); % get new dir - update_dirlist; - else - - setappdata(gcf,'ready',1); - - [fpath fname fext]= fileparts(selected_file); - if exist(fpath) ~=7 % fpath is not a dir - setappdata(gcf,'ready',0); - msg = 'ERROR: Cannot access directory'; - uiwait(msgbox(msg,'File Selection Error','modal')); - end - - % if the file format user entered is not supported by matlab - if isempty(strmatch(['*',fext],filter_string,'exact')) - setappdata(gcf,'ready',0); - msg = 'ERROR: File format is not supported by Matlab.'; - uiwait(msgbox(msg,'File Selection Error','modal')); - end - - end - - return; % EditSelection - - -% -------------------------------------------------------------------- - -function delete_fig() - - try - load('pls_profile'); - pls_profile = which('pls_profile.mat'); - - rri_select_file_pos = get(gcbf,'position'); - - save(pls_profile, '-append', 'rri_select_file_pos'); - catch - end - - return; - diff --git a/func/utils/nii/rri_xhair.m b/func/utils/nii/rri_xhair.m deleted file mode 100644 index 92c9145..0000000 --- a/func/utils/nii/rri_xhair.m +++ /dev/null @@ -1,92 +0,0 @@ -% rri_xhair: create a pair of full_cross_hair at point [x y] in -% axes h_ax, and return xhair struct -% -% Usage: xhair = rri_xhair([x y], xhair, h_ax); -% -% If omit xhair, rri_xhair will create a pair of xhair; otherwise, -% rri_xhair will update the xhair. If omit h_ax, current axes will -% be used. -% - -% 24-nov-2003 jimmy (jimmy@rotman-baycrest.on.ca) -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function xhair = rri_xhair(varargin) - - if nargin == 0 - error('Please enter a point position as first argument'); - return; - end - - if nargin > 0 - p = varargin{1}; - - if ~isnumeric(p) | length(p) ~= 2 - error('Invalid point position'); - return; - else - xhair = []; - end - end - - if nargin > 1 - xhair = varargin{2}; - - if ~isempty(xhair) - if ~isstruct(xhair) - error('Invalid xhair struct'); - return; - elseif ~isfield(xhair,'lx') | ~isfield(xhair,'ly') - error('Invalid xhair struct'); - return; - elseif ~ishandle(xhair.lx) | ~ishandle(xhair.ly) - error('Invalid xhair struct'); - return; - end - - lx = xhair.lx; - ly = xhair.ly; - else - lx = []; - ly = []; - end - end - - if nargin > 2 - h_ax = varargin{3}; - - if ~ishandle(h_ax) - error('Invalid axes handle'); - return; - elseif ~strcmp(lower(get(h_ax,'type')), 'axes') - error('Invalid axes handle'); - return; - end - else - h_ax = gca; - end - - x_range = get(h_ax,'xlim'); - y_range = get(h_ax,'ylim'); - - if ~isempty(xhair) - set(lx, 'ydata', [p(2) p(2)]); - set(ly, 'xdata', [p(1) p(1)]); - set(h_ax, 'selected', 'on'); - set(h_ax, 'selected', 'off'); - else - figure(get(h_ax,'parent')); - axes(h_ax); - - xhair.lx = line('xdata', x_range, 'ydata', [p(2) p(2)], ... - 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); - xhair.ly = line('xdata', [p(1) p(1)], 'ydata', y_range, ... - 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); - end - - set(h_ax,'xlim',x_range); - set(h_ax,'ylim',y_range); - - return; - diff --git a/func/utils/nii/rri_zoom_menu.m b/func/utils/nii/rri_zoom_menu.m deleted file mode 100644 index f7b7ae0..0000000 --- a/func/utils/nii/rri_zoom_menu.m +++ /dev/null @@ -1,33 +0,0 @@ -% Imbed a zoom menu to any figure. -% -% Usage: rri_zoom_menu(fig); -% - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -%-------------------------------------------------------------------- -function menu_hdl = rri_zoom_menu(fig) - - if isnumeric(fig) - menu_hdl = uimenu('Parent',fig, ... - 'Label','Zoom on', ... - 'Userdata', 1, ... - 'Callback','rri_zoom_menu(''zoom'');'); - - return; - end - - zoom_on_state = get(gcbo,'Userdata'); - - if (zoom_on_state == 1) - zoom on; - set(gcbo,'Userdata',0,'Label','Zoom off'); - set(gcbf,'pointer','crosshair'); - else - zoom off; - set(gcbo,'Userdata',1,'Label','Zoom on'); - set(gcbf,'pointer','arrow'); - end - - return % rri_zoom_menu - diff --git a/func/utils/nii/save_nii.m b/func/utils/nii/save_nii.m deleted file mode 100644 index 98f7aef..0000000 --- a/func/utils/nii/save_nii.m +++ /dev/null @@ -1,286 +0,0 @@ -% Save NIFTI dataset. Support both *.nii and *.hdr/*.img file extension. -% If file extension is not provided, *.hdr/*.img will be used as default. -% -% Usage: save_nii(nii, filename, [old_RGB]) -% -% nii.hdr - struct with NIFTI header fields (from load_nii.m or make_nii.m) -% -% nii.img - 3D (or 4D) matrix of NIFTI data. -% -% filename - NIFTI file name. -% -% old_RGB - an optional boolean variable to handle special RGB data -% sequence [R1 R2 ... G1 G2 ... B1 B2 ...] that is used only by -% AnalyzeDirect (Analyze Software). Since both NIfTI and Analyze -% file format use RGB triple [R1 G1 B1 R2 G2 B2 ...] sequentially -% for each voxel, this variable is set to FALSE by default. If you -% would like the saved image only to be opened by AnalyzeDirect -% Software, set old_RGB to TRUE (or 1). It will be set to 0, if it -% is default or empty. -% -% Tip: to change the data type, set nii.hdr.dime.datatype, -% and nii.hdr.dime.bitpix to: -% -% 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN -% 1 Binary (ubit1, bitpix=1) % DT_BINARY -% 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 -% 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 -% 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 -% 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 -% 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 -% 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 -% 128 uint RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 -% 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 -% 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 -% 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 -% 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 -% 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 -% 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 -% 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 -% 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 -% 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 -% -% Part of this file is copied and modified from: -% http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% - "old_RGB" related codes in "save_nii.m" are added by Mike Harms (2006.06.28) -% -function save_nii(nii, fileprefix, old_RGB) - - if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... - ~isfield(nii,'img') | ~exist('fileprefix','var') | isempty(fileprefix) - - error('Usage: save_nii(nii, filename, [old_RGB])'); - end - - if isfield(nii,'untouch') & nii.untouch == 1 - error('Usage: please use ''save_untouch_nii.m'' for the untouched structure.'); - end - - if ~exist('old_RGB','var') | isempty(old_RGB) - old_RGB = 0; - end - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(fileprefix) > 2 & strcmp(fileprefix(end-2:end), '.gz') - - if ~strcmp(fileprefix(end-6:end), '.img.gz') & ... - ~strcmp(fileprefix(end-6:end), '.hdr.gz') & ... - ~strcmp(fileprefix(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - else - gzFile = 1; - fileprefix = fileprefix(1:end-3); - end - end - - filetype = 1; - - % Note: fileprefix is actually the filename you want to save - % - if findstr('.nii',fileprefix) & strcmp(fileprefix(end-3:end), '.nii') - filetype = 2; - fileprefix(end-3:end)=''; - end - - if findstr('.hdr',fileprefix) & strcmp(fileprefix(end-3:end), '.hdr') - fileprefix(end-3:end)=''; - end - - if findstr('.img',fileprefix) & strcmp(fileprefix(end-3:end), '.img') - fileprefix(end-3:end)=''; - end - - write_nii(nii, filetype, fileprefix, old_RGB); - - % gzip output file if requested - % - if exist('gzFile', 'var') - if filetype == 1 - gzip([fileprefix, '.img']); - delete([fileprefix, '.img']); - gzip([fileprefix, '.hdr']); - delete([fileprefix, '.hdr']); - elseif filetype == 2 - gzip([fileprefix, '.nii']); - delete([fileprefix, '.nii']); - end; - end; - - if filetype == 1 - - % So earlier versions of SPM can also open it with correct originator - % - M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; - save([fileprefix '.mat'], 'M'); - end - - return % save_nii - - -%----------------------------------------------------------------------------------- -function write_nii(nii, filetype, fileprefix, old_RGB) - - hdr = nii.hdr; - - if isfield(nii,'ext') & ~isempty(nii.ext) - ext = nii.ext; - [ext, esize_total] = verify_nii_ext(ext); - else - ext = []; - end - - switch double(hdr.dime.datatype), - case 1, - hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; - case 2, - hdr.dime.bitpix = int16(8 ); precision = 'uint8'; - case 4, - hdr.dime.bitpix = int16(16); precision = 'int16'; - case 8, - hdr.dime.bitpix = int16(32); precision = 'int32'; - case 16, - hdr.dime.bitpix = int16(32); precision = 'float32'; - case 32, - hdr.dime.bitpix = int16(64); precision = 'float32'; - case 64, - hdr.dime.bitpix = int16(64); precision = 'float64'; - case 128, - hdr.dime.bitpix = int16(24); precision = 'uint8'; - case 256 - hdr.dime.bitpix = int16(8 ); precision = 'int8'; - case 511, - hdr.dime.bitpix = int16(96); precision = 'float32'; - case 512 - hdr.dime.bitpix = int16(16); precision = 'uint16'; - case 768 - hdr.dime.bitpix = int16(32); precision = 'uint32'; - case 1024 - hdr.dime.bitpix = int16(64); precision = 'int64'; - case 1280 - hdr.dime.bitpix = int16(64); precision = 'uint64'; - case 1792, - hdr.dime.bitpix = int16(128); precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - - hdr.dime.glmax = round(double(max(nii.img(:)))); - hdr.dime.glmin = round(double(min(nii.img(:)))); - - if filetype == 2 - fid = fopen(sprintf('%s.nii',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.nii.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 352; - - if ~isempty(ext) - hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; - end - - hdr.hist.magic = 'n+1'; - save_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - else - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 0; - hdr.hist.magic = 'ni1'; - save_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - - fclose(fid); - fid = fopen(sprintf('%s.img',fileprefix),'w'); - end - - ScanDim = double(hdr.dime.dim(5)); % t - SliceDim = double(hdr.dime.dim(4)); % z - RowDim = double(hdr.dime.dim(3)); % y - PixelDim = double(hdr.dime.dim(2)); % x - SliceSz = double(hdr.dime.pixdim(4)); - RowSz = double(hdr.dime.pixdim(3)); - PixelSz = double(hdr.dime.pixdim(2)); - - x = 1:PixelDim; - - if filetype == 2 & isempty(ext) - skip_bytes = double(hdr.dime.vox_offset) - 348; - else - skip_bytes = 0; - end - - if double(hdr.dime.datatype) == 128 - - % RGB planes are expected to be in the 4th dimension of nii.img - % - if(size(nii.img,4)~=3) - error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); - end - - if old_RGB - nii.img = permute(nii.img, [1 2 4 3 5 6 7 8]); - else - nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); - end - end - - if double(hdr.dime.datatype) == 511 - - % RGB planes are expected to be in the 4th dimension of nii.img - % - if(size(nii.img,4)~=3) - error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); - end - - if old_RGB - nii.img = permute(nii.img, [1 2 4 3 5 6 7 8]); - else - nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); - end - end - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - real_img = real(nii.img(:))'; - nii.img = imag(nii.img(:))'; - nii.img = [real_img; nii.img]; - end - - if skip_bytes - fwrite(fid, zeros(1,skip_bytes), 'uint8'); - end - - fwrite(fid, nii.img, precision); -% fwrite(fid, nii.img, precision, skip_bytes); % error using skip - fclose(fid); - - return; % write_nii - diff --git a/func/utils/nii/save_nii_ext.m b/func/utils/nii/save_nii_ext.m deleted file mode 100644 index 4788649..0000000 --- a/func/utils/nii/save_nii_ext.m +++ /dev/null @@ -1,38 +0,0 @@ -% Save NIFTI header extension. -% -% Usage: save_nii_ext(ext, fid) -% -% ext - struct with NIFTI header extension fields. -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function save_nii_ext(ext, fid) - - if ~exist('ext','var') | ~exist('fid','var') - error('Usage: save_nii_ext(ext, fid)'); - end - - if ~isfield(ext,'extension') | ~isfield(ext,'section') | ~isfield(ext,'num_ext') - error('Wrong header extension'); - end - - write_ext(ext, fid); - - return; % save_nii_ext - - -%--------------------------------------------------------------------- -function write_ext(ext, fid) - - fwrite(fid, ext.extension, 'uchar'); - - for i=1:ext.num_ext - fwrite(fid, ext.section(i).esize, 'int32'); - fwrite(fid, ext.section(i).ecode, 'int32'); - fwrite(fid, ext.section(i).edata, 'uchar'); - end - - return; % write_ext - diff --git a/func/utils/nii/save_nii_hdr.m b/func/utils/nii/save_nii_hdr.m deleted file mode 100644 index d3160a2..0000000 --- a/func/utils/nii/save_nii_hdr.m +++ /dev/null @@ -1,227 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function save_nii_hdr(hdr, fid) - - if ~exist('hdr','var') | ~exist('fid','var') - error('Usage: save_nii_hdr(hdr, fid)'); - end - - if ~isequal(hdr.hk.sizeof_hdr,348), - error('hdr.hk.sizeof_hdr must be 348.'); - end - - if hdr.hist.qform_code == 0 & hdr.hist.sform_code == 0 - hdr.hist.sform_code = 1; - hdr.hist.srow_x(1) = hdr.dime.pixdim(2); - hdr.hist.srow_x(2) = 0; - hdr.hist.srow_x(3) = 0; - hdr.hist.srow_y(1) = 0; - hdr.hist.srow_y(2) = hdr.dime.pixdim(3); - hdr.hist.srow_y(3) = 0; - hdr.hist.srow_z(1) = 0; - hdr.hist.srow_z(2) = 0; - hdr.hist.srow_z(3) = hdr.dime.pixdim(4); - hdr.hist.srow_x(4) = (1-hdr.hist.originator(1))*hdr.dime.pixdim(2); - hdr.hist.srow_y(4) = (1-hdr.hist.originator(2))*hdr.dime.pixdim(3); - hdr.hist.srow_z(4) = (1-hdr.hist.originator(3))*hdr.dime.pixdim(4); - end - - write_header(hdr, fid); - - return; % save_nii_hdr - - -%--------------------------------------------------------------------- -function write_header(hdr, fid) - - % Original header structures - % struct dsr /* dsr = hdr */ - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - header_key(fid, hdr.hk); - image_dimension(fid, hdr.dime); - data_history(fid, hdr.hist); - - % check the file size is 348 bytes - % - fbytes = ftell(fid); - - if ~isequal(fbytes,348), - msg = sprintf('Header size is not 348 bytes.'); - warning(msg); - end - - return; % write_header - - -%--------------------------------------------------------------------- -function header_key(fid, hk) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char dim_info; % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - - fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. - - % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left - % fwrite(fid, data_type(1:10), 'uchar'); - pad = zeros(1, 10-length(hk.data_type)); - hk.data_type = [hk.data_type char(pad)]; - fwrite(fid, hk.data_type(1:10), 'uchar'); - - % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left - % fwrite(fid, db_name(1:18), 'uchar'); - pad = zeros(1, 18-length(hk.db_name)); - hk.db_name = [hk.db_name char(pad)]; - fwrite(fid, hk.db_name(1:18), 'uchar'); - - fwrite(fid, hk.extents(1), 'int32'); - fwrite(fid, hk.session_error(1), 'int16'); - fwrite(fid, hk.regular(1), 'uchar'); % might be uint8 - - % fwrite(fid, hk.hkey_un0(1), 'uchar'); - % fwrite(fid, hk.hkey_un0(1), 'uint8'); - fwrite(fid, hk.dim_info(1), 'uchar'); - - return; % header_key - - -%--------------------------------------------------------------------- -function image_dimension(fid, dime) - - % Original header structures - % struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % float intent_p1; % char vox_units[4]; /* 16 + 4 */ - % float intent_p2; % char cal_units[8]; /* 20 + 4 */ - % float intent_p3; % char cal_units[8]; /* 24 + 4 */ - % short int intent_code; % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int slice_start; % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width - % pixdim[2] - voxel height - % pixdim[3] - interslice distance - % pixdim[4] - volume timing, in msec - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float scl_slope; % float roi_scale; /* 72 + 4 */ - % float scl_inter; % float funused1; /* 76 + 4 */ - % short slice_end; % float funused2; /* 80 + 2 */ - % char slice_code; % float funused2; /* 82 + 1 */ - % char xyzt_units; % float funused2; /* 83 + 1 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % float slice_duration; % int compressed; /* 92 + 4 */ - % float toffset; % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - fwrite(fid, dime.dim(1:8), 'int16'); - fwrite(fid, dime.intent_p1(1), 'float32'); - fwrite(fid, dime.intent_p2(1), 'float32'); - fwrite(fid, dime.intent_p3(1), 'float32'); - fwrite(fid, dime.intent_code(1), 'int16'); - fwrite(fid, dime.datatype(1), 'int16'); - fwrite(fid, dime.bitpix(1), 'int16'); - fwrite(fid, dime.slice_start(1), 'int16'); - fwrite(fid, dime.pixdim(1:8), 'float32'); - fwrite(fid, dime.vox_offset(1), 'float32'); - fwrite(fid, dime.scl_slope(1), 'float32'); - fwrite(fid, dime.scl_inter(1), 'float32'); - fwrite(fid, dime.slice_end(1), 'int16'); - fwrite(fid, dime.slice_code(1), 'uchar'); - fwrite(fid, dime.xyzt_units(1), 'uchar'); - fwrite(fid, dime.cal_max(1), 'float32'); - fwrite(fid, dime.cal_min(1), 'float32'); - fwrite(fid, dime.slice_duration(1), 'float32'); - fwrite(fid, dime.toffset(1), 'float32'); - fwrite(fid, dime.glmax(1), 'int32'); - fwrite(fid, dime.glmin(1), 'int32'); - - return; % image_dimension - - -%--------------------------------------------------------------------- -function data_history(fid, hist) - - % Original header structures - %struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % short int qform_code; /* 104 + 2 */ - % short int sform_code; /* 106 + 2 */ - % float quatern_b; /* 108 + 4 */ - % float quatern_c; /* 112 + 4 */ - % float quatern_d; /* 116 + 4 */ - % float qoffset_x; /* 120 + 4 */ - % float qoffset_y; /* 124 + 4 */ - % float qoffset_z; /* 128 + 4 */ - % float srow_x[4]; /* 132 + 16 */ - % float srow_y[4]; /* 148 + 16 */ - % float srow_z[4]; /* 164 + 16 */ - % char intent_name[16]; /* 180 + 16 */ - % char magic[4]; % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left - % fwrite(fid, descrip(1:80), 'uchar'); - pad = zeros(1, 80-length(hist.descrip)); - hist.descrip = [hist.descrip char(pad)]; - fwrite(fid, hist.descrip(1:80), 'uchar'); - - % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left - % fwrite(fid, aux_file(1:24), 'uchar'); - pad = zeros(1, 24-length(hist.aux_file)); - hist.aux_file = [hist.aux_file char(pad)]; - fwrite(fid, hist.aux_file(1:24), 'uchar'); - - fwrite(fid, hist.qform_code, 'int16'); - fwrite(fid, hist.sform_code, 'int16'); - fwrite(fid, hist.quatern_b, 'float32'); - fwrite(fid, hist.quatern_c, 'float32'); - fwrite(fid, hist.quatern_d, 'float32'); - fwrite(fid, hist.qoffset_x, 'float32'); - fwrite(fid, hist.qoffset_y, 'float32'); - fwrite(fid, hist.qoffset_z, 'float32'); - fwrite(fid, hist.srow_x(1:4), 'float32'); - fwrite(fid, hist.srow_y(1:4), 'float32'); - fwrite(fid, hist.srow_z(1:4), 'float32'); - - % intent_name = sprintf('%-16s', hist.intent_name); % 16 chars from left - % fwrite(fid, intent_name(1:16), 'uchar'); - pad = zeros(1, 16-length(hist.intent_name)); - hist.intent_name = [hist.intent_name char(pad)]; - fwrite(fid, hist.intent_name(1:16), 'uchar'); - - % magic = sprintf('%-4s', hist.magic); % 4 chars from left - % fwrite(fid, magic(1:4), 'uchar'); - pad = zeros(1, 4-length(hist.magic)); - hist.magic = [hist.magic char(pad)]; - fwrite(fid, hist.magic(1:4), 'uchar'); - - return; % data_history - diff --git a/func/utils/nii/save_untouch0_nii_hdr.m b/func/utils/nii/save_untouch0_nii_hdr.m deleted file mode 100644 index b812776..0000000 --- a/func/utils/nii/save_untouch0_nii_hdr.m +++ /dev/null @@ -1,219 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function save_nii_hdr(hdr, fid) - - if ~isequal(hdr.hk.sizeof_hdr,348), - error('hdr.hk.sizeof_hdr must be 348.'); - end - - write_header(hdr, fid); - - return; % save_nii_hdr - - -%--------------------------------------------------------------------- -function write_header(hdr, fid) - - % Original header structures - % struct dsr /* dsr = hdr */ - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - header_key(fid, hdr.hk); - image_dimension(fid, hdr.dime); - data_history(fid, hdr.hist); - - % check the file size is 348 bytes - % - fbytes = ftell(fid); - - if ~isequal(fbytes,348), - msg = sprintf('Header size is not 348 bytes.'); - warning(msg); - end - - return; % write_header - - -%--------------------------------------------------------------------- -function header_key(fid, hk) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - - fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. - - % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left - % fwrite(fid, data_type(1:10), 'uchar'); - pad = zeros(1, 10-length(hk.data_type)); - hk.data_type = [hk.data_type char(pad)]; - fwrite(fid, hk.data_type(1:10), 'uchar'); - - % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left - % fwrite(fid, db_name(1:18), 'uchar'); - pad = zeros(1, 18-length(hk.db_name)); - hk.db_name = [hk.db_name char(pad)]; - fwrite(fid, hk.db_name(1:18), 'uchar'); - - fwrite(fid, hk.extents(1), 'int32'); - fwrite(fid, hk.session_error(1), 'int16'); - fwrite(fid, hk.regular(1), 'uchar'); - - fwrite(fid, hk.hkey_un0(1), 'uchar'); - - return; % header_key - - -%--------------------------------------------------------------------- -function image_dimension(fid, dime) - - %struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % char vox_units[4]; /* 16 + 4 */ - % char cal_units[8]; /* 20 + 8 */ - % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width - % pixdim[2] - voxel height - % pixdim[3] - interslice distance - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float roi_scale; /* 72 + 4 */ - % float funused1; /* 76 + 4 */ - % float funused2; /* 80 + 4 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % int compressed; /* 92 + 4 */ - % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - fwrite(fid, dime.dim(1:8), 'int16'); - - pad = zeros(1, 4-length(dime.vox_units)); - dime.vox_units = [dime.vox_units char(pad)]; - fwrite(fid, dime.vox_units(1:4), 'uchar'); - - pad = zeros(1, 8-length(dime.cal_units)); - dime.cal_units = [dime.cal_units char(pad)]; - fwrite(fid, dime.cal_units(1:8), 'uchar'); - - fwrite(fid, dime.unused1(1), 'int16'); - fwrite(fid, dime.datatype(1), 'int16'); - fwrite(fid, dime.bitpix(1), 'int16'); - fwrite(fid, dime.dim_un0(1), 'int16'); - fwrite(fid, dime.pixdim(1:8), 'float32'); - fwrite(fid, dime.vox_offset(1), 'float32'); - fwrite(fid, dime.roi_scale(1), 'float32'); - fwrite(fid, dime.funused1(1), 'float32'); - fwrite(fid, dime.funused2(1), 'float32'); - fwrite(fid, dime.cal_max(1), 'float32'); - fwrite(fid, dime.cal_min(1), 'float32'); - fwrite(fid, dime.compressed(1), 'int32'); - fwrite(fid, dime.verified(1), 'int32'); - fwrite(fid, dime.glmax(1), 'int32'); - fwrite(fid, dime.glmin(1), 'int32'); - - return; % image_dimension - - -%--------------------------------------------------------------------- -function data_history(fid, hist) - - % Original header structures - ANALYZE 7.5 - %struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % char orient; /* 104 + 1 */ - % char originator[10]; /* 105 + 10 */ - % char generated[10]; /* 115 + 10 */ - % char scannum[10]; /* 125 + 10 */ - % char patient_id[10]; /* 135 + 10 */ - % char exp_date[10]; /* 145 + 10 */ - % char exp_time[10]; /* 155 + 10 */ - % char hist_un0[3]; /* 165 + 3 */ - % int views /* 168 + 4 */ - % int vols_added; /* 172 + 4 */ - % int start_field; /* 176 + 4 */ - % int field_skip; /* 180 + 4 */ - % int omax; /* 184 + 4 */ - % int omin; /* 188 + 4 */ - % int smax; /* 192 + 4 */ - % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left - % fwrite(fid, descrip(1:80), 'uchar'); - pad = zeros(1, 80-length(hist.descrip)); - hist.descrip = [hist.descrip char(pad)]; - fwrite(fid, hist.descrip(1:80), 'uchar'); - - % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left - % fwrite(fid, aux_file(1:24), 'uchar'); - pad = zeros(1, 24-length(hist.aux_file)); - hist.aux_file = [hist.aux_file char(pad)]; - fwrite(fid, hist.aux_file(1:24), 'uchar'); - - fwrite(fid, hist.orient(1), 'uchar'); - fwrite(fid, hist.originator(1:5), 'int16'); - - pad = zeros(1, 10-length(hist.generated)); - hist.generated = [hist.generated char(pad)]; - fwrite(fid, hist.generated(1:10), 'uchar'); - - pad = zeros(1, 10-length(hist.scannum)); - hist.scannum = [hist.scannum char(pad)]; - fwrite(fid, hist.scannum(1:10), 'uchar'); - - pad = zeros(1, 10-length(hist.patient_id)); - hist.patient_id = [hist.patient_id char(pad)]; - fwrite(fid, hist.patient_id(1:10), 'uchar'); - - pad = zeros(1, 10-length(hist.exp_date)); - hist.exp_date = [hist.exp_date char(pad)]; - fwrite(fid, hist.exp_date(1:10), 'uchar'); - - pad = zeros(1, 10-length(hist.exp_time)); - hist.exp_time = [hist.exp_time char(pad)]; - fwrite(fid, hist.exp_time(1:10), 'uchar'); - - pad = zeros(1, 3-length(hist.hist_un0)); - hist.hist_un0 = [hist.hist_un0 char(pad)]; - fwrite(fid, hist.hist_un0(1:3), 'uchar'); - - fwrite(fid, hist.views(1), 'int32'); - fwrite(fid, hist.vols_added(1), 'int32'); - fwrite(fid, hist.start_field(1),'int32'); - fwrite(fid, hist.field_skip(1), 'int32'); - fwrite(fid, hist.omax(1), 'int32'); - fwrite(fid, hist.omin(1), 'int32'); - fwrite(fid, hist.smax(1), 'int32'); - fwrite(fid, hist.smin(1), 'int32'); - - return; % data_history - diff --git a/func/utils/nii/save_untouch_header_only.m b/func/utils/nii/save_untouch_header_only.m deleted file mode 100644 index edbce71..0000000 --- a/func/utils/nii/save_untouch_header_only.m +++ /dev/null @@ -1,71 +0,0 @@ -% This function is only used to save Analyze or NIfTI header that is -% ended with .hdr and loaded by load_untouch_header_only.m. If you -% have NIfTI file that is ended with .nii and you want to change its -% header only, you can use load_untouch_nii / save_untouch_nii pair. -% -% Usage: save_untouch_header_only(hdr, new_header_file_name) -% -% hdr - struct with NIfTI / Analyze header fields, which is obtained from: -% hdr = load_untouch_header_only(original_header_file_name) -% -% new_header_file_name - NIfTI / Analyze header name ended with .hdr. -% You can either copy original.img(.gz) to new.img(.gz) manually, -% or simply input original.hdr(.gz) in save_untouch_header_only.m -% to overwrite the original header. -% -% - Jimmy Shen (jshen@research.baycrest.org) -% -function save_untouch_header_only(hdr, filename) - - if ~exist('hdr','var') | isempty(hdr) | ~exist('filename','var') | isempty(filename) - error('Usage: save_untouch_header_only(hdr, filename)'); - end - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.hdr.gz') - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - else - gzFile = 1; - filename = filename(1:end-3); - end - end - - [p,f] = fileparts(filename); - fileprefix = fullfile(p, f); - - write_hdr(hdr, fileprefix); - - % gzip output file if requested - % - if exist('gzFile', 'var') - gzip([fileprefix, '.hdr']); - delete([fileprefix, '.hdr']); - end; - - return % save_untouch_header_only - - -%----------------------------------------------------------------------------------- -function write_hdr(hdr, fileprefix) - - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if isfield(hdr.hist,'magic') - save_untouch_nii_hdr(hdr, fid); - else - save_untouch0_nii_hdr(hdr, fid); - end - - fclose(fid); - - return % write_hdr - diff --git a/func/utils/nii/save_untouch_nii.m b/func/utils/nii/save_untouch_nii.m deleted file mode 100644 index 3faa64c..0000000 --- a/func/utils/nii/save_untouch_nii.m +++ /dev/null @@ -1,232 +0,0 @@ -% Save NIFTI or ANALYZE dataset that is loaded by "load_untouch_nii.m". -% The output image format and file extension will be the same as the -% input one (NIFTI.nii, NIFTI.img or ANALYZE.img). Therefore, any file -% extension that you specified will be ignored. -% -% Usage: save_untouch_nii(nii, filename) -% -% nii - nii structure that is loaded by "load_untouch_nii.m" -% -% filename - NIFTI or ANALYZE file name. -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function save_untouch_nii(nii, filename) - - if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... - ~isfield(nii,'img') | ~exist('filename','var') | isempty(filename) - - error('Usage: save_untouch_nii(nii, filename)'); - end - - if ~isfield(nii,'untouch') | nii.untouch == 0 - error('Usage: please use ''save_nii.m'' for the modified structure.'); - end - - if isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'ni1') - filetype = 1; - elseif isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'n+1') - filetype = 2; - else - filetype = 0; - end - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - else - gzFile = 1; - filename = filename(1:end-3); - end - end - - [p,f] = fileparts(filename); - fileprefix = fullfile(p, f); - - write_nii(nii, filetype, fileprefix); - - % gzip output file if requested - % - if exist('gzFile', 'var') - if filetype == 1 - gzip([fileprefix, '.img']); - delete([fileprefix, '.img']); - gzip([fileprefix, '.hdr']); - delete([fileprefix, '.hdr']); - elseif filetype == 2 - gzip([fileprefix, '.nii']); - delete([fileprefix, '.nii']); - end; - end; - -% % So earlier versions of SPM can also open it with correct originator - % % - % if filetype == 0 - % M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; - % save(fileprefix, 'M'); -% elseif filetype == 1 - % M=[]; - % save(fileprefix, 'M'); - %end - - return % save_untouch_nii - - -%----------------------------------------------------------------------------------- -function write_nii(nii, filetype, fileprefix) - - hdr = nii.hdr; - - if isfield(nii,'ext') & ~isempty(nii.ext) - ext = nii.ext; - [ext, esize_total] = verify_nii_ext(ext); - else - ext = []; - end - - switch double(hdr.dime.datatype), - case 1, - hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; - case 2, - hdr.dime.bitpix = int16(8 ); precision = 'uint8'; - case 4, - hdr.dime.bitpix = int16(16); precision = 'int16'; - case 8, - hdr.dime.bitpix = int16(32); precision = 'int32'; - case 16, - hdr.dime.bitpix = int16(32); precision = 'float32'; - case 32, - hdr.dime.bitpix = int16(64); precision = 'float32'; - case 64, - hdr.dime.bitpix = int16(64); precision = 'float64'; - case 128, - hdr.dime.bitpix = int16(24); precision = 'uint8'; - case 256 - hdr.dime.bitpix = int16(8 ); precision = 'int8'; - case 512 - hdr.dime.bitpix = int16(16); precision = 'uint16'; - case 768 - hdr.dime.bitpix = int16(32); precision = 'uint32'; - case 1024 - hdr.dime.bitpix = int16(64); precision = 'int64'; - case 1280 - hdr.dime.bitpix = int16(64); precision = 'uint64'; - case 1792, - hdr.dime.bitpix = int16(128); precision = 'float64'; - otherwise - error('This datatype is not supported'); - end - -% hdr.dime.glmax = round(double(max(nii.img(:)))); - % hdr.dime.glmin = round(double(min(nii.img(:)))); - - if filetype == 2 - fid = fopen(sprintf('%s.nii',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.nii.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 352; - - if ~isempty(ext) - hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; - end - - hdr.hist.magic = 'n+1'; - save_untouch_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - elseif filetype == 1 - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - hdr.dime.vox_offset = 0; - hdr.hist.magic = 'ni1'; - save_untouch_nii_hdr(hdr, fid); - - if ~isempty(ext) - save_nii_ext(ext, fid); - end - - fclose(fid); - fid = fopen(sprintf('%s.img',fileprefix),'w'); - else - fid = fopen(sprintf('%s.hdr',fileprefix),'w'); - - if fid < 0, - msg = sprintf('Cannot open file %s.hdr.',fileprefix); - error(msg); - end - - save_untouch0_nii_hdr(hdr, fid); - - fclose(fid); - fid = fopen(sprintf('%s.img',fileprefix),'w'); - end - - ScanDim = double(hdr.dime.dim(5)); % t - SliceDim = double(hdr.dime.dim(4)); % z - RowDim = double(hdr.dime.dim(3)); % y - PixelDim = double(hdr.dime.dim(2)); % x - SliceSz = double(hdr.dime.pixdim(4)); - RowSz = double(hdr.dime.pixdim(3)); - PixelSz = double(hdr.dime.pixdim(2)); - - x = 1:PixelDim; - - if filetype == 2 & isempty(ext) - skip_bytes = double(hdr.dime.vox_offset) - 348; - else - skip_bytes = 0; - end - - if double(hdr.dime.datatype) == 128 - - % RGB planes are expected to be in the 4th dimension of nii.img - % - if(size(nii.img,4)~=3) - error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); - end - - nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); - end - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - real_img = real(nii.img(:))'; - nii.img = imag(nii.img(:))'; - nii.img = [real_img; nii.img]; - end - - if skip_bytes - fwrite(fid, zeros(1,skip_bytes), 'uint8'); - end - - fwrite(fid, nii.img, precision); -% fwrite(fid, nii.img, precision, skip_bytes); % error using skip - fclose(fid); - - return; % write_nii - diff --git a/func/utils/nii/save_untouch_nii_hdr.m b/func/utils/nii/save_untouch_nii_hdr.m deleted file mode 100644 index 9ee0fd6..0000000 --- a/func/utils/nii/save_untouch_nii_hdr.m +++ /dev/null @@ -1,207 +0,0 @@ -% internal function - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) - -function save_nii_hdr(hdr, fid) - - if ~isequal(hdr.hk.sizeof_hdr,348), - error('hdr.hk.sizeof_hdr must be 348.'); - end - - write_header(hdr, fid); - - return; % save_nii_hdr - - -%--------------------------------------------------------------------- -function write_header(hdr, fid) - - % Original header structures - % struct dsr /* dsr = hdr */ - % { - % struct header_key hk; /* 0 + 40 */ - % struct image_dimension dime; /* 40 + 108 */ - % struct data_history hist; /* 148 + 200 */ - % }; /* total= 348 bytes*/ - - header_key(fid, hdr.hk); - image_dimension(fid, hdr.dime); - data_history(fid, hdr.hist); - - % check the file size is 348 bytes - % - fbytes = ftell(fid); - - if ~isequal(fbytes,348), - msg = sprintf('Header size is not 348 bytes.'); - warning(msg); - end - - return; % write_header - - -%--------------------------------------------------------------------- -function header_key(fid, hk) - - fseek(fid,0,'bof'); - - % Original header structures - % struct header_key /* header key */ - % { /* off + size */ - % int sizeof_hdr /* 0 + 4 */ - % char data_type[10]; /* 4 + 10 */ - % char db_name[18]; /* 14 + 18 */ - % int extents; /* 32 + 4 */ - % short int session_error; /* 36 + 2 */ - % char regular; /* 38 + 1 */ - % char dim_info; % char hkey_un0; /* 39 + 1 */ - % }; /* total=40 bytes */ - - fwrite(fid, hk.sizeof_hdr(1), 'int32'); % must be 348. - - % data_type = sprintf('%-10s',hk.data_type); % ensure it is 10 chars from left - % fwrite(fid, data_type(1:10), 'uchar'); - pad = zeros(1, 10-length(hk.data_type)); - hk.data_type = [hk.data_type char(pad)]; - fwrite(fid, hk.data_type(1:10), 'uchar'); - - % db_name = sprintf('%-18s', hk.db_name); % ensure it is 18 chars from left - % fwrite(fid, db_name(1:18), 'uchar'); - pad = zeros(1, 18-length(hk.db_name)); - hk.db_name = [hk.db_name char(pad)]; - fwrite(fid, hk.db_name(1:18), 'uchar'); - - fwrite(fid, hk.extents(1), 'int32'); - fwrite(fid, hk.session_error(1), 'int16'); - fwrite(fid, hk.regular(1), 'uchar'); % might be uint8 - - % fwrite(fid, hk.hkey_un0(1), 'uchar'); - % fwrite(fid, hk.hkey_un0(1), 'uint8'); - fwrite(fid, hk.dim_info(1), 'uchar'); - - return; % header_key - - -%--------------------------------------------------------------------- -function image_dimension(fid, dime) - - % Original header structures - % struct image_dimension - % { /* off + size */ - % short int dim[8]; /* 0 + 16 */ - % float intent_p1; % char vox_units[4]; /* 16 + 4 */ - % float intent_p2; % char cal_units[8]; /* 20 + 4 */ - % float intent_p3; % char cal_units[8]; /* 24 + 4 */ - % short int intent_code; % short int unused1; /* 28 + 2 */ - % short int datatype; /* 30 + 2 */ - % short int bitpix; /* 32 + 2 */ - % short int slice_start; % short int dim_un0; /* 34 + 2 */ - % float pixdim[8]; /* 36 + 32 */ - % /* - % pixdim[] specifies the voxel dimensions: - % pixdim[1] - voxel width - % pixdim[2] - voxel height - % pixdim[3] - interslice distance - % pixdim[4] - volume timing, in msec - % ..etc - % */ - % float vox_offset; /* 68 + 4 */ - % float scl_slope; % float roi_scale; /* 72 + 4 */ - % float scl_inter; % float funused1; /* 76 + 4 */ - % short slice_end; % float funused2; /* 80 + 2 */ - % char slice_code; % float funused2; /* 82 + 1 */ - % char xyzt_units; % float funused2; /* 83 + 1 */ - % float cal_max; /* 84 + 4 */ - % float cal_min; /* 88 + 4 */ - % float slice_duration; % int compressed; /* 92 + 4 */ - % float toffset; % int verified; /* 96 + 4 */ - % int glmax; /* 100 + 4 */ - % int glmin; /* 104 + 4 */ - % }; /* total=108 bytes */ - - fwrite(fid, dime.dim(1:8), 'int16'); - fwrite(fid, dime.intent_p1(1), 'float32'); - fwrite(fid, dime.intent_p2(1), 'float32'); - fwrite(fid, dime.intent_p3(1), 'float32'); - fwrite(fid, dime.intent_code(1), 'int16'); - fwrite(fid, dime.datatype(1), 'int16'); - fwrite(fid, dime.bitpix(1), 'int16'); - fwrite(fid, dime.slice_start(1), 'int16'); - fwrite(fid, dime.pixdim(1:8), 'float32'); - fwrite(fid, dime.vox_offset(1), 'float32'); - fwrite(fid, dime.scl_slope(1), 'float32'); - fwrite(fid, dime.scl_inter(1), 'float32'); - fwrite(fid, dime.slice_end(1), 'int16'); - fwrite(fid, dime.slice_code(1), 'uchar'); - fwrite(fid, dime.xyzt_units(1), 'uchar'); - fwrite(fid, dime.cal_max(1), 'float32'); - fwrite(fid, dime.cal_min(1), 'float32'); - fwrite(fid, dime.slice_duration(1), 'float32'); - fwrite(fid, dime.toffset(1), 'float32'); - fwrite(fid, dime.glmax(1), 'int32'); - fwrite(fid, dime.glmin(1), 'int32'); - - return; % image_dimension - - -%--------------------------------------------------------------------- -function data_history(fid, hist) - - % Original header structures - %struct data_history - % { /* off + size */ - % char descrip[80]; /* 0 + 80 */ - % char aux_file[24]; /* 80 + 24 */ - % short int qform_code; /* 104 + 2 */ - % short int sform_code; /* 106 + 2 */ - % float quatern_b; /* 108 + 4 */ - % float quatern_c; /* 112 + 4 */ - % float quatern_d; /* 116 + 4 */ - % float qoffset_x; /* 120 + 4 */ - % float qoffset_y; /* 124 + 4 */ - % float qoffset_z; /* 128 + 4 */ - % float srow_x[4]; /* 132 + 16 */ - % float srow_y[4]; /* 148 + 16 */ - % float srow_z[4]; /* 164 + 16 */ - % char intent_name[16]; /* 180 + 16 */ - % char magic[4]; % int smin; /* 196 + 4 */ - % }; /* total=200 bytes */ - - % descrip = sprintf('%-80s', hist.descrip); % 80 chars from left - % fwrite(fid, descrip(1:80), 'uchar'); - pad = zeros(1, 80-length(hist.descrip)); - hist.descrip = [hist.descrip char(pad)]; - fwrite(fid, hist.descrip(1:80), 'uchar'); - - % aux_file = sprintf('%-24s', hist.aux_file); % 24 chars from left - % fwrite(fid, aux_file(1:24), 'uchar'); - pad = zeros(1, 24-length(hist.aux_file)); - hist.aux_file = [hist.aux_file char(pad)]; - fwrite(fid, hist.aux_file(1:24), 'uchar'); - - fwrite(fid, hist.qform_code, 'int16'); - fwrite(fid, hist.sform_code, 'int16'); - fwrite(fid, hist.quatern_b, 'float32'); - fwrite(fid, hist.quatern_c, 'float32'); - fwrite(fid, hist.quatern_d, 'float32'); - fwrite(fid, hist.qoffset_x, 'float32'); - fwrite(fid, hist.qoffset_y, 'float32'); - fwrite(fid, hist.qoffset_z, 'float32'); - fwrite(fid, hist.srow_x(1:4), 'float32'); - fwrite(fid, hist.srow_y(1:4), 'float32'); - fwrite(fid, hist.srow_z(1:4), 'float32'); - - % intent_name = sprintf('%-16s', hist.intent_name); % 16 chars from left - % fwrite(fid, intent_name(1:16), 'uchar'); - pad = zeros(1, 16-length(hist.intent_name)); - hist.intent_name = [hist.intent_name char(pad)]; - fwrite(fid, hist.intent_name(1:16), 'uchar'); - - % magic = sprintf('%-4s', hist.magic); % 4 chars from left - % fwrite(fid, magic(1:4), 'uchar'); - pad = zeros(1, 4-length(hist.magic)); - hist.magic = [hist.magic char(pad)]; - fwrite(fid, hist.magic(1:4), 'uchar'); - - return; % data_history - diff --git a/func/utils/nii/save_untouch_slice.m b/func/utils/nii/save_untouch_slice.m deleted file mode 100644 index a9668d2..0000000 --- a/func/utils/nii/save_untouch_slice.m +++ /dev/null @@ -1,580 +0,0 @@ -% Save back to the original image with a portion of slices that was -% loaded by "load_untouch_nii". You can process those slices matrix -% in any way, as long as their dimension is not altered. -% -% Usage: save_untouch_slice(slice, filename, ... -% slice_idx, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx]) -% -% slice - a portion of slices that was loaded by "load_untouch_nii". -% This should be a numeric matrix (i.e. only the .img field in the -% loaded structure) -% -% filename - NIfTI or ANALYZE file name. -% -% slice_idx (depending on slice size) - a numerical array of image -% slice indices, which should be the same as that you entered -% in "load_untouch_nii" command. -% -% img_idx (depending on slice size) - a numerical array of image -% volume indices, which should be the same as that you entered -% in "load_untouch_nii" command. -% -% dim5_idx (depending on slice size) - a numerical array of 5th -% dimension indices, which should be the same as that you entered -% in "load_untouch_nii" command. -% -% dim6_idx (depending on slice size) - a numerical array of 6th -% dimension indices, which should be the same as that you entered -% in "load_untouch_nii" command. -% -% dim7_idx (depending on slice size) - a numerical array of 7th -% dimension indices, which should be the same as that you entered -% in "load_untouch_nii" command. -% -% Example: -% nii = load_nii('avg152T1_LR_nifti.nii'); -% save_nii(nii, 'test.nii'); -% view_nii(nii); -% nii = load_untouch_nii('test.nii','','','','','',[40 51:53]); -% nii.img = ones(91,109,4)*122; -% save_untouch_slice(nii.img, 'test.nii', [40 51:52]); -% nii = load_nii('test.nii'); -% view_nii(nii); -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function save_untouch_slice(slice, filename, slice_idx, img_idx, dim5_idx, dim6_idx, dim7_idx) - - if ~exist('slice','var') | ~isnumeric(slice) - msg = [char(10) '"slice" argument should be a portion of slices that was loaded' char(10)]; - msg = [msg 'by "load_untouch_nii.m". This should be a numeric matrix (i.e.' char(10)]; - msg = [msg 'only the .img field in the loaded structure).']; - error(msg); - end - - if ~exist('filename','var') | ~exist(filename,'file') - error('In order to save back, original NIfTI or ANALYZE file must exist.'); - end - - if ~exist('slice_idx','var') | isempty(slice_idx) | ~isequal(size(slice,3),length(slice_idx)) - msg = [char(10) '"slice_idx" is a numerical array of image slice indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - - if ~exist('img_idx','var') | isempty(img_idx) - img_idx = []; - - if ~isequal(size(slice,4),1) - msg = [char(10) '"img_idx" is a numerical array of image volume indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - elseif ~isequal(size(slice,4),length(img_idx)) - msg = [char(10) '"img_idx" is a numerical array of image volume indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) - dim5_idx = []; - - if ~isequal(size(slice,5),1) - msg = [char(10) '"dim5_idx" is a numerical array of 5th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - elseif ~isequal(size(slice,5),length(img_idx)) - msg = [char(10) '"img_idx" is a numerical array of 5th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) - dim6_idx = []; - - if ~isequal(size(slice,6),1) - msg = [char(10) '"dim6_idx" is a numerical array of 6th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - elseif ~isequal(size(slice,6),length(img_idx)) - msg = [char(10) '"img_idx" is a numerical array of 6th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) - dim7_idx = []; - - if ~isequal(size(slice,7),1) - msg = [char(10) '"dim7_idx" is a numerical array of 7th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - elseif ~isequal(size(slice,7),length(img_idx)) - msg = [char(10) '"img_idx" is a numerical array of 7th dimension indices, which' char(10)]; - msg = [msg 'should be the same as that you entered in "load_untouch_nii.m"' char(10)]; - msg = [msg 'command.']; - error(msg); - end - - - v = version; - - % Check file extension. If .gz, unpack it into temp folder - % - if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') - - if ~strcmp(filename(end-6:end), '.img.gz') & ... - ~strcmp(filename(end-6:end), '.hdr.gz') & ... - ~strcmp(filename(end-6:end), '.nii.gz') - - error('Please check filename.'); - end - - if str2num(v(1:3)) < 7.1 | ~usejava('jvm') - error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); - elseif strcmp(filename(end-6:end), '.img.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.hdr.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.hdr.gz') - filename1 = filename; - filename2 = filename; - filename2(end-6:end) = ''; - filename2 = [filename2, '.img.gz']; - - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - - filename1 = gunzip(filename1, tmpDir); - filename2 = gunzip(filename2, tmpDir); - filename = char(filename1); % convert from cell to string - elseif strcmp(filename(end-6:end), '.nii.gz') - tmpDir = tempname; - mkdir(tmpDir); - gzFileName = filename; - filename = gunzip(filename, tmpDir); - filename = char(filename); % convert from cell to string - end - end - - % Read the dataset header - % - [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); - - if nii.filetype == 0 - nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine); - else - nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype); - end - - - % Clean up after gunzip - % - if exist('gzFileName', 'var') - - % fix fileprefix so it doesn't point to temp location - % - nii.fileprefix = gzFileName(1:end-7); -% rmdir(tmpDir,'s'); - end - - [p,f] = fileparts(filename); - fileprefix = fullfile(p, f); -% fileprefix = nii.fileprefix; - filetype = nii.filetype; - - if ~isequal( nii.hdr.dime.dim(2:3), [size(slice,1),size(slice,2)] ) - msg = [char(10) 'The first two dimensions of slice matrix should be the same as' char(10)]; - msg = [msg 'the first two dimensions of image loaded by "load_untouch_nii".']; - error(msg); - end - - - % Save the dataset body - % - save_untouch_slice_img(slice, nii.hdr, filetype, fileprefix, ... - nii.machine, slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx); - - % gzip output file if requested - % - if exist('gzFileName', 'var') - [p,f] = fileparts(gzFileName); - - if filetype == 1 - gzip([fileprefix, '.img']); - delete([fileprefix, '.img']); - movefile([fileprefix, '.img.gz']); - gzip([fileprefix, '.hdr']); - delete([fileprefix, '.hdr']); - movefile([fileprefix, '.hdr.gz']); - elseif filetype == 2 - gzip([fileprefix, '.nii']); - delete([fileprefix, '.nii']); - movefile([fileprefix, '.nii.gz']); - end; - - rmdir(tmpDir,'s'); - end; - - return % save_untouch_slice - - -%-------------------------------------------------------------------------- -function save_untouch_slice_img(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx) - - if ~exist('hdr','var') | ~exist('filetype','var') | ~exist('fileprefix','var') | ~exist('machine','var') - error('Usage: save_untouch_slice_img(slice,hdr,filetype,fileprefix,machine,slice_idx,[img_idx],[dim5_idx],[dim6_idx],[dim7_idx]);'); - end - - if ~exist('slice_idx','var') | isempty(slice_idx) | hdr.dime.dim(4)<1 - slice_idx = []; - end - - if ~exist('img_idx','var') | isempty(img_idx) | hdr.dime.dim(5)<1 - img_idx = []; - end - - if ~exist('dim5_idx','var') | isempty(dim5_idx) | hdr.dime.dim(6)<1 - dim5_idx = []; - end - - if ~exist('dim6_idx','var') | isempty(dim6_idx) | hdr.dime.dim(7)<1 - dim6_idx = []; - end - - if ~exist('dim7_idx','var') | isempty(dim7_idx) | hdr.dime.dim(8)<1 - dim7_idx = []; - end - - % check img_idx - % - if ~isempty(img_idx) & ~isnumeric(img_idx) - error('"img_idx" should be a numerical array.'); - end - - if length(unique(img_idx)) ~= length(img_idx) - error('Duplicate image index in "img_idx"'); - end - - if ~isempty(img_idx) & (min(img_idx) < 1 | max(img_idx) > hdr.dime.dim(5)) - max_range = hdr.dime.dim(5); - - if max_range == 1 - error(['"img_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"img_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim5_idx - % - if ~isempty(dim5_idx) & ~isnumeric(dim5_idx) - error('"dim5_idx" should be a numerical array.'); - end - - if length(unique(dim5_idx)) ~= length(dim5_idx) - error('Duplicate index in "dim5_idx"'); - end - - if ~isempty(dim5_idx) & (min(dim5_idx) < 1 | max(dim5_idx) > hdr.dime.dim(6)) - max_range = hdr.dime.dim(6); - - if max_range == 1 - error(['"dim5_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim5_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim6_idx - % - if ~isempty(dim6_idx) & ~isnumeric(dim6_idx) - error('"dim6_idx" should be a numerical array.'); - end - - if length(unique(dim6_idx)) ~= length(dim6_idx) - error('Duplicate index in "dim6_idx"'); - end - - if ~isempty(dim6_idx) & (min(dim6_idx) < 1 | max(dim6_idx) > hdr.dime.dim(7)) - max_range = hdr.dime.dim(7); - - if max_range == 1 - error(['"dim6_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim6_idx" should be an integer within the range of [' range '].']); - end - end - - % check dim7_idx - % - if ~isempty(dim7_idx) & ~isnumeric(dim7_idx) - error('"dim7_idx" should be a numerical array.'); - end - - if length(unique(dim7_idx)) ~= length(dim7_idx) - error('Duplicate index in "dim7_idx"'); - end - - if ~isempty(dim7_idx) & (min(dim7_idx) < 1 | max(dim7_idx) > hdr.dime.dim(8)) - max_range = hdr.dime.dim(8); - - if max_range == 1 - error(['"dim7_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"dim7_idx" should be an integer within the range of [' range '].']); - end - end - - % check slice_idx - % - if ~isempty(slice_idx) & ~isnumeric(slice_idx) - error('"slice_idx" should be a numerical array.'); - end - - if length(unique(slice_idx)) ~= length(slice_idx) - error('Duplicate index in "slice_idx"'); - end - - if ~isempty(slice_idx) & (min(slice_idx) < 1 | max(slice_idx) > hdr.dime.dim(4)) - max_range = hdr.dime.dim(4); - - if max_range == 1 - error(['"slice_idx" should be 1.']); - else - range = ['1 ' num2str(max_range)]; - error(['"slice_idx" should be an integer within the range of [' range '].']); - end - end - - write_image(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx); - - return % save_untouch_slice_img - - -%--------------------------------------------------------------------- -function write_image(slice,hdr,filetype,fileprefix,machine,slice_idx,img_idx,dim5_idx,dim6_idx,dim7_idx) - - if filetype == 2 - fid = fopen(sprintf('%s.nii',fileprefix),'r+'); - - if fid < 0, - msg = sprintf('Cannot open file %s.nii.',fileprefix); - error(msg); - end - else - fid = fopen(sprintf('%s.img',fileprefix),'r+'); - - if fid < 0, - msg = sprintf('Cannot open file %s.img.',fileprefix); - error(msg); - end - end - - % Set bitpix according to datatype - % - % /*Acceptable values for datatype are*/ - % - % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN - % 1 Binary (ubit1, bitpix=1) % DT_BINARY - % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 - % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 - % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 - % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 - % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 - % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 - % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 - % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 - % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 - % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 - % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 - % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 - % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 - % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 - % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 - % - switch hdr.dime.datatype - case 2, - hdr.dime.bitpix = 8; precision = 'uint8'; - case 4, - hdr.dime.bitpix = 16; precision = 'int16'; - case 8, - hdr.dime.bitpix = 32; precision = 'int32'; - case 16, - hdr.dime.bitpix = 32; precision = 'float32'; - case 64, - hdr.dime.bitpix = 64; precision = 'float64'; - case 128, - hdr.dime.bitpix = 24; precision = 'uint8'; - case 256 - hdr.dime.bitpix = 8; precision = 'int8'; - case 511 - hdr.dime.bitpix = 96; precision = 'float32'; - case 512 - hdr.dime.bitpix = 16; precision = 'uint16'; - case 768 - hdr.dime.bitpix = 32; precision = 'uint32'; - case 1024 - hdr.dime.bitpix = 64; precision = 'int64'; - case 1280 - hdr.dime.bitpix = 64; precision = 'uint64'; - otherwise - error('This datatype is not supported'); - end - - hdr.dime.dim(find(hdr.dime.dim < 1)) = 1; - - % move pointer to the start of image block - % - switch filetype - case {0, 1} - fseek(fid, 0, 'bof'); - case 2 - fseek(fid, hdr.dime.vox_offset, 'bof'); - end - - if hdr.dime.datatype == 1 | isequal(hdr.dime.dim(4:8),ones(1,5)) | ... - (isempty(img_idx) & isempty(dim5_idx) & isempty(dim6_idx) & isempty(dim7_idx) & isempty(slice_idx)) - - msg = [char(10) char(10) ' "save_untouch_slice" is used to save back to the original image a' char(10)]; - msg = [msg ' portion of slices that were loaded by "load_untouch_nii". You can' char(10)]; - msg = [msg ' process those slices matrix in any way, as long as their dimension' char(10)]; - msg = [msg ' is not changed.']; - error(msg); - else - - d1 = hdr.dime.dim(2); - d2 = hdr.dime.dim(3); - d3 = hdr.dime.dim(4); - d4 = hdr.dime.dim(5); - d5 = hdr.dime.dim(6); - d6 = hdr.dime.dim(7); - d7 = hdr.dime.dim(8); - - if isempty(slice_idx) - slice_idx = 1:d3; - end - - if isempty(img_idx) - img_idx = 1:d4; - end - - if isempty(dim5_idx) - dim5_idx = 1:d5; - end - - if isempty(dim6_idx) - dim6_idx = 1:d6; - end - - if isempty(dim7_idx) - dim7_idx = 1:d7; - end - - %ROMAN: begin - roman = 1; - if(roman) - - % compute size of one slice - % - img_siz = prod(hdr.dime.dim(2:3)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - - end; %if(roman) - % ROMAN: end - - for i7=1:length(dim7_idx) - for i6=1:length(dim6_idx) - for i5=1:length(dim5_idx) - for t=1:length(img_idx) - for s=1:length(slice_idx) - - % Position is seeked in bytes. To convert dimension size - % to byte storage size, hdr.dime.bitpix/8 will be - % applied. - % - pos = sub2ind([d1 d2 d3 d4 d5 d6 d7], 1, 1, slice_idx(s), ... - img_idx(t), dim5_idx(i5),dim6_idx(i6),dim7_idx(i7)) -1; - pos = pos * hdr.dime.bitpix/8; - - % ROMAN: begin - if(roman) - % do nothing - else - img_siz = prod(hdr.dime.dim(2:3)); - - % For complex float32 or complex float64, voxel values - % include [real, imag] - % - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 - img_siz = img_siz * 2; - end - - %MPH: For RGB24, voxel values include 3 separate color planes - % - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - img_siz = img_siz * 3; - end - end; % if (roman) - % ROMAN: end - - if filetype == 2 - fseek(fid, pos + hdr.dime.vox_offset, 'bof'); - else - fseek(fid, pos, 'bof'); - end - - % For each frame, fwrite will write precision of value - % in img_siz times - % - fwrite(fid, slice(:,:,s,t,i5,i6,i7), sprintf('*%s',precision)); - - end - end - end - end - end - end - - fclose(fid); - - return % write_image - diff --git a/func/utils/nii/unxform_nii.m b/func/utils/nii/unxform_nii.m deleted file mode 100644 index d522ee1..0000000 --- a/func/utils/nii/unxform_nii.m +++ /dev/null @@ -1,40 +0,0 @@ -% Undo the flipping and rotations performed by xform_nii; spit back only -% the raw img data block. Initial cut will only deal with 3D volumes -% strongly assume we have called xform_nii to write down the steps used -% in xform_nii. -% -% Usage: a = load_nii('original_name'); -% manipulate a.img to make array b; -% -% if you use unxform_nii to un-tranform the image (img) data -% block, then nii.original.hdr is the corresponding header. -% -% nii.original.img = unxform_nii(a, b); -% save_nii(nii.original,'newname'); -% -% Where, 'newname' is created with data in the same space as the -% original_name data -% -% - Jeff Gunter, 26-JUN-06 -% -function outblock = unxform_nii(nii, inblock) - - if isempty(nii.hdr.hist.rot_orient) - outblock=inblock; - else - [dummy unrotate_orient] = sort(nii.hdr.hist.rot_orient); - outblock = permute(inblock, unrotate_orient); - end - - if ~isempty(nii.hdr.hist.flip_orient) - flip_orient = nii.hdr.hist.flip_orient(unrotate_orient); - - for i = 1:3 - if flip_orient(i) - outblock = flipdim(outblock, i); - end - end - end; - - return; - diff --git a/func/utils/nii/verify_nii_ext.m b/func/utils/nii/verify_nii_ext.m deleted file mode 100644 index 71bda97..0000000 --- a/func/utils/nii/verify_nii_ext.m +++ /dev/null @@ -1,45 +0,0 @@ -% Verify NIFTI header extension to make sure that each extension section -% must be an integer multiple of 16 byte long that includes the first 8 -% bytes of esize and ecode. If the length of extension section is not the -% above mentioned case, edata should be padded with all 0. -% -% Usage: [ext, esize_total] = verify_nii_ext(ext) -% -% ext - Structure of NIFTI header extension, which includes num_ext, -% and all the extended header sections in the header extension. -% Each extended header section will have its esize, ecode, and -% edata, where edata can be plain text, xml, or any raw data -% that was saved in the extended header section. -% -% esize_total - Sum of all esize variable in all header sections. -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function [ext, esize_total] = verify_nii_ext(ext) - - if ~isfield(ext, 'section') - error('Incorrect NIFTI header extension structure.'); - elseif ~isfield(ext, 'num_ext') - ext.num_ext = length(ext.section); - elseif ~isfield(ext, 'extension') - ext.extension = [1 0 0 0]; - end - - esize_total = 0; - - for i=1:ext.num_ext - if ~isfield(ext.section(i), 'ecode') | ~isfield(ext.section(i), 'edata') - error('Incorrect NIFTI header extension structure.'); - end - - ext.section(i).esize = ceil((length(ext.section(i).edata)+8)/16)*16; - ext.section(i).edata = ... - [ext.section(i).edata ... - zeros(1,ext.section(i).esize-length(ext.section(i).edata)-8)]; - esize_total = esize_total + ext.section(i).esize; - end - - return % verify_nii_ext - diff --git a/func/utils/nii/view_nii.m b/func/utils/nii/view_nii.m deleted file mode 100644 index e8b2615..0000000 --- a/func/utils/nii/view_nii.m +++ /dev/null @@ -1,4873 +0,0 @@ -% VIEW_NII: Create or update a 3-View (Front, Top, Side) of the -% brain data that is specified by nii structure -% -% Usage: status = view_nii([h], nii, [option]) or -% status = view_nii(h, [option]) -% -% Where, h is the figure on which the 3-View will be plotted; -% nii is the brain data in NIFTI format; -% option is a struct that configures the view plotted, can be: -% -% option.command = 'init' -% option.command = 'update' -% option.command = 'clearnii' -% option.command = 'updatenii' -% option.command = 'updateimg' (nii is nii.img here) -% -% option.usecolorbar = 0 | [1] -% option.usepanel = 0 | [1] -% option.usecrosshair = 0 | [1] -% option.usestretch = 0 | [1] -% option.useimagesc = 0 | [1] -% option.useinterp = [0] | 1 -% -% option.setarea = [x y w h] | [0.05 0.05 0.9 0.9] -% option.setunit = ['vox'] | 'mm' -% option.setviewpoint = [x y z] | [origin] -% option.setscanid = [t] | [1] -% option.setcrosshaircolor = [r g b] | [1 0 0] -% option.setcolorindex = From 1 to 9 (default is 2 or 3) -% option.setcolormap = (Mx3 matrix, 0 <= val <= 1) -% option.setcolorlevel = No more than 256 (default 256) -% option.sethighcolor = [] -% option.setcbarminmax = [] -% option.setvalue = [] -% option.glblocminmax = [] -% option.setbuttondown = '' -% option.setcomplex = [0] | 1 | 2 -% -% Options description in detail: -% ============================== -% -% 1. command: A char string that can control program. -% -% init: If option.command='init', the program will display -% a 3-View plot on the figure specified by figure h -% or on a new figure. If there is already a 3-View -% plot on the figure, please use option.command = -% 'updatenii' (see detail below); otherwise, the -% new 3-View plot will superimpose on the old one. -% If there is no option provided, the program will -% assume that this is an initial plot. If the figure -% handle is omitted, the program knows that it is -% an initial plot. -% -% update: If there is no command specified, and a figure -% handle of the existing 3-View plot is provided, -% the program will choose option.command='update' -% to update the 3-View plot with some new option -% items. -% -% clearnii: Clear 3-View plot on specific figure -% -% updatenii: If a new nii is going to be loaded on a fig -% that has already 3-View plot on it, use this -% command to clear existing 3-View plot, and then -% display with new nii. So, the new nii will not -% superimpose on the existing one. All options -% for 'init' can be used for 'updatenii'. -% -% updateimg: If a new 3D matrix with the same dimension -% is going to be loaded, option.command='updateimg' -% can be used as a light-weighted 'updatenii, since -% it only updates the 3 slices with new values. -% inputing argument nii should be a 3D matrix -% (nii.img) instead of nii struct. No other option -% should be used together with 'updateimg' to keep -% this command as simple as possible. -% -% -% 2. usecolorbar: If specified and usecolorbar=0, the program -% will not include the colorbar in plot area; otherwise, -% a colorbar will be included in plot area. -% -% 3. usepanel: If specified and usepanel=0, the control panel -% at lower right cornor will be invisible; otherwise, -% it will be visible. -% -% 4. usecrosshair: If specified and usecrosshair=0, the crosshair -% will be invisible; otherwise, it will be visible. -% -% 5. usestretch: If specified and usestretch=0, the 3 slices will -% not be stretched, and will be displayed according to -% the actual voxel size; otherwise, the 3 slices will be -% stretched to the edge. -% -% 6. useimagesc: If specified and useimagesc=0, images data will -% be used directly to match the colormap (like 'image' -% command); otherwise, image data will be scaled to full -% colormap with 'imagesc' command in Matlab. -% -% 7. useinterp: If specified and useinterp=1, the image will be -% displayed using interpolation. Otherwise, it will be -% displayed like mosaic, and each tile stands for a -% pixel. This option does not apply to 'setvalue' option -% is set. -% -% -% 8. setarea: 3-View plot will be displayed on this specific -% region. If it is not specified, program will set the -% plot area to [0.05 0.05 0.9 0.9]. -% -% 9. setunit: It can be specified to setunit='voxel' or 'mm' -% and the view will change the axes unit of [X Y Z] -% accordingly. -% -% 10. setviewpoint: If specified, [X Y Z] values will be used -% to set the viewpoint of 3-View plot. -% -% 11. setscanid: If specified, [t] value will be used to display -% the specified image scan in NIFTI data. -% -% 12. setcrosshaircolor: If specified, [r g b] value will be used -% for Crosshair Color. Otherwise, red will be the default. -% -% 13. setcolorindex: If specified, the 3-View will choose the -% following colormap: 2 - Bipolar; 3 - Gray; 4 - Jet; -% 5 - Cool; 6 - Bone; 7 - Hot; 8 - Copper; 9 - Pink; -% If not specified, it will choose 3 - Gray if all data -% values are not less than 0; otherwise, it will choose -% 2 - Bipolar if there is value less than 0. (Contrast -% control can only apply to 3 - Gray colormap. -% -% 14. setcolormap: 3-View plot will use it as a customized colormap. -% It is a 3-column matrix with value between 0 and 1. If -% using MS-Windows version of Matlab, the number of rows -% can not be more than 256, because of Matlab limitation. -% When colormap is used, setcolorlevel option will be -% disabled automatically. -% -% 15. setcolorlevel: If specified (must be no more than 256, and -% cannot be used for customized colormap), row number of -% colormap will be squeezed down to this level; otherwise, -% it will assume that setcolorlevel=256. -% -% 16. sethighcolor: If specified, program will squeeze down the -% colormap, and allocate sethighcolor (an Mx3 matrix) -% to high-end portion of the colormap. The sum of M and -% setcolorlevel should be less than 256. If setcolormap -% option is used, sethighcolor will be inserted on top -% of the setcolormap, and the setcolorlevel option will -% be disabled automatically. -% -% 17. setcbarminmax: if specified, the [min max] will be used to -% set the min and max of the colorbar, which does not -% include any data for highcolor. -% -% 18. setvalue: If specified, setvalue.val (with the same size as -% the source data on solution points) in the source area -% setvalue.idx will be superimposed on the current nii -% image. So, the size of setvalue.val should be equal to -% the size of setvalue.idx. To use this feature, it needs -% single or double nii structure for background image. -% -% 19. glblocminmax: If specified, pgm will use glblocminmax to -% calculate the colormap, instead of minmax of image. -% -% 20. setbuttondown: If specified, pgm will evaluate the command -% after a click or slide action is invoked to the new -% view point. -% -% 21. setcomplex: This option will decide how complex data to be -% displayed: 0 - Real part of complex data; 1 - Imaginary -% part of complex data; 2 - Modulus (magnitude) of complex -% data; If not specified, it will be set to 0 (Real part -% of complex data as default option. This option only apply -% when option.command is set to 'init or 'updatenii'. -% -% -% Additional Options for 'update' command: -% ======================================= -% -% option.enablecursormove = [1] | 0 -% option.enableviewpoint = 0 | [1] -% option.enableorigin = 0 | [1] -% option.enableunit = 0 | [1] -% option.enablecrosshair = 0 | [1] -% option.enablehistogram = 0 | [1] -% option.enablecolormap = 0 | [1] -% option.enablecontrast = 0 | [1] -% option.enablebrightness = 0 | [1] -% option.enableslider = 0 | [1] -% option.enabledirlabel = 0 | [1] -% -% -% e.g.: -% nii = load_nii('T1'); % T1.img/hdr -% view_nii(nii); -% -% or -% -% h = figure('unit','normal','pos', [0.18 0.08 0.64 0.85]); -% opt.setarea = [0.05 0.05 0.9 0.9]; -% view_nii(h, nii, opt); -% -% -% Part of this file is copied and modified from: -% http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function status = view_nii(varargin) - - if nargin < 1 - error('Please check inputs using ''help view_nii'''); - end; - - nii = ''; - opt = ''; - command = ''; - - usecolorbar = []; - usepanel = []; - usecrosshair = ''; - usestretch = []; - useimagesc = []; - useinterp = []; - - setarea = []; - setunit = ''; - setviewpoint = []; - setscanid = []; - setcrosshaircolor = []; - setcolorindex = ''; - setcolormap = 'NA'; - setcolorlevel = []; - sethighcolor = 'NA'; - setcbarminmax = []; - setvalue = []; - glblocminmax = []; - setbuttondown = ''; - setcomplex = 0; - - status = []; - - if ishandle(varargin{1}) % plot on top of this figure - - fig = varargin{1}; - - if nargin < 2 - command = 'update'; % just to get 3-View status - end - - if nargin == 2 - if ~isstruct(varargin{2}) - error('2nd parameter should be either nii struct or option struct'); - end - - opt = varargin{2}; - - if isfield(opt,'hdr') & isfield(opt,'img') - nii = opt; - elseif isfield(opt, 'command') & (strcmpi(opt.command,'init') ... - | strcmpi(opt.command,'updatenii') ... - | strcmpi(opt.command,'updateimg') ) - - error('Option here cannot contain "init", "updatenii", or "updateimg" comand'); - end - end - - if nargin == 3 - nii = varargin{2}; - opt = varargin{3}; - - if ~isstruct(opt) - error('3rd parameter should be option struct'); - end - - if ~isfield(opt,'command') | ~strcmpi(opt.command,'updateimg') - if ~isstruct(nii) | ~isfield(nii,'hdr') | ~isfield(nii,'img') - error('2nd parameter should be nii struct'); - end - - if isfield(nii,'untouch') & nii.untouch == 1 - error('Usage: please use ''load_nii.m'' to load the structure.'); - end - end - end - - set(fig, 'menubar', 'none'); - - elseif ischar(varargin{1}) % call back by event - - command = lower(varargin{1}); - fig = gcbf; - - else % start nii with a new figure - - nii = varargin{1}; - - if ~isstruct(nii) | ~isfield(nii,'hdr') | ~isfield(nii,'img') - error('1st parameter should be either a figure handle or nii struct'); - end - - if isfield(nii,'untouch') & nii.untouch == 1 - error('Usage: please use ''load_nii.m'' to load the structure.'); - end - - if nargin > 1 - opt = varargin{2}; - - if isfield(opt, 'command') & ~strcmpi(opt.command,'init') - error('Option here must use "init" comand'); - end - end - - command = 'init'; - fig = figure('unit','normal','position',[0.15 0.08 0.70 0.85]); - view_nii_menu(fig); - rri_file_menu(fig); - - end - - if ~isempty(opt) - - if isfield(opt,'command') - command = lower(opt.command); - end - - if isempty(command) - command = 'update'; - end - - if isfield(opt,'usecolorbar') - usecolorbar = opt.usecolorbar; - end - - if isfield(opt,'usepanel') - usepanel = opt.usepanel; - end - - if isfield(opt,'usecrosshair') - usecrosshair = opt.usecrosshair; - end - - if isfield(opt,'usestretch') - usestretch = opt.usestretch; - end - - if isfield(opt,'useimagesc') - useimagesc = opt.useimagesc; - end - - if isfield(opt,'useinterp') - useinterp = opt.useinterp; - end - - if isfield(opt,'setarea') - setarea = opt.setarea; - end - - if isfield(opt,'setunit') - setunit = opt.setunit; - end - - if isfield(opt,'setviewpoint') - setviewpoint = opt.setviewpoint; - end - - if isfield(opt,'setscanid') - setscanid = opt.setscanid; - end - - if isfield(opt,'setcrosshaircolor') - setcrosshaircolor = opt.setcrosshaircolor; - - if ~isempty(setcrosshaircolor) & (~isnumeric(setcrosshaircolor) | ~isequal(size(setcrosshaircolor),[1 3]) | min(setcrosshaircolor(:))<0 | max(setcrosshaircolor(:))>1) - error('Crosshair Color should be a 1x3 matrix with value between 0 and 1'); - end - end - - if isfield(opt,'setcolorindex') - setcolorindex = round(opt.setcolorindex); - - if ~isnumeric(setcolorindex) | setcolorindex < 1 | setcolorindex > 9 - error('Colorindex should be a number between 1 and 9'); - end - end - - if isfield(opt,'setcolormap') - setcolormap = opt.setcolormap; - - if ~isempty(setcolormap) & (~isnumeric(setcolormap) | size(setcolormap,2) ~= 3 | min(setcolormap(:))<0 | max(setcolormap(:))>1) - error('Colormap should be a Mx3 matrix with value between 0 and 1'); - end - end - - if isfield(opt,'setcolorlevel') - setcolorlevel = round(opt.setcolorlevel); - - if ~isnumeric(setcolorlevel) | setcolorlevel > 256 | setcolorlevel < 1 - error('Colorlevel should be a number between 1 and 256'); - end - end - - if isfield(opt,'sethighcolor') - sethighcolor = opt.sethighcolor; - - if ~isempty(sethighcolor) & (~isnumeric(sethighcolor) | size(sethighcolor,2) ~= 3 | min(sethighcolor(:))<0 | max(sethighcolor(:))>1) - error('Highcolor should be a Mx3 matrix with value between 0 and 1'); - end - end - - if isfield(opt,'setcbarminmax') - setcbarminmax = opt.setcbarminmax; - - if isempty(setcbarminmax) | ~isnumeric(setcbarminmax) | length(setcbarminmax) ~= 2 - error('Colorbar MinMax should contain 2 values: [min max]'); - end - end - - if isfield(opt,'setvalue') - setvalue = opt.setvalue; - - if isempty(setvalue) | ~isstruct(setvalue) | ... - ~isfield(opt.setvalue,'idx') | ~isfield(opt.setvalue,'val') - error('setvalue should be a struct contains idx and val'); - end - - if length(opt.setvalue.idx(:)) ~= length(opt.setvalue.val(:)) - error('length of idx and val fields should be the same'); - end - - if ~strcmpi(class(opt.setvalue.idx),'single') - opt.setvalue.idx = single(opt.setvalue.idx); - end - - if ~strcmpi(class(opt.setvalue.val),'single') - opt.setvalue.val = single(opt.setvalue.val); - end - end - - if isfield(opt,'glblocminmax') - glblocminmax = opt.glblocminmax; - end - - if isfield(opt,'setbuttondown') - setbuttondown = opt.setbuttondown; - end - - if isfield(opt,'setcomplex') - setcomplex = opt.setcomplex; - end - - end - - switch command - - case {'init'} - - set(fig, 'InvertHardcopy','off'); - set(fig, 'PaperPositionMode','auto'); - - fig = init(nii, fig, setarea, setunit, setviewpoint, setscanid, setbuttondown, ... - setcolorindex, setcolormap, setcolorlevel, sethighcolor, setcbarminmax, ... - usecolorbar, usepanel, usecrosshair, usestretch, useimagesc, useinterp, ... - setvalue, glblocminmax, setcrosshaircolor, setcomplex); - - % get status - % - status = get_status(fig); - - case {'update'} - - nii_view = getappdata(fig,'nii_view'); - h = fig; - - if isempty(nii_view) - error('The figure should already contain a 3-View plot.'); - end - - if ~isempty(opt) - - % Order of the following update matters. - % - update_shape(h, setarea, usecolorbar, usestretch, useimagesc); - update_useinterp(h, useinterp); - update_useimagesc(h, useimagesc); - update_usepanel(h, usepanel); - update_colorindex(h, setcolorindex); - update_colormap(h, setcolormap); - update_highcolor(h, sethighcolor, setcolorlevel); - update_cbarminmax(h, setcbarminmax); - update_unit(h, setunit); - update_viewpoint(h, setviewpoint); - update_scanid(h, setscanid); - update_buttondown(h, setbuttondown); - update_crosshaircolor(h, setcrosshaircolor); - update_usecrosshair(h, usecrosshair); - - % Enable/Disable object - % - update_enable(h, opt); - - end - - % get status - % - status = get_status(h); - - case {'updateimg'} - - if ~exist('nii','var') - msg = sprintf('Please input a 3D matrix brain data'); - error(msg); - end - - % Note: nii is not nii, nii should be a 3D matrix here - % - if ~isnumeric(nii) - msg = sprintf('2nd parameter should be a 3D matrix, not nii struct'); - error(msg); - end - - nii_view = getappdata(fig,'nii_view'); - - if isempty(nii_view) - error('The figure should already contain a 3-View plot.'); - end - - img = nii; - update_img(img, fig, opt); - - % get status - % - status = get_status(fig); - - case {'updatenii'} - - nii_view = getappdata(fig,'nii_view'); - - if isempty(nii_view) - error('The figure should already contain a 3-View plot.'); - end - - if ~isstruct(nii) | ~isfield(nii,'hdr') | ~isfield(nii,'img') - error('2nd parameter should be nii struct'); - end - - if isfield(nii,'untouch') & nii.untouch == 1 - error('Usage: please use ''load_nii.m'' to load the structure.'); - end - - opt.command = 'clearnii'; - view_nii(fig, opt); - - opt.command = 'init'; - view_nii(fig, nii, opt); - - % get status - % - status = get_status(fig); - - case {'clearnii'} - - nii_view = getappdata(fig,'nii_view'); - - handles = struct2cell(nii_view.handles); - - for i=1:length(handles) - if ishandle(handles{i}) % in case already del by parent - delete(handles{i}); - end - end - - rmappdata(fig,'nii_view'); - buttonmotion = get(fig,'windowbuttonmotion'); - mymotion = '; view_nii(''move_cursor'');'; - buttonmotion = strrep(buttonmotion, mymotion, ''); - set(fig, 'windowbuttonmotion', buttonmotion); - - case {'axial_image','coronal_image','sagittal_image'} - - switch command - case 'axial_image', view = 'axi'; axi = 0; cor = 1; sag = 1; - case 'coronal_image', view = 'cor'; axi = 1; cor = 0; sag = 1; - case 'sagittal_image', view = 'sag'; axi = 1; cor = 1; sag = 0; - end - - nii_view = getappdata(fig,'nii_view'); - nii_view = get_slice_position(nii_view,view); - - if isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - % CData must be double() for Matlab 6.5 for Windows - % - if axi, - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) & nii_view.useinterp - Saxi = squeeze(nii_view.bgimg(:,:,nii_view.slices.axi)); - set(nii_view.handles.axial_bg,'CData',double(Saxi)'); - end - - if isfield(nii_view.handles,'axial_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Saxi = squeeze(img(:,:,nii_view.slices.axi,:,nii_view.scanid)); - Saxi = permute(Saxi, [2 1 3]); - else - Saxi = squeeze(img(:,:,nii_view.slices.axi,nii_view.scanid)); - Saxi = Saxi'; - end - - set(nii_view.handles.axial_image,'CData',double(Saxi)); - end - - if isfield(nii_view.handles,'axial_slider'), - set(nii_view.handles.axial_slider,'Value',nii_view.slices.axi); - end; - end - - if cor, - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) & nii_view.useinterp - Scor = squeeze(nii_view.bgimg(:,nii_view.slices.cor,:)); - set(nii_view.handles.coronal_bg,'CData',double(Scor)'); - end - - if isfield(nii_view.handles,'coronal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Scor = squeeze(img(:,nii_view.slices.cor,:,:,nii_view.scanid)); - Scor = permute(Scor, [2 1 3]); - else - Scor = squeeze(img(:,nii_view.slices.cor,:,nii_view.scanid)); - Scor = Scor'; - end - - set(nii_view.handles.coronal_image,'CData',double(Scor)); - end - - if isfield(nii_view.handles,'coronal_slider'), - slider_val = nii_view.dims(2) - nii_view.slices.cor + 1; - set(nii_view.handles.coronal_slider,'Value',slider_val); - end; - end; - - if sag, - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) & nii_view.useinterp - Ssag = squeeze(nii_view.bgimg(nii_view.slices.sag,:,:)); - set(nii_view.handles.sagittal_bg,'CData',double(Ssag)'); - end - - if isfield(nii_view.handles,'sagittal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Ssag = squeeze(img(nii_view.slices.sag,:,:,:,nii_view.scanid)); - Ssag = permute(Ssag, [2 1 3]); - else - Ssag = squeeze(img(nii_view.slices.sag,:,:,nii_view.scanid)); - Ssag = Ssag'; - end - - set(nii_view.handles.sagittal_image,'CData',double(Ssag)); - end - - if isfield(nii_view.handles,'sagittal_slider'), - set(nii_view.handles.sagittal_slider,'Value',nii_view.slices.sag); - end; - end; - - update_nii_view(nii_view); - - if ~isempty(nii_view.buttondown) - eval(nii_view.buttondown); - end - - case {'axial_slider','coronal_slider','sagittal_slider'}, - - switch command - case 'axial_slider', view = 'axi'; axi = 1; cor = 0; sag = 0; - case 'coronal_slider', view = 'cor'; axi = 0; cor = 1; sag = 0; - case 'sagittal_slider', view = 'sag'; axi = 0; cor = 0; sag = 1; - end - - nii_view = getappdata(fig,'nii_view'); - nii_view = get_slider_position(nii_view); - - if isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - if axi, - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) & nii_view.useinterp - Saxi = squeeze(nii_view.bgimg(:,:,nii_view.slices.axi)); - set(nii_view.handles.axial_bg,'CData',double(Saxi)'); - end - - if isfield(nii_view.handles,'axial_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Saxi = squeeze(img(:,:,nii_view.slices.axi,:,nii_view.scanid)); - Saxi = permute(Saxi, [2 1 3]); - else - Saxi = squeeze(img(:,:,nii_view.slices.axi,nii_view.scanid)); - Saxi = Saxi'; - end - - set(nii_view.handles.axial_image,'CData',double(Saxi)); - end - - if isfield(nii_view.handles,'axial_slider'), - set(nii_view.handles.axial_slider,'Value',nii_view.slices.axi); - end - end - - if cor, - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) & nii_view.useinterp - Scor = squeeze(nii_view.bgimg(:,nii_view.slices.cor,:)); - set(nii_view.handles.coronal_bg,'CData',double(Scor)'); - end - - if isfield(nii_view.handles,'coronal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Scor = squeeze(img(:,nii_view.slices.cor,:,:,nii_view.scanid)); - Scor = permute(Scor, [2 1 3]); - else - Scor = squeeze(img(:,nii_view.slices.cor,:,nii_view.scanid)); - Scor = Scor'; - end - - set(nii_view.handles.coronal_image,'CData',double(Scor)); - end - - if isfield(nii_view.handles,'coronal_slider'), - slider_val = nii_view.dims(2) - nii_view.slices.cor + 1; - set(nii_view.handles.coronal_slider,'Value',slider_val); - end - end - - if sag, - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) & nii_view.useinterp - Ssag = squeeze(nii_view.bgimg(nii_view.slices.sag,:,:)); - set(nii_view.handles.sagittal_bg,'CData',double(Ssag)'); - end - - if isfield(nii_view.handles,'sagittal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Ssag = squeeze(img(nii_view.slices.sag,:,:,:,nii_view.scanid)); - Ssag = permute(Ssag, [2 1 3]); - else - Ssag = squeeze(img(nii_view.slices.sag,:,:,nii_view.scanid)); - Ssag = Ssag'; - end - - set(nii_view.handles.sagittal_image,'CData',double(Ssag)); - end - - if isfield(nii_view.handles,'sagittal_slider'), - set(nii_view.handles.sagittal_slider,'Value',nii_view.slices.sag); - end - end - - update_nii_view(nii_view); - - if ~isempty(nii_view.buttondown) - eval(nii_view.buttondown); - end - - case {'impos_edit'} - - nii_view = getappdata(fig,'nii_view'); - impos = str2num(get(nii_view.handles.impos,'string')); - - if isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - if isempty(impos) | ~all(size(impos) == [1 3]) - msg = 'Please use 3 numbers to represent X,Y and Z'; - msgbox(msg,'Error'); - return; - end - - slices.sag = round(impos(1)); - slices.cor = round(impos(2)); - slices.axi = round(impos(3)); - - nii_view = convert2voxel(nii_view,slices); - nii_view = check_slices(nii_view); - - impos(1) = nii_view.slices.sag; - impos(2) = nii_view.dims(2) - nii_view.slices.cor + 1; - impos(3) = nii_view.slices.axi; - - if isfield(nii_view.handles,'sagittal_slider'), - set(nii_view.handles.sagittal_slider,'Value',impos(1)); - end - - if isfield(nii_view.handles,'coronal_slider'), - set(nii_view.handles.coronal_slider,'Value',impos(2)); - end - - if isfield(nii_view.handles,'axial_slider'), - set(nii_view.handles.axial_slider,'Value',impos(3)); - end - - nii_view = get_slider_position(nii_view); - update_nii_view(nii_view); - - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) & nii_view.useinterp - Saxi = squeeze(nii_view.bgimg(:,:,nii_view.slices.axi)); - set(nii_view.handles.axial_bg,'CData',double(Saxi)'); - end - - if isfield(nii_view.handles,'axial_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Saxi = squeeze(img(:,:,nii_view.slices.axi,:,nii_view.scanid)); - Saxi = permute(Saxi, [2 1 3]); - else - Saxi = squeeze(img(:,:,nii_view.slices.axi,nii_view.scanid)); - Saxi = Saxi'; - end - - set(nii_view.handles.axial_image,'CData',double(Saxi)); - end - - if isfield(nii_view.handles,'axial_slider'), - set(nii_view.handles.axial_slider,'Value',nii_view.slices.axi); - end - - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) & nii_view.useinterp - Scor = squeeze(nii_view.bgimg(:,nii_view.slices.cor,:)); - set(nii_view.handles.coronal_bg,'CData',double(Scor)'); - end - - if isfield(nii_view.handles,'coronal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Scor = squeeze(img(:,nii_view.slices.cor,:,:,nii_view.scanid)); - Scor = permute(Scor, [2 1 3]); - else - Scor = squeeze(img(:,nii_view.slices.cor,:,nii_view.scanid)); - Scor = Scor'; - end - - set(nii_view.handles.coronal_image,'CData',double(Scor)); - end - - if isfield(nii_view.handles,'coronal_slider'), - slider_val = nii_view.dims(2) - nii_view.slices.cor + 1; - set(nii_view.handles.coronal_slider,'Value',slider_val); - end - - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) & nii_view.useinterp - Ssag = squeeze(nii_view.bgimg(nii_view.slices.sag,:,:)); - set(nii_view.handles.sagittal_bg,'CData',double(Ssag)'); - end - - if isfield(nii_view.handles,'sagittal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Ssag = squeeze(img(nii_view.slices.sag,:,:,:,nii_view.scanid)); - Ssag = permute(Ssag, [2 1 3]); - else - Ssag = squeeze(img(nii_view.slices.sag,:,:,nii_view.scanid)); - Ssag = Ssag'; - end - - set(nii_view.handles.sagittal_image,'CData',double(Ssag)); - end - - if isfield(nii_view.handles,'sagittal_slider'), - set(nii_view.handles.sagittal_slider,'Value',nii_view.slices.sag); - end - - axes(nii_view.handles.axial_axes); - axes(nii_view.handles.coronal_axes); - axes(nii_view.handles.sagittal_axes); - - if ~isempty(nii_view.buttondown) - eval(nii_view.buttondown); - end - - case 'coordinates', - - nii_view = getappdata(fig,'nii_view'); - set_image_value(nii_view); - - case 'crosshair', - - nii_view = getappdata(fig,'nii_view'); - - if get(nii_view.handles.xhair,'value') == 2 % off - set(nii_view.axi_xhair.lx,'visible','off'); - set(nii_view.axi_xhair.ly,'visible','off'); - set(nii_view.cor_xhair.lx,'visible','off'); - set(nii_view.cor_xhair.ly,'visible','off'); - set(nii_view.sag_xhair.lx,'visible','off'); - set(nii_view.sag_xhair.ly,'visible','off'); - else - set(nii_view.axi_xhair.lx,'visible','on'); - set(nii_view.axi_xhair.ly,'visible','on'); - set(nii_view.cor_xhair.lx,'visible','on'); - set(nii_view.cor_xhair.ly,'visible','on'); - set(nii_view.sag_xhair.lx,'visible','on'); - set(nii_view.sag_xhair.ly,'visible','on'); - - set(nii_view.handles.axial_axes,'selected','on'); - set(nii_view.handles.axial_axes,'selected','off'); - set(nii_view.handles.coronal_axes,'selected','on'); - set(nii_view.handles.coronal_axes,'selected','off'); - set(nii_view.handles.sagittal_axes,'selected','on'); - set(nii_view.handles.sagittal_axes,'selected','off'); - end - - case 'xhair_color', - - old_color = get(gcbo,'user'); - new_color = uisetcolor(old_color); - update_crosshaircolor(fig, new_color); - - case {'color','contrast_def'} - - nii_view = getappdata(fig,'nii_view'); - - if nii_view.numscan == 1 - if get(nii_view.handles.colorindex,'value') == 2 - set(nii_view.handles.contrast,'value',128); - elseif get(nii_view.handles.colorindex,'value') == 3 - set(nii_view.handles.contrast,'value',1); - end - end - - [custom_color_map, custom_colorindex] = change_colormap(fig); - - if strcmpi(command, 'color') - - setcolorlevel = nii_view.colorlevel; - - if ~isempty(custom_color_map) % isfield(nii_view, 'color_map') - setcolormap = custom_color_map; % nii_view.color_map; - else - setcolormap = []; - end - - if isfield(nii_view, 'highcolor') - sethighcolor = nii_view.highcolor; - else - sethighcolor = []; - end - - redraw_cbar(fig, setcolorlevel, setcolormap, sethighcolor); - - if nii_view.numscan == 1 & ... - (custom_colorindex < 2 | custom_colorindex > 3) - contrastopt.enablecontrast = 0; - else - contrastopt.enablecontrast = 1; - end - - update_enable(fig, contrastopt); - - end - - case {'neg_color','brightness','contrast'} - - change_colormap(fig); - - case {'brightness_def'} - - nii_view = getappdata(fig,'nii_view'); - set(nii_view.handles.brightness,'value',0); - change_colormap(fig); - - case 'hist_plot' - - hist_plot(fig); - - case 'hist_eq' - - hist_eq(fig); - - case 'move_cursor' - - move_cursor(fig); - - case 'edit_change_scan' - - change_scan('edit_change_scan'); - - case 'slider_change_scan' - - change_scan('slider_change_scan'); - - end - - return; % view_nii - - -%---------------------------------------------------------------- -function fig = init(nii, fig, area, setunit, setviewpoint, setscanid, buttondown, ... - colorindex, color_map, colorlevel, highcolor, cbarminmax, ... - usecolorbar, usepanel, usecrosshair, usestretch, useimagesc, ... - useinterp, setvalue, glblocminmax, setcrosshaircolor, ... - setcomplex) - - % Support data type COMPLEX64 & COMPLEX128 - % - if nii.hdr.dime.datatype == 32 | nii.hdr.dime.datatype == 1792 - switch setcomplex, - case 0, - nii.img = real(nii.img); - case 1, - nii.img = imag(nii.img); - case 2, - if isa(nii.img, 'double') - nii.img = abs(double(nii.img)); - else - nii.img = single(abs(double(nii.img))); - end - end - end - - if isempty(area) - area = [0.05 0.05 0.9 0.9]; - end - - if isempty(setscanid) - setscanid = 1; - else - setscanid = round(setscanid); - - if setscanid < 1 - setscanid = 1; - end - - if setscanid > nii.hdr.dime.dim(5) - setscanid = nii.hdr.dime.dim(5); - end - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - usecolorbar = 0; - elseif isempty(usecolorbar) - usecolorbar = 1; - end - - if isempty(usepanel) - usepanel = 1; - end - - if isempty(usestretch) - usestretch = 1; - end - - if isempty(useimagesc) - useimagesc = 1; - end - - if isempty(useinterp) - useinterp = 0; - end - - if isempty(colorindex) - tmp = min(nii.img(:,:,:,setscanid)); - - if min(tmp(:)) < 0 - colorindex = 2; - setcrosshaircolor = [1 1 0]; - else - colorindex = 3; - end - end - - if isempty(color_map) | ischar(color_map) - color_map = []; - else - colorindex = 1; - end - - bgimg = []; - - if ~isempty(glblocminmax) - minvalue = glblocminmax(1); - maxvalue = glblocminmax(2); - else - minvalue = nii.img(:,:,:,setscanid); - minvalue = double(minvalue(:)); - minvalue = min(minvalue(~isnan(minvalue))); - maxvalue = nii.img(:,:,:,setscanid); - maxvalue = double(maxvalue(:)); - maxvalue = max(maxvalue(~isnan(maxvalue))); - end - - if ~isempty(setvalue) - if ~isempty(glblocminmax) - minvalue = glblocminmax(1); - maxvalue = glblocminmax(2); - else - minvalue = double(min(setvalue.val)); - maxvalue = double(max(setvalue.val)); - end - - bgimg = double(nii.img); - minbg = double(min(bgimg(:))); - maxbg = double(max(bgimg(:))); - - bgimg = scale_in(bgimg, minbg, maxbg, 55) + 200; % scale to 201~256 - - % 56 level for brain structure - % -% highcolor = [zeros(1,3);gray(55)]; - highcolor = gray(56); - cbarminmax = [minvalue maxvalue]; - - if useinterp - - % scale signal data to 1~200 - % - nii.img = repmat(nan, size(nii.img)); - nii.img(setvalue.idx) = setvalue.val; - - % 200 level for source image - % - bgimg = single(scale_out(bgimg, cbarminmax(1), cbarminmax(2), 199)); - else - - bgimg(setvalue.idx) = NaN; - minbg = double(min(bgimg(:))); - maxbg = double(max(bgimg(:))); - bgimg(setvalue.idx) = minbg; - - % bgimg must be normalized to [201 256] - % - bgimg = 55 * (bgimg-min(bgimg(:))) / (max(bgimg(:))-min(bgimg(:))) + 201; - bgimg(setvalue.idx) = 0; - - % scale signal data to 1~200 - % - nii.img = zeros(size(nii.img)); - nii.img(setvalue.idx) = scale_in(setvalue.val, minvalue, maxvalue, 199); - nii.img = nii.img + bgimg; - bgimg = []; - nii.img = scale_out(nii.img, cbarminmax(1), cbarminmax(2), 199); - - minvalue = double(nii.img(:)); - minvalue = min(minvalue(~isnan(minvalue))); - maxvalue = double(nii.img(:)); - maxvalue = max(maxvalue(~isnan(maxvalue))); - - if ~isempty(glblocminmax) % maxvalue is gray - minvalue = glblocminmax(1); - end - - end - - colorindex = 2; - setcrosshaircolor = [1 1 0]; - - end - - if isempty(highcolor) | ischar(highcolor) - highcolor = []; - num_highcolor = 0; - else - num_highcolor = size(highcolor,1); - end - - if isempty(colorlevel) - colorlevel = 256 - num_highcolor; - end - - if usecolorbar - cbar_area = area; - cbar_area(1) = area(1) + area(3)*0.93; - cbar_area(3) = area(3)*0.04; - area(3) = area(3)*0.9; % 90% used for main axes - else - cbar_area = []; - end - - % init color (gray) scaling to make sure the slice clim take the - % global clim [min(nii.img(:)) max(nii.img(:))] - % - if isempty(bgimg) - clim = [minvalue maxvalue]; - else - clim = [minvalue double(max(bgimg(:)))]; - end - - if clim(1) == clim(2) - clim(2) = clim(1) + 0.000001; - end - - if isempty(cbarminmax) - cbarminmax = [minvalue maxvalue]; - end - - xdim = size(nii.img, 1); - ydim = size(nii.img, 2); - zdim = size(nii.img, 3); - - dims = [xdim ydim zdim]; - voxel_size = abs(nii.hdr.dime.pixdim(2:4)); % vol in mm - - if any(voxel_size <= 0) - voxel_size(find(voxel_size <= 0)) = 1; - end - - origin = abs(nii.hdr.hist.originator(1:3)); - - if isempty(origin) | all(origin == 0) % according to SPM - origin = (dims+1)/2; - end; - - origin = round(origin); - - if any(origin > dims) % simulate fMRI - origin(find(origin > dims)) = dims(find(origin > dims)); - end - - if any(origin <= 0) - origin(find(origin <= 0)) = 1; - end - - nii_view.dims = dims; - nii_view.voxel_size = voxel_size; - nii_view.origin = origin; - - nii_view.slices.sag = 1; - nii_view.slices.cor = 1; - nii_view.slices.axi = 1; - if xdim > 1, nii_view.slices.sag = origin(1); end - if ydim > 1, nii_view.slices.cor = origin(2); end - if zdim > 1, nii_view.slices.axi = origin(3); end - - nii_view.area = area; - nii_view.fig = fig; - nii_view.nii = nii; % image data - nii_view.bgimg = bgimg; % background - nii_view.setvalue = setvalue; - nii_view.minvalue = minvalue; - nii_view.maxvalue = maxvalue; - nii_view.numscan = nii.hdr.dime.dim(5); - nii_view.scanid = setscanid; - - Font.FontUnits = 'point'; - Font.FontSize = 12; - - % create axes for colorbar - % - [cbar_axes cbarminmax_axes] = create_cbar_axes(fig, cbar_area); - - if isempty(cbar_area) - nii_view.cbar_area = []; - else - nii_view.cbar_area = cbar_area; - end - - % create axes for top/front/side view - % - vol_size = voxel_size .* dims; - [top_ax, front_ax, side_ax] ... - = create_ax(fig, area, vol_size, usestretch); - - top_pos = get(top_ax,'position'); - front_pos = get(front_ax,'position'); - side_pos = get(side_ax,'position'); - - % Sagittal Slider - % - x = side_pos(1); - y = top_pos(2) + top_pos(4); - w = side_pos(3); - h = (front_pos(2) - y) / 2; - y = y + h; - - pos = [x y w h]; - - if xdim > 1, - slider_step(1) = 1/(xdim); - slider_step(2) = 1.00001/(xdim); - - handles.sagittal_slider = uicontrol('Parent',fig, ... - 'Style','slider','Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment','center',... - 'BackgroundColor',[0.5 0.5 0.5],'ForegroundColor',[0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Sagittal slice navigation',... - 'Min',1,'Max',xdim,'SliderStep',slider_step, ... - 'Value',nii_view.slices.sag,... - 'Callback','view_nii(''sagittal_slider'');'); - - set(handles.sagittal_slider,'position',pos); % linux66 - end - - % Coronal Slider - % - x = top_pos(1); - y = top_pos(2) + top_pos(4); - w = top_pos(3); - h = (front_pos(2) - y) / 2; - y = y + h; - - pos = [x y w h]; - - if ydim > 1, - slider_step(1) = 1/(ydim); - slider_step(2) = 1.00001/(ydim); - - slider_val = nii_view.dims(2) - nii_view.slices.cor + 1; - - handles.coronal_slider = uicontrol('Parent',fig, ... - 'Style','slider','Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment','center',... - 'BackgroundColor',[0.5 0.5 0.5],'ForegroundColor',[0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Coronal slice navigation',... - 'Min',1,'Max',ydim,'SliderStep',slider_step, ... - 'Value',slider_val,... - 'Callback','view_nii(''coronal_slider'');'); - - set(handles.coronal_slider,'position',pos); % linux66 - end - - % Axial Slider - % -% x = front_pos(1) + front_pos(3); -% y = front_pos(2); -% w = side_pos(1) - x; -% h = front_pos(4); - - x = top_pos(1); - y = area(2); - w = top_pos(3); - h = top_pos(2) - y; - - pos = [x y w h]; - - if zdim > 1, - slider_step(1) = 1/(zdim); - slider_step(2) = 1.00001/(zdim); - - handles.axial_slider = uicontrol('Parent',fig, ... - 'Style','slider','Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment','center',... - 'BackgroundColor',[0.5 0.5 0.5],'ForegroundColor',[0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Axial slice navigation',... - 'Min',1,'Max',zdim,'SliderStep',slider_step, ... - 'Value',nii_view.slices.axi,... - 'Callback','view_nii(''axial_slider'');'); - - set(handles.axial_slider,'position',pos); % linux66 - end - - % plot info view - % -% info_pos = [side_pos([1,3]); top_pos([2,4])]; -% info_pos = info_pos(:); - gap = side_pos(1)-(top_pos(1)+top_pos(3)); - info_pos(1) = side_pos(1) + gap; - info_pos(2) = area(2); - info_pos(3) = side_pos(3) - gap; - info_pos(4) = top_pos(2) + top_pos(4) - area(2) - gap; - - num_inputline = 10; - inputline_space =info_pos(4) / num_inputline; - - - % for any info_area change, update_usestretch should also be changed - - - % Image Intensity Value at Cursor - % - x = info_pos(1); - y = info_pos(2); - w = info_pos(3)*0.5; - h = inputline_space*0.6; - - pos = [x y w h]; - - handles.Timvalcur = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Value at cursor:'); - - if usepanel - set(handles.Timvalcur, 'visible', 'on'); - end - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.imvalcur = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'right',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String',' '); - - if usepanel - set(handles.imvalcur, 'visible', 'on'); - end - - % Position at Cursor - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.Timposcur = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','[X Y Z] at cursor:'); - - if usepanel - set(handles.Timposcur, 'visible', 'on'); - end - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.imposcur = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'right',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String',' ','Value',[0 0 0]); - - if usepanel - set(handles.imposcur, 'visible', 'on'); - end - - % Image Intensity Value at Mouse Click - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.Timval = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Value at crosshair:'); - - if usepanel - set(handles.Timval, 'visible', 'on'); - end - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.imval = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'right',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String',' '); - - if usepanel - set(handles.imval, 'visible', 'on'); - end - - % Viewpoint Position at Mouse Click - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.Timpos = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','[X Y Z] at crosshair:'); - - if usepanel - set(handles.Timpos, 'visible', 'on'); - end - - x = x + w + 0.005; - y = y - 0.008; - w = info_pos(3)*0.5; - h = inputline_space*0.9; - - pos = [x y w h]; - - handles.impos = uicontrol('Parent',fig,'Style','edit', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'right',... - 'BackgroundColor', [1 1 1], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'Callback','view_nii(''impos_edit'');', ... - 'TooltipString','Viewpoint Location in Axes Unit', ... - 'visible','off', ... - 'String',' ','Value',[0 0 0]); - - if usepanel - set(handles.impos, 'visible', 'on'); - end - - % Origin Position - % - x = info_pos(1); - y = y + inputline_space*1.2; - w = info_pos(3)*0.5; - h = inputline_space*0.6; - - pos = [x y w h]; - - handles.Torigin = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','[X Y Z] at origin:'); - - if usepanel - set(handles.Torigin, 'visible', 'on'); - end - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.origin = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'right',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String',' ','Value',[0 0 0]); - - if usepanel - set(handles.origin, 'visible', 'on'); - end - -if 0 - % Voxel Unit - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - - handles.Tcoord = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Axes Unit:'); - - if usepanel - set(handles.Tcoord, 'visible', 'on'); - end - - x = x + w + 0.005; - w = info_pos(3)*0.5 - 0.005; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.coord = uicontrol('Parent',fig,'Style','popupmenu', ... - 'Units','Normalized', Font, ... - 'Position',pos, ... - 'BackgroundColor', [1 1 1], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Choose Voxel or Millimeter',... - 'String',{'Voxel','Millimeter'},... - 'visible','off', ... - 'Callback','view_nii(''coordinates'');'); - -% 'TooltipString','Choose Voxel, MNI or Talairach Coordinates',... -% 'String',{'Voxel','MNI (mm)','Talairach (mm)'},... - - Font.FontSize = 12; - - if usepanel - set(handles.coord, 'visible', 'on'); - end -end - - % Crosshair - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.4; - - pos = [x y w h]; - - handles.Txhair = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Crosshair:'); - - if usepanel - set(handles.Txhair, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.2; - h = inputline_space*0.7; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.xhair_color = uicontrol('Parent',fig,'Style','push', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Crosshair Color',... - 'User',[1 0 0],... - 'String','Color',... - 'visible','off', ... - 'Callback','view_nii(''xhair_color'');'); - - if usepanel - set(handles.xhair_color, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.7; - w = info_pos(3)*0.3; - - pos = [x y w h]; - - handles.xhair = uicontrol('Parent',fig,'Style','popupmenu', ... - 'Units','Normalized', Font, ... - 'Position',pos, ... - 'BackgroundColor', [1 1 1], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Display or Hide Crosshair',... - 'String',{'On','Off'},... - 'visible','off', ... - 'Callback','view_nii(''crosshair'');'); - - if usepanel - set(handles.xhair, 'visible', 'on'); - end - - % Histogram & Color - % - x = info_pos(1); - w = info_pos(3)*0.45; - h = inputline_space * 1.5; - - pos = [x, y+inputline_space*0.9, w, h]; - - handles.hist_frame = uicontrol('Parent',fig, ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'Position',pos, ... - 'visible','off', ... - 'Style','frame'); - - if usepanel -% set(handles.hist_frame, 'visible', 'on'); - end - - handles.coord_frame = uicontrol('Parent',fig, ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'Position',pos, ... - 'visible','off', ... - 'Style','frame'); - - if usepanel - set(handles.coord_frame, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.475; - w = info_pos(3)*0.525; - h = inputline_space * 1.5; - - pos = [x, y+inputline_space*0.9, w, h]; - - handles.color_frame = uicontrol('Parent',fig, ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'Position',pos, ... - 'visible','off', ... - 'Style','frame'); - - if usepanel - set(handles.color_frame, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space*1.2; - w = info_pos(3)*0.2; - h = inputline_space*0.7; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.hist_eq = uicontrol('Parent',fig,'Style','toggle', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Histogram Equalization',... - 'String','Hist EQ',... - 'visible','off', ... - 'Callback','view_nii(''hist_eq'');'); - - if usepanel -% set(handles.hist_eq, 'visible', 'on'); - end - - x = x + w; - w = info_pos(3)*0.2; - - pos = [x y w h]; - - handles.hist_plot = uicontrol('Parent',fig,'Style','push', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Histogram Plot',... - 'String','Hist Plot',... - 'visible','off', ... - 'Callback','view_nii(''hist_plot'');'); - - if usepanel -% set(handles.hist_plot, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.025; - w = info_pos(3)*0.4; - - pos = [x y w h]; - - handles.coord = uicontrol('Parent',fig,'Style','popupmenu', ... - 'Units','Normalized', Font, ... - 'Position',pos, ... - 'BackgroundColor', [1 1 1], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Choose Voxel or Millimeter',... - 'String',{'Voxel','Millimeter'},... - 'visible','off', ... - 'Callback','view_nii(''coordinates'');'); - -% 'TooltipString','Choose Voxel, MNI or Talairach Coordinates',... -% 'String',{'Voxel','MNI (mm)','Talairach (mm)'},... - - if usepanel - set(handles.coord, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.2; - - pos = [x y w h]; - - handles.neg_color = uicontrol('Parent',fig,'Style','toggle', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Negative Colormap',... - 'String','Negative',... - 'visible','off', ... - 'Callback','view_nii(''neg_color'');'); - - if usepanel - set(handles.neg_color, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.neg_color, 'enable', 'off'); - end - - x = info_pos(1) + info_pos(3)*0.7; - w = info_pos(3)*0.275; - - pos = [x y w h]; - - handles.colorindex = uicontrol('Parent',fig,'Style','popupmenu', ... - 'Units','Normalized', Font, ... - 'Position',pos, ... - 'BackgroundColor', [1 1 1], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Change Colormap',... - 'String',{'Custom','Bipolar','Gray','Jet','Cool','Bone','Hot','Copper','Pink'},... - 'value', colorindex, ... - 'visible','off', ... - 'Callback','view_nii(''color'');'); - - if usepanel - set(handles.colorindex, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.colorindex, 'enable', 'off'); - end - - x = info_pos(1) + info_pos(3)*0.1; - y = y + inputline_space; - w = info_pos(3)*0.28; - h = inputline_space*0.6; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.Thist = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Histogram'); - - handles.Tcoord = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Axes Unit'); - - if usepanel -% set(handles.Thist, 'visible', 'on'); - set(handles.Tcoord, 'visible', 'on'); - end - - x = info_pos(1) + info_pos(3)*0.60; - w = info_pos(3)*0.28; - - pos = [x y w h]; - - handles.Tcolor = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Colormap'); - - if usepanel - set(handles.Tcolor, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.Tcolor, 'enable', 'off'); - end - - % Contrast Frame - % - x = info_pos(1); - w = info_pos(3)*0.45; - h = inputline_space * 2; - - pos = [x, y+inputline_space*0.8, w, h]; - - handles.contrast_frame = uicontrol('Parent',fig, ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'Position',pos, ... - 'visible','off', ... - 'Style','frame'); - - if usepanel - set(handles.contrast_frame, 'visible', 'on'); - end - - if colorindex < 2 | colorindex > 3 - set(handles.contrast_frame, 'visible', 'off'); - end - - % Brightness Frame - % - x = info_pos(1) + info_pos(3)*0.475; - w = info_pos(3)*0.525; - - pos = [x, y+inputline_space*0.8, w, h]; - - handles.brightness_frame = uicontrol('Parent',fig, ... - 'Units','normal', ... - 'BackgroundColor',[0.8 0.8 0.8], ... - 'Position',pos, ... - 'visible','off', ... - 'Style','frame'); - - if usepanel - set(handles.brightness_frame, 'visible', 'on'); - end - - % Contrast - % - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space; - w = info_pos(3)*0.4; - h = inputline_space*0.6; - - pos = [x y w h]; - - Font.FontSize = 12; - - slider_step(1) = 5/255; - slider_step(2) = 5.00001/255; - - handles.contrast = uicontrol('Parent',fig, ... - 'Style','slider','Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor',[0.5 0.5 0.5],'ForegroundColor',[0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Change contrast',... - 'Min',1,'Max',256,'SliderStep',slider_step, ... - 'Value',1, ... - 'visible','off', ... - 'Callback','view_nii(''contrast'');'); - - if usepanel - set(handles.contrast, 'visible', 'on'); - end - - if (nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511) & nii_view.numscan <= 1 - set(handles.contrast, 'enable', 'off'); - end - - if nii_view.numscan > 1 - set(handles.contrast, 'min', 1, 'max', nii_view.numscan, ... - 'sliderstep',[1/(nii_view.numscan-1) 1.00001/(nii_view.numscan-1)], ... - 'Callback', 'view_nii(''slider_change_scan'');'); - elseif colorindex < 2 | colorindex > 3 - set(handles.contrast, 'visible', 'off'); - elseif colorindex == 2 - set(handles.contrast,'value',128); - end - - set(handles.contrast,'position',pos); % linux66 - - % Brightness - % - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.475; - - pos = [x y w h]; - - Font.FontSize = 12; - - slider_step(1) = 1/50; - slider_step(2) = 1.00001/50; - - handles.brightness = uicontrol('Parent',fig, ... - 'Style','slider','Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor',[0.5 0.5 0.5],'ForegroundColor',[0 0 0],... - 'BusyAction','queue',... - 'TooltipString','Change brightness',... - 'Min',-1,'Max',1,'SliderStep',slider_step, ... - 'Value',0, ... - 'visible','off', ... - 'Callback','view_nii(''brightness'');'); - - if usepanel - set(handles.brightness, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.brightness, 'enable', 'off'); - end - - set(handles.brightness,'position',pos); % linux66 - - % Contrast text/def - % - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space; - w = info_pos(3)*0.22; - - pos = [x y w h]; - - handles.Tcontrast = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Contrast:'); - - if usepanel - set(handles.Tcontrast, 'visible', 'on'); - end - - if (nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511) & nii_view.numscan <= 1 - set(handles.Tcontrast, 'enable', 'off'); - end - - if nii_view.numscan > 1 - set(handles.Tcontrast, 'string', 'Scan ID:'); - set(handles.contrast, 'TooltipString', 'Change Scan ID'); - elseif colorindex < 2 | colorindex > 3 - set(handles.Tcontrast, 'visible', 'off'); - end - - x = x + w; - w = info_pos(3)*0.18; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.contrast_def = uicontrol('Parent',fig,'Style','push', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Restore initial contrast',... - 'String','Reset',... - 'visible','off', ... - 'Callback','view_nii(''contrast_def'');'); - - if usepanel - set(handles.contrast_def, 'visible', 'on'); - end - - if (nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511) & nii_view.numscan <= 1 - set(handles.contrast_def, 'enable', 'off'); - end - - if nii_view.numscan > 1 - set(handles.contrast_def, 'style', 'edit', 'background', 'w', ... - 'TooltipString','Scan (or volume) index in the time series',... - 'string', '1', 'Callback', 'view_nii(''edit_change_scan'');'); - elseif colorindex < 2 | colorindex > 3 - set(handles.contrast_def, 'visible', 'off'); - end - - % Brightness text/def - % - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.295; - - pos = [x y w h]; - - Font.FontSize = 12; - - handles.Tbrightness = uicontrol('Parent',fig,'Style','text', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'left',... - 'BackgroundColor', [0.8 0.8 0.8], 'ForegroundColor', [0 0 0],... - 'BusyAction','queue',... - 'visible','off', ... - 'String','Brightness:'); - - if usepanel - set(handles.Tbrightness, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.Tbrightness, 'enable', 'off'); - end - - x = x + w; - w = info_pos(3)*0.18; - - pos = [x y w h]; - - Font.FontSize = 8; - - handles.brightness_def = uicontrol('Parent',fig,'Style','push', ... - 'Units','Normalized', Font, ... - 'Position',pos, 'HorizontalAlignment', 'center',... - 'TooltipString','Restore initial brightness',... - 'String','Reset',... - 'visible','off', ... - 'Callback','view_nii(''brightness_def'');'); - - if usepanel - set(handles.brightness_def, 'visible', 'on'); - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(handles.brightness_def, 'enable', 'off'); - end - - % init image handles - % - handles.axial_image = []; - handles.coronal_image = []; - handles.sagittal_image = []; - - % plot axial view - % - if ~isempty(nii_view.bgimg) - bg_slice = squeeze(bgimg(:,:,nii_view.slices.axi)); - h1 = plot_view(fig, xdim, ydim, top_ax, bg_slice', clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - handles.axial_bg = h1; - else - handles.axial_bg = []; - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - img_slice = squeeze(nii.img(:,:,nii_view.slices.axi,:,setscanid)); - img_slice = permute(img_slice, [2 1 3]); - else - img_slice = squeeze(nii.img(:,:,nii_view.slices.axi,setscanid)); - img_slice = img_slice'; - end - h1 = plot_view(fig, xdim, ydim, top_ax, img_slice, clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - set(h1,'buttondown','view_nii(''axial_image'');'); - handles.axial_image = h1; - handles.axial_axes = top_ax; - - if size(img_slice,1) == 1 | size(img_slice,2) == 1 - set(top_ax,'visible','off'); - - if isfield(handles,'sagittal_slider') & ishandle(handles.sagittal_slider) - set(handles.sagittal_slider, 'visible', 'off'); - end - - if isfield(handles,'coronal_slider') & ishandle(handles.coronal_slider) - set(handles.coronal_slider, 'visible', 'off'); - end - - if isfield(handles,'axial_slider') & ishandle(handles.axial_slider) - set(handles.axial_slider, 'visible', 'off'); - end - end - - % plot coronal view - % - if ~isempty(nii_view.bgimg) - bg_slice = squeeze(bgimg(:,nii_view.slices.cor,:)); - h1 = plot_view(fig, xdim, zdim, front_ax, bg_slice', clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - handles.coronal_bg = h1; - else - handles.coronal_bg = []; - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - img_slice = squeeze(nii.img(:,nii_view.slices.cor,:,:,setscanid)); - img_slice = permute(img_slice, [2 1 3]); - else - img_slice = squeeze(nii.img(:,nii_view.slices.cor,:,setscanid)); - img_slice = img_slice'; - end - h1 = plot_view(fig, xdim, zdim, front_ax, img_slice, clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - set(h1,'buttondown','view_nii(''coronal_image'');'); - handles.coronal_image = h1; - handles.coronal_axes = front_ax; - - if size(img_slice,1) == 1 | size(img_slice,2) == 1 - set(front_ax,'visible','off'); - - if isfield(handles,'sagittal_slider') & ishandle(handles.sagittal_slider) - set(handles.sagittal_slider, 'visible', 'off'); - end - - if isfield(handles,'coronal_slider') & ishandle(handles.coronal_slider) - set(handles.coronal_slider, 'visible', 'off'); - end - - if isfield(handles,'axial_slider') & ishandle(handles.axial_slider) - set(handles.axial_slider, 'visible', 'off'); - end - end - - % plot sagittal view - % - if ~isempty(nii_view.bgimg) - bg_slice = squeeze(bgimg(nii_view.slices.sag,:,:)); - - h1 = plot_view(fig, ydim, zdim, side_ax, bg_slice', clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - handles.sagittal_bg = h1; - else - handles.sagittal_bg = []; - end - - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - img_slice = squeeze(nii.img(nii_view.slices.sag,:,:,:,setscanid)); - img_slice = permute(img_slice, [2 1 3]); - else - img_slice = squeeze(nii.img(nii_view.slices.sag,:,:,setscanid)); - img_slice = img_slice'; - end - - h1 = plot_view(fig, ydim, zdim, side_ax, img_slice, clim, cbarminmax, ... - handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, nii_view.numscan); - set(h1,'buttondown','view_nii(''sagittal_image'');'); - set(side_ax,'Xdir', 'reverse'); - handles.sagittal_image = h1; - handles.sagittal_axes = side_ax; - - if size(img_slice,1) == 1 | size(img_slice,2) == 1 - set(side_ax,'visible','off'); - - if isfield(handles,'sagittal_slider') & ishandle(handles.sagittal_slider) - set(handles.sagittal_slider, 'visible', 'off'); - end - - if isfield(handles,'coronal_slider') & ishandle(handles.coronal_slider) - set(handles.coronal_slider, 'visible', 'off'); - end - - if isfield(handles,'axial_slider') & ishandle(handles.axial_slider) - set(handles.axial_slider, 'visible', 'off'); - end - end - - [top1_label, top2_label, side1_label, side2_label] = ... - dir_label(fig, top_ax, front_ax, side_ax); - - % store label handles - % - handles.top1_label = top1_label; - handles.top2_label = top2_label; - handles.side1_label = side1_label; - handles.side2_label = side2_label; - - % plot colorbar - % - if ~isempty(cbar_axes) & ~isempty(cbarminmax_axes) - -if 0 - if isempty(color_map) - level = colorlevel + num_highcolor; - else - level = size([color_map; highcolor], 1); - end -end - - if isempty(color_map) - level = colorlevel; - else - level = size([color_map], 1); - end - - niiclass = class(nii.img); - - h1 = plot_cbar(fig, cbar_axes, cbarminmax_axes, cbarminmax, ... - level, handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, niiclass, nii_view.numscan); - handles.cbar_image = h1; - handles.cbar_axes = cbar_axes; - handles.cbarminmax_axes = cbarminmax_axes; - - end - - nii_view.handles = handles; % store handles - - nii_view.usepanel = usepanel; % whole panel at low right cornor - nii_view.usestretch = usestretch; % stretch display of voxel_size - nii_view.useinterp = useinterp; % use interpolation - nii_view.colorindex = colorindex; % store colorindex variable - nii_view.buttondown = buttondown; % command after button down click - nii_view.cbarminmax = cbarminmax; % store min max value for colorbar - - set_coordinates(nii_view,useinterp); % coord unit - - if ~isfield(nii_view, 'axi_xhair') | ... - ~isfield(nii_view, 'cor_xhair') | ... - ~isfield(nii_view, 'sag_xhair') - - nii_view.axi_xhair = []; % top cross hair - nii_view.cor_xhair = []; % front cross hair - nii_view.sag_xhair = []; % side cross hair - - end - - if ~isempty(color_map) - nii_view.color_map = color_map; - end - - if ~isempty(colorlevel) - nii_view.colorlevel = colorlevel; - end - - if ~isempty(highcolor) - nii_view.highcolor = highcolor; - end - - update_nii_view(nii_view); - - if ~isempty(setunit) - update_unit(fig, setunit); - end - - if ~isempty(setviewpoint) - update_viewpoint(fig, setviewpoint); - end - - if ~isempty(setcrosshaircolor) - update_crosshaircolor(fig, setcrosshaircolor); - end - - if ~isempty(usecrosshair) - update_usecrosshair(fig, usecrosshair); - end - - nii_menu = getappdata(fig, 'nii_menu'); - - if ~isempty(nii_menu) - if nii.hdr.dime.datatype == 128 | nii.hdr.dime.datatype == 511 - set(nii_menu.Minterp,'Userdata',1,'Label','Interp on','enable','off'); - elseif useinterp - set(nii_menu.Minterp,'Userdata',0,'Label','Interp off'); - else - set(nii_menu.Minterp,'Userdata',1,'Label','Interp on'); - end - end - - windowbuttonmotion = get(fig, 'windowbuttonmotion'); - windowbuttonmotion = [windowbuttonmotion '; view_nii(''move_cursor'');']; - set(fig, 'windowbuttonmotion', windowbuttonmotion); - - return; % init - - -%---------------------------------------------------------------- -function fig = update_img(img, fig, opt) - - nii_menu = getappdata(fig,'nii_menu'); - - if ~isempty(nii_menu) - set(nii_menu.Mzoom,'Userdata',1,'Label','Zoom on'); - set(fig,'pointer','arrow'); - zoom off; - end - - nii_view = getappdata(fig,'nii_view'); - change_interp = 0; - - if isfield(opt, 'useinterp') & opt.useinterp ~= nii_view.useinterp - nii_view.useinterp = opt.useinterp; - change_interp = 1; - end - - setscanid = 1; - - if isfield(opt, 'setscanid') - setscanid = round(opt.setscanid); - - if setscanid < 1 - setscanid = 1; - end - - if setscanid > nii_view.numscan - setscanid = nii_view.numscan; - end - end - - if isfield(opt, 'glblocminmax') & ~isempty(opt.glblocminmax) - minvalue = opt.glblocminmax(1); - maxvalue = opt.glblocminmax(2); - else - minvalue = img(:,:,:,setscanid); - minvalue = double(minvalue(:)); - minvalue = min(minvalue(~isnan(minvalue))); - maxvalue = img(:,:,:,setscanid); - maxvalue = double(maxvalue(:)); - maxvalue = max(maxvalue(~isnan(maxvalue))); - end - - if isfield(opt, 'setvalue') - setvalue = opt.setvalue; - - if isfield(opt, 'glblocminmax') & ~isempty(opt.glblocminmax) - minvalue = opt.glblocminmax(1); - maxvalue = opt.glblocminmax(2); - else - minvalue = double(min(setvalue.val)); - maxvalue = double(max(setvalue.val)); - end - - bgimg = double(img); - minbg = double(min(bgimg(:))); - maxbg = double(max(bgimg(:))); - - bgimg = scale_in(bgimg, minbg, maxbg, 55) + 200; % scale to 201~256 - - cbarminmax = [minvalue maxvalue]; - - if nii_view.useinterp - - % scale signal data to 1~200 - % - img = repmat(nan, size(img)); - img(setvalue.idx) = setvalue.val; - - % 200 level for source image - % - bgimg = single(scale_out(bgimg, cbarminmax(1), cbarminmax(2), 199)); - - else - - bgimg(setvalue.idx) = NaN; - minbg = double(min(bgimg(:))); - maxbg = double(max(bgimg(:))); - bgimg(setvalue.idx) = minbg; - - % bgimg must be normalized to [201 256] - % - bgimg = 55 * (bgimg-min(bgimg(:))) / (max(bgimg(:))-min(bgimg(:))) + 201; - bgimg(setvalue.idx) = 0; - - % scale signal data to 1~200 - % - img = zeros(size(img)); - img(setvalue.idx) = scale_in(setvalue.val, minvalue, maxvalue, 199); - img = img + bgimg; - bgimg = []; - img = scale_out(img, cbarminmax(1), cbarminmax(2), 199); - - minvalue = double(min(img(:))); - maxvalue = double(max(img(:))); - - if isfield(opt,'glblocminmax') & ~isempty(opt.glblocminmax) - minvalue = opt.glblocminmax(1); - end - - end - - nii_view.bgimg = bgimg; - nii_view.setvalue = setvalue; - - else - cbarminmax = [minvalue maxvalue]; - end - - update_cbarminmax(fig, cbarminmax); - nii_view.cbarminmax = cbarminmax; - nii_view.nii.img = img; - nii_view.minvalue = minvalue; - nii_view.maxvalue = maxvalue; - nii_view.scanid = setscanid; - change_colormap(fig); - - % init color (gray) scaling to make sure the slice clim take the - % global clim [min(nii.img(:)) max(nii.img(:))] - % - if isempty(nii_view.bgimg) - clim = [minvalue maxvalue]; - else - clim = [minvalue double(max(nii_view.bgimg(:)))]; - end - - if clim(1) == clim(2) - clim(2) = clim(1) + 0.000001; - end - - if strcmpi(get(nii_view.handles.axial_image,'cdatamapping'), 'direct') - useimagesc = 0; - else - useimagesc = 1; - end - - if ~isempty(nii_view.bgimg) % with interpolation - - Saxi = squeeze(nii_view.bgimg(:,:,nii_view.slices.axi)); - - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) - set(nii_view.handles.axial_bg,'CData',double(Saxi)'); - else - axes(nii_view.handles.axial_axes); - - if useimagesc - nii_view.handles.axial_bg = surface(zeros(size(Saxi')),double(Saxi'),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.axial_bg = surface(zeros(size(Saxi')),double(Saxi'),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - - order = get(gca,'child'); - order(find(order == nii_view.handles.axial_bg)) = []; - order = [order; nii_view.handles.axial_bg]; - set(gca, 'child', order); - end - - end - - if isfield(nii_view.handles,'axial_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Saxi = squeeze(nii_view.nii.img(:,:,nii_view.slices.axi,:,setscanid)); - Saxi = permute(Saxi, [2 1 3]); - else - Saxi = squeeze(nii_view.nii.img(:,:,nii_view.slices.axi,setscanid)); - Saxi = Saxi'; - end - - set(nii_view.handles.axial_image,'CData',double(Saxi)); - end - - set(nii_view.handles.axial_axes,'CLim',clim); - - if ~isempty(nii_view.bgimg) - Scor = squeeze(nii_view.bgimg(:,nii_view.slices.cor,:)); - - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) - set(nii_view.handles.coronal_bg,'CData',double(Scor)'); - else - axes(nii_view.handles.coronal_axes); - - if useimagesc - nii_view.handles.coronal_bg = surface(zeros(size(Scor')),double(Scor'),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.coronal_bg = surface(zeros(size(Scor')),double(Scor'),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - - order = get(gca,'child'); - order(find(order == nii_view.handles.coronal_bg)) = []; - order = [order; nii_view.handles.coronal_bg]; - set(gca, 'child', order); - end - end - - if isfield(nii_view.handles,'coronal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Scor = squeeze(nii_view.nii.img(:,nii_view.slices.cor,:,:,setscanid)); - Scor = permute(Scor, [2 1 3]); - else - Scor = squeeze(nii_view.nii.img(:,nii_view.slices.cor,:,setscanid)); - Scor = Scor'; - end - - set(nii_view.handles.coronal_image,'CData',double(Scor)); - end - - set(nii_view.handles.coronal_axes,'CLim',clim); - - if ~isempty(nii_view.bgimg) - Ssag = squeeze(nii_view.bgimg(nii_view.slices.sag,:,:)); - - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) - set(nii_view.handles.sagittal_bg,'CData',double(Ssag)'); - else - axes(nii_view.handles.sagittal_axes); - - if useimagesc - nii_view.handles.sagittal_bg = surface(zeros(size(Ssag')),double(Ssag'),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.sagittal_bg = surface(zeros(size(Ssag')),double(Ssag'),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - - order = get(gca,'child'); - order(find(order == nii_view.handles.sagittal_bg)) = []; - order = [order; nii_view.handles.sagittal_bg]; - set(gca, 'child', order); - end - end - - if isfield(nii_view.handles,'sagittal_image'), - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - Ssag = squeeze(nii_view.nii.img(nii_view.slices.sag,:,:,:,setscanid)); - Ssag = permute(Ssag, [2 1 3]); - else - Ssag = squeeze(nii_view.nii.img(nii_view.slices.sag,:,:,setscanid)); - Ssag = Ssag'; - end - - set(nii_view.handles.sagittal_image,'CData',double(Ssag)); - end - - set(nii_view.handles.sagittal_axes,'CLim',clim); - - update_nii_view(nii_view); - - if isfield(opt, 'setvalue') - - if ~isfield(nii_view,'highcolor') | ~isequal(size(nii_view.highcolor),[56 3]) - - % 55 level for brain structure (paded 0 for highcolor level 1, i.e. normal level 201, to make 56 highcolor) - % - update_highcolor(fig, [zeros(1,3);gray(55)], []); - - end - - if nii_view.colorindex ~= 2 - update_colorindex(fig, 2); - end - - old_color = get(nii_view.handles.xhair_color,'user'); - - if isequal(old_color, [1 0 0]) - update_crosshaircolor(fig, [1 1 0]); - end - -% if change_interp - % update_useinterp(fig, nii_view.useinterp); - % end - - end - - if change_interp - update_useinterp(fig, nii_view.useinterp); - end - - return; % update_img - - -%---------------------------------------------------------------- -function [top_pos, front_pos, side_pos] = ... - axes_pos(fig,area,vol_size,usestretch) - - set(fig,'unit','pixel'); - - fig_pos = get(fig,'position'); - - gap_x = 15/fig_pos(3); % width of vertical scrollbar - gap_y = 15/fig_pos(4); % width of horizontal scrollbar - - a = (area(3) - gap_x * 1.3) * fig_pos(3) / (vol_size(1) + vol_size(2)); % no crosshair lost in zoom - b = (area(4) - gap_y * 3) * fig_pos(4) / (vol_size(2) + vol_size(3)); - c = min([a b]); % make sure 'ax' is inside 'area' - - top_w = vol_size(1) * c / fig_pos(3); - side_w = vol_size(2) * c / fig_pos(3); - top_h = vol_size(2) * c / fig_pos(4); - side_h = vol_size(3) * c / fig_pos(4); - side_x = area(1) + top_w + gap_x * 1.3; % no crosshair lost in zoom - side_y = area(2) + top_h + gap_y * 3; - - if usestretch - if a > b % top touched ceiling, use b - d = (area(3) - gap_x * 1.3) / (top_w + side_w); % no crosshair lost in zoom - top_w = top_w * d; - side_w = side_w * d; - side_x = area(1) + top_w + gap_x * 1.3; % no crosshair lost in zoom - else - d = (area(4) - gap_y * 3) / (top_h + side_h); - top_h = top_h * d; - side_h = side_h * d; - side_y = area(2) + top_h + gap_y * 3; - end - end - - top_pos = [area(1) area(2)+gap_y top_w top_h]; - front_pos = [area(1) side_y top_w side_h]; - side_pos = [side_x side_y side_w side_h]; - - set(fig,'unit','normal'); - - return; % axes_pos - - -%---------------------------------------------------------------- -function [top_ax, front_ax, side_ax] ... - = create_ax(fig, area, vol_size, usestretch) - - cur_fig = gcf; % save h_wait fig - figure(fig); - - [top_pos, front_pos, side_pos] = ... - axes_pos(fig,area,vol_size,usestretch); - - nii_view = getappdata(fig, 'nii_view'); - - if isempty(nii_view) - top_ax = axes('position', top_pos); - front_ax = axes('position', front_pos); - side_ax = axes('position', side_pos); - else - top_ax = nii_view.handles.axial_axes; - front_ax = nii_view.handles.coronal_axes; - side_ax = nii_view.handles.sagittal_axes; - - set(top_ax, 'position', top_pos); - set(front_ax, 'position', front_pos); - set(side_ax, 'position', side_pos); - end - - figure(cur_fig); - - return; % create_ax - - -%---------------------------------------------------------------- -function [cbar_axes, cbarminmax_axes] = create_cbar_axes(fig, cbar_area, nii_view) - - if isempty(cbar_area) % without_cbar - cbar_axes = []; - cbarminmax_axes = []; - return; - end - - cur_fig = gcf; % save h_wait fig - figure(fig); - - if ~exist('nii_view', 'var') - nii_view = getappdata(fig, 'nii_view'); - end - - if isempty(nii_view) | ~isfield(nii_view.handles,'cbar_axes') | isempty(nii_view.handles.cbar_axes) - cbarminmax_axes = axes('position', cbar_area); - cbar_axes = axes('position', cbar_area); - else - cbarminmax_axes = nii_view.handles.cbarminmax_axes; - cbar_axes = nii_view.handles.cbar_axes; - set(cbarminmax_axes, 'position', cbar_area); - set(cbar_axes, 'position', cbar_area); - end - - figure(cur_fig); - - return; % create_cbar_axes - - -%---------------------------------------------------------------- -function h1 = plot_view(fig, x, y, img_ax, img_slice, clim, ... - cbarminmax, handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, useinterp, numscan) - - h1 = []; - - if x > 1 & y > 1, - - axes(img_ax); - - nii_view = getappdata(fig, 'nii_view'); - - if isempty(nii_view) - - % set colormap first - % - nii.handles = handles; - nii.handles.axial_axes = img_ax; - nii.colorindex = colorindex; - nii.color_map = color_map; - nii.colorlevel = colorlevel; - nii.highcolor = highcolor; - nii.numscan = numscan; - - change_colormap(fig, nii, colorindex, cbarminmax); - - if useinterp - if useimagesc - h1 = surface(zeros(size(img_slice)),double(img_slice),'edgecolor','none','facecolor','interp'); - else - h1 = surface(zeros(size(img_slice)),double(img_slice),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - - set(gca,'clim',clim); - else - if useimagesc - h1 = imagesc(img_slice,clim); - else - h1 = image(img_slice); - end - - set(gca,'clim',clim); - end - - else - - h1 = nii_view.handles.axial_image; - - if ~isequal(get(h1,'parent'), img_ax) - h1 = nii_view.handles.coronal_image; - end - - if ~isequal(get(h1,'parent'), img_ax) - h1 = nii_view.handles.sagittal_image; - end - - set(h1, 'cdata', double(img_slice)); - set(h1, 'xdata', 1:size(img_slice,2)); - set(h1, 'ydata', 1:size(img_slice,1)); - - end - - set(img_ax,'YDir','normal','XLimMode','manual','YLimMode','manual',... - 'ClimMode','manual','visible','off', ... - 'xtick',[],'ytick',[], 'clim', clim); - - end - - return; % plot_view - - -%---------------------------------------------------------------- -function h1 = plot_cbar(fig, cbar_axes, cbarminmax_axes, cbarminmax, ... - level, handles, useimagesc, colorindex, color_map, ... - colorlevel, highcolor, niiclass, numscan, nii_view) - - cbar_image = [1:level]'; - - % In a uint8 or uint16 indexed image, 0 points to the first row - % in the colormap - % - if 0 % strcmpi(niiclass,'uint8') | strcmpi(niiclass,'uint16') - % we use single for display anyway - ylim = [0, level-1]; - else - ylim = [1, level]; - end - - axes(cbarminmax_axes); - - plot([0 0], cbarminmax, 'w'); - axis tight; - - set(cbarminmax_axes,'YDir','normal', ... - 'XLimMode','manual','YLimMode','manual','YColor',[0 0 0], ... - 'XColor',[0 0 0],'xtick',[],'YAxisLocation','right'); - - ylimb = get(cbarminmax_axes,'ylim'); - ytickb = get(cbarminmax_axes,'ytick'); - ytick=(ylim(2)-ylim(1))*(ytickb-ylimb(1))/(ylimb(2)-ylimb(1))+ylim(1); - - axes(cbar_axes); - - if ~exist('nii_view', 'var') - nii_view = getappdata(fig, 'nii_view'); - end - - if isempty(nii_view) | ~isfield(nii_view.handles,'cbar_image') | isempty(nii_view.handles.cbar_image) - - % set colormap first - % - nii.handles = handles; - nii.colorindex = colorindex; - nii.color_map = color_map; - nii.colorlevel = colorlevel; - nii.highcolor = highcolor; - nii.numscan = numscan; - - change_colormap(fig, nii, colorindex, cbarminmax); - h1 = image([0,1], [ylim(1),ylim(2)], cbar_image); - - else - h1 = nii_view.handles.cbar_image; - set(h1, 'cdata', double(cbar_image)); - end - - set(cbar_axes,'YDir','normal','XLimMode','manual', ... - 'YLimMode','manual','YColor',[0 0 0],'XColor',[0 0 0],'xtick',[], ... - 'YAxisLocation','right','ylim',ylim,'ytick',ytick,'yticklabel',''); - - return; % plot_cbar - - -%---------------------------------------------------------------- -function set_coordinates(nii_view,useinterp) - - imgPlim.vox = nii_view.dims; - imgNlim.vox = [1 1 1]; - - if useinterp - xdata_ax = [imgNlim.vox(1) imgPlim.vox(1)]; - ydata_ax = [imgNlim.vox(2) imgPlim.vox(2)]; - zdata_ax = [imgNlim.vox(3) imgPlim.vox(3)]; - else - xdata_ax = [imgNlim.vox(1)-0.5 imgPlim.vox(1)+0.5]; - ydata_ax = [imgNlim.vox(2)-0.5 imgPlim.vox(2)+0.5]; - zdata_ax = [imgNlim.vox(3)-0.5 imgPlim.vox(3)+0.5]; - end - - if isfield(nii_view.handles,'axial_image') & ~isempty(nii_view.handles.axial_image) - set(nii_view.handles.axial_axes,'Xlim',xdata_ax); - set(nii_view.handles.axial_axes,'Ylim',ydata_ax); - end; - if isfield(nii_view.handles,'coronal_image') & ~isempty(nii_view.handles.coronal_image) - set(nii_view.handles.coronal_axes,'Xlim',xdata_ax); - set(nii_view.handles.coronal_axes,'Ylim',zdata_ax); - end; - if isfield(nii_view.handles,'sagittal_image') & ~isempty(nii_view.handles.sagittal_image) - set(nii_view.handles.sagittal_axes,'Xlim',ydata_ax); - set(nii_view.handles.sagittal_axes,'Ylim',zdata_ax); - end; - - return % set_coordinates - - -%---------------------------------------------------------------- -function set_image_value(nii_view), - - % get coordinates of selected voxel and the image intensity there - % - sag = round(nii_view.slices.sag); - cor = round(nii_view.slices.cor); - axi = round(nii_view.slices.axi); - - if 0 % isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - if nii_view.nii.hdr.dime.datatype == 128 - imgvalue = [double(img(sag,cor,axi,1,nii_view.scanid)) double(img(sag,cor,axi,2,nii_view.scanid)) double(img(sag,cor,axi,3,nii_view.scanid))]; - set(nii_view.handles.imval,'Value',imgvalue); - set(nii_view.handles.imval,'String',sprintf('%7.4g %7.4g %7.4g',imgvalue)); - elseif nii_view.nii.hdr.dime.datatype == 511 - R = double(img(sag,cor,axi,1,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - G = double(img(sag,cor,axi,2,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - B = double(img(sag,cor,axi,3,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - imgvalue = [double(img(sag,cor,axi,1,nii_view.scanid)) double(img(sag,cor,axi,2,nii_view.scanid)) double(img(sag,cor,axi,3,nii_view.scanid))]; - set(nii_view.handles.imval,'Value',imgvalue); - imgvalue = [R G B]; - set(nii_view.handles.imval,'String',sprintf('%7.4g %7.4g %7.4g',imgvalue)); - else - imgvalue = double(img(sag,cor,axi,nii_view.scanid)); - set(nii_view.handles.imval,'Value',imgvalue); - - if isnan(imgvalue) | imgvalue > nii_view.cbarminmax(2) - imgvalue = 0; - end - - set(nii_view.handles.imval,'String',sprintf('%.6g',imgvalue)); - end - - % Now update the coordinates of the selected voxel - - nii_view = update_imgXYZ(nii_view); - - if get(nii_view.handles.coord,'value') == 1, - sag = nii_view.imgXYZ.vox(1); - cor = nii_view.imgXYZ.vox(2); - axi = nii_view.imgXYZ.vox(3); - org = nii_view.origin; - elseif get(nii_view.handles.coord,'value') == 2, - sag = nii_view.imgXYZ.mm(1); - cor = nii_view.imgXYZ.mm(2); - axi = nii_view.imgXYZ.mm(3); - org = [0 0 0]; - elseif get(nii_view.handles.coord,'value') == 3, - sag = nii_view.imgXYZ.tal(1); - cor = nii_view.imgXYZ.tal(2); - axi = nii_view.imgXYZ.tal(3); - org = [0 0 0]; - end - - set(nii_view.handles.impos,'Value',[sag,cor,axi]); - - if get(nii_view.handles.coord,'value') == 1, - string = sprintf('%7.0f %7.0f %7.0f',sag,cor,axi); - org_str = sprintf('%7.0f %7.0f %7.0f', org(1), org(2), org(3)); - else - string = sprintf('%7.1f %7.1f %7.1f',sag,cor,axi); - org_str = sprintf('%7.1f %7.1f %7.1f', org(1), org(2), org(3)); - end; - - set(nii_view.handles.impos,'String',string); - set(nii_view.handles.origin, 'string', org_str); - - return % set_image_value - - -%---------------------------------------------------------------- -function nii_view = get_slice_position(nii_view,view), - - % obtain slices that is in correct unit, then update slices - % - slices = nii_view.slices; - - switch view, - case 'sag', - currentpoint = get(nii_view.handles.sagittal_axes,'CurrentPoint'); - slices.cor = currentpoint(1,1); - slices.axi = currentpoint(1,2); - case 'cor', - currentpoint = get(nii_view.handles.coronal_axes,'CurrentPoint'); - slices.sag = currentpoint(1,1); - slices.axi = currentpoint(1,2); - case 'axi', - currentpoint = get(nii_view.handles.axial_axes,'CurrentPoint'); - slices.sag = currentpoint(1,1); - slices.cor = currentpoint(1,2); - end - - % update nii_view.slices with the updated slices - % - nii_view.slices.axi = round(slices.axi); - nii_view.slices.cor = round(slices.cor); - nii_view.slices.sag = round(slices.sag); - - return % get_slice_position - - -%---------------------------------------------------------------- -function nii_view = get_slider_position(nii_view), - - [nii_view.slices.sag,nii_view.slices.cor,nii_view.slices.axi] = deal(0); - - if isfield(nii_view.handles,'sagittal_slider'), - if ishandle(nii_view.handles.sagittal_slider), - nii_view.slices.sag = ... - round(get(nii_view.handles.sagittal_slider,'Value')); - end - end - - if isfield(nii_view.handles,'coronal_slider'), - if ishandle(nii_view.handles.coronal_slider), - nii_view.slices.cor = ... - round(nii_view.dims(2) - ... - get(nii_view.handles.coronal_slider,'Value') + 1); - end - end - - if isfield(nii_view.handles,'axial_slider'), - if ishandle(nii_view.handles.axial_slider), - nii_view.slices.axi = ... - round(get(nii_view.handles.axial_slider,'Value')); - end - end - - nii_view = check_slices(nii_view); - - return % get_slider_position - - -%---------------------------------------------------------------- -function nii_view = update_imgXYZ(nii_view), - - nii_view.imgXYZ.vox = ... - [nii_view.slices.sag,nii_view.slices.cor,nii_view.slices.axi]; - nii_view.imgXYZ.mm = ... - (nii_view.imgXYZ.vox - nii_view.origin) .* nii_view.voxel_size; -% nii_view.imgXYZ.tal = mni2tal(nii_view.imgXYZ.mni); - - return % update_imgXYZ - - -%---------------------------------------------------------------- -function nii_view = convert2voxel(nii_view,slices), - - if get(nii_view.handles.coord,'value') == 1, - - % [slices.axi, slices.cor, slices.sag] are in vox - % - nii_view.slices.axi = round(slices.axi); - nii_view.slices.cor = round(slices.cor); - nii_view.slices.sag = round(slices.sag); - - elseif get(nii_view.handles.coord,'value') == 2, - - % [slices.axi, slices.cor, slices.sag] are in mm - % - xpix = nii_view.voxel_size(1); - ypix = nii_view.voxel_size(2); - zpix = nii_view.voxel_size(3); - - nii_view.slices.axi = round(slices.axi / zpix + nii_view.origin(3)); - nii_view.slices.cor = round(slices.cor / ypix + nii_view.origin(2)); - nii_view.slices.sag = round(slices.sag / xpix + nii_view.origin(1)); - elseif get(nii_view.handles.coord,'value') == 3, - - % [slices.axi, slices.cor, slices.sag] are in talairach - % - xpix = nii_view.voxel_size(1); - ypix = nii_view.voxel_size(2); - zpix = nii_view.voxel_size(3); - - xyz_tal = [slices.sag, slices.cor, slices.axi]; - xyz_mni = tal2mni(xyz_tal); - - nii_view.slices.axi = round(xyz_mni(3) / zpix + nii_view.origin(3)); - nii_view.slices.cor = round(xyz_mni(2) / ypix + nii_view.origin(2)); - nii_view.slices.sag = round(xyz_mni(1) / xpix + nii_view.origin(1)); - - end - - return % convert2voxel - - -%---------------------------------------------------------------- -function nii_view = check_slices(nii_view), - - img = nii_view.nii.img; - - [ SagSize, CorSize, AxiSize, TimeSize ] = size(img); - if nii_view.slices.sag > SagSize, nii_view.slices.sag = SagSize; end; - if nii_view.slices.sag < 1, nii_view.slices.sag = 1; end; - if nii_view.slices.cor > CorSize, nii_view.slices.cor = CorSize; end; - if nii_view.slices.cor < 1, nii_view.slices.cor = 1; end; - if nii_view.slices.axi > AxiSize, nii_view.slices.axi = AxiSize; end; - if nii_view.slices.axi < 1, nii_view.slices.axi = 1; end; - if nii_view.scanid > TimeSize, nii_view.scanid = TimeSize; end; - if nii_view.scanid < 1, nii_view.scanid = 1; end; - - return % check_slices - - -%---------------------------------------------------------------- -% -% keep this function small, since it will be called for every click -% -function nii_view = update_nii_view(nii_view) - - % add imgXYZ into nii_view struct - % - nii_view = check_slices(nii_view); - nii_view = update_imgXYZ(nii_view); - - % update xhair - % - p_axi = nii_view.imgXYZ.vox([1 2]); - p_cor = nii_view.imgXYZ.vox([1 3]); - p_sag = nii_view.imgXYZ.vox([2 3]); - - nii_view.axi_xhair = ... - rri_xhair(p_axi, nii_view.axi_xhair, nii_view.handles.axial_axes); - - nii_view.cor_xhair = ... - rri_xhair(p_cor, nii_view.cor_xhair, nii_view.handles.coronal_axes); - - nii_view.sag_xhair = ... - rri_xhair(p_sag, nii_view.sag_xhair, nii_view.handles.sagittal_axes); - - setappdata(nii_view.fig, 'nii_view', nii_view); - set_image_value(nii_view); - - return; % update_nii_view - - -%---------------------------------------------------------------- -function hist_plot(fig) - - nii_view = getappdata(fig,'nii_view'); - - if isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - img = double(img(:)); - - if length(unique(round(img))) == length(unique(img)) - is_integer = 1; - range = max(img) - min(img) + 1; - figure; hist(img, range); - set(gca, 'xlim', [-range/5, max(img)]); - else - is_integer = 0; - figure; hist(img); - end - - xlabel('Voxel Intensity'); - ylabel('Voxel Numbers for Each Intensity'); - set(gcf, 'NumberTitle','off','Name','Histogram Plot'); - - return; % hist_plot - - -%---------------------------------------------------------------- -function hist_eq(fig) - - nii_view = getappdata(fig,'nii_view'); - - old_pointer = get(fig,'Pointer'); - set(fig,'Pointer','watch'); - - if get(nii_view.handles.hist_eq,'value') - max_img = double(max(nii_view.nii.img(:))); - tmp = double(nii_view.nii.img) / max_img; % normalize for histeq - tmp = histeq(tmp(:)); - nii_view.disp = reshape(tmp, size(nii_view.nii.img)); - min_disp = min(nii_view.disp(:)); - nii_view.disp = (nii_view.disp - min_disp); % range having eq hist - nii_view.disp = nii_view.disp * max_img / max(nii_view.disp(:)); - nii_view.disp = single(nii_view.disp); - else - if isfield(nii_view, 'disp') - nii_view.disp = nii_view.nii.img; - else - set(fig,'Pointer',old_pointer); - return; - end - end - - % update axial view - % - img_slice = squeeze(double(nii_view.disp(:,:,nii_view.slices.axi))); - h1 = nii_view.handles.axial_image; - set(h1, 'cdata', double(img_slice)'); - - % update coronal view - % - img_slice = squeeze(double(nii_view.disp(:,nii_view.slices.cor,:))); - h1 = nii_view.handles.coronal_image; - set(h1, 'cdata', double(img_slice)'); - - % update sagittal view - % - img_slice = squeeze(double(nii_view.disp(nii_view.slices.sag,:,:))); - - h1 = nii_view.handles.sagittal_image; - set(h1, 'cdata', double(img_slice)'); - - % remove disp field if un-check 'histeq' button - % - if ~get(nii_view.handles.hist_eq,'value') & isfield(nii_view, 'disp') - nii_view = rmfield(nii_view, 'disp'); - end - - update_nii_view(nii_view); - - set(fig,'Pointer',old_pointer); - - return; % hist_eq - - -%---------------------------------------------------------------- -function [top1_label, top2_label, side1_label, side2_label] = ... - dir_label(fig, top_ax, front_ax, side_ax) - - nii_view = getappdata(fig,'nii_view'); - - top_pos = get(top_ax,'position'); - front_pos = get(front_ax,'position'); - side_pos = get(side_ax,'position'); - - top_gap_x = (side_pos(1)-top_pos(1)-top_pos(3)) / (2*top_pos(3)); - top_gap_y = (front_pos(2)-top_pos(2)-top_pos(4)) / (2*top_pos(4)); - side_gap_x = (side_pos(1)-top_pos(1)-top_pos(3)) / (2*side_pos(3)); - side_gap_y = (front_pos(2)-top_pos(2)-top_pos(4)) / (2*side_pos(4)); - - top1_label_pos = [0, 1]; % rot0 - top2_label_pos = [1, 0]; % rot90 - side1_label_pos = [1, - side_gap_y]; % rot0 - side2_label_pos = [0, 0]; % rot90 - - if isempty(nii_view) - axes(top_ax); - top1_label = text(double(top1_label_pos(1)),double(top1_label_pos(2)), ... - '== X =>', ... - 'vertical', 'bottom', ... - 'unit', 'normal', 'fontsize', 8); - - axes(top_ax); - top2_label = text(double(top2_label_pos(1)),double(top2_label_pos(2)), ... - '== Y =>', ... - 'rotation', 90, 'vertical', 'top', ... - 'unit', 'normal', 'fontsize', 8); - - axes(side_ax); - side1_label = text(double(side1_label_pos(1)),double(side1_label_pos(2)), ... - '<= Y ==', ... - 'horizontal', 'right', 'vertical', 'top', ... - 'unit', 'normal', 'fontsize', 8); - - axes(side_ax); - side2_label = text(double(side2_label_pos(1)),double(side2_label_pos(2)), ... - '== Z =>', ... - 'rotation', 90, 'vertical', 'bottom', ... - 'unit', 'normal', 'fontsize', 8); - else - top1_label = nii_view.handles.top1_label; - top2_label = nii_view.handles.top2_label; - side1_label = nii_view.handles.side1_label; - side2_label = nii_view.handles.side2_label; - - set(top1_label, 'position', [top1_label_pos 0]); - set(top2_label, 'position', [top2_label_pos 0]); - set(side1_label, 'position', [side1_label_pos 0]); - set(side2_label, 'position', [side2_label_pos 0]); - end - - return; % dir_label - - -%---------------------------------------------------------------- -function update_enable(h, opt); - - nii_view = getappdata(h,'nii_view'); - handles = nii_view.handles; - - if isfield(opt,'enablecursormove') - if opt.enablecursormove - v = 'on'; - else - v = 'off'; - end - - set(handles.Timposcur, 'visible', v); - set(handles.imposcur, 'visible', v); - set(handles.Timvalcur, 'visible', v); - set(handles.imvalcur, 'visible', v); - end - - if isfield(opt,'enableviewpoint') - if opt.enableviewpoint - v = 'on'; - else - v = 'off'; - end - - set(handles.Timpos, 'visible', v); - set(handles.impos, 'visible', v); - set(handles.Timval, 'visible', v); - set(handles.imval, 'visible', v); - end - - if isfield(opt,'enableorigin') - if opt.enableorigin - v = 'on'; - else - v = 'off'; - end - - set(handles.Torigin, 'visible', v); - set(handles.origin, 'visible', v); - end - - if isfield(opt,'enableunit') - if opt.enableunit - v = 'on'; - else - v = 'off'; - end - - set(handles.Tcoord, 'visible', v); - set(handles.coord_frame, 'visible', v); - set(handles.coord, 'visible', v); - end - - if isfield(opt,'enablecrosshair') - if opt.enablecrosshair - v = 'on'; - else - v = 'off'; - end - - set(handles.Txhair, 'visible', v); - set(handles.xhair_color, 'visible', v); - set(handles.xhair, 'visible', v); - end - - if isfield(opt,'enablehistogram') - if opt.enablehistogram - v = 'on'; - vv = 'off'; - else - v = 'off'; - vv = 'on'; - end - - set(handles.Tcoord, 'visible', vv); - set(handles.coord_frame, 'visible', vv); - set(handles.coord, 'visible', vv); - - set(handles.Thist, 'visible', v); - set(handles.hist_frame, 'visible', v); - set(handles.hist_eq, 'visible', v); - set(handles.hist_plot, 'visible', v); - end - - if isfield(opt,'enablecolormap') - if opt.enablecolormap - v = 'on'; - else - v = 'off'; - end - - set(handles.Tcolor, 'visible', v); - set(handles.color_frame, 'visible', v); - set(handles.neg_color, 'visible', v); - set(handles.colorindex, 'visible', v); - end - - if isfield(opt,'enablecontrast') - if opt.enablecontrast - v = 'on'; - else - v = 'off'; - end - - set(handles.Tcontrast, 'visible', v); - set(handles.contrast_frame, 'visible', v); - set(handles.contrast_def, 'visible', v); - set(handles.contrast, 'visible', v); - end - - if isfield(opt,'enablebrightness') - if opt.enablebrightness - v = 'on'; - else - v = 'off'; - end - - set(handles.Tbrightness, 'visible', v); - set(handles.brightness_frame, 'visible', v); - set(handles.brightness_def, 'visible', v); - set(handles.brightness, 'visible', v); - end - - if isfield(opt,'enabledirlabel') - if opt.enabledirlabel - v = 'on'; - else - v = 'off'; - end - - set(handles.top1_label, 'visible', v); - set(handles.top2_label, 'visible', v); - set(handles.side1_label, 'visible', v); - set(handles.side2_label, 'visible', v); - end - - if isfield(opt,'enableslider') - if opt.enableslider - v = 'on'; - else - v = 'off'; - end - - if isfield(handles,'sagittal_slider') & ishandle(handles.sagittal_slider) - set(handles.sagittal_slider, 'visible', v); - end - - if isfield(handles,'coronal_slider') & ishandle(handles.coronal_slider) - set(handles.coronal_slider, 'visible', v); - end - - if isfield(handles,'axial_slider') & ishandle(handles.axial_slider) - set(handles.axial_slider, 'visible', v); - end - end - - return; % update_enable - - -%---------------------------------------------------------------- -function update_usepanel(fig, usepanel) - - if isempty(usepanel) - return; - end - - if usepanel - opt.enablecursormove = 1; - opt.enableviewpoint = 1; - opt.enableorigin = 1; - opt.enableunit = 1; - opt.enablecrosshair = 1; -% opt.enablehistogram = 1; - opt.enablecolormap = 1; - opt.enablecontrast = 1; - opt.enablebrightness = 1; - else - opt.enablecursormove = 0; - opt.enableviewpoint = 0; - opt.enableorigin = 0; - opt.enableunit = 0; - opt.enablecrosshair = 0; -% opt.enablehistogram = 0; - opt.enablecolormap = 0; - opt.enablecontrast = 0; - opt.enablebrightness = 0; - end - - update_enable(fig, opt); - - nii_view = getappdata(fig,'nii_view'); - nii_view.usepanel = usepanel; - setappdata(fig,'nii_view',nii_view); - - return; % update_usepanel - - -%---------------------------------------------------------------- -function update_usecrosshair(fig, usecrosshair) - - if isempty(usecrosshair) - return; - end - - if usecrosshair - v=1; - else - v=2; - end - - nii_view = getappdata(fig,'nii_view'); - set(nii_view.handles.xhair,'value',v); - - opt.command = 'crosshair'; - view_nii(fig, opt); - - return; % update_usecrosshair - - -%---------------------------------------------------------------- -function update_usestretch(fig, usestretch) - - nii_view = getappdata(fig,'nii_view'); - - handles = nii_view.handles; - fig = nii_view.fig; - area = nii_view.area; - vol_size = nii_view.voxel_size .* nii_view.dims; - - % Three Axes & label - % - [top_ax, front_ax, side_ax] = ... - create_ax(fig, area, vol_size, usestretch); - - dir_label(fig, top_ax, front_ax, side_ax); - - top_pos = get(top_ax,'position'); - front_pos = get(front_ax,'position'); - side_pos = get(side_ax,'position'); - - % Sagittal Slider - % - x = side_pos(1); - y = top_pos(2) + top_pos(4); - w = side_pos(3); - h = (front_pos(2) - y) / 2; - y = y + h; - pos = [x y w h]; - - if isfield(handles,'sagittal_slider') & ishandle(handles.sagittal_slider) - set(handles.sagittal_slider,'position',pos); - end - - % Coronal Slider - % - x = top_pos(1); - y = top_pos(2) + top_pos(4); - w = top_pos(3); - h = (front_pos(2) - y) / 2; - y = y + h; - pos = [x y w h]; - - if isfield(handles,'coronal_slider') & ishandle(handles.coronal_slider) - set(handles.coronal_slider,'position',pos); - end - - % Axial Slider - % - x = top_pos(1); - y = area(2); - w = top_pos(3); - h = top_pos(2) - y; - pos = [x y w h]; - - if isfield(handles,'axial_slider') & ishandle(handles.axial_slider) - set(handles.axial_slider,'position',pos); - end - - % plot info view - % -% info_pos = [side_pos([1,3]); top_pos([2,4])]; -% info_pos = info_pos(:); - gap = side_pos(1)-(top_pos(1)+top_pos(3)); - info_pos(1) = side_pos(1) + gap; - info_pos(2) = area(2); - info_pos(3) = side_pos(3) - gap; - info_pos(4) = top_pos(2) + top_pos(4) - area(2) - gap; - - num_inputline = 10; - inputline_space =info_pos(4) / num_inputline; - - - % Image Intensity Value at Cursor - % - x = info_pos(1); - y = info_pos(2); - w = info_pos(3)*0.5; - h = inputline_space*0.6; - - pos = [x y w h]; - set(handles.Timvalcur,'position',pos); - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.imvalcur,'position',pos); - - % Position at Cursor - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.Timposcur,'position',pos); - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.imposcur,'position',pos); - - % Image Intensity Value at Mouse Click - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.Timval,'position',pos); - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.imval,'position',pos); - - % Viewpoint Position at Mouse Click - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.Timpos,'position',pos); - - x = x + w + 0.005; - y = y - 0.008; - w = info_pos(3)*0.5; - h = inputline_space*0.9; - - pos = [x y w h]; - set(handles.impos,'position',pos); - - % Origin Position - % - x = info_pos(1); - y = y + inputline_space*1.2; - w = info_pos(3)*0.5; - h = inputline_space*0.6; - - pos = [x y w h]; - set(handles.Torigin,'position',pos); - - x = x + w; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.origin,'position',pos); - -if 0 - % Axes Unit - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.5; - - pos = [x y w h]; - set(handles.Tcoord,'position',pos); - - x = x + w + 0.005; - w = info_pos(3)*0.5 - 0.005; - - pos = [x y w h]; - set(handles.coord,'position',pos); -end - - % Crosshair - % - x = info_pos(1); - y = y + inputline_space; - w = info_pos(3)*0.4; - - pos = [x y w h]; - set(handles.Txhair,'position',pos); - - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.2; - h = inputline_space*0.7; - - pos = [x y w h]; - set(handles.xhair_color,'position',pos); - - x = info_pos(1) + info_pos(3)*0.7; - w = info_pos(3)*0.3; - - pos = [x y w h]; - set(handles.xhair,'position',pos); - - % Histogram & Color - % - x = info_pos(1); - w = info_pos(3)*0.45; - h = inputline_space * 1.5; - pos = [x, y+inputline_space*0.9, w, h]; - set(handles.hist_frame,'position',pos); - set(handles.coord_frame,'position',pos); - - x = info_pos(1) + info_pos(3)*0.475; - w = info_pos(3)*0.525; - h = inputline_space * 1.5; - - pos = [x, y+inputline_space*0.9, w, h]; - set(handles.color_frame,'position',pos); - - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space*1.2; - w = info_pos(3)*0.2; - h = inputline_space*0.7; - - pos = [x y w h]; - set(handles.hist_eq,'position',pos); - - x = x + w; - w = info_pos(3)*0.2; - - pos = [x y w h]; - set(handles.hist_plot,'position',pos); - - x = info_pos(1) + info_pos(3)*0.025; - w = info_pos(3)*0.4; - - pos = [x y w h]; - set(handles.coord,'position',pos); - - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.2; - pos = [x y w h]; - set(handles.neg_color,'position',pos); - - x = info_pos(1) + info_pos(3)*0.7; - w = info_pos(3)*0.275; - - pos = [x y w h]; - set(handles.colorindex,'position',pos); - - x = info_pos(1) + info_pos(3)*0.1; - y = y + inputline_space; - w = info_pos(3)*0.28; - h = inputline_space*0.6; - - pos = [x y w h]; - set(handles.Thist,'position',pos); - set(handles.Tcoord,'position',pos); - - x = info_pos(1) + info_pos(3)*0.60; - w = info_pos(3)*0.28; - - pos = [x y w h]; - set(handles.Tcolor,'position',pos); - - % Contrast Frame - % - x = info_pos(1); - w = info_pos(3)*0.45; - h = inputline_space * 2; - - pos = [x, y+inputline_space*0.8, w, h]; - set(handles.contrast_frame,'position',pos); - - % Brightness Frame - % - x = info_pos(1) + info_pos(3)*0.475; - w = info_pos(3)*0.525; - - pos = [x, y+inputline_space*0.8, w, h]; - set(handles.brightness_frame,'position',pos); - - % Contrast - % - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space; - w = info_pos(3)*0.4; - h = inputline_space*0.6; - - pos = [x y w h]; - set(handles.contrast,'position',pos); - - % Brightness - % - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.475; - - pos = [x y w h]; - set(handles.brightness,'position',pos); - - % Contrast text/def - % - x = info_pos(1) + info_pos(3)*0.025; - y = y + inputline_space; - w = info_pos(3)*0.22; - - pos = [x y w h]; - set(handles.Tcontrast,'position',pos); - - x = x + w; - w = info_pos(3)*0.18; - - pos = [x y w h]; - set(handles.contrast_def,'position',pos); - - % Brightness text/def - % - x = info_pos(1) + info_pos(3)*0.5; - w = info_pos(3)*0.295; - - pos = [x y w h]; - set(handles.Tbrightness,'position',pos); - - x = x + w; - w = info_pos(3)*0.18; - - pos = [x y w h]; - set(handles.brightness_def,'position',pos); - - return; % update_usestretch - - -%---------------------------------------------------------------- -function update_useinterp(fig, useinterp) - - if isempty(useinterp) - return; - end - - nii_menu = getappdata(fig, 'nii_menu'); - - if ~isempty(nii_menu) - if get(nii_menu.Minterp,'user') - set(nii_menu.Minterp,'Userdata',0,'Label','Interp off'); - else - set(nii_menu.Minterp,'Userdata',1,'Label','Interp on'); - end - end - - nii_view = getappdata(fig, 'nii_view'); - nii_view.useinterp = useinterp; - - if ~isempty(nii_view.handles.axial_image) - if strcmpi(get(nii_view.handles.axial_image,'cdatamapping'), 'direct') - useimagesc = 0; - else - useimagesc = 1; - end - elseif ~isempty(nii_view.handles.coronal_image) - if strcmpi(get(nii_view.handles.coronal_image,'cdatamapping'), 'direct') - useimagesc = 0; - else - useimagesc = 1; - end - else - if strcmpi(get(nii_view.handles.sagittal_image,'cdatamapping'), 'direct') - useimagesc = 0; - else - useimagesc = 1; - end - end - - if ~isempty(nii_view.handles.axial_image) - img_slice = get(nii_view.handles.axial_image, 'cdata'); - delete(nii_view.handles.axial_image); - axes(nii_view.handles.axial_axes); - clim = get(gca,'clim'); - - if useinterp - if useimagesc - nii_view.handles.axial_image = surface(zeros(size(img_slice)),double(img_slice),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.axial_image = surface(zeros(size(img_slice)),double(img_slice),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - else - if useimagesc - nii_view.handles.axial_image = imagesc('cdata',img_slice); - else - nii_view.handles.axial_image = image('cdata',img_slice); - end - end - - set(gca,'clim',clim); - - order = get(gca,'child'); - order(find(order == nii_view.handles.axial_image)) = []; - order = [order; nii_view.handles.axial_image]; - - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) - order(find(order == nii_view.handles.axial_bg)) = []; - order = [order; nii_view.handles.axial_bg]; - end - - set(gca, 'child', order); - - if ~useinterp - if isfield(nii_view.handles,'axial_bg') & ~isempty(nii_view.handles.axial_bg) - delete(nii_view.handles.axial_bg); - nii_view.handles.axial_bg = []; - end - end - - set(nii_view.handles.axial_image,'buttondown','view_nii(''axial_image'');'); - end - - if ~isempty(nii_view.handles.coronal_image) - img_slice = get(nii_view.handles.coronal_image, 'cdata'); - delete(nii_view.handles.coronal_image); - axes(nii_view.handles.coronal_axes); - clim = get(gca,'clim'); - - if useinterp - if useimagesc - nii_view.handles.coronal_image = surface(zeros(size(img_slice)),double(img_slice),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.coronal_image = surface(zeros(size(img_slice)),double(img_slice),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - else - if useimagesc - nii_view.handles.coronal_image = imagesc('cdata',img_slice); - else - nii_view.handles.coronal_image = image('cdata',img_slice); - end - end - - set(gca,'clim',clim); - - order = get(gca,'child'); - order(find(order == nii_view.handles.coronal_image)) = []; - order = [order; nii_view.handles.coronal_image]; - - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) - order(find(order == nii_view.handles.coronal_bg)) = []; - order = [order; nii_view.handles.coronal_bg]; - end - - set(gca, 'child', order); - - if ~useinterp - if isfield(nii_view.handles,'coronal_bg') & ~isempty(nii_view.handles.coronal_bg) - delete(nii_view.handles.coronal_bg); - nii_view.handles.coronal_bg = []; - end - end - - set(nii_view.handles.coronal_image,'buttondown','view_nii(''coronal_image'');'); - end - - if ~isempty(nii_view.handles.sagittal_image) - img_slice = get(nii_view.handles.sagittal_image, 'cdata'); - delete(nii_view.handles.sagittal_image); - axes(nii_view.handles.sagittal_axes); - clim = get(gca,'clim'); - - if useinterp - if useimagesc - nii_view.handles.sagittal_image = surface(zeros(size(img_slice)),double(img_slice),'edgecolor','none','facecolor','interp'); - else - nii_view.handles.sagittal_image = surface(zeros(size(img_slice)),double(img_slice),'cdatamapping','direct','edgecolor','none','facecolor','interp'); - end - else - if useimagesc - nii_view.handles.sagittal_image = imagesc('cdata',img_slice); - else - nii_view.handles.sagittal_image = image('cdata',img_slice); - end - end - - set(gca,'clim',clim); - - order = get(gca,'child'); - order(find(order == nii_view.handles.sagittal_image)) = []; - order = [order; nii_view.handles.sagittal_image]; - - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) - order(find(order == nii_view.handles.sagittal_bg)) = []; - order = [order; nii_view.handles.sagittal_bg]; - end - - set(gca, 'child', order); - - if ~useinterp - if isfield(nii_view.handles,'sagittal_bg') & ~isempty(nii_view.handles.sagittal_bg) - delete(nii_view.handles.sagittal_bg); - nii_view.handles.sagittal_bg = []; - end - end - - set(nii_view.handles.sagittal_image,'buttondown','view_nii(''sagittal_image'');'); - end - - if ~useinterp - nii_view.bgimg = []; - end - - set_coordinates(nii_view,useinterp); - setappdata(fig, 'nii_view', nii_view); - - return; % update_useinterp - - -%---------------------------------------------------------------- -function update_useimagesc(fig, useimagesc) - - if isempty(useimagesc) - return; - end - - if useimagesc - v='scaled'; - else - v='direct'; - end - - nii_view = getappdata(fig,'nii_view'); - handles = nii_view.handles; - - if isfield(handles,'cbar_image') & ishandle(handles.cbar_image) -% set(handles.cbar_image,'cdatamapping',v); - end - - set(handles.axial_image,'cdatamapping',v); - set(handles.coronal_image,'cdatamapping',v); - set(handles.sagittal_image,'cdatamapping',v); - - return; % update_useimagesc - - -%---------------------------------------------------------------- -function update_shape(fig, area, usecolorbar, usestretch, useimagesc) - - nii_view = getappdata(fig,'nii_view'); - - if isempty(usestretch) % no change, get usestretch - stretchchange = 0; - usestretch = nii_view.usestretch; - else % change, set usestretch - stretchchange = 1; - nii_view.usestretch = usestretch; - end - - if isempty(area) % no change, get area - - areachange = 0; - area = nii_view.area; - - elseif ~isempty(nii_view.cbar_area) % change, set area & cbar_area - - areachange = 1; - cbar_area = area; - cbar_area(1) = area(1) + area(3)*0.93; - cbar_area(3) = area(3)*0.04; - area(3) = area(3)*0.9; % 90% used for main axes - - [cbar_axes cbarminmax_axes] = create_cbar_axes(fig, cbar_area); - - nii_view.area = area; - nii_view.cbar_area = cbar_area; - - else % change, set area only - areachange = 1; - nii_view.area = area; - end - - % Add colorbar - % - if ~isempty(usecolorbar) & usecolorbar & isempty(nii_view.cbar_area) - - colorbarchange = 1; - - cbar_area = area; - cbar_area(1) = area(1) + area(3)*0.93; - cbar_area(3) = area(3)*0.04; - area(3) = area(3)*0.9; % 90% used for main axes - - % create axes for colorbar - % - [cbar_axes cbarminmax_axes] = create_cbar_axes(fig, cbar_area); - - nii_view.area = area; - nii_view.cbar_area = cbar_area; - - % useimagesc follows axial image - % - if isempty(useimagesc) - if strcmpi(get(nii_view.handles.axial_image,'cdatamap'),'scaled') - useimagesc = 1; - else - useimagesc = 0; - end - end - - if isfield(nii_view, 'highcolor') & ~isempty(highcolor) - num_highcolor = size(nii_view.highcolor,1); - else - num_highcolor = 0; - end - - if isfield(nii_view, 'colorlevel') & ~isempty(nii_view.colorlevel) - colorlevel = nii_view.colorlevel; - else - colorlevel = 256 - num_highcolor; - end - - if isfield(nii_view, 'color_map') - color_map = nii_view.color_map; - else - color_map = []; - end - - if isfield(nii_view, 'highcolor') - highcolor = nii_view.highcolor; - else - highcolor = []; - end - - % plot colorbar - % -if 0 - if isempty(color_map) - level = colorlevel + num_highcolor; - else - level = size([color_map; highcolor], 1); - end -end - - if isempty(color_map) - level = colorlevel; - else - level = size([color_map], 1); - end - - cbar_image = [1:level]'; - - niiclass = class(nii_view.nii.img); - - h1 = plot_cbar(fig, cbar_axes, cbarminmax_axes, nii_view.cbarminmax, ... - level, nii_view.handles, useimagesc, nii_view.colorindex, ... - color_map, colorlevel, highcolor, niiclass, nii_view.numscan); - nii_view.handles.cbar_image = h1; - nii_view.handles.cbar_axes = cbar_axes; - nii_view.handles.cbarminmax_axes = cbar_axes; - - % remove colorbar - % - elseif ~isempty(usecolorbar) & ~usecolorbar & ~isempty(nii_view.cbar_area) - - colorbarchange = 1; - - area(3) = area(3) / 0.9; - - nii_view.area = area; - nii_view.cbar_area = []; - - nii_view.handles = rmfield(nii_view.handles,'cbar_image'); - delete(nii_view.handles.cbarminmax_axes); - nii_view.handles = rmfield(nii_view.handles,'cbarminmax_axes'); - delete(nii_view.handles.cbar_axes); - nii_view.handles = rmfield(nii_view.handles,'cbar_axes'); - - else - colorbarchange = 0; - end - - if colorbarchange | stretchchange | areachange - setappdata(fig,'nii_view',nii_view); - update_usestretch(fig, usestretch); - end - - return; % update_shape - - -%---------------------------------------------------------------- -function update_unit(fig, setunit) - - if isempty(setunit) - return; - end - - if strcmpi(setunit,'mm') | strcmpi(setunit,'millimeter') | strcmpi(setunit,'mni') - v = 2; -% elseif strcmpi(setunit,'tal') | strcmpi(setunit,'talairach') - % v = 3; - elseif strcmpi(setunit,'vox') | strcmpi(setunit,'voxel') - v = 1; - else - v = 1; - end - - nii_view = getappdata(fig,'nii_view'); - set(nii_view.handles.coord, 'value', v); - set_image_value(nii_view); - - return; % update_unit - - -%---------------------------------------------------------------- -function update_viewpoint(fig, setviewpoint) - - if isempty(setviewpoint) - return; - end - - nii_view = getappdata(fig,'nii_view'); - - if length(setviewpoint) ~= 3 - error('Viewpoint position should contain [x y z]'); - end - - set(nii_view.handles.impos,'string',num2str(setviewpoint)); - - opt.command = 'impos_edit'; - view_nii(fig, opt); - - set(nii_view.handles.axial_axes,'selected','on'); - set(nii_view.handles.axial_axes,'selected','off'); - set(nii_view.handles.coronal_axes,'selected','on'); - set(nii_view.handles.coronal_axes,'selected','off'); - set(nii_view.handles.sagittal_axes,'selected','on'); - set(nii_view.handles.sagittal_axes,'selected','off'); - - return; % update_viewpoint - - -%---------------------------------------------------------------- -function update_scanid(fig, setscanid) - - if isempty(setscanid) - return; - end - - nii_view = getappdata(fig,'nii_view'); - - if setscanid < 1 - setscanid = 1; - end - - if setscanid > nii_view.numscan - setscanid = nii_view.numscan; - end - - set(nii_view.handles.contrast_def,'string',num2str(setscanid)); - set(nii_view.handles.contrast,'value',setscanid); - - opt.command = 'updateimg'; - opt.setscanid = setscanid; - - view_nii(fig, nii_view.nii.img, opt); - - return; % update_scanid - - -%---------------------------------------------------------------- -function update_crosshaircolor(fig, new_color) - - if isempty(new_color) - return; - end - - nii_view = getappdata(fig,'nii_view'); - xhair_color = nii_view.handles.xhair_color; - - set(xhair_color,'user',new_color); - set(nii_view.axi_xhair.lx,'color',new_color); - set(nii_view.axi_xhair.ly,'color',new_color); - set(nii_view.cor_xhair.lx,'color',new_color); - set(nii_view.cor_xhair.ly,'color',new_color); - set(nii_view.sag_xhair.lx,'color',new_color); - set(nii_view.sag_xhair.ly,'color',new_color); - - return; % update_crosshaircolor - - -%---------------------------------------------------------------- -function update_colorindex(fig, colorindex) - - if isempty(colorindex) - return; - end - - nii_view = getappdata(fig,'nii_view'); - nii_view.colorindex = colorindex; - setappdata(fig, 'nii_view', nii_view); - set(nii_view.handles.colorindex,'value',colorindex); - - opt.command = 'color'; - view_nii(fig, opt); - - return; % update_colorindex - - -%---------------------------------------------------------------- -function redraw_cbar(fig, colorlevel, color_map, highcolor) - - nii_view = getappdata(fig,'nii_view'); - - if isempty(nii_view.cbar_area) - return; - end - - colorindex = nii_view.colorindex; - - if isempty(highcolor) - num_highcolor = 0; - else - num_highcolor = size(highcolor,1); - end - - if isempty(colorlevel) - colorlevel=256; - end - - if colorindex == 1 - colorlevel = size(color_map, 1); - end - -% level = colorlevel + num_highcolor; - level = colorlevel; - - cbar_image = [1:level]'; - - cbar_area = nii_view.cbar_area; - - % useimagesc follows axial image - % - if strcmpi(get(nii_view.handles.axial_image,'cdatamap'),'scaled') - useimagesc = 1; - else - useimagesc = 0; - end - - niiclass = class(nii_view.nii.img); - - delete(nii_view.handles.cbar_image); - delete(nii_view.handles.cbar_axes); - delete(nii_view.handles.cbarminmax_axes); - - [nii_view.handles.cbar_axes nii_view.handles.cbarminmax_axes] = ... - create_cbar_axes(fig, cbar_area, []); - - nii_view.handles.cbar_image = plot_cbar(fig, ... - nii_view.handles.cbar_axes, nii_view.handles.cbarminmax_axes, ... - nii_view.cbarminmax, level, nii_view.handles, useimagesc, ... - colorindex, color_map, colorlevel, highcolor, niiclass, ... - nii_view.numscan, []); - - setappdata(fig, 'nii_view', nii_view); - - return; % redraw_cbar - - -%---------------------------------------------------------------- -function update_buttondown(fig, setbuttondown) - - if isempty(setbuttondown) - return; - end - - nii_view = getappdata(fig,'nii_view'); - nii_view.buttondown = setbuttondown; - setappdata(fig, 'nii_view', nii_view); - - return; % update_buttondown - - -%---------------------------------------------------------------- -function update_cbarminmax(fig, cbarminmax) - - if isempty(cbarminmax) - return; - end - - nii_view = getappdata(fig, 'nii_view'); - - if ~isfield(nii_view.handles, 'cbarminmax_axes') - return; - end - - nii_view.cbarminmax = cbarminmax; - setappdata(fig, 'nii_view', nii_view); - - axes(nii_view.handles.cbarminmax_axes); - - plot([0 0], cbarminmax, 'w'); - axis tight; - - set(nii_view.handles.cbarminmax_axes,'YDir','normal', ... - 'XLimMode','manual','YLimMode','manual','YColor',[0 0 0], ... - 'XColor',[0 0 0],'xtick',[],'YAxisLocation','right'); - - ylim = get(nii_view.handles.cbar_axes,'ylim'); - ylimb = get(nii_view.handles.cbarminmax_axes,'ylim'); - ytickb = get(nii_view.handles.cbarminmax_axes,'ytick'); - ytick=(ylim(2)-ylim(1))*(ytickb-ylimb(1))/(ylimb(2)-ylimb(1))+ylim(1); - - axes(nii_view.handles.cbar_axes); - - set(nii_view.handles.cbar_axes,'YDir','normal','XLimMode','manual', ... - 'YLimMode','manual','YColor',[0 0 0],'XColor',[0 0 0],'xtick',[], ... - 'YAxisLocation','right','ylim',ylim,'ytick',ytick,'yticklabel',''); - - return; % update_cbarminmax - - -%---------------------------------------------------------------- -function update_highcolor(fig, highcolor, colorlevel) - - nii_view = getappdata(fig,'nii_view'); - - if ischar(highcolor) & (isempty(colorlevel) | nii_view.colorindex == 1) - return; - end - - if ~ischar(highcolor) - nii_view.highcolor = highcolor; - - if isempty(highcolor) - nii_view = rmfield(nii_view, 'highcolor'); - end - else - highcolor = []; - end - - if isempty(colorlevel) | nii_view.colorindex == 1 - nii_view.colorlevel = nii_view.colorlevel - size(highcolor,1); - else - nii_view.colorlevel = colorlevel; - end - - setappdata(fig, 'nii_view', nii_view); - - if isfield(nii_view,'color_map') - color_map = nii_view.color_map; - else - color_map = []; - end - - redraw_cbar(fig, nii_view.colorlevel, color_map, highcolor); - change_colormap(fig); - - return; % update_highcolor - - -%---------------------------------------------------------------- -function update_colormap(fig, color_map) - - if ischar(color_map) - return; - end - - nii_view = getappdata(fig,'nii_view'); - nii = nii_view.nii; - minvalue = nii_view.minvalue; - - if isempty(color_map) - if minvalue < 0 - colorindex = 2; - else - colorindex = 3; - end - - nii_view = rmfield(nii_view, 'color_map'); - setappdata(fig,'nii_view',nii_view); - update_colorindex(fig, colorindex); - return; - else - colorindex = 1; - nii_view.color_map = color_map; - nii_view.colorindex = colorindex; - setappdata(fig,'nii_view',nii_view); - set(nii_view.handles.colorindex,'value',colorindex); - end - - colorlevel = nii_view.colorlevel; - - if isfield(nii_view, 'highcolor') - highcolor = nii_view.highcolor; - else - highcolor = []; - end - - redraw_cbar(fig, colorlevel, color_map, highcolor); - change_colormap(fig); - - opt.enablecontrast = 0; - update_enable(fig, opt); - - return; % update_colormap - - -%---------------------------------------------------------------- -function status = get_status(h); - - nii_view = getappdata(h,'nii_view'); - - status.fig = h; - status.area = nii_view.area; - - if isempty(nii_view.cbar_area) - status.usecolorbar = 0; - else - status.usecolorbar = 1; - width = status.area(3) / 0.9; - status.area(3) = width; - end - - if strcmpi(get(nii_view.handles.imval,'visible'), 'on') - status.usepanel = 1; - else - status.usepanel = 0; - end - - if get(nii_view.handles.xhair,'value') == 1 - status.usecrosshair = 1; - else - status.usecrosshair = 0; - end - - status.usestretch = nii_view.usestretch; - - if strcmpi(get(nii_view.handles.axial_image,'cdatamapping'), 'direct') - status.useimagesc = 0; - else - status.useimagesc = 1; - end - - status.useinterp = nii_view.useinterp; - - if get(nii_view.handles.coord,'value') == 1 - status.unit = 'vox'; - elseif get(nii_view.handles.coord,'value') == 2 - status.unit = 'mm'; - elseif get(nii_view.handles.coord,'value') == 3 - status.unit = 'tal'; - end - - status.viewpoint = get(nii_view.handles.impos,'value'); - status.scanid = nii_view.scanid; - status.intensity = get(nii_view.handles.imval,'value'); - status.colorindex = get(nii_view.handles.colorindex,'value'); - - if isfield(nii_view,'color_map') - status.colormap = nii_view.color_map; - else - status.colormap = []; - end - - status.colorlevel = nii_view.colorlevel; - - if isfield(nii_view,'highcolor') - status.highcolor = nii_view.highcolor; - else - status.highcolor = []; - end - - status.cbarminmax = nii_view.cbarminmax; - status.buttondown = nii_view.buttondown; - - return; % get_status - - -%---------------------------------------------------------------- -function [custom_color_map, colorindex] ... - = change_colormap(fig, nii, colorindex, cbarminmax) - - custom_color_map = []; - - if ~exist('nii', 'var') - nii_view = getappdata(fig,'nii_view'); - else - nii_view = nii; - end - - if ~exist('colorindex', 'var') - colorindex = get(nii_view.handles.colorindex,'value'); - end - - if ~exist('cbarminmax', 'var') - cbarminmax = nii_view.cbarminmax; - end - - if isfield(nii_view, 'highcolor') & ~isempty(nii_view.highcolor) - highcolor = nii_view.highcolor; - num_highcolor = size(highcolor,1); - else - highcolor = []; - num_highcolor = 0; - end - -% if isfield(nii_view, 'colorlevel') & ~isempty(nii_view.colorlevel) - if nii_view.colorlevel < 256 - num_color = nii_view.colorlevel; - else - num_color = 256 - num_highcolor; - end - - contrast = []; - - if colorindex == 3 % for gray - if nii_view.numscan > 1 - contrast = 1; - else - contrast = (num_color-1)*(get(nii_view.handles.contrast,'value')-1)/255+1; - contrast = floor(contrast); - end - elseif colorindex == 2 % for bipolar - if nii_view.numscan > 1 - contrast = 128; - else - contrast = get(nii_view.handles.contrast,'value'); - end - end - - if isfield(nii_view,'color_map') & ~isempty(nii_view.color_map) - color_map = nii_view.color_map; - custom_color_map = color_map; - elseif colorindex == 1 - [f p] = uigetfile('*.txt', 'Input colormap text file'); - - if p==0 - colorindex = nii_view.colorindex; - set(nii_view.handles.colorindex,'value',colorindex); - return; - end; - - try - custom_color_map = load(fullfile(p,f)); - loadfail = 0; - catch - loadfail = 1; - end - - if loadfail | isempty(custom_color_map) | size(custom_color_map,2)~=3 ... - | min(custom_color_map(:)) < 0 | max(custom_color_map(:)) > 1 - - msg = 'Colormap should be a Mx3 matrix with value between 0 and 1'; - msgbox(msg,'Error in colormap file'); - colorindex = nii_view.colorindex; - set(nii_view.handles.colorindex,'value',colorindex); - return; - end - - color_map = custom_color_map; - nii_view.color_map = color_map; - end - - switch colorindex - case {2} - color_map = bipolar(num_color, cbarminmax(1), cbarminmax(2), contrast); - case {3} - color_map = gray(num_color - contrast + 1); - case {4} - color_map = jet(num_color); - case {5} - color_map = cool(num_color); - case {6} - color_map = bone(num_color); - case {7} - color_map = hot(num_color); - case {8} - color_map = copper(num_color); - case {9} - color_map = pink(num_color); - end - - nii_view.colorindex = colorindex; - - if ~exist('nii', 'var') - setappdata(fig,'nii_view',nii_view); - end - - if colorindex == 3 - color_map = [zeros(contrast,3); color_map(2:end,:)]; - end - - if get(nii_view.handles.neg_color,'value') & isempty(highcolor) - color_map = flipud(color_map); - elseif get(nii_view.handles.neg_color,'value') & ~isempty(highcolor) - highcolor = flipud(highcolor); - end - - brightness = get(nii_view.handles.brightness,'value'); - color_map = brighten(color_map, brightness); - - color_map = [color_map; highcolor]; - - set(fig, 'colormap', color_map); - - return; % change_colormap - - -%---------------------------------------------------------------- -function move_cursor(fig) - - nii_view = getappdata(fig, 'nii_view'); - - if isempty(nii_view) - return; - end - - axi = get(nii_view.handles.axial_axes, 'pos'); - cor = get(nii_view.handles.coronal_axes, 'pos'); - sag = get(nii_view.handles.sagittal_axes, 'pos'); - curr = get(fig, 'currentpoint'); - - if curr(1) >= axi(1) & curr(1) <= axi(1)+axi(3) & ... - curr(2) >= axi(2) & curr(2) <= axi(2)+axi(4) - - curr = get(nii_view.handles.axial_axes, 'current'); - sag = curr(1,1); - cor = curr(1,2); - axi = nii_view.slices.axi; - - elseif curr(1) >= cor(1) & curr(1) <= cor(1)+cor(3) & ... - curr(2) >= cor(2) & curr(2) <= cor(2)+cor(4) - - curr = get(nii_view.handles.coronal_axes, 'current'); - sag = curr(1,1); - cor = nii_view.slices.cor; - axi = curr(1,2); - - elseif curr(1) >= sag(1) & curr(1) <= sag(1)+sag(3) & ... - curr(2) >= sag(2) & curr(2) <= sag(2)+sag(4) - - curr = get(nii_view.handles.sagittal_axes, 'current'); - - sag = nii_view.slices.sag; - cor = curr(1,1); - axi = curr(1,2); - - else - - set(nii_view.handles.imvalcur,'String',' '); - set(nii_view.handles.imposcur,'String',' '); - return; - - end - - sag = round(sag); - cor = round(cor); - axi = round(axi); - - if sag < 1 - sag = 1; - elseif sag > nii_view.dims(1) - sag = nii_view.dims(1); - end - - if cor < 1 - cor = 1; - elseif cor > nii_view.dims(2) - cor = nii_view.dims(2); - end - - if axi < 1 - axi = 1; - elseif axi > nii_view.dims(3) - axi = nii_view.dims(3); - end - - if 0 % isfield(nii_view, 'disp') - img = nii_view.disp; - else - img = nii_view.nii.img; - end - - if nii_view.nii.hdr.dime.datatype == 128 - imgvalue = [double(img(sag,cor,axi,1,nii_view.scanid)) double(img(sag,cor,axi,2,nii_view.scanid)) double(img(sag,cor,axi,3,nii_view.scanid))]; - set(nii_view.handles.imvalcur,'String',sprintf('%7.4g %7.4g %7.4g',imgvalue)); - elseif nii_view.nii.hdr.dime.datatype == 511 - R = double(img(sag,cor,axi,1,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - G = double(img(sag,cor,axi,2,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - B = double(img(sag,cor,axi,3,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - imgvalue = [R G B]; - set(nii_view.handles.imvalcur,'String',sprintf('%7.4g %7.4g %7.4g',imgvalue)); - else - imgvalue = double(img(sag,cor,axi,nii_view.scanid)); - - if isnan(imgvalue) | imgvalue > nii_view.cbarminmax(2) - imgvalue = 0; - end - - set(nii_view.handles.imvalcur,'String',sprintf('%.6g',imgvalue)); - end - - nii_view.slices.sag = sag; - nii_view.slices.cor = cor; - nii_view.slices.axi = axi; - - nii_view = update_imgXYZ(nii_view); - - if get(nii_view.handles.coord,'value') == 1, - sag = nii_view.imgXYZ.vox(1); - cor = nii_view.imgXYZ.vox(2); - axi = nii_view.imgXYZ.vox(3); - elseif get(nii_view.handles.coord,'value') == 2, - sag = nii_view.imgXYZ.mm(1); - cor = nii_view.imgXYZ.mm(2); - axi = nii_view.imgXYZ.mm(3); - elseif get(nii_view.handles.coord,'value') == 3, - sag = nii_view.imgXYZ.tal(1); - cor = nii_view.imgXYZ.tal(2); - axi = nii_view.imgXYZ.tal(3); - end - - if get(nii_view.handles.coord,'value') == 1, - string = sprintf('%7.0f %7.0f %7.0f',sag,cor,axi); - else - string = sprintf('%7.1f %7.1f %7.1f',sag,cor,axi); - end; - - set(nii_view.handles.imposcur,'String',string); - - return; % move_cursor - - -%---------------------------------------------------------------- -function change_scan(hdl_str) - - fig = gcbf; - nii_view = getappdata(fig,'nii_view'); - - if strcmpi(hdl_str, 'edit_change_scan') % edit - hdl = nii_view.handles.contrast_def; - setscanid = round(str2num(get(hdl, 'string'))); - else % slider - hdl = nii_view.handles.contrast; - setscanid = round(get(hdl, 'value')); - end - - update_scanid(fig, setscanid); - - return; % change_scan - - -%---------------------------------------------------------------- -function val = scale_in(val, minval, maxval, range) - - % scale value into range - % - val = range*(double(val)-double(minval))/(double(maxval)-double(minval))+1; - - return; % scale_in - - -%---------------------------------------------------------------- -function val = scale_out(val, minval, maxval, range) - - % according to [minval maxval] and range of color levels (e.g. 199) - % scale val back from any thing between 1~256 to a small number that - % is corresonding to [minval maxval]. - % - val = (double(val)-1)*(double(maxval)-double(minval))/range+double(minval); - - return; % scale_out - diff --git a/func/utils/nii/view_nii_menu.m b/func/utils/nii/view_nii_menu.m deleted file mode 100644 index d113053..0000000 --- a/func/utils/nii/view_nii_menu.m +++ /dev/null @@ -1,480 +0,0 @@ -% Imbed Zoom, Interp, and Info menu to view_nii window. -% -% Usage: view_nii_menu(fig); -% - -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -%-------------------------------------------------------------------- -function menu_hdl = view_nii_menu(fig, varargin) - - if isnumeric(fig) - menu_hdl = init(fig); - return; - end - - menu_hdl = []; - - switch fig - case 'interp' - if nargin > 1 - fig = varargin{1}; - else - fig = gcbf; - end - - nii_menu = getappdata(fig, 'nii_menu'); - interp_on_state = get(nii_menu.Minterp,'Userdata'); - - if (interp_on_state == 1) - opt.useinterp = 1; - view_nii(fig,opt); - set(nii_menu.Minterp,'Userdata',0,'Label','Interp off'); - reset_zoom(fig); - else - opt.useinterp = 0; - view_nii(fig,opt); - set(nii_menu.Minterp,'Userdata',1,'Label','Interp on'); - reset_zoom(fig); - end - case 'reset_zoom' - if nargin > 1 - fig = varargin{1}; - else - fig = gcbf; - end - - reset_zoom(fig); - case 'orient' - orient; - case 'editvox' - editvox; - case 'img_info' - img_info; - case 'img_hist' - img_hist; - case 'save_disp' - save_disp; - end - - return % view_nii_menu - - -%-------------------------------------------------------------------- -function menu_hdl = init(fig) - - % search for edit, view menu - % - nii_menu.Mfile = []; - nii_menu.Medit = []; - nii_menu.Mview = []; - menuitems = findobj(fig, 'type', 'uimenu'); - - for i=1:length(menuitems) - filelabel = get(menuitems(i),'label'); - - if strcmpi(strrep(filelabel, '&', ''), 'file') - nii_menu.Mfile = menuitems(i); - end - - editlabel = get(menuitems(i),'label'); - - if strcmpi(strrep(editlabel, '&', ''), 'edit') - nii_menu.Medit = menuitems(i); - end - - viewlabel = get(menuitems(i),'label'); - - if strcmpi(strrep(viewlabel, '&', ''), 'view') - nii_menu.Mview = menuitems(i); - end - end - - set(fig, 'menubar', 'none'); - - if isempty(nii_menu.Mfile) - nii_menu.Mfile = uimenu('Parent',fig, ... - 'Label','File'); - - nii_menu.Mfile_save = uimenu('Parent',nii_menu.Mfile, ... - 'Label','Save displayed image as ...', ... - 'Callback','view_nii_menu(''save_disp'');'); - else - nii_menu.Mfile_save = uimenu('Parent',nii_menu.Mfile, ... - 'Label','Save displayed image as ...', ... - 'separator','on', ... - 'Callback','view_nii_menu(''save_disp'');'); - end - - if isempty(nii_menu.Medit) - nii_menu.Medit = uimenu('Parent',fig, ... - 'Label','Edit'); - - nii_menu.Medit_orient = uimenu('Parent',nii_menu.Medit, ... - 'Label','Convert to RAS orientation', ... - 'Callback','view_nii_menu(''orient'');'); - - nii_menu.Medit_editvox = uimenu('Parent',nii_menu.Medit, ... - 'Label','Edit voxel value at crosshair', ... - 'Callback','view_nii_menu(''editvox'');'); - else - nii_menu.Medit_orient = uimenu('Parent',nii_menu.Medit, ... - 'Label','Convert to RAS orientation', ... - 'separator','on', ... - 'Callback','view_nii_menu(''orient'');'); - - nii_menu.Medit_editvox = uimenu('Parent',nii_menu.Medit, ... - 'Label','Edit voxel value at crosshair', ... - 'Callback','view_nii_menu(''editvox'');'); - end - - if isempty(nii_menu.Mview) - nii_menu.Mview = uimenu('Parent',fig, ... - 'Label','View'); - - nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ... - 'Label','Image Information', ... - 'Callback','view_nii_menu(''img_info'');'); - - nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ... - 'Label','Volume Histogram', ... - 'Callback','view_nii_menu(''img_hist'');'); - else - nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ... - 'Label','Image Information', ... - 'separator','on', ... - 'Callback','view_nii_menu(''img_info'');'); - - nii_menu.Mview_info = uimenu('Parent',nii_menu.Mview, ... - 'Label','Volume Histogram', ... - 'Callback','view_nii_menu(''img_hist'');'); - end - - nii_menu.Mzoom = rri_zoom_menu(fig); - - nii_menu.Minterp = uimenu('Parent',fig, ... - 'Label','Interp on', ... - 'Userdata', 1, ... - 'Callback','view_nii_menu(''interp'');'); - - setappdata(fig,'nii_menu',nii_menu); - menu_hdl = nii_menu.Minterp; - - return % init - - -%---------------------------------------------------------------- -function reset_zoom(fig) - - old_handle_vis = get(fig, 'HandleVisibility'); - set(fig, 'HandleVisibility', 'on'); - - nii_view = getappdata(fig, 'nii_view'); - nii_menu = getappdata(fig, 'nii_menu'); - - set(nii_menu.Mzoom,'Userdata',1,'Label','Zoom on'); - set(fig,'pointer','arrow'); - zoom off; - - axes(nii_view.handles.axial_axes); - setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ... - [get(gca, 'xlim') get(gca, 'ylim')]) -% zoom reset; - % zoom getlimits; - zoom out; - - axes(nii_view.handles.coronal_axes); - setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ... - [get(gca, 'xlim') get(gca, 'ylim')]) -% zoom reset; - % zoom getlimits; - zoom out; - - axes(nii_view.handles.sagittal_axes); - setappdata(get(gca,'zlabel'), 'ZOOMAxesData', ... - [get(gca, 'xlim') get(gca, 'ylim')]) -% zoom reset; - % zoom getlimits; - zoom out; - - set(fig, 'HandleVisibility', old_handle_vis); - - return; % reset_zoom - - -%---------------------------------------------------------------- -function img_info - - nii_view = getappdata(gcbf, 'nii_view'); - hdr = nii_view.nii.hdr; - - max_value = num2str(double(max(nii_view.nii.img(:)))); - min_value = num2str(double(min(nii_view.nii.img(:)))); - - dim = sprintf('%d %d %d', double(hdr.dime.dim(2:4))); - vox = sprintf('%.3f %.3f %.3f', double(hdr.dime.pixdim(2:4))); - - if double(hdr.dime.datatype) == 1 - type = '1-bit binary'; - elseif double(hdr.dime.datatype) == 2 - type = '8-bit unsigned integer'; - elseif double(hdr.dime.datatype) == 4 - type = '16-bit signed integer'; - elseif double(hdr.dime.datatype) == 8 - type = '32-bit signed integer'; - elseif double(hdr.dime.datatype) == 16 - type = '32-bit single float'; - elseif double(hdr.dime.datatype) == 64 - type = '64-bit double precision'; - elseif double(hdr.dime.datatype) == 128 - type = '24-bit RGB true color'; - elseif double(hdr.dime.datatype) == 256 - type = '8-bit signed integer'; - elseif double(hdr.dime.datatype) == 511 - type = '96-bit RGB true color'; - elseif double(hdr.dime.datatype) == 512 - type = '16-bit unsigned integer'; - elseif double(hdr.dime.datatype) == 768 - type = '32-bit unsigned integer'; - elseif double(hdr.dime.datatype) == 1024 - type = '64-bit signed integer'; - elseif double(hdr.dime.datatype) == 1280 - type = '64-bit unsigned integer'; - end - - msg = {}; - msg = [msg {''}]; - msg = [msg {['Dimension: [', dim, ']']}]; - msg = [msg {''}]; - msg = [msg {['Voxel Size: [', vox, ']']}]; - msg = [msg {''}]; - msg = [msg {['Data Type: [', type, ']']}]; - msg = [msg {''}]; - msg = [msg {['Max Value: [', max_value, ']']}]; - msg = [msg {''}]; - msg = [msg {['Min Value: [', min_value, ']']}]; - msg = [msg {''}]; - - if isfield(nii_view.nii, 'fileprefix') - if isfield(nii_view.nii, 'filetype') & nii_view.nii.filetype == 2 - msg = [msg {['File Name: [', nii_view.nii.fileprefix, '.nii]']}]; - msg = [msg {''}]; - elseif isfield(nii_view.nii, 'filetype') - msg = [msg {['File Name: [', nii_view.nii.fileprefix, '.img]']}]; - msg = [msg {''}]; - else - msg = [msg {['File Prefix: [', nii_view.nii.fileprefix, ']']}]; - msg = [msg {''}]; - end - end - - h = msgbox(msg, 'Image Information', 'modal'); - set(h,'color',[1 1 1]); - - return; % img_info - - -%---------------------------------------------------------------- -function orient - - fig = gcbf; - nii_view = getappdata(fig, 'nii_view'); - nii = nii_view.nii; - - if ~isempty(nii_view.bgimg) - msg = 'You can not modify an overlay image'; - h = msgbox(msg, 'Error', 'modal'); - return; - end - - old_pointer = get(fig,'Pointer'); - set(fig,'Pointer','watch'); - - [nii orient] = rri_orient(nii); - - if isequal(orient, [1 2 3]) % do nothing - set(fig,'Pointer',old_pointer); - return; - end - - oldopt = view_nii(fig); - opt.command = 'updatenii'; - opt.usecolorbar = oldopt.usecolorbar; - opt.usepanel = oldopt.usepanel; - opt.usecrosshair = oldopt.usecrosshair; - opt.usestretch = oldopt.usestretch; - opt.useimagesc = oldopt.useimagesc; - opt.useinterp = oldopt.useinterp; - opt.setarea = oldopt.area; - opt.setunit = oldopt.unit; - opt.setviewpoint = oldopt.viewpoint; - opt.setscanid = oldopt.scanid; - opt.setcbarminmax = oldopt.cbarminmax; - opt.setcolorindex = oldopt.colorindex; - opt.setcolormap = oldopt.colormap; - opt.setcolorlevel = oldopt.colorlevel; - - if isfield(oldopt,'highcolor') - opt.sethighcolor = oldopt.highcolor; - end - - view_nii(fig, nii, opt); - set(fig,'Pointer',old_pointer); - reset_zoom(fig); - - return; % orient - - -%---------------------------------------------------------------- -function editvox - - fig = gcbf; - nii_view = getappdata(fig, 'nii_view'); - - if ~isempty(nii_view.bgimg) - msg = 'You can not modify an overlay image'; - h = msgbox(msg, 'Error', 'modal'); - return; - end - - nii = nii_view.nii; - oldopt = view_nii(fig); - sag = nii_view.imgXYZ.vox(1); - cor = nii_view.imgXYZ.vox(2); - axi = nii_view.imgXYZ.vox(3); - - if nii_view.nii.hdr.dime.datatype == 128 - imgvalue = [double(nii.img(sag,cor,axi,1,nii_view.scanid)) double(nii.img(sag,cor,axi,2,nii_view.scanid)) double(nii.img(sag,cor,axi,3,nii_view.scanid))]; - init_val = sprintf('%7.4g %7.4g %7.4g',imgvalue); - elseif nii_view.nii.hdr.dime.datatype == 511 - R = double(nii.img(sag,cor,axi,1,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - G = double(nii.img(sag,cor,axi,2,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - B = double(nii.img(sag,cor,axi,3,nii_view.scanid)) * (nii_view.nii.hdr.dime.glmax - ... - nii_view.nii.hdr.dime.glmin) + nii_view.nii.hdr.dime.glmin; - imgvalue = [R G B]; - init_val = sprintf('%7.4g %7.4g %7.4g',imgvalue); - else - imgvalue = double(nii.img(sag,cor,axi,nii_view.scanid)); - init_val = sprintf('%.6g',imgvalue); - end - - old_pointer = get(fig,'Pointer'); - set(fig,'Pointer','watch'); - - repeat = 1; - while repeat - if nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511 - init_val = inputdlg({'Replace the current voxel values with 3 new numbers:'}, ... - 'Edit voxel value at crosshair', 1, {num2str(init_val)}); - else - init_val = inputdlg({'Replace the current voxel value with 1 new number:'}, ... - 'Edit voxel value at crosshair', 1, {num2str(init_val)}); - end - - if isempty(init_val) - set(fig,'Pointer',old_pointer); - return - end - - imgvalue = str2num(init_val{1}); - - if ( (nii_view.nii.hdr.dime.datatype == 128 | nii_view.nii.hdr.dime.datatype == 511) ... - & length(imgvalue) ~= 3 ) | ... - ( (nii_view.nii.hdr.dime.datatype ~= 128 & nii_view.nii.hdr.dime.datatype ~= 511) ... - & length(imgvalue) ~= 1 ) - % do nothing - else - repeat = 0; - end - end - - if nii_view.nii.hdr.dime.datatype == 128 - nii.img(sag,cor,axi,1,nii_view.scanid) = imgvalue(1); - nii.img(sag,cor,axi,2,nii_view.scanid) = imgvalue(2); - nii.img(sag,cor,axi,3,nii_view.scanid) = imgvalue(3); - elseif nii_view.nii.hdr.dime.datatype == 511 - nii.img(sag,cor,axi,1,nii_view.scanid) = (imgvalue(1) - nii_view.nii.hdr.dime.glmin) ... - / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin); - nii.img(sag,cor,axi,2,nii_view.scanid) = (imgvalue(2) - nii_view.nii.hdr.dime.glmin) ... - / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin); - nii.img(sag,cor,axi,3,nii_view.scanid) = (imgvalue(3) - nii_view.nii.hdr.dime.glmin) ... - / (nii_view.nii.hdr.dime.glmax - nii_view.nii.hdr.dime.glmin); - else - nii.img(sag,cor,axi,nii_view.scanid) = imgvalue; - end - - opt.command = 'updatenii'; - opt.usecolorbar = oldopt.usecolorbar; - opt.usepanel = oldopt.usepanel; - opt.usecrosshair = oldopt.usecrosshair; - opt.usestretch = oldopt.usestretch; - opt.useimagesc = oldopt.useimagesc; - opt.useinterp = oldopt.useinterp; - opt.setarea = oldopt.area; - opt.setunit = oldopt.unit; - opt.setviewpoint = oldopt.viewpoint; - opt.setscanid = oldopt.scanid; - opt.setcbarminmax = oldopt.cbarminmax; - opt.setcolorindex = oldopt.colorindex; - opt.setcolormap = oldopt.colormap; - opt.setcolorlevel = oldopt.colorlevel; - - if isfield(oldopt,'highcolor') - opt.sethighcolor = oldopt.highcolor; - end - - view_nii(fig, nii, opt); - set(fig,'Pointer',old_pointer); - reset_zoom(fig); - - return; % editvox - - -%---------------------------------------------------------------- -function save_disp - - [filename pathname] = uiputfile('*.*', 'Save displayed image as (*.nii or *.img)'); - - if isequal(filename,0) | isequal(pathname,0) - return; - else - out_imgfile = fullfile(pathname, filename); % original image file - end - - old_pointer = get(gcbf,'Pointer'); - set(gcbf,'Pointer','watch'); - - nii_view = getappdata(gcbf, 'nii_view'); - nii = nii_view.nii; - - try - save_nii(nii, out_imgfile); - catch - msg = 'File can not be saved.'; - msgbox(msg, 'File write error', 'modal'); - end - - set(gcbf,'Pointer',old_pointer); - - return; % save_disp - - -%---------------------------------------------------------------- -function img_hist - - nii_view = getappdata(gcbf, 'nii_view'); - N = hist(double(nii_view.nii.img(:)),256); - x = linspace(double(min(nii_view.nii.img(:))), double(max(nii_view.nii.img(:))), 256); - figure;bar(x,N); - set(gcf, 'number', 'off', 'name', 'Volume Histogram'); - set(gcf, 'windowstyle', 'modal'); % no zoom ... - - xspan = max(x) - min(x) + 1; - yspan = max(N) + 1; - set(gca, 'xlim', [min(x)-xspan/20, max(x)+xspan/20]); - set(gca, 'ylim', [-yspan/20, max(N)+yspan/20]); - - return; % img_hist - diff --git a/func/utils/nii/xform_nii.m b/func/utils/nii/xform_nii.m deleted file mode 100644 index 21d82cd..0000000 --- a/func/utils/nii/xform_nii.m +++ /dev/null @@ -1,521 +0,0 @@ -% internal function - -% 'xform_nii.m' is an internal function called by "load_nii.m", so -% you do not need run this program by yourself. It does simplified -% NIfTI sform/qform affine transform, and supports some of the -% affine transforms, including translation, reflection, and -% orthogonal rotation (N*90 degree). -% -% For other affine transforms, e.g. any degree rotation, shearing -% etc. you will have to use the included 'reslice_nii.m' program -% to reslice the image volume. 'reslice_nii.m' is not called by -% any other program, and you have to run 'reslice_nii.m' explicitly -% for those NIfTI files that you want to reslice them. -% -% Since 'xform_nii.m' does not involve any interpolation or any -% slice change, the original image volume is supposed to be -% untouched, although it is translated, reflected, or even -% orthogonally rotated, based on the affine matrix in the -% NIfTI header. -% -% However, the affine matrix in the header of a lot NIfTI files -% contain slightly non-orthogonal rotation. Therefore, optional -% input parameter 'tolerance' is used to allow some distortion -% in the loaded image for any non-orthogonal rotation or shearing -% of NIfTI affine matrix. If you set 'tolerance' to 0, it means -% that you do not allow any distortion. If you set 'tolerance' to -% 1, it means that you do not care any distortion. The image will -% fail to be loaded if it can not be tolerated. The tolerance will -% be set to 0.1 (10%), if it is default or empty. -% -% Because 'reslice_nii.m' has to perform 3D interpolation, it can -% be slow depending on image size and affine matrix in the header. -% -% After you perform the affine transform, the 'nii' structure -% generated from 'xform_nii.m' or new NIfTI file created from -% 'reslice_nii.m' will be in RAS orientation, i.e. X axis from -% Left to Right, Y axis from Posterior to Anterior, and Z axis -% from Inferior to Superior. -% -% NOTE: This function should be called immediately after load_nii. -% -% Usage: [ nii ] = xform_nii(nii, [tolerance], [preferredForm]) -% -% nii - NIFTI structure (returned from load_nii) -% -% tolerance (optional) - distortion allowed for non-orthogonal rotation -% or shearing in NIfTI affine matrix. It will be set to 0.1 (10%), -% if it is default or empty. -% -% preferredForm (optional) - selects which transformation from voxels -% to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate -% "prefer sform or qform, but use others if preferred not present". -% Upper case indicate the program is forced to use the specificied -% tranform or fail loading. 'preferredForm' will be 's', if it is -% default or empty. - Jeff Gunter -% -% NIFTI data format can be found on: http://nifti.nimh.nih.gov -% -% - Jimmy Shen (jimmy@rotman-baycrest.on.ca) -% -function nii = xform_nii(nii, tolerance, preferredForm) - - % save a copy of the header as it was loaded. This is the - % header before any sform, qform manipulation is done. - % - nii.original.hdr = nii.hdr; - - if ~exist('tolerance','var') | isempty(tolerance) - tolerance = 0.1; - elseif(tolerance<=0) - tolerance = eps; - end - - if ~exist('preferredForm','var') | isempty(preferredForm) - preferredForm= 's'; % Jeff - end - - % if scl_slope field is nonzero, then each voxel value in the - % dataset should be scaled as: y = scl_slope * x + scl_inter - % I bring it here because hdr will be modified by change_hdr. - % - if nii.hdr.dime.scl_slope ~= 0 & ... - ismember(nii.hdr.dime.datatype, [2,4,8,16,64,256,512,768]) & ... - (nii.hdr.dime.scl_slope ~= 1 | nii.hdr.dime.scl_inter ~= 0) - - nii.img = ... - nii.hdr.dime.scl_slope * double(nii.img) + nii.hdr.dime.scl_inter; - - if nii.hdr.dime.datatype == 64 - - nii.hdr.dime.datatype = 64; - nii.hdr.dime.bitpix = 64; - else - nii.img = single(nii.img); - - nii.hdr.dime.datatype = 16; - nii.hdr.dime.bitpix = 32; - end - - nii.hdr.dime.glmax = max(double(nii.img(:))); - nii.hdr.dime.glmin = min(double(nii.img(:))); - - % set scale to non-use, because it is applied in xform_nii - % - nii.hdr.dime.scl_slope = 0; - - end - - % However, the scaling is to be ignored if datatype is DT_RGB24. - - % If datatype is a complex type, then the scaling is to be applied - % to both the real and imaginary parts. - % - if nii.hdr.dime.scl_slope ~= 0 & ... - ismember(nii.hdr.dime.datatype, [32,1792]) - - nii.img = ... - nii.hdr.dime.scl_slope * double(nii.img) + nii.hdr.dime.scl_inter; - - if nii.hdr.dime.datatype == 32 - nii.img = single(nii.img); - end - - nii.hdr.dime.glmax = max(double(nii.img(:))); - nii.hdr.dime.glmin = min(double(nii.img(:))); - - % set scale to non-use, because it is applied in xform_nii - % - nii.hdr.dime.scl_slope = 0; - - end - - % There is no need for this program to transform Analyze data - % - if nii.filetype == 0 & exist([nii.fileprefix '.mat'],'file') - load([nii.fileprefix '.mat']); % old SPM affine matrix - R=M(1:3,1:3); - T=M(1:3,4); - T=R*ones(3,1)+T; - M(1:3,4)=T; - nii.hdr.hist.qform_code=0; - nii.hdr.hist.sform_code=1; - nii.hdr.hist.srow_x=M(1,:); - nii.hdr.hist.srow_y=M(2,:); - nii.hdr.hist.srow_z=M(3,:); - elseif nii.filetype == 0 - nii.hdr.hist.rot_orient = []; - nii.hdr.hist.flip_orient = []; - return; % no sform/qform for Analyze format - end - - hdr = nii.hdr; - - [hdr,orient]=change_hdr(hdr,tolerance,preferredForm); - - % flip and/or rotate image data - % - if ~isequal(orient, [1 2 3]) - - old_dim = hdr.dime.dim([2:4]); - - % More than 1 time frame - % - if ndims(nii.img) > 3 - pattern = 1:prod(old_dim); - else - pattern = []; - end - - if ~isempty(pattern) - pattern = reshape(pattern, old_dim); - end - - % calculate for rotation after flip - % - rot_orient = mod(orient + 2, 3) + 1; - - % do flip: - % - flip_orient = orient - rot_orient; - - for i = 1:3 - if flip_orient(i) - if ~isempty(pattern) - pattern = flipdim(pattern, i); - else - nii.img = flipdim(nii.img, i); - end - end - end - - % get index of orient (rotate inversely) - % - [tmp rot_orient] = sort(rot_orient); - - new_dim = old_dim; - new_dim = new_dim(rot_orient); - hdr.dime.dim([2:4]) = new_dim; - - new_pixdim = hdr.dime.pixdim([2:4]); - new_pixdim = new_pixdim(rot_orient); - hdr.dime.pixdim([2:4]) = new_pixdim; - - % re-calculate originator - % - tmp = hdr.hist.originator([1:3]); - tmp = tmp(rot_orient); - flip_orient = flip_orient(rot_orient); - - for i = 1:3 - if flip_orient(i) & ~isequal(tmp(i), 0) - tmp(i) = new_dim(i) - tmp(i) + 1; - end - end - - hdr.hist.originator([1:3]) = tmp; - hdr.hist.rot_orient = rot_orient; - hdr.hist.flip_orient = flip_orient; - - % do rotation: - % - if ~isempty(pattern) - pattern = permute(pattern, rot_orient); - pattern = pattern(:); - - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 | ... - hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - - tmp = reshape(nii.img(:,:,:,1), [prod(new_dim) hdr.dime.dim(5:8)]); - tmp = tmp(pattern, :); - nii.img(:,:,:,1) = reshape(tmp, [new_dim hdr.dime.dim(5:8)]); - - tmp = reshape(nii.img(:,:,:,2), [prod(new_dim) hdr.dime.dim(5:8)]); - tmp = tmp(pattern, :); - nii.img(:,:,:,2) = reshape(tmp, [new_dim hdr.dime.dim(5:8)]); - - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - tmp = reshape(nii.img(:,:,:,3), [prod(new_dim) hdr.dime.dim(5:8)]); - tmp = tmp(pattern, :); - nii.img(:,:,:,3) = reshape(tmp, [new_dim hdr.dime.dim(5:8)]); - end - - else - nii.img = reshape(nii.img, [prod(new_dim) hdr.dime.dim(5:8)]); - nii.img = nii.img(pattern, :); - nii.img = reshape(nii.img, [new_dim hdr.dime.dim(5:8)]); - end - else - if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 | ... - hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - - nii.img(:,:,:,1) = permute(nii.img(:,:,:,1), rot_orient); - nii.img(:,:,:,2) = permute(nii.img(:,:,:,2), rot_orient); - - if hdr.dime.datatype == 128 | hdr.dime.datatype == 511 - nii.img(:,:,:,3) = permute(nii.img(:,:,:,3), rot_orient); - end - else - nii.img = permute(nii.img, rot_orient); - end - end - else - hdr.hist.rot_orient = []; - hdr.hist.flip_orient = []; - end - - nii.hdr = hdr; - - return; % xform_nii - - -%----------------------------------------------------------------------- -function [hdr, orient] = change_hdr(hdr, tolerance, preferredForm) - - orient = [1 2 3]; - affine_transform = 1; - - % NIFTI can have both sform and qform transform. This program - % will check sform_code prior to qform_code by default. - % - % If user specifys "preferredForm", user can then choose the - % priority. - Jeff - % - useForm=[]; % Jeff - - if isequal(preferredForm,'S') - if isequal(hdr.hist.sform_code,0) - error('User requires sform, sform not set in header'); - else - useForm='s'; - end - end % Jeff - - if isequal(preferredForm,'Q') - if isequal(hdr.hist.qform_code,0) - error('User requires qform, qform not set in header'); - else - useForm='q'; - end - end % Jeff - - if isequal(preferredForm,'s') - if hdr.hist.sform_code > 0 - useForm='s'; - elseif hdr.hist.qform_code > 0 - useForm='q'; - end - end % Jeff - - if isequal(preferredForm,'q') - if hdr.hist.qform_code > 0 - useForm='q'; - elseif hdr.hist.sform_code > 0 - useForm='s'; - end - end % Jeff - - if isequal(useForm,'s') - R = [hdr.hist.srow_x(1:3) - hdr.hist.srow_y(1:3) - hdr.hist.srow_z(1:3)]; - - T = [hdr.hist.srow_x(4) - hdr.hist.srow_y(4) - hdr.hist.srow_z(4)]; - - if det(R) == 0 | ~isequal(R(find(R)), sum(R)') - hdr.hist.old_affine = [ [R;[0 0 0]] [T;1] ]; - R_sort = sort(abs(R(:))); - R( find( abs(R) < tolerance*min(R_sort(end-2:end)) ) ) = 0; - hdr.hist.new_affine = [ [R;[0 0 0]] [T;1] ]; - - if det(R) == 0 | ~isequal(R(find(R)), sum(R)') - msg = [char(10) char(10) ' Non-orthogonal rotation or shearing ']; - msg = [msg 'found inside the affine matrix' char(10)]; - msg = [msg ' in this NIfTI file. You have 3 options:' char(10) char(10)]; - msg = [msg ' 1. Using included ''reslice_nii.m'' program to reslice the NIfTI' char(10)]; - msg = [msg ' file. I strongly recommand this, because it will not cause' char(10)]; - msg = [msg ' negative effect, as long as you remember not to do slice' char(10)]; - msg = [msg ' time correction after using ''reslice_nii.m''.' char(10) char(10)]; - msg = [msg ' 2. Using included ''load_untouch_nii.m'' program to load image' char(10)]; - msg = [msg ' without applying any affine geometric transformation or' char(10)]; - msg = [msg ' voxel intensity scaling. This is only for people who want' char(10)]; - msg = [msg ' to do some image processing regardless of image orientation' char(10)]; - msg = [msg ' and to save data back with the same NIfTI header.' char(10) char(10)]; - msg = [msg ' 3. Increasing the tolerance to allow more distortion in loaded' char(10)]; - msg = [msg ' image, but I don''t suggest this.' char(10) char(10)]; - msg = [msg ' To get help, please type:' char(10) char(10) ' help reslice_nii.m' char(10)]; - msg = [msg ' help load_untouch_nii.m' char(10) ' help load_nii.m']; - error(msg); - end - end - - elseif isequal(useForm,'q') - b = hdr.hist.quatern_b; - c = hdr.hist.quatern_c; - d = hdr.hist.quatern_d; - - if 1.0-(b*b+c*c+d*d) < 0 - if abs(1.0-(b*b+c*c+d*d)) < 1e-5 - a = 0; - else - error('Incorrect quaternion values in this NIFTI data.'); - end - else - a = sqrt(1.0-(b*b+c*c+d*d)); - end - - qfac = hdr.dime.pixdim(1); - if qfac==0, qfac = 1; end - i = hdr.dime.pixdim(2); - j = hdr.dime.pixdim(3); - k = qfac * hdr.dime.pixdim(4); - - R = [a*a+b*b-c*c-d*d 2*b*c-2*a*d 2*b*d+2*a*c - 2*b*c+2*a*d a*a+c*c-b*b-d*d 2*c*d-2*a*b - 2*b*d-2*a*c 2*c*d+2*a*b a*a+d*d-c*c-b*b]; - - T = [hdr.hist.qoffset_x - hdr.hist.qoffset_y - hdr.hist.qoffset_z]; - - % qforms are expected to generate rotation matrices R which are - % det(R) = 1; we'll make sure that happens. - % - % now we make the same checks as were done above for sform data - % BUT we do it on a transform that is in terms of voxels not mm; - % after we figure out the angles and squash them to closest - % rectilinear direction. After that, the voxel sizes are then - % added. - % - % This part is modified by Jeff Gunter. - % - if det(R) == 0 | ~isequal(R(find(R)), sum(R)') - - % det(R) == 0 is not a common trigger for this --- - % R(find(R)) is a list of non-zero elements in R; if that - % is straight (not oblique) then it should be the same as - % columnwise summation. Could just as well have checked the - % lengths of R(find(R)) and sum(R)' (which should be 3) - % - hdr.hist.old_affine = [ [R * diag([i j k]);[0 0 0]] [T;1] ]; - R_sort = sort(abs(R(:))); - R( find( abs(R) < tolerance*min(R_sort(end-2:end)) ) ) = 0; - R = R * diag([i j k]); - hdr.hist.new_affine = [ [R;[0 0 0]] [T;1] ]; - - if det(R) == 0 | ~isequal(R(find(R)), sum(R)') - msg = [char(10) char(10) ' Non-orthogonal rotation or shearing ']; - msg = [msg 'found inside the affine matrix' char(10)]; - msg = [msg ' in this NIfTI file. You have 3 options:' char(10) char(10)]; - msg = [msg ' 1. Using included ''reslice_nii.m'' program to reslice the NIfTI' char(10)]; - msg = [msg ' file. I strongly recommand this, because it will not cause' char(10)]; - msg = [msg ' negative effect, as long as you remember not to do slice' char(10)]; - msg = [msg ' time correction after using ''reslice_nii.m''.' char(10) char(10)]; - msg = [msg ' 2. Using included ''load_untouch_nii.m'' program to load image' char(10)]; - msg = [msg ' without applying any affine geometric transformation or' char(10)]; - msg = [msg ' voxel intensity scaling. This is only for people who want' char(10)]; - msg = [msg ' to do some image processing regardless of image orientation' char(10)]; - msg = [msg ' and to save data back with the same NIfTI header.' char(10) char(10)]; - msg = [msg ' 3. Increasing the tolerance to allow more distortion in loaded' char(10)]; - msg = [msg ' image, but I don''t suggest this.' char(10) char(10)]; - msg = [msg ' To get help, please type:' char(10) char(10) ' help reslice_nii.m' char(10)]; - msg = [msg ' help load_untouch_nii.m' char(10) ' help load_nii.m']; - error(msg); - end - - else - R = R * diag([i j k]); - end % 1st det(R) - - else - affine_transform = 0; % no sform or qform transform - end - - if affine_transform == 1 - voxel_size = abs(sum(R,1)); - inv_R = inv(R); - originator = inv_R*(-T)+1; - orient = get_orient(inv_R); - - % modify pixdim and originator - % - hdr.dime.pixdim(2:4) = voxel_size; - hdr.hist.originator(1:3) = originator; - - % set sform or qform to non-use, because they have been - % applied in xform_nii - % - hdr.hist.qform_code = 0; - hdr.hist.sform_code = 0; - end - - % apply space_unit to pixdim if not 1 (mm) - % - space_unit = get_units(hdr); - - if space_unit ~= 1 - hdr.dime.pixdim(2:4) = hdr.dime.pixdim(2:4) * space_unit; - - % set space_unit of xyzt_units to millimeter, because - % voxel_size has been re-scaled - % - hdr.dime.xyzt_units = char(bitset(hdr.dime.xyzt_units,1,0)); - hdr.dime.xyzt_units = char(bitset(hdr.dime.xyzt_units,2,1)); - hdr.dime.xyzt_units = char(bitset(hdr.dime.xyzt_units,3,0)); - end - - hdr.dime.pixdim = abs(hdr.dime.pixdim); - - return; % change_hdr - - -%----------------------------------------------------------------------- -function orient = get_orient(R) - - orient = []; - - for i = 1:3 - switch find(R(i,:)) * sign(sum(R(i,:))) - case 1 - orient = [orient 1]; % Left to Right - case 2 - orient = [orient 2]; % Posterior to Anterior - case 3 - orient = [orient 3]; % Inferior to Superior - case -1 - orient = [orient 4]; % Right to Left - case -2 - orient = [orient 5]; % Anterior to Posterior - case -3 - orient = [orient 6]; % Superior to Inferior - end - end - - return; % get_orient - - -%----------------------------------------------------------------------- -function [space_unit, time_unit] = get_units(hdr) - - switch bitand(hdr.dime.xyzt_units, 7) % mask with 0x07 - case 1 - space_unit = 1e+3; % meter, m - case 3 - space_unit = 1e-3; % micrometer, um - otherwise - space_unit = 1; % millimeter, mm - end - - switch bitand(hdr.dime.xyzt_units, 56) % mask with 0x38 - case 16 - time_unit = 1e-3; % millisecond, ms - case 24 - time_unit = 1e-6; % microsecond, us - otherwise - time_unit = 1; % second, s - end - - return; % get_units - diff --git a/func/utils/process_options.m b/func/utils/process_options.m deleted file mode 100644 index a2ecc13..0000000 --- a/func/utils/process_options.m +++ /dev/null @@ -1,132 +0,0 @@ -% PROCESS_OPTIONS - Processes options passed to a Matlab function. -% This function provides a simple means of -% parsing attribute-value options. Each option is -% named by a unique string and is given a default -% value. -% -% Usage: [var1, var2, ..., varn[, unused]] = ... -% process_options(args, ... -% str1, def1, str2, def2, ..., strn, defn) -% -% Arguments: -% args - a cell array of input arguments, such -% as that provided by VARARGIN. Its contents -% should alternate between strings and -% values. -% str1, ..., strn - Strings that are associated with a -% particular variable -% def1, ..., defn - Default values returned if no option -% is supplied -% -% Returns: -% var1, ..., varn - values to be assigned to variables -% unused - an optional cell array of those -% string-value pairs that were unused; -% if this is not supplied, then a -% warning will be issued for each -% option in args that lacked a match. -% -% Examples: -% -% Suppose we wish to define a Matlab function 'func' that has -% required parameters x and y, and optional arguments 'u' and 'v'. -% With the definition -% -% function y = func(x, y, varargin) -% -% [u, v] = process_options(varargin, 'u', 0, 'v', 1); -% -% calling func(0, 1, 'v', 2) will assign 0 to x, 1 to y, 0 to u, and 2 -% to v. The parameter names are insensitive to case; calling -% func(0, 1, 'V', 2) has the same effect. The function call -% -% func(0, 1, 'u', 5, 'z', 2); -% -% will result in u having the value 5 and v having value 1, but -% will issue a warning that the 'z' option has not been used. On -% the other hand, if func is defined as -% -% function y = func(x, y, varargin) -% -% [u, v, unused_args] = process_options(varargin, 'u', 0, 'v', 1); -% -% then the call func(0, 1, 'u', 5, 'z', 2) will yield no warning, -% and unused_args will have the value {'z', 2}. This behaviour is -% useful for functions with options that invoke other functions -% with options; all options can be passed to the outer function and -% its unprocessed arguments can be passed to the inner function. - -% Copyright (C) 2002 Mark A. Paskin -% -% 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 2 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, write to the Free Software -% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -% USA. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function [varargout] = process_options(args, varargin) - -% Check the number of input arguments -n = length(varargin); -if (mod(n, 2)) - error('Each option must be a string/value pair.'); -end - -% Check the number of supplied output arguments -if (nargout < (n / 2)) - error('Insufficient number of output arguments given'); -elseif (nargout == (n / 2)) - warn = 1; - nout = n / 2; -else - warn = 0; - nout = n / 2 + 1; -end - -% Set outputs to be defaults -varargout = cell(1, nout); -for i=2:2:n - varargout{i/2} = varargin{i}; -end - -% Now process all arguments -nunused = 0; -for i=1:2:length(args) - found = 0; - for j=1:2:n - if strcmpi(args{i}, varargin{j}) - varargout{(j + 1)/2} = args{i + 1}; - found = 1; - break; - end - end - if (~found) - if (warn) - warning(sprintf('Option ''%s'' not used.', args{i})); - args{i} - else - nunused = nunused + 1; - unused{2 * nunused - 1} = args{i}; - unused{2 * nunused} = args{i + 1}; - end - end -end - -% Assign the unused arguments -if (~warn) - if (nunused) - varargout{nout} = unused; - else - varargout{nout} = cell(0); - end -end diff --git a/func/utils/reisert-unring-ddd43da65219/README.txt b/func/utils/reisert-unring-ddd43da65219/README.txt deleted file mode 100644 index 0c2ddd7..0000000 --- a/func/utils/reisert-unring-ddd43da65219/README.txt +++ /dev/null @@ -1,22 +0,0 @@ -unring - tool for removal of the Gibbs ringing artefact - -based on the algorithm in the publication -Kellner, E, Dhital B., Kiselev VG and Reisert, M. -Gibbs‐ringing artifact removal based on local subvoxel‐shifts. -Magnetic resonance in medicine, 76(5), 1574-1581. - - -Content -------- - -matlab - contains MATLAB/mex implementation of the algorithm, you need the fftw3.h header to compile the mex file via - mex ringRm.cpp -lfftw3 - this usually links to MATLAB's libfftw3 library - In case of a compile error, the switch -compatibleArrayDims might help - - -fsl - contains an implementation within the FSL framework, you need fsl sources to compile, but - a binary is included compiled on a 64bit linux system (kubuntu) - - -javascript - a javascript implementation. Runs in nodejs or the webbrowser diff --git a/func/utils/reisert-unring-ddd43da65219/fsl/Makefile b/func/utils/reisert-unring-ddd43da65219/fsl/Makefile deleted file mode 100644 index c863e14..0000000 --- a/func/utils/reisert-unring-ddd43da65219/fsl/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ${FSLCONFDIR}/default.mk - -PROJNAME=unring - -USRINCFLAGS=-I${INC_NEWMAT} -I${INC_BOOST} -USRLDFLAGS=-L${LIB_NEWMAT} - -OBJS=unring.o -LIBS=-lwarpfns -lmeshclass -lbasisfield -lnewimage -lmiscmaths -lprob -lfslio -lniftiio -lznz -lutils -lnewmat -lm -lz -lfftw3 - -XFILES=unring -FXFILES= - -all: ${XFILES} schedule - -schedule: - @if [ ! -d ${DESTDIR}/etc ] ; then ${MKDIR} ${DESTDIR}/etc ; ${CHMOD} g+w ${DESTDIR}/etc ; fi - -unring: ${OBJS} - ${CXX} ${LDFLAGS} -o $@ ${OBJS} ${LIBS} diff --git a/func/utils/reisert-unring-ddd43da65219/fsl/unring.a64 b/func/utils/reisert-unring-ddd43da65219/fsl/unring.a64 deleted file mode 100644 index bc4ced8..0000000 Binary files a/func/utils/reisert-unring-ddd43da65219/fsl/unring.a64 and /dev/null differ diff --git a/func/utils/reisert-unring-ddd43da65219/fsl/unring.cc b/func/utils/reisert-unring-ddd43da65219/fsl/unring.cc deleted file mode 100644 index a2d686e..0000000 --- a/func/utils/reisert-unring-ddd43da65219/fsl/unring.cc +++ /dev/null @@ -1,527 +0,0 @@ -// unring.cc unrings 4D volumes -// Marco Reisert, Elias Kellner, Medical Physics, University Medical Center Freiburg - -/* - LICENCE - - The Software remains the property of the University Medical Center - Freiburg ("the University"). - - The Software is distributed "AS IS" under this Licence solely for - non-commercial use in the hope that it will be useful, but in order - that the University as a charitable foundation protects its assets for - the benefit of its educational and research purposes, the University - makes clear that no condition is made or to be implied, nor is any - warranty given or to be implied, as to the accuracy of the Software, - or that it will be suitable for any particular purpose or for use - under any specific conditions. Furthermore, the University disclaims - all responsibility for the use which is made of the Software. It - further disclaims any liability for the outcomes arising from using - the Software. - - The Licensee agrees to indemnify the University and hold the - University harmless from and against any and all claims, damages and - liabilities asserted by third parties (including claims for - negligence) which arise directly or indirectly from the use of the - Software or the sale of any products based on the Software. - - No part of the Software may be reproduced, modified, transmitted or - transferred in any form or by any means, electronic or mechanical, - without the express permission of the University. The permission of - the University is not required if the said reproduction, modification, - transmission or transference is done without financial return, the - conditions of this Licence are imposed upon the receiver of the - product, and all original and amended source code is included in any - transmitted product. You may be held legally responsible for any - copyright infringement that is caused or encouraged by your failure to - abide by these terms and conditions. - - You are not permitted under this Licence to use this Software - commercially. Use for which any financial return is received shall be - defined as commercial use, and includes (1) integration of all or part - of the source code or the Software into a product for sale or license - by or on behalf of Licensee to third parties or (2) use of the - Software or any derivative of it for research with the final aim of - developing software products for sale or license to a third party or - (3) use of the Software or any derivative of it for research with the - final aim of developing non-software products for sale or license to a - third party, or (4) use of the Software to provide any service to an - external organisation for which payment is received. */ - -#include "newimage/newimageall.h" -#include "newimage/fmribmain.h" -#include -#include -#define PI 3.1416 - -using namespace NEWIMAGE; - - -void unring_1D(fftw_complex *data,int n, int numlines,int nsh,int minW, int maxW) -{ - - - fftw_complex *in, *out; - fftw_plan p,pinv; - - in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n); - out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n); - p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE); - pinv = fftw_plan_dft_1d(n, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); - - fftw_complex *sh = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n *(2*nsh+1)); - fftw_complex *sh2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n *(2*nsh+1)); - - - double nfac = 1/double(n); - - int *shifts = (int*) malloc(sizeof(int)*(2*nsh+1)); - shifts[0] = 0; - for (int j = 0; j < nsh;j++) - { - shifts[j+1] = j+1; - shifts[1+nsh+j] = -(j+1); - } - - double *TV1arr = new double[2*nsh+1]; - double *TV2arr = new double[2*nsh+1]; - - for (int k = 0; k < numlines; k++) - { - - - fftw_execute_dft(p,&(data[n*k]),sh); - - int maxn = (n%2 == 1)? (n-1)/2 : n/2 -1; - - for (int j = 1; j < 2*nsh+1; j++) - { - double phi = PI/double(n) * double(shifts[j])/double(nsh); - fftw_complex u = {cos(phi),sin(phi)}; - fftw_complex e = {1,0}; - - sh[j*n ][0] = sh[0][0]; - sh[j*n ][1] = sh[0][1]; - - if (n%2 == 0) - { - sh[j*n + n/2][0] = 0; - sh[j*n + n/2][1] = 0; - } - - for (int l = 0; l < maxn; l++) - { - - double tmp = e[0]; - e[0] = u[0]*e[0] - u[1]*e[1]; - e[1] = tmp*u[1] + u[0]*e[1]; - - int L ; - L = l+1; - sh[j*n +L][0] = (e[0]*sh[L][0] - e[1]*sh[L][1]); - sh[j*n +L][1] = (e[0]*sh[L][1] + e[1]*sh[L][0]); - L = n-1-l; - sh[j*n +L][0] = (e[0]*sh[L][0] + e[1]*sh[L][1]); - sh[j*n +L][1] = (e[0]*sh[L][1] - e[1]*sh[L][0]); - - } - } - - - for (int j = 0; j < 2*nsh+1; j++) - { - fftw_execute_dft(pinv,&(sh[j*n]),&sh2[j*n]); - } - - for (int j=0;j < 2*nsh+1;j++) - { - TV1arr[j] = 0; - TV2arr[j] = 0; - const int l = 0; - for (int t = minW; t <= maxW;t++) - { - TV1arr[j] += fabs(sh2[j*n + (l-t+n)%n ][0] - sh2[j*n + (l-(t+1)+n)%n ][0]); - TV1arr[j] += fabs(sh2[j*n + (l-t+n)%n ][1] - sh2[j*n + (l-(t+1)+n)%n ][1]); - TV2arr[j] += fabs(sh2[j*n + (l+t+n)%n ][0] - sh2[j*n + (l+(t+1)+n)%n ][0]); - TV2arr[j] += fabs(sh2[j*n + (l+t+n)%n ][1] - sh2[j*n + (l+(t+1)+n)%n ][1]); - } - } - - - - - for(int l=0; l < n; l++) - { - double minTV = 999999999999; - int minidx= 0; - for (int j=0;j < 2*nsh+1;j++) - { - -// double TV1 = 0; -// double TV2 = 0; -// for (int t = minW; t <= maxW;t++) -// { -// TV1 += fabs(sh2[j*n + (l-t)%n ][0] - sh2[j*n + (l-(t+1))%n ][0]); -// TV1 += fabs(sh2[j*n + (l-t)%n ][1] - sh2[j*n + (l-(t+1))%n ][1]); -// TV2 += fabs(sh2[j*n + (l+t)%n ][0] - sh2[j*n + (l+(t+1))%n ][0]); -// TV2 += fabs(sh2[j*n + (l+t)%n ][1] - sh2[j*n + (l+(t+1))%n ][1]); -// -// } -// -// -// if (TV1 < minTV) -// { -// minTV = TV1; -// minidx = j; -// } -// if (TV2 < minTV) -// { -// minTV = TV2; -// minidx = j; -// } - - - if (TV1arr[j] < minTV) - { - minTV = TV1arr[j]; - minidx = j; - } - if (TV2arr[j] < minTV) - { - minTV = TV2arr[j]; - minidx = j; - } - - TV1arr[j] += fabs(sh2[j*n + (l-minW+1+n)%n ][0] - sh2[j*n + (l-(minW)+n)%n ][0]); - TV1arr[j] -= fabs(sh2[j*n + (l-maxW+n)%n ][0] - sh2[j*n + (l-(maxW+1)+n)%n ][0]); - TV2arr[j] += fabs(sh2[j*n + (l+maxW+1+n)%n ][0] - sh2[j*n + (l+(maxW+2)+n)%n ][0]); - TV2arr[j] -= fabs(sh2[j*n + (l+minW+n)%n ][0] - sh2[j*n + (l+(minW+1)+n)%n ][0]); - - TV1arr[j] += fabs(sh2[j*n + (l-minW+1+n)%n ][1] - sh2[j*n + (l-(minW)+n)%n ][1]); - TV1arr[j] -= fabs(sh2[j*n + (l-maxW+n)%n ][1] - sh2[j*n + (l-(maxW+1)+n)%n ][1]); - TV2arr[j] += fabs(sh2[j*n + (l+maxW+1+n)%n ][1] - sh2[j*n + (l+(maxW+2)+n)%n ][1]); - TV2arr[j] -= fabs(sh2[j*n + (l+minW+n)%n ][1] - sh2[j*n + (l+(minW+1)+n)%n ][1]); - - } - - - double a0r = sh2[minidx*n + (l-1+n)%n ][0]; - double a1r = sh2[minidx*n + l][0]; - double a2r = sh2[minidx*n + (l+1+n)%n ][0]; - double a0i = sh2[minidx*n + (l-1+n)%n ][1]; - double a1i = sh2[minidx*n + l][1]; - double a2i = sh2[minidx*n + (l+1+n)%n ][1]; - double s = double(shifts[minidx])/nsh/2; - - //data[k*n + l][0] = (a1r - 0.5*(a2r-a0r)*s + (0.5*(a2r+a0r) - a1r)*s*s)*nfac; - //data[k*n + l][1] = (a1i - 0.5*(a2i-a0i)*s + (0.5*(a2i+a0i) - a1i)*s*s)*nfac; - - - if (s>0) - { - data[k*n + l][0] = (a1r*(1-s) + a0r*s)*nfac; - data[k*n + l][1] = (a1i*(1-s) + a0i*s)*nfac; - } - else - { - s = -s; - data[k*n + l][0] = (a1r*(1-s) + a2r*s)*nfac; - data[k*n + l][1] = (a1i*(1-s) + a2i*s)*nfac; - } - - } - - - - - } - - - delete TV1arr; - delete TV2arr; - free(shifts); - fftw_destroy_plan(p); - fftw_destroy_plan(pinv); - fftw_free(in); - fftw_free(out); - fftw_free(sh); - fftw_free(sh2); - - - - -} - - -void unring_2d(fftw_complex *data1,fftw_complex *tmp2, const int *dim_sz, int nsh, int minW, int maxW) -{ - - - double eps = 0; - fftw_complex *tmp1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - fftw_complex *data2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - - fftw_plan p,pinv,p_tr,pinv_tr; - p = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_FORWARD, FFTW_ESTIMATE); - pinv = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_BACKWARD, FFTW_ESTIMATE); - p_tr = fftw_plan_dft_2d(dim_sz[0],dim_sz[1], data2, tmp2, FFTW_FORWARD, FFTW_ESTIMATE); - pinv_tr = fftw_plan_dft_2d(dim_sz[0],dim_sz[1], data2, tmp2, FFTW_BACKWARD, FFTW_ESTIMATE); - double nfac = 1/double(dim_sz[0]*dim_sz[1]); - - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data2[j*dim_sz[1]+k][0] = data1[k*dim_sz[0]+j][0]; - data2[j*dim_sz[1]+k][1] = data1[k*dim_sz[0]+j][1]; - } - - fftw_execute_dft(p,data1,tmp1); - fftw_execute_dft(p_tr,data2,tmp2); - - for (int k = 0 ; k < dim_sz[1];k++) - { - double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5 +eps; - for (int j = 0 ; j < dim_sz[0];j++) - { - double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5 +eps; - tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] * ck) / (ck+cj); - tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] * ck) / (ck+cj); - tmp2[j*dim_sz[1]+k][0] = nfac*(tmp2[j*dim_sz[1]+k][0] * cj) / (ck+cj); - tmp2[j*dim_sz[1]+k][1] = nfac*(tmp2[j*dim_sz[1]+k][1] * cj) / (ck+cj); - } - } - - fftw_execute_dft(pinv,tmp1,data1); - fftw_execute_dft(pinv_tr,tmp2,data2); - - unring_1D(data1,dim_sz[0],dim_sz[1],nsh,minW,maxW); - unring_1D(data2,dim_sz[1],dim_sz[0],nsh,minW,maxW); - - - fftw_execute_dft(p,data1,tmp1); - fftw_execute_dft(p_tr,data2,tmp2); - - - for (int k = 0 ; k < dim_sz[1];k++) - { -// double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5 +eps; - for (int j = 0 ; j < dim_sz[0];j++) - { - // double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5 +eps; - tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] + tmp2[j*dim_sz[1]+k][0] ) ; - tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] + tmp2[j*dim_sz[1]+k][1] ) ; - // tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] + tmp2[j*dim_sz[1]+k][0] ) /(ck+cj); - // tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] + tmp2[j*dim_sz[1]+k][1] ) /(ck+cj); -// tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0]*ck + tmp2[j*dim_sz[1]+k][0]*cj ) /(ck+cj); -// tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1]*ck + tmp2[j*dim_sz[1]+k][1]*cj ) /(ck+cj); - } - } - - fftw_execute_dft(pinv,tmp1,tmp2); - - fftw_free(data2); - fftw_free(tmp1); -} - - - -void print_usage(const string& progname) { - cout << endl; - cout << "unring - tool for removal of the Gibbs ringing artefact" << endl; - cout << "Usage: unring [options]" << endl; - cout << " Options: -d slice direction, in the perpendicular plane unringing is performed. Could be either 1,2 or 3 (default 3)" << endl; - cout << " -nsh discretization of subpixel spaceing (default 20)" << endl; - cout << " -minW left border of window used for TV computation (default 1)" << endl; - cout << " -maxW right border of window used for TV computation (default 3)" << endl; -} - - -template -int fmrib_main(int argc, char *argv[]) -{ - - string alongdim = "3"; - int nsh = 20; - int minW = 1; - int maxW = 3; - - for (int k = 3; k < argc;k+=2) - { - string pname = string(argv[k]); - - if (k+1 >= argc) - { - fprintf(stderr,"missing parameter value\n"); - return -1; - } - - string pval = string(argv[k+1]); - if (pname.compare(string("-d"))==0) - alongdim = pval; - else if (pname.compare(string("-n"))==0) - nsh = atoi(pval.c_str()); - else if (pname.compare(string("-minW"))==0) - minW = atoi(pval.c_str()); - else if (pname.compare(string("-maxW"))==0) - maxW = atoi(pval.c_str()); - else - { - fprintf(stderr,"unknown parameter %s \n",pname.c_str()); - } - - } - - - if (minW<0 || minW > 10 || minW >= maxW || maxW<0 || maxW > 128) - { - fprintf(stderr,"sth wrong with minW/maxW\n"); - return -1 ; - } - - if (nsh< 16 || nsh > 128) - { - fprintf(stderr,"sth wrong with nsh\n"); - return -1 ; - } - - - - - - volume4D input_vol,output_vol; - string input_name=string(argv[1]); - string output_name=string(argv[2]); - read_volume4D(input_vol,input_name); - - - output_vol=input_vol; - - int dim_sz[4]; - dim_sz[0] = input_vol.xsize(); - dim_sz[1] = input_vol.ysize(); - dim_sz[2] = 1; - dim_sz[3] = 1 ; - - - - - - for (int t=0; t1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a"}else{ret=name}paramLoop:while(i0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}function enlargeMemory(){abortOnCannotGrowMemory()}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var totalMemory=64*1024;while(totalMemory0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+752;__ATINIT__.push();allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,239,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,82,101,97,108,32,70,70,84,32,111,112,116,105,109,105,122,97,116,105,111,110,32,109,117,115,116,32,98,101,32,101,118,101,110,46,10,0,107,105,115,115,32,102,102,116,32,117,115,97,103,101,32,101,114,114,111,114,58,32,105,109,112,114,111,112,101,114,32,97,108,108,111,99,10,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}function __exit(status){Module["exit"](status)}function _exit(status){__exit(status)}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}Module["_memset"]=_memset;function _pthread_cleanup_push(routine,arg){__ATEXIT__.push((function(){Runtime.dynCall("vi",routine,[arg])}));_pthread_cleanup_push.level=__ATEXIT__.length}function _pthread_cleanup_pop(){assert(_pthread_cleanup_push.level==__ATEXIT__.length,"cannot pop if something else added meanwhile!");__ATEXIT__.pop();_pthread_cleanup_push.level=__ATEXIT__.length}function _abort(){Module["abort"]()}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;var SYSCALLS={varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall6(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD();FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var _cos=Math_cos;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}var _floor=Math_floor;var _sqrt=Math_sqrt;function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}function _pthread_self(){return 0}function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;assert(offset_high===0);FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;if(!___syscall146.buffer)___syscall146.buffer=[];var buffer=___syscall146.buffer;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Ha(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ia(a){a=a|0;B=a}function Ja(){return B|0}function Ka(a){a=a|0;cb(a);return}function La(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0.0,i=0,j=0.0;f=(a<<3)+264|0;if(!e)i=bb(f)|0;else{if(!d)d=0;else d=(c[e>>2]|0)>>>0>>0?0:d;c[e>>2]=f;i=d}if(!i)return i|0;c[i>>2]=a;e=i+4|0;c[e>>2]=b;h=+(a|0);a:do if((a|0)>0){f=b;d=0;while(1){j=+(d|0)*-6.283185307179586/h;j=(f|0)==0?j:-j;g[i+264+(d<<3)>>2]=+P(+j);g[i+264+(d<<3)+4>>2]=+Q(+j);d=d+1|0;if((d|0)==(a|0))break a;f=c[e>>2]|0}}while(0);h=+L(+(+N(+h)));f=a;e=i+8|0;d=4;while(1){b:do if((f|0)%(d|0)|0)while(1){switch(d|0){case 4:{d=2;break}case 2:{d=3;break}default:d=d+2|0}d=+(d|0)>h?f:d;if(!((f|0)%(d|0)|0))break b}while(0);f=(f|0)/(d|0)|0;c[e>>2]=d;c[e+4>>2]=f;if((f|0)<=1)break;else e=e+8|0}return i|0}function Ma(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0,j=0,l=0,m=0,n=0.0,o=0.0,p=0.0,q=0.0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0.0,z=0.0,A=0.0,B=0.0,C=0,D=0.0,E=0.0,F=0.0,G=0.0,H=0.0,I=0.0,J=0.0,K=0.0,L=0.0,M=0.0;w=c[f>>2]|0;m=f+8|0;x=c[f+4>>2]|0;r=a+((Z(x,w)|0)<<3)|0;if((x|0)==1){j=Z(e,d)|0;i=a;f=b;while(1){t=f;u=c[t+4>>2]|0;v=i;c[v>>2]=c[t>>2];c[v+4>>2]=u;i=i+8|0;if((i|0)==(r|0))break;else f=f+(j<<3)|0}}else{j=Z(w,d)|0;l=Z(e,d)|0;i=a;f=b;while(1){Ma(i,f,j,e,m,h);i=i+(x<<3)|0;if((i|0)==(r|0))break;else f=f+(l<<3)|0}}switch(w|0){case 2:{j=a;l=x;i=a+(x<<3)|0;f=h+264|0;while(1){o=+g[i>>2];y=+g[f>>2];a=i+4|0;n=+g[a>>2];q=+g[f+4>>2];p=o*y-n*q;q=y*n+o*q;g[i>>2]=+g[j>>2]-p;x=j+4|0;g[a>>2]=+g[x>>2]-q;g[j>>2]=p+ +g[j>>2];g[x>>2]=q+ +g[x>>2];l=l+-1|0;if(!l)break;else{j=j+8|0;i=i+8|0;f=f+(d<<3)|0}}return}case 3:{e=x<<1;n=+g[h+264+((Z(x,d)|0)<<3)+4>>2];l=h+264|0;m=d<<1;f=a;i=x;j=l;while(1){h=f+(x<<3)|0;o=+g[h>>2];p=+g[j>>2];a=f+(x<<3)+4|0;B=+g[a>>2];z=+g[j+4>>2];A=o*p-B*z;z=p*B+o*z;v=f+(e<<3)|0;o=+g[v>>2];B=+g[l>>2];w=f+(e<<3)+4|0;p=+g[w>>2];q=+g[l+4>>2];y=o*B-p*q;q=B*p+o*q;o=A+y;p=z+q;g[h>>2]=+g[f>>2]-o*.5;u=f+4|0;g[a>>2]=+g[u>>2]-p*.5;y=n*(A-y);q=n*(z-q);g[f>>2]=+g[f>>2]+o;g[u>>2]=p+ +g[u>>2];g[v>>2]=q+ +g[h>>2];g[w>>2]=+g[a>>2]-y;g[h>>2]=+g[h>>2]-q;g[a>>2]=y+ +g[a>>2];i=i+-1|0;if(!i)break;else{f=f+8|0;j=j+(d<<3)|0;l=l+(m<<3)|0}}return}case 4:{e=x<<1;b=x*3|0;f=h+264|0;r=d<<1;s=d*3|0;if(!(c[h+4>>2]|0)){i=a;j=x;l=f;m=f;while(1){v=i+(x<<3)|0;n=+g[v>>2];o=+g[l>>2];w=i+(x<<3)+4|0;y=+g[w>>2];D=+g[l+4>>2];E=n*o-y*D;D=o*y+n*D;C=i+(e<<3)|0;n=+g[C>>2];y=+g[m>>2];t=i+(e<<3)+4|0;o=+g[t>>2];p=+g[m+4>>2];q=n*y-o*p;p=y*o+n*p;h=i+(b<<3)|0;n=+g[h>>2];o=+g[f>>2];a=i+(b<<3)+4|0;y=+g[a>>2];z=+g[f+4>>2];B=n*o-y*z;z=o*y+n*z;n=+g[i>>2];y=n-q;u=i+4|0;o=+g[u>>2];A=o-p;n=q+n;g[i>>2]=n;o=p+o;g[u>>2]=o;p=E+B;q=D+z;B=E-B;z=D-z;g[C>>2]=n-p;g[t>>2]=o-q;g[i>>2]=p+ +g[i>>2];g[u>>2]=q+ +g[u>>2];g[v>>2]=y+z;g[w>>2]=A-B;g[h>>2]=y-z;g[a>>2]=A+B;j=j+-1|0;if(!j)break;else{i=i+8|0;l=l+(d<<3)|0;m=m+(r<<3)|0;f=f+(s<<3)|0}}return}else{i=a;j=x;l=f;m=f;while(1){w=i+(x<<3)|0;p=+g[w>>2];q=+g[l>>2];h=i+(x<<3)+4|0;A=+g[h>>2];o=+g[l+4>>2];n=p*q-A*o;o=q*A+p*o;t=i+(e<<3)|0;p=+g[t>>2];A=+g[m>>2];u=i+(e<<3)+4|0;q=+g[u>>2];y=+g[m+4>>2];z=p*A-q*y;y=A*q+p*y;a=i+(b<<3)|0;p=+g[a>>2];q=+g[f>>2];C=i+(b<<3)+4|0;A=+g[C>>2];B=+g[f+4>>2];E=p*q-A*B;B=q*A+p*B;p=+g[i>>2];A=p-z;v=i+4|0;q=+g[v>>2];D=q-y;p=z+p;g[i>>2]=p;q=y+q;g[v>>2]=q;y=n+E;z=o+B;E=n-E;B=o-B;g[t>>2]=p-y;g[u>>2]=q-z;g[i>>2]=y+ +g[i>>2];g[v>>2]=z+ +g[v>>2];g[w>>2]=A-B;g[h>>2]=D+E;g[a>>2]=A+B;g[C>>2]=D-E;j=j+-1|0;if(!j)break;else{i=i+8|0;l=l+(d<<3)|0;m=m+(r<<3)|0;f=f+(s<<3)|0}}return}}case 5:{C=Z(x,d)|0;n=+g[h+264+(C<<3)>>2];o=+g[h+264+(C<<3)+4>>2];C=Z(x,d<<1)|0;p=+g[h+264+(C<<3)>>2];q=+g[h+264+(C<<3)+4>>2];if((x|0)<=0)return;j=d*3|0;l=a;m=a+(x<<3)|0;e=a+(x<<1<<3)|0;b=a+(x*3<<3)|0;f=a+(x<<2<<3)|0;i=0;while(1){H=+g[l>>2];u=l+4|0;F=+g[u>>2];A=+g[m>>2];t=Z(i,d)|0;D=+g[h+264+(t<<3)>>2];v=m+4|0;M=+g[v>>2];I=+g[h+264+(t<<3)+4>>2];G=A*D-M*I;I=D*M+A*I;A=+g[e>>2];t=Z(i<<1,d)|0;M=+g[h+264+(t<<3)>>2];a=e+4|0;D=+g[a>>2];L=+g[h+264+(t<<3)+4>>2];J=A*M-D*L;L=M*D+A*L;A=+g[b>>2];t=Z(j,i)|0;D=+g[h+264+(t<<3)>>2];C=b+4|0;M=+g[C>>2];y=+g[h+264+(t<<3)+4>>2];E=A*D-M*y;y=D*M+A*y;A=+g[f>>2];t=Z(i<<2,d)|0;M=+g[h+264+(t<<3)>>2];w=f+4|0;D=+g[w>>2];B=+g[h+264+(t<<3)+4>>2];z=A*M-D*B;B=M*D+A*B;A=G+z;D=I+B;z=G-z;B=I-B;I=J+E;G=L+y;E=J-E;y=L-y;g[l>>2]=H+(I+A);g[u>>2]=F+(G+D);L=p*I+(H+n*A);J=p*G+(F+n*D);M=q*y+o*B;K=-(o*z)-q*E;g[m>>2]=L-M;g[v>>2]=J-K;g[f>>2]=M+L;g[w>>2]=K+J;A=n*I+(H+p*A);D=n*G+(F+p*D);B=o*y-q*B;E=q*z-o*E;g[e>>2]=B+A;g[a>>2]=E+D;g[b>>2]=A-B;g[C>>2]=D-E;i=i+1|0;if((i|0)==(x|0))break;else{l=l+8|0;m=m+8|0;e=e+8|0;b=b+8|0;f=f+8|0}}return}default:{t=c[h>>2]|0;v=bb(w<<3)|0;a:do if((x|0)>0?(w|0)>0:0){if((w|0)>1)u=0;else{m=0;while(1){f=m;i=0;while(1){h=a+(f<<3)|0;d=c[h+4>>2]|0;C=v+(i<<3)|0;c[C>>2]=c[h>>2];c[C+4>>2]=d;i=i+1|0;if((i|0)==(w|0))break;else f=f+x|0}i=v;f=c[i>>2]|0;i=c[i+4>>2]|0;j=m;l=0;while(1){C=a+(j<<3)|0;c[C>>2]=f;c[C+4>>2]=i;l=l+1|0;if((l|0)==(w|0))break;else j=j+x|0}m=m+1|0;if((m|0)==(x|0))break a}}do{f=u;i=0;while(1){r=a+(f<<3)|0;s=c[r+4>>2]|0;C=v+(i<<3)|0;c[C>>2]=c[r>>2];c[C+4>>2]=s;i=i+1|0;if((i|0)==(w|0))break;else f=f+x|0}i=v;f=c[i>>2]|0;i=c[i+4>>2]|0;n=(c[k>>2]=f,+g[k>>2]);e=u;r=0;while(1){j=a+(e<<3)|0;l=j;c[l>>2]=f;c[l+4>>2]=i;l=Z(e,d)|0;m=a+(e<<3)+4|0;o=n;p=+g[m>>2];b=1;s=0;do{C=s+l|0;s=C-((C|0)<(t|0)?0:t)|0;L=+g[v+(b<<3)>>2];J=+g[h+264+(s<<3)>>2];K=+g[v+(b<<3)+4>>2];M=+g[h+264+(s<<3)+4>>2];o=o+(L*J-K*M);g[j>>2]=o;p=p+(J*K+L*M);g[m>>2]=p;b=b+1|0}while((b|0)!=(w|0));r=r+1|0;if((r|0)==(w|0))break;else e=e+x|0}u=u+1|0}while((u|0)!=(x|0))}while(0);cb(v);return}}}function Na(a,b,d){a=a|0;b=b|0;d=d|0;if((b|0)==(d|0)){d=bb(c[a>>2]<<3)|0;Ma(d,b,1,1,a+8|0,a);fb(b|0,d|0,c[a>>2]<<3|0)|0;cb(d);return}else{Ma(d,b,1,1,a+8|0,a);return}}function Oa(a){a=a|0;cb(a);return}function Pa(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0.0,j=0,k=0,l=0,m=0,n=0.0;l=i;i=i+16|0;k=l;if(a&1){Za(668,36,1,c[13]|0)|0;b=0;i=l;return b|0}j=a>>1;La(j,b,0,k)|0;f=c[k>>2]|0;a=f+12+(((j*3|0)/2|0)<<3)|0;if(e){m=(c[e>>2]|0)>>>0>>0;c[e>>2]=a;if(m){m=0;i=l;return m|0}}else d=bb(a)|0;if(!d){m=0;i=l;return m|0}e=d+12|0;c[d>>2]=e;m=e+f|0;c[d+4>>2]=m;a=d+8|0;c[a>>2]=m+(j<<3);La(j,b,e,k)|0;e=(j|0)/2|0;if((j|0)<=1){m=d;i=l;return m|0}h=+(j|0);f=c[a>>2]|0;if(!b){a=0;do{m=a;a=a+1|0;n=(+(a|0)/h+.5)*-3.141592653589793;g[f+(m<<3)>>2]=+P(+n);g[f+(m<<3)+4>>2]=+Q(+n)}while((a|0)<(e|0));i=l;return d|0}else{a=0;do{m=a;a=a+1|0;n=(+(a|0)/h+.5)*-3.141592653589793;g[f+(m<<3)>>2]=+P(+n);g[f+(m<<3)+4>>2]=+Q(+-n)}while((a|0)<(e|0));i=l;return d|0}return 0}function Qa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,i=0,j=0.0,k=0.0,l=0.0,m=0.0,n=0.0,o=0.0,p=0.0,q=0;e=c[a>>2]|0;if(c[e+4>>2]|0){Za(705,37,1,c[13]|0)|0;ua(1)}i=c[e>>2]|0;h=a+4|0;Na(e,b,c[h>>2]|0);h=c[h>>2]|0;k=+g[h>>2];j=+g[h+4>>2];g[d>>2]=k+j;g[d+(i<<3)>>2]=k-j;g[d+4>>2]=0.0;g[d+(i<<3)+4>>2]=0.0;f=(i|0)/2|0;if((i|0)<2)return;e=c[a+8>>2]|0;b=1;while(1){j=+g[h+(b<<3)>>2];o=+g[h+(b<<3)+4>>2];a=i-b|0;n=+g[h+(a<<3)>>2];p=+g[h+(a<<3)+4>>2];m=j+n;k=o-p;n=j-n;p=o+p;q=b+-1|0;o=+g[e+(q<<3)>>2];j=+g[e+(q<<3)+4>>2];l=n*o-p*j;j=p*o+n*j;g[d+(b<<3)>>2]=(m+l)*.5;g[d+(b<<3)+4>>2]=(k+j)*.5;g[d+(a<<3)>>2]=(m-l)*.5;g[d+(a<<3)+4>>2]=(j-k)*.5;if((b|0)<(f|0))b=b+1|0;else break}return}function Ra(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,i=0,j=0,k=0,l=0.0,m=0.0,n=0.0,o=0.0,p=0.0,q=0.0,r=0.0,s=0;f=c[a>>2]|0;if(!(c[f+4>>2]|0)){Za(705,37,1,c[13]|0)|0;ua(1)}j=c[f>>2]|0;i=b+(j<<3)|0;h=c[a+4>>2]|0;g[h>>2]=+g[b>>2]+ +g[i>>2];g[h+4>>2]=+g[b>>2]-+g[i>>2];i=(j|0)/2|0;if((j|0)<2){Na(f,h,d);return}a=c[a+8>>2]|0;e=1;while(1){l=+g[b+(e<<3)>>2];q=+g[b+(e<<3)+4>>2];k=j-e|0;p=+g[b+(k<<3)>>2];r=+g[b+(k<<3)+4>>2];o=l+p;m=q-r;p=l-p;r=q+r;s=e+-1|0;q=+g[a+(s<<3)>>2];l=+g[a+(s<<3)+4>>2];n=p*q-r*l;l=r*q+p*l;g[h+(e<<3)>>2]=o+n;g[h+(e<<3)+4>>2]=m+l;g[h+(k<<3)>>2]=o-n;g[h+(k<<3)+4>>2]=-(m-l);if((e|0)<(i|0))e=e+1|0;else break}Na(f,h,d);return}function Sa(){var a=0;if(!(c[2]|0))a=56;else a=c[(ka()|0)+60>>2]|0;return a|0}function Ta(a){a=a|0;if(a>>>0>4294963200){c[(Sa()|0)>>2]=0-a;a=-1}return a|0}function Ua(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=i;i=i+48|0;n=q+16|0;m=q;e=q+32|0;o=a+28|0;f=c[o>>2]|0;c[e>>2]=f;p=a+20|0;f=(c[p>>2]|0)-f|0;c[e+4>>2]=f;c[e+8>>2]=b;c[e+12>>2]=d;k=a+60|0;l=a+44|0;b=2;f=f+d|0;while(1){if(!(c[2]|0)){c[n>>2]=c[k>>2];c[n+4>>2]=e;c[n+8>>2]=b;h=Ta(wa(146,n|0)|0)|0}else{qa(1,a|0);c[m>>2]=c[k>>2];c[m+4>>2]=e;c[m+8>>2]=b;h=Ta(wa(146,m|0)|0)|0;fa(0)}if((f|0)==(h|0)){f=6;break}if((h|0)<0){f=8;break}f=f-h|0;g=c[e+4>>2]|0;if(h>>>0<=g>>>0)if((b|0)==2){c[o>>2]=(c[o>>2]|0)+h;j=g;b=2}else j=g;else{j=c[l>>2]|0;c[o>>2]=j;c[p>>2]=j;j=c[e+12>>2]|0;h=h-g|0;e=e+8|0;b=b+-1|0}c[e>>2]=(c[e>>2]|0)+h;c[e+4>>2]=j-h}if((f|0)==6){n=c[l>>2]|0;c[a+16>>2]=n+(c[a+48>>2]|0);a=n;c[o>>2]=a;c[p>>2]=a}else if((f|0)==8){c[a+16>>2]=0;c[o>>2]=0;c[p>>2]=0;c[a>>2]=c[a>>2]|32;if((b|0)==2)d=0;else d=d-(c[e+4>>2]|0)|0}i=q;return d|0}function Va(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=c[a+60>>2];a=Ta(la(6,d|0)|0)|0;i=b;return a|0}function Wa(b){b=b|0;var d=0,e=0;d=b+74|0;e=a[d>>0]|0;a[d>>0]=e+255|e;d=c[b>>2]|0;if(!(d&8)){c[b+8>>2]=0;c[b+4>>2]=0;d=c[b+44>>2]|0;c[b+28>>2]=d;c[b+20>>2]=d;c[b+16>>2]=d+(c[b+48>>2]|0);d=0}else{c[b>>2]=d|32;d=-1}return d|0}function Xa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;f=i;i=i+32|0;g=f;e=f+20|0;c[g>>2]=c[a+60>>2];c[g+4>>2]=0;c[g+8>>2]=b;c[g+12>>2]=e;c[g+16>>2]=d;if((Ta(ta(140,g|0)|0)|0)<0){c[e>>2]=-1;a=-1}else a=c[e>>2]|0;i=f;return a|0}function Ya(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=e+16|0;g=c[f>>2]|0;if(!g)if(!(Wa(e)|0)){g=c[f>>2]|0;h=5}else f=0;else h=5;a:do if((h|0)==5){i=e+20|0;f=c[i>>2]|0;h=f;if((g-f|0)>>>0>>0){f=za[c[e+36>>2]&3](e,b,d)|0;break}b:do if((a[e+75>>0]|0)>-1){f=d;while(1){if(!f){g=h;f=0;break b}g=f+-1|0;if((a[b+g>>0]|0)==10)break;else f=g}if((za[c[e+36>>2]&3](e,b,f)|0)>>>0>>0)break a;d=d-f|0;b=b+f|0;g=c[i>>2]|0}else{g=h;f=0}while(0);fb(g|0,b|0,d|0)|0;c[i>>2]=(c[i>>2]|0)+d;f=f+d|0}while(0);return f|0}function Za(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=Z(d,b)|0;if((c[e+76>>2]|0)>-1){g=(_a(e)|0)==0;a=Ya(a,f,e)|0;if(!g)$a(e)}else a=Ya(a,f,e)|0;if((a|0)!=(f|0))d=(a>>>0)/(b>>>0)|0;return d|0}function _a(a){a=a|0;return 0}function $a(a){a=a|0;return}function ab(a){a=a|0;if(!(c[a+68>>2]|0))$a(a);return}function bb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;do if(a>>>0<245){o=a>>>0<11?16:a+11&-8;a=o>>>3;j=c[43]|0;b=j>>>a;if(b&3){b=(b&1^1)+a|0;d=212+(b<<1<<2)|0;e=d+8|0;f=c[e>>2]|0;g=f+8|0;h=c[g>>2]|0;do if((d|0)!=(h|0)){if(h>>>0<(c[47]|0)>>>0)na();a=h+12|0;if((c[a>>2]|0)==(f|0)){c[a>>2]=d;c[e>>2]=h;break}else na()}else c[43]=j&~(1<>2]=L|3;L=f+L+4|0;c[L>>2]=c[L>>2]|1;L=g;return L|0}h=c[45]|0;if(o>>>0>h>>>0){if(b){d=2<>>12&16;d=d>>>i;f=d>>>5&8;d=d>>>f;g=d>>>2&4;d=d>>>g;e=d>>>1&2;d=d>>>e;b=d>>>1&1;b=(f|i|g|e|b)+(d>>>b)|0;d=212+(b<<1<<2)|0;e=d+8|0;g=c[e>>2]|0;i=g+8|0;f=c[i>>2]|0;do if((d|0)!=(f|0)){if(f>>>0<(c[47]|0)>>>0)na();a=f+12|0;if((c[a>>2]|0)==(g|0)){c[a>>2]=d;c[e>>2]=f;k=c[45]|0;break}else na()}else{c[43]=j&~(1<>2]=o|3;e=g+o|0;c[e+4>>2]=h|1;c[e+h>>2]=h;if(k){f=c[48]|0;b=k>>>3;d=212+(b<<1<<2)|0;a=c[43]|0;b=1<>2]|0;if(b>>>0<(c[47]|0)>>>0)na();else{l=a;m=b}}else{c[43]=a|b;l=d+8|0;m=d}c[l>>2]=f;c[m+12>>2]=f;c[f+8>>2]=m;c[f+12>>2]=d}c[45]=h;c[48]=e;L=i;return L|0}a=c[44]|0;if(a){d=(a&0-a)+-1|0;K=d>>>12&16;d=d>>>K;J=d>>>5&8;d=d>>>J;L=d>>>2&4;d=d>>>L;b=d>>>1&2;d=d>>>b;e=d>>>1&1;e=c[476+((J|K|L|b|e)+(d>>>e)<<2)>>2]|0;d=(c[e+4>>2]&-8)-o|0;b=e;while(1){a=c[b+16>>2]|0;if(!a){a=c[b+20>>2]|0;if(!a){j=e;break}}b=(c[a+4>>2]&-8)-o|0;L=b>>>0>>0;d=L?b:d;b=a;e=L?a:e}g=c[47]|0;if(j>>>0>>0)na();i=j+o|0;if(j>>>0>=i>>>0)na();h=c[j+24>>2]|0;e=c[j+12>>2]|0;do if((e|0)==(j|0)){b=j+20|0;a=c[b>>2]|0;if(!a){b=j+16|0;a=c[b>>2]|0;if(!a){n=0;break}}while(1){e=a+20|0;f=c[e>>2]|0;if(f){a=f;b=e;continue}e=a+16|0;f=c[e>>2]|0;if(!f)break;else{a=f;b=e}}if(b>>>0>>0)na();else{c[b>>2]=0;n=a;break}}else{f=c[j+8>>2]|0;if(f>>>0>>0)na();a=f+12|0;if((c[a>>2]|0)!=(j|0))na();b=e+8|0;if((c[b>>2]|0)==(j|0)){c[a>>2]=e;c[b>>2]=f;n=e;break}else na()}while(0);do if(h){a=c[j+28>>2]|0;b=476+(a<<2)|0;if((j|0)==(c[b>>2]|0)){c[b>>2]=n;if(!n){c[44]=c[44]&~(1<>>0<(c[47]|0)>>>0)na();a=h+16|0;if((c[a>>2]|0)==(j|0))c[a>>2]=n;else c[h+20>>2]=n;if(!n)break}b=c[47]|0;if(n>>>0>>0)na();c[n+24>>2]=h;a=c[j+16>>2]|0;do if(a)if(a>>>0>>0)na();else{c[n+16>>2]=a;c[a+24>>2]=n;break}while(0);a=c[j+20>>2]|0;if(a)if(a>>>0<(c[47]|0)>>>0)na();else{c[n+20>>2]=a;c[a+24>>2]=n;break}}while(0);if(d>>>0<16){L=d+o|0;c[j+4>>2]=L|3;L=j+L+4|0;c[L>>2]=c[L>>2]|1}else{c[j+4>>2]=o|3;c[i+4>>2]=d|1;c[i+d>>2]=d;a=c[45]|0;if(a){f=c[48]|0;b=a>>>3;e=212+(b<<1<<2)|0;a=c[43]|0;b=1<>2]|0;if(b>>>0<(c[47]|0)>>>0)na();else{p=a;q=b}}else{c[43]=a|b;p=e+8|0;q=e}c[p>>2]=f;c[q+12>>2]=f;c[f+8>>2]=q;c[f+12>>2]=e}c[45]=d;c[48]=i}L=j+8|0;return L|0}}}else if(a>>>0<=4294967231){a=a+11|0;o=a&-8;j=c[44]|0;if(j){d=0-o|0;a=a>>>8;if(a)if(o>>>0>16777215)i=31;else{q=(a+1048320|0)>>>16&8;E=a<>>16&4;E=E<>>16&2;i=14-(p|q|i)+(E<>>15)|0;i=o>>>(i+7|0)&1|i<<1}else i=0;b=c[476+(i<<2)>>2]|0;a:do if(!b){a=0;b=0;E=86}else{f=d;a=0;g=o<<((i|0)==31?0:25-(i>>>1)|0);h=b;b=0;while(1){e=c[h+4>>2]&-8;d=e-o|0;if(d>>>0>>0)if((e|0)==(o|0)){a=h;b=h;E=90;break a}else b=h;else d=f;e=c[h+20>>2]|0;h=c[h+16+(g>>>31<<2)>>2]|0;a=(e|0)==0|(e|0)==(h|0)?a:e;e=(h|0)==0;if(e){E=86;break}else{f=d;g=g<<(e&1^1)}}}while(0);if((E|0)==86){if((a|0)==0&(b|0)==0){a=2<>>12&16;q=q>>>m;l=q>>>5&8;q=q>>>l;n=q>>>2&4;q=q>>>n;p=q>>>1&2;q=q>>>p;a=q>>>1&1;a=c[476+((l|m|n|p|a)+(q>>>a)<<2)>>2]|0}if(!a){i=d;j=b}else E=90}if((E|0)==90)while(1){E=0;q=(c[a+4>>2]&-8)-o|0;e=q>>>0>>0;d=e?q:d;b=e?a:b;e=c[a+16>>2]|0;if(e){a=e;E=90;continue}a=c[a+20>>2]|0;if(!a){i=d;j=b;break}else E=90}if((j|0)!=0?i>>>0<((c[45]|0)-o|0)>>>0:0){f=c[47]|0;if(j>>>0>>0)na();h=j+o|0;if(j>>>0>=h>>>0)na();g=c[j+24>>2]|0;d=c[j+12>>2]|0;do if((d|0)==(j|0)){b=j+20|0;a=c[b>>2]|0;if(!a){b=j+16|0;a=c[b>>2]|0;if(!a){s=0;break}}while(1){d=a+20|0;e=c[d>>2]|0;if(e){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0>>0)na();else{c[b>>2]=0;s=a;break}}else{e=c[j+8>>2]|0;if(e>>>0>>0)na();a=e+12|0;if((c[a>>2]|0)!=(j|0))na();b=d+8|0;if((c[b>>2]|0)==(j|0)){c[a>>2]=d;c[b>>2]=e;s=d;break}else na()}while(0);do if(g){a=c[j+28>>2]|0;b=476+(a<<2)|0;if((j|0)==(c[b>>2]|0)){c[b>>2]=s;if(!s){c[44]=c[44]&~(1<>>0<(c[47]|0)>>>0)na();a=g+16|0;if((c[a>>2]|0)==(j|0))c[a>>2]=s;else c[g+20>>2]=s;if(!s)break}b=c[47]|0;if(s>>>0>>0)na();c[s+24>>2]=g;a=c[j+16>>2]|0;do if(a)if(a>>>0>>0)na();else{c[s+16>>2]=a;c[a+24>>2]=s;break}while(0);a=c[j+20>>2]|0;if(a)if(a>>>0<(c[47]|0)>>>0)na();else{c[s+20>>2]=a;c[a+24>>2]=s;break}}while(0);do if(i>>>0>=16){c[j+4>>2]=o|3;c[h+4>>2]=i|1;c[h+i>>2]=i;a=i>>>3;if(i>>>0<256){d=212+(a<<1<<2)|0;b=c[43]|0;a=1<>2]|0;if(b>>>0<(c[47]|0)>>>0)na();else{u=a;v=b}}else{c[43]=b|a;u=d+8|0;v=d}c[u>>2]=h;c[v+12>>2]=h;c[h+8>>2]=v;c[h+12>>2]=d;break}a=i>>>8;if(a)if(i>>>0>16777215)d=31;else{K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=i>>>(d+7|0)&1|d<<1}else d=0;e=476+(d<<2)|0;c[h+28>>2]=d;a=h+16|0;c[a+4>>2]=0;c[a>>2]=0;a=c[44]|0;b=1<>2]=h;c[h+24>>2]=e;c[h+12>>2]=h;c[h+8>>2]=h;break}f=i<<((d|0)==31?0:25-(d>>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(i|0)){d=a;E=148;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=145;break}else{f=f<<1;a=d}}if((E|0)==145)if(b>>>0<(c[47]|0)>>>0)na();else{c[b>>2]=h;c[h+24>>2]=a;c[h+12>>2]=h;c[h+8>>2]=h;break}else if((E|0)==148){a=d+8|0;b=c[a>>2]|0;L=c[47]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=h;c[a>>2]=h;c[h+8>>2]=b;c[h+12>>2]=d;c[h+24>>2]=0;break}else na()}}else{L=i+o|0;c[j+4>>2]=L|3;L=j+L+4|0;c[L>>2]=c[L>>2]|1}while(0);L=j+8|0;return L|0}}}else o=-1;while(0);d=c[45]|0;if(d>>>0>=o>>>0){a=d-o|0;b=c[48]|0;if(a>>>0>15){L=b+o|0;c[48]=L;c[45]=a;c[L+4>>2]=a|1;c[L+a>>2]=a;c[b+4>>2]=o|3}else{c[45]=0;c[48]=0;c[b+4>>2]=d|3;L=b+d+4|0;c[L>>2]=c[L>>2]|1}L=b+8|0;return L|0}a=c[46]|0;if(a>>>0>o>>>0){J=a-o|0;c[46]=J;L=c[49]|0;K=L+o|0;c[49]=K;c[K+4>>2]=J|1;c[L+4>>2]=o|3;L=L+8|0;return L|0}do if(!(c[161]|0)){a=ja(30)|0;if(!(a+-1&a)){c[163]=a;c[162]=a;c[164]=-1;c[165]=-1;c[166]=0;c[154]=0;c[161]=(pa(0)|0)&-16^1431655768;break}else na()}while(0);h=o+48|0;g=c[163]|0;i=o+47|0;f=g+i|0;g=0-g|0;j=f&g;if(j>>>0<=o>>>0){L=0;return L|0}a=c[153]|0;if((a|0)!=0?(u=c[151]|0,v=u+j|0,v>>>0<=u>>>0|v>>>0>a>>>0):0){L=0;return L|0}b:do if(!(c[154]&4)){a=c[49]|0;c:do if(a){d=620;while(1){b=c[d>>2]|0;if(b>>>0<=a>>>0?(r=d+4|0,(b+(c[r>>2]|0)|0)>>>0>a>>>0):0){e=d;d=r;break}d=c[d+8>>2]|0;if(!d){E=173;break c}}a=f-(c[46]|0)&g;if(a>>>0<2147483647){b=oa(a|0)|0;if((b|0)==((c[e>>2]|0)+(c[d>>2]|0)|0)){if((b|0)!=(-1|0)){h=b;f=a;E=193;break b}}else E=183}}else E=173;while(0);do if((E|0)==173?(t=oa(0)|0,(t|0)!=(-1|0)):0){a=t;b=c[162]|0;d=b+-1|0;if(!(d&a))a=j;else a=j-a+(d+a&0-b)|0;b=c[151]|0;d=b+a|0;if(a>>>0>o>>>0&a>>>0<2147483647){v=c[153]|0;if((v|0)!=0?d>>>0<=b>>>0|d>>>0>v>>>0:0)break;b=oa(a|0)|0;if((b|0)==(t|0)){h=t;f=a;E=193;break b}else E=183}}while(0);d:do if((E|0)==183){d=0-a|0;do if(h>>>0>a>>>0&(a>>>0<2147483647&(b|0)!=(-1|0))?(w=c[163]|0,w=i-a+w&0-w,w>>>0<2147483647):0)if((oa(w|0)|0)==(-1|0)){oa(d|0)|0;break d}else{a=w+a|0;break}while(0);if((b|0)!=(-1|0)){h=b;f=a;E=193;break b}}while(0);c[154]=c[154]|4;E=190}else E=190;while(0);if((((E|0)==190?j>>>0<2147483647:0)?(x=oa(j|0)|0,y=oa(0)|0,x>>>0>>0&((x|0)!=(-1|0)&(y|0)!=(-1|0))):0)?(z=y-x|0,z>>>0>(o+40|0)>>>0):0){h=x;f=z;E=193}if((E|0)==193){a=(c[151]|0)+f|0;c[151]=a;if(a>>>0>(c[152]|0)>>>0)c[152]=a;i=c[49]|0;do if(i){e=620;do{a=c[e>>2]|0;b=e+4|0;d=c[b>>2]|0;if((h|0)==(a+d|0)){A=a;B=b;C=d;D=e;E=203;break}e=c[e+8>>2]|0}while((e|0)!=0);if(((E|0)==203?(c[D+12>>2]&8|0)==0:0)?i>>>0>>0&i>>>0>=A>>>0:0){c[B>>2]=C+f;L=i+8|0;L=(L&7|0)==0?0:0-L&7;K=i+L|0;L=f-L+(c[46]|0)|0;c[49]=K;c[46]=L;c[K+4>>2]=L|1;c[K+L+4>>2]=40;c[50]=c[165];break}a=c[47]|0;if(h>>>0>>0){c[47]=h;j=h}else j=a;d=h+f|0;a=620;while(1){if((c[a>>2]|0)==(d|0)){b=a;E=211;break}a=c[a+8>>2]|0;if(!a){b=620;break}}if((E|0)==211)if(!(c[a+12>>2]&8)){c[b>>2]=h;l=a+4|0;c[l>>2]=(c[l>>2]|0)+f;l=h+8|0;l=h+((l&7|0)==0?0:0-l&7)|0;a=d+8|0;a=d+((a&7|0)==0?0:0-a&7)|0;k=l+o|0;g=a-l-o|0;c[l+4>>2]=o|3;do if((a|0)!=(i|0)){if((a|0)==(c[48]|0)){L=(c[45]|0)+g|0;c[45]=L;c[48]=k;c[k+4>>2]=L|1;c[k+L>>2]=L;break}b=c[a+4>>2]|0;if((b&3|0)==1){i=b&-8;f=b>>>3;e:do if(b>>>0>=256){h=c[a+24>>2]|0;e=c[a+12>>2]|0;do if((e|0)==(a|0)){d=a+16|0;e=d+4|0;b=c[e>>2]|0;if(!b){b=c[d>>2]|0;if(!b){J=0;break}}else d=e;while(1){e=b+20|0;f=c[e>>2]|0;if(f){b=f;d=e;continue}e=b+16|0;f=c[e>>2]|0;if(!f)break;else{b=f;d=e}}if(d>>>0>>0)na();else{c[d>>2]=0;J=b;break}}else{f=c[a+8>>2]|0;if(f>>>0>>0)na();b=f+12|0;if((c[b>>2]|0)!=(a|0))na();d=e+8|0;if((c[d>>2]|0)==(a|0)){c[b>>2]=e;c[d>>2]=f;J=e;break}else na()}while(0);if(!h)break;b=c[a+28>>2]|0;d=476+(b<<2)|0;do if((a|0)!=(c[d>>2]|0)){if(h>>>0<(c[47]|0)>>>0)na();b=h+16|0;if((c[b>>2]|0)==(a|0))c[b>>2]=J;else c[h+20>>2]=J;if(!J)break e}else{c[d>>2]=J;if(J)break;c[44]=c[44]&~(1<>>0>>0)na();c[J+24>>2]=h;b=a+16|0;d=c[b>>2]|0;do if(d)if(d>>>0>>0)na();else{c[J+16>>2]=d;c[d+24>>2]=J;break}while(0);b=c[b+4>>2]|0;if(!b)break;if(b>>>0<(c[47]|0)>>>0)na();else{c[J+20>>2]=b;c[b+24>>2]=J;break}}else{d=c[a+8>>2]|0;e=c[a+12>>2]|0;b=212+(f<<1<<2)|0;do if((d|0)!=(b|0)){if(d>>>0>>0)na();if((c[d+12>>2]|0)==(a|0))break;na()}while(0);if((e|0)==(d|0)){c[43]=c[43]&~(1<>>0>>0)na();b=e+8|0;if((c[b>>2]|0)==(a|0)){G=b;break}na()}while(0);c[d+12>>2]=e;c[G>>2]=d}while(0);a=a+i|0;g=i+g|0}a=a+4|0;c[a>>2]=c[a>>2]&-2;c[k+4>>2]=g|1;c[k+g>>2]=g;a=g>>>3;if(g>>>0<256){d=212+(a<<1<<2)|0;b=c[43]|0;a=1<>2]|0;if(b>>>0>=(c[47]|0)>>>0){K=a;L=b;break}na()}while(0);c[K>>2]=k;c[L+12>>2]=k;c[k+8>>2]=L;c[k+12>>2]=d;break}a=g>>>8;do if(!a)d=0;else{if(g>>>0>16777215){d=31;break}K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=g>>>(d+7|0)&1|d<<1}while(0);e=476+(d<<2)|0;c[k+28>>2]=d;a=k+16|0;c[a+4>>2]=0;c[a>>2]=0;a=c[44]|0;b=1<>2]=k;c[k+24>>2]=e;c[k+12>>2]=k;c[k+8>>2]=k;break}f=g<<((d|0)==31?0:25-(d>>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(g|0)){d=a;E=281;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=278;break}else{f=f<<1;a=d}}if((E|0)==278)if(b>>>0<(c[47]|0)>>>0)na();else{c[b>>2]=k;c[k+24>>2]=a;c[k+12>>2]=k;c[k+8>>2]=k;break}else if((E|0)==281){a=d+8|0;b=c[a>>2]|0;L=c[47]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=k;c[a>>2]=k;c[k+8>>2]=b;c[k+12>>2]=d;c[k+24>>2]=0;break}else na()}}else{L=(c[46]|0)+g|0;c[46]=L;c[49]=k;c[k+4>>2]=L|1}while(0);L=l+8|0;return L|0}else b=620;while(1){a=c[b>>2]|0;if(a>>>0<=i>>>0?(F=a+(c[b+4>>2]|0)|0,F>>>0>i>>>0):0){b=F;break}b=c[b+8>>2]|0}g=b+-47|0;d=g+8|0;d=g+((d&7|0)==0?0:0-d&7)|0;g=i+16|0;d=d>>>0>>0?i:d;a=d+8|0;e=h+8|0;e=(e&7|0)==0?0:0-e&7;L=h+e|0;e=f+-40-e|0;c[49]=L;c[46]=e;c[L+4>>2]=e|1;c[L+e+4>>2]=40;c[50]=c[165];e=d+4|0;c[e>>2]=27;c[a>>2]=c[155];c[a+4>>2]=c[156];c[a+8>>2]=c[157];c[a+12>>2]=c[158];c[155]=h;c[156]=f;c[158]=0;c[157]=a;a=d+24|0;do{a=a+4|0;c[a>>2]=7}while((a+4|0)>>>0>>0);if((d|0)!=(i|0)){h=d-i|0;c[e>>2]=c[e>>2]&-2;c[i+4>>2]=h|1;c[d>>2]=h;a=h>>>3;if(h>>>0<256){d=212+(a<<1<<2)|0;b=c[43]|0;a=1<>2]|0;if(b>>>0<(c[47]|0)>>>0)na();else{H=a;I=b}}else{c[43]=b|a;H=d+8|0;I=d}c[H>>2]=i;c[I+12>>2]=i;c[i+8>>2]=I;c[i+12>>2]=d;break}a=h>>>8;if(a)if(h>>>0>16777215)d=31;else{K=(a+1048320|0)>>>16&8;L=a<>>16&4;L=L<>>16&2;d=14-(J|K|d)+(L<>>15)|0;d=h>>>(d+7|0)&1|d<<1}else d=0;f=476+(d<<2)|0;c[i+28>>2]=d;c[i+20>>2]=0;c[g>>2]=0;a=c[44]|0;b=1<>2]=i;c[i+24>>2]=f;c[i+12>>2]=i;c[i+8>>2]=i;break}e=h<<((d|0)==31?0:25-(d>>>1)|0);a=c[f>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(h|0)){d=a;E=307;break}b=a+16+(e>>>31<<2)|0;d=c[b>>2]|0;if(!d){E=304;break}else{e=e<<1;a=d}}if((E|0)==304)if(b>>>0<(c[47]|0)>>>0)na();else{c[b>>2]=i;c[i+24>>2]=a;c[i+12>>2]=i;c[i+8>>2]=i;break}else if((E|0)==307){a=d+8|0;b=c[a>>2]|0;L=c[47]|0;if(b>>>0>=L>>>0&d>>>0>=L>>>0){c[b+12>>2]=i;c[a>>2]=i;c[i+8>>2]=b;c[i+12>>2]=d;c[i+24>>2]=0;break}else na()}}}else{L=c[47]|0;if((L|0)==0|h>>>0>>0)c[47]=h;c[155]=h;c[156]=f;c[158]=0;c[52]=c[161];c[51]=-1;a=0;do{L=212+(a<<1<<2)|0;c[L+12>>2]=L;c[L+8>>2]=L;a=a+1|0}while((a|0)!=32);L=h+8|0;L=(L&7|0)==0?0:0-L&7;K=h+L|0;L=f+-40-L|0;c[49]=K;c[46]=L;c[K+4>>2]=L|1;c[K+L+4>>2]=40;c[50]=c[165]}while(0);a=c[46]|0;if(a>>>0>o>>>0){J=a-o|0;c[46]=J;L=c[49]|0;K=L+o|0;c[49]=K;c[K+4>>2]=J|1;c[L+4>>2]=o|3;L=L+8|0;return L|0}}c[(Sa()|0)>>2]=12;L=0;return L|0}function cb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;if(!a)return;d=a+-8|0;h=c[47]|0;if(d>>>0>>0)na();a=c[a+-4>>2]|0;b=a&3;if((b|0)==1)na();e=a&-8;m=d+e|0;do if(!(a&1)){a=c[d>>2]|0;if(!b)return;k=d+(0-a)|0;j=a+e|0;if(k>>>0>>0)na();if((k|0)==(c[48]|0)){a=m+4|0;b=c[a>>2]|0;if((b&3|0)!=3){q=k;g=j;break}c[45]=j;c[a>>2]=b&-2;c[k+4>>2]=j|1;c[k+j>>2]=j;return}e=a>>>3;if(a>>>0<256){b=c[k+8>>2]|0;d=c[k+12>>2]|0;a=212+(e<<1<<2)|0;if((b|0)!=(a|0)){if(b>>>0>>0)na();if((c[b+12>>2]|0)!=(k|0))na()}if((d|0)==(b|0)){c[43]=c[43]&~(1<>>0>>0)na();a=d+8|0;if((c[a>>2]|0)==(k|0))f=a;else na()}else f=d+8|0;c[b+12>>2]=d;c[f>>2]=b;q=k;g=j;break}f=c[k+24>>2]|0;d=c[k+12>>2]|0;do if((d|0)==(k|0)){b=k+16|0;d=b+4|0;a=c[d>>2]|0;if(!a){a=c[b>>2]|0;if(!a){i=0;break}}else b=d;while(1){d=a+20|0;e=c[d>>2]|0;if(e){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0>>0)na();else{c[b>>2]=0;i=a;break}}else{e=c[k+8>>2]|0;if(e>>>0>>0)na();a=e+12|0;if((c[a>>2]|0)!=(k|0))na();b=d+8|0;if((c[b>>2]|0)==(k|0)){c[a>>2]=d;c[b>>2]=e;i=d;break}else na()}while(0);if(f){a=c[k+28>>2]|0;b=476+(a<<2)|0;if((k|0)==(c[b>>2]|0)){c[b>>2]=i;if(!i){c[44]=c[44]&~(1<>>0<(c[47]|0)>>>0)na();a=f+16|0;if((c[a>>2]|0)==(k|0))c[a>>2]=i;else c[f+20>>2]=i;if(!i){q=k;g=j;break}}d=c[47]|0;if(i>>>0>>0)na();c[i+24>>2]=f;a=k+16|0;b=c[a>>2]|0;do if(b)if(b>>>0>>0)na();else{c[i+16>>2]=b;c[b+24>>2]=i;break}while(0);a=c[a+4>>2]|0;if(a)if(a>>>0<(c[47]|0)>>>0)na();else{c[i+20>>2]=a;c[a+24>>2]=i;q=k;g=j;break}else{q=k;g=j}}else{q=k;g=j}}else{q=d;g=e}while(0);if(q>>>0>=m>>>0)na();a=m+4|0;b=c[a>>2]|0;if(!(b&1))na();if(!(b&2)){if((m|0)==(c[49]|0)){p=(c[46]|0)+g|0;c[46]=p;c[49]=q;c[q+4>>2]=p|1;if((q|0)!=(c[48]|0))return;c[48]=0;c[45]=0;return}if((m|0)==(c[48]|0)){p=(c[45]|0)+g|0;c[45]=p;c[48]=q;c[q+4>>2]=p|1;c[q+p>>2]=p;return}g=(b&-8)+g|0;e=b>>>3;do if(b>>>0>=256){f=c[m+24>>2]|0;a=c[m+12>>2]|0;do if((a|0)==(m|0)){b=m+16|0;d=b+4|0;a=c[d>>2]|0;if(!a){a=c[b>>2]|0;if(!a){n=0;break}}else b=d;while(1){d=a+20|0;e=c[d>>2]|0;if(e){a=e;b=d;continue}d=a+16|0;e=c[d>>2]|0;if(!e)break;else{a=e;b=d}}if(b>>>0<(c[47]|0)>>>0)na();else{c[b>>2]=0;n=a;break}}else{b=c[m+8>>2]|0;if(b>>>0<(c[47]|0)>>>0)na();d=b+12|0;if((c[d>>2]|0)!=(m|0))na();e=a+8|0;if((c[e>>2]|0)==(m|0)){c[d>>2]=a;c[e>>2]=b;n=a;break}else na()}while(0);if(f){a=c[m+28>>2]|0;b=476+(a<<2)|0;if((m|0)==(c[b>>2]|0)){c[b>>2]=n;if(!n){c[44]=c[44]&~(1<>>0<(c[47]|0)>>>0)na();a=f+16|0;if((c[a>>2]|0)==(m|0))c[a>>2]=n;else c[f+20>>2]=n;if(!n)break}d=c[47]|0;if(n>>>0>>0)na();c[n+24>>2]=f;a=m+16|0;b=c[a>>2]|0;do if(b)if(b>>>0>>0)na();else{c[n+16>>2]=b;c[b+24>>2]=n;break}while(0);a=c[a+4>>2]|0;if(a)if(a>>>0<(c[47]|0)>>>0)na();else{c[n+20>>2]=a;c[a+24>>2]=n;break}}}else{b=c[m+8>>2]|0;d=c[m+12>>2]|0;a=212+(e<<1<<2)|0;if((b|0)!=(a|0)){if(b>>>0<(c[47]|0)>>>0)na();if((c[b+12>>2]|0)!=(m|0))na()}if((d|0)==(b|0)){c[43]=c[43]&~(1<>>0<(c[47]|0)>>>0)na();a=d+8|0;if((c[a>>2]|0)==(m|0))l=a;else na()}else l=d+8|0;c[b+12>>2]=d;c[l>>2]=b}while(0);c[q+4>>2]=g|1;c[q+g>>2]=g;if((q|0)==(c[48]|0)){c[45]=g;return}}else{c[a>>2]=b&-2;c[q+4>>2]=g|1;c[q+g>>2]=g}a=g>>>3;if(g>>>0<256){d=212+(a<<1<<2)|0;b=c[43]|0;a=1<>2]|0;if(b>>>0<(c[47]|0)>>>0)na();else{o=a;p=b}}else{c[43]=b|a;o=d+8|0;p=d}c[o>>2]=q;c[p+12>>2]=q;c[q+8>>2]=p;c[q+12>>2]=d;return}a=g>>>8;if(a)if(g>>>0>16777215)d=31;else{o=(a+1048320|0)>>>16&8;p=a<>>16&4;p=p<>>16&2;d=14-(n|o|d)+(p<>>15)|0;d=g>>>(d+7|0)&1|d<<1}else d=0;e=476+(d<<2)|0;c[q+28>>2]=d;c[q+20>>2]=0;c[q+16>>2]=0;a=c[44]|0;b=1<>>1)|0);a=c[e>>2]|0;while(1){if((c[a+4>>2]&-8|0)==(g|0)){d=a;e=130;break}b=a+16+(f>>>31<<2)|0;d=c[b>>2]|0;if(!d){e=127;break}else{f=f<<1;a=d}}if((e|0)==127)if(b>>>0<(c[47]|0)>>>0)na();else{c[b>>2]=q;c[q+24>>2]=a;c[q+12>>2]=q;c[q+8>>2]=q;break}else if((e|0)==130){a=d+8|0;b=c[a>>2]|0;p=c[47]|0;if(b>>>0>=p>>>0&d>>>0>=p>>>0){c[b+12>>2]=q;c[a>>2]=q;c[q+8>>2]=b;c[q+12>>2]=d;c[q+24>>2]=0;break}else na()}}else{c[44]=a|b;c[e>>2]=q;c[q+24>>2]=e;c[q+12>>2]=q;c[q+8>>2]=q}while(0);q=(c[51]|0)+-1|0;c[51]=q;if(!q)a=628;else return;while(1){a=c[a>>2]|0;if(!a)break;else a=a+8|0}c[51]=-1;return}function db(){}function eb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;h=b&3;i=d|d<<8|d<<16|d<<24;g=f&~3;if(h){h=b+4-h|0;while((b|0)<(h|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(g|0)){c[b>>2]=i;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function fb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return ra(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function gb(a,b){a=a|0;b=b|0;return ya[a&1](b|0)|0}function hb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return za[a&3](b|0,c|0,d|0)|0}function ib(a,b){a=a|0;b=b|0;Aa[a&1](b|0)}function jb(a){a=a|0;aa(0);return 0}function kb(a,b,c){a=a|0;b=b|0;c=c|0;aa(1);return 0}function lb(a){a=a|0;aa(2)} - -// EMSCRIPTEN_END_FUNCS -var ya=[jb,Va];var za=[kb,Ua,Xa,kb];var Aa=[lb,ab];return{_malloc:bb,_free:cb,_kiss_fftr_alloc:Pa,_kiss_fftri:Ra,_kiss_fftr_free:Oa,_kiss_fft_alloc:La,_memset:eb,_kiss_fftr:Qa,_kiss_fft:Na,_memcpy:fb,_kiss_fft_free:Ka,runPostSets:db,stackAlloc:Ba,stackSave:Ca,stackRestore:Da,establishStackSpace:Ea,setThrew:Fa,setTempRet0:Ia,getTempRet0:Ja,dynCall_ii:gb,dynCall_iiii:hb,dynCall_vi:ib}}) - - -// EMSCRIPTEN_END_ASM -(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _kiss_fftr=Module["_kiss_fftr"]=asm["_kiss_fftr"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _kiss_fftr_alloc=Module["_kiss_fftr_alloc"]=asm["_kiss_fftr_alloc"];var _kiss_fftr_free=Module["_kiss_fftr_free"]=asm["_kiss_fftr_free"];var _kiss_fftri=Module["_kiss_fftri"]=asm["_kiss_fftri"];var _kiss_fft_alloc=Module["_kiss_fft_alloc"]=asm["_kiss_fft_alloc"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _kiss_fft=Module["_kiss_fft"]=asm["_kiss_fft"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _kiss_fft_free=Module["_kiss_fft_free"]=asm["_kiss_fft_free"];var dynCall_ii=Module["dynCall_ii"]=asm["dynCall_ii"];var dynCall_iiii=Module["dynCall_iiii"]=asm["dynCall_iiii"];var dynCall_vi=Module["dynCall_vi"]=asm["dynCall_vi"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"]){shouldRunNow=false}run() - - - return Module; -}; - -if(typeof module != "undefined") - module.exports = KissFFTModule; diff --git a/func/utils/reisert-unring-ddd43da65219/javascript/kissFFT_main.js b/func/utils/reisert-unring-ddd43da65219/javascript/kissFFT_main.js deleted file mode 100644 index a9c3d68..0000000 --- a/func/utils/reisert-unring-ddd43da65219/javascript/kissFFT_main.js +++ /dev/null @@ -1,118 +0,0 @@ -"use strict"; -if (typeof module != "undefined") -{ - var KissFFTModule = require('./kissFFT.js'); -} - -var kissFFTModule = KissFFTModule({}); - -var kiss_fftr_alloc = kissFFTModule.cwrap( - 'kiss_fftr_alloc', 'number', ['number', 'number', 'number', 'number' ] -); - -var kiss_fftr = kissFFTModule.cwrap( - 'kiss_fftr', 'void', ['number', 'number', 'number' ] -); - -var kiss_fftri = kissFFTModule.cwrap( - 'kiss_fftri', 'void', ['number', 'number', 'number' ] -); - -var kiss_fftr_free = kissFFTModule.cwrap( - 'kiss_fftr_free', 'void', ['number'] -); - -var kiss_fft_alloc = kissFFTModule.cwrap( - 'kiss_fft_alloc', 'number', ['number', 'number', 'number', 'number' ] -); - -var kiss_fft = kissFFTModule.cwrap( - 'kiss_fft', 'void', ['number', 'number', 'number' ] -); - -var kiss_fft_free = kissFFTModule.cwrap( - 'kiss_fft_free', 'void', ['number'] -); - -var FFT = function (size) { - - this.size = size; - this.fcfg = kiss_fft_alloc(size, false); - this.icfg = kiss_fft_alloc(size, true); - - this.inptr = kissFFTModule._malloc(size*8 + size*8); - this.outptr = this.inptr + size*8; - - this.cin = new Float32Array(kissFFTModule.HEAPU8.buffer, this.inptr, size*2); - this.cout = new Float32Array(kissFFTModule.HEAPU8.buffer, this.outptr, size*2); - - this.forward = function(cin) { - this.cin.set(cin); - kiss_fft(this.fcfg, this.inptr, this.outptr); - return new Float32Array(kissFFTModule.HEAPU8.buffer, - this.outptr, this.size * 2); - }; - - this.inverse = function(cpx) { - this.cin.set(cpx); - kiss_fft(this.icfg, this.inptr, this.outptr); - return new Float32Array(kissFFTModule.HEAPU8.buffer, - this.outptr, this.size * 2); - }; - - this.dispose = function() { - kissFFTModule._free(this.inptr); - kiss_fft_free(this.fcfg); - kiss_fft_free(this.icfg); - } -}; - -var FFTR = function (size) { - - this.size = size; - this.fcfg = kiss_fftr_alloc(size, false); - this.icfg = kiss_fftr_alloc(size, true); - - this.rptr = kissFFTModule._malloc(size*4 + (size+2)*4); - this.cptr = this.rptr + size*4; - - this.ri = new Float32Array(kissFFTModule.HEAPU8.buffer, this.rptr, size); - this.ci = new Float32Array(kissFFTModule.HEAPU8.buffer, this.cptr, size+2); - - this.forward = function(real) { - this.ri.set(real); - kiss_fftr(this.fcfg, this.rptr, this.cptr); - return new Float32Array(kissFFTModule.HEAPU8.buffer, - this.cptr, this.size + 2); - }; - - this.inverse = function(cpx) { - this.ci.set(cpx); - kiss_fftri(this.icfg, this.cptr, this.rptr); - return new Float32Array(kissFFTModule.HEAPU8.buffer, - this.rptr, this.size); - }; - - this.dispose = function() { - kissFFTModule._free(this.rptr); - kiss_fftr_free(this.fcfg); - kiss_fftr_free(this.icfg); - } -}; - -if(typeof module != "undefined") -{ - module.exports = - { - FFT: FFT, - FFTR: FFTR - }; -} -else -{ - var KissFFT = - { - FFT: FFT, - FFTR: FFTR - }; -} \ No newline at end of file diff --git a/func/utils/reisert-unring-ddd43da65219/javascript/kmath.js b/func/utils/reisert-unring-ddd43da65219/javascript/kmath.js deleted file mode 100644 index d479cd0..0000000 --- a/func/utils/reisert-unring-ddd43da65219/javascript/kmath.js +++ /dev/null @@ -1,457 +0,0 @@ - -var clone = function(x) {return JSON.parse(JSON.stringify(x)) } - -var kmath = {} - - -module.exports = kmath; - - -kmath.matrix = function(v) -{ - var data; - var sizes; - if (typeof v[0] == 'number') - { - data = v.slice(0); - sizes = [v.length]; - } - else - { - if (typeof v == 'object' && v._data != undefined) - { - v = clone(v); - return v; - } - - data = []; - sizes = [v.length, v[0].length]; - for (var k = 0 ; k < v.length ;k++) - data[k] = v[k].slice(0); - } - return {_data:data,_size:sizes}; -} - -kmath.Transpose = function(v) -{ - if (v._data == undefined) - v = kmath.matrix(v); - else - v = clone(v); - - if (v._size.length == 1) - { - v._size = [1,v._size[0]]; - v._data = [v._data]; - } - - var n = {_data:[],_size:[v._size[1],v._size[0]]} - for (var k = 0; k< n._size[0];k++) - { - n._data[k] = []; - for (var j = 0; j< n._size[1];j++) - { - n._data[k][j] = v._data[j][k]; - } - } - return n; - -} -kmath.transpose = kmath.Transpose; - - -kmath.diag = function(v) -{ - - var n = v.length; - var data = []; - for (var i = 0; i < n; i++) - { - data[i] = []; - for (var j = 0; j < n; j++) - data[i][j] = 0; - } - for (var i = 0; i < n; i++) - data[i][i] = v[i]; - - return kmath.matrix(data); -} - -kmath.inv = function(M) -{ - M = kmath.matrix(M); - var E = kmath.eye(M._size[0]); - for (var k = 0; k < E._size[0];k++) - { - E._data[k] = kmath.mdiv(M,kmath.matrix(E._data[k]))._data; - } - - return kmath.Transpose(E); -} - - -kmath.eye = function(n) -{ - var data = []; - for (var i = 0; i < n; i++) - data[i] = 1; - return kmath.diag(data) -} - -kmath.pow = Math.pow; -kmath.abs = Math.abs; -kmath.sqrt = Math.sqrt; -kmath.round = function(x) -{ - if (Array.isArray(x)) - { - x = x.slice(0); - for (var k = 0; k < x.length;k++) - { - x[k] = Math.round(x[k]); - } - return x; - } - else - return Math.round(x); - -} -kmath.floor = Math.floor; -kmath.ceil = Math.ceil; -kmath.exp = Math.exp; - - -kmath.sign = function(x) { - return (x>=0)?1:-1; } - - -kmath.sum = function(x) -{ - var s = 0; - for (var k = 0;k < x.length;k++) - { - s += x[k]; - } - return s; - -} - - -kmath.maxEV = function(M) -{ - var n = M._data.length; - var v = new Array(n).fill(0); v[0] = 1; - v = kmath.matrix(v); - var old = v; - var ev; - for (var k = 0;k < 20; k++) - { - v = kmath.multiply(M,v); - ev = kmath.normalize(v); - var dif = 0; - for (var j = 0; j < n;j++) - dif += (v._data[j]-old._data[j])*(v._data[j]-old._data[j]); - old = v; - if (dif < 0.00000001) - break; - } - - return {v:v,ev:ev} ; - -} - -kmath.normalize = function (v) -{ - var n = 0; - for (var k = 0; k < v._data.length;k++) - n += v._data[k]*v._data[k]; - n = kmath.sqrt(n); - for (var k = 0; k < v._data.length;k++) - v._data[k] /= n; - return n; -} - - -kmath.norm = function (v) -{ - var n = 0; - for (var k = 0; k < v.length;k++) - { - n += v[k]*v[k]; - } - n = kmath.sqrt(n); - return n; -} - - - -kmath.mdiv = function(M,b) -{ - var abs = Math.abs; - M = clone(M); - - var A = M._data; - var y = b._data.slice(0); - - var r = clone(b); - r._data = gauss(A,y); - - return r; - - - function array_fill(i, n, v) { - var a = []; - for (; i < n; i++) { - a.push(v); - } - return a; - } - - function gauss(A, x) { - - var i, k, j; - - // Just make a single matrix - for (i=0; i < A.length; i++) { - A[i].push(x[i]); - } - var n = A.length; - - for (i=0; i < n; i++) { - // Search for maximum in this column - var maxEl = abs(A[i][i]), - maxRow = i; - for (k=i+1; k < n; k++) { - if (abs(A[k][i]) > maxEl) { - maxEl = abs(A[k][i]); - maxRow = k; - } - } - - - // Swap maximum row with current row (column by column) - for (k=i; k < n+1; k++) { - var tmp = A[maxRow][k]; - A[maxRow][k] = A[i][k]; - A[i][k] = tmp; - } - - // Make all rows below this one 0 in current column - for (k=i+1; k < n; k++) { - var c = -A[k][i]/A[i][i]; - for (j=i; j < n+1; j++) { - if (i===j) { - A[k][j] = 0; - } else { - A[k][j] += c * A[i][j]; - } - } - } - } - - // Solve equation Ax=b for an upper triangular matrix A - var z = array_fill(0, n, 0); - for (i=n-1; i > -1; i--) { - z[i] = A[i][n]/A[i][i]; - for (k=i-1; k > -1; k--) { - A[k][n] -= A[k][i] * z[i]; - } - } - - return z; - } -} - -kmath.multiply = function(a,b) -{ - if (Array.isArray(a)) - a = kmath.matrix(a); - if (Array.isArray(b)) - b = kmath.matrix(b); - - if (typeof a == 'number') - { - var r = kmath.matrix(b._data); - if (r._size.length == 1) - for (var k = 0; k < r._size[0];k++) - r._data[k] = r._data[k] * a; - else - { - for (var k = 0; k < r._size[0];k++) - for (var j = 0; j < r._size[1];j++) - r._data[k][j] = r._data[k][j] * a; - } - return r; - } - else if (typeof b == 'number') - return kmath.multiply(b,a); - else - { - var data = []; - var trans = false; - if (b._size.length == 1) - { - b = kmath.Transpose(b); - trans = true; - } - - for (var k=0;k < a._size[0];k++) - { - data[k] = []; - for (var j=0;j < b._size[1];j++) - { - var v = 0; - for (var i = 0; i < a._size[1];i++) - v += a._data[k][i]*b._data[i][j]; - data[k][j] = v; - } - } - - var r = {_data:data,_size:[a._size[0],b._size[1]]}; - if (trans) - { - r = kmath.Transpose(r); - r._data = r._data[0]; - r._size = [r._size[1]]; - return r; - } - else - return r; - - - } - - -} - -kmath.max = function(a,b) -{ - if (b==undefined) - { - if (a._data != undefined) - a = a._data - - var m = a[0] - for (var k = 1; k < a.length; k++) - { - if (mb) - return a; - else - return b; - } -} - - -kmath.min = function(a,b) -{ - if (b==undefined) - { - if (a._data != undefined) - a = a._data - - var m = a[0] - for (var k = 1; k < a.length; k++) - { - if (m>a[k]) - m = a[k]; - } - return m; - } - else - { - if (adim[0] || dim[0]>7) { - littleEndian = !littleEndian - dim[0] = view.getInt16(40, littleEndian) - } - if (1>dim[0] || dim[0]>7) { - // Even if there were other /byte/ orders, we wouldn't be able to detect them using a short (16 bits, so only two bytes). - console.warn("dim[0] is out-of-range, we'll simply try continuing to read the file, but this will most likely fail horribly.") - } - - // Now check header size and magic - var sizeof_hdr = view.getInt32(0, littleEndian) - if (sizeof_hdr !== 348 && (1>dim[0] || dim[0]>7)) { - // Try to recover from weird dim info - littleEndian = !littleEndian - dim[0] = view.getInt16(40, littleEndian) - sizeof_hdr = view.getInt32(0, littleEndian) - if (sizeof_hdr !== 348) { - throw new Error("I'm sorry, but I really cannot determine the byte order of the (NIfTI) file at all.") - } - } else if (sizeof_hdr < 348) { - throw new Error("Header of file is smaller than expected, I cannot deal with this.") - } else if (sizeof_hdr !== 348) { - console.warn("Size of NIfTI header different from what I expect, but I'll try to do my best anyway (might cause trouble).") - } - var magic = String.fromCharCode.apply(null, buf8.subarray(344, 348)) - if (magic !== "ni1\0" && magic !== "n+1\0") { - throw new Error("Sorry, but this does not appear to be a NIfTI-1 file. Maybe Analyze 7.5 format? or NIfTI-2?") - } - - // Continue reading actual header fields - var dim_info = view.getInt8(39) - dim.length = 1+Math.min(7, dim[0]) - for(var i=1; i 352) - { - var extension = view.getInt32(348, littleEndian) // Actually a different format, but this suffices for checking === zero - if (extension !== 0) { - var offs = 352; - var ext = {}; - ext.size = view.getInt32(offs, littleEndian); - ext.code = view.getInt32(offs + 4, littleEndian); - ext.content = ""; - for (var k = 0; k < ext.size-10; k++) - { - var c = view.getUint8(offs + 8 + k); - if (c != 0) - ext.content += String.fromCharCode(c); - } - ret.extension = ext; - if (ext.content.substring(0,10).search("xml")>-1) - { - try - { - ext.content = $.parseXML(ext.content); - console.log('extended nifti header contains XML'); - } - catch(err) - { - console.warn("Looks like there is a corrupt XML within the nifti header.") - } - } - - - } - } - - - - // Check bitpix - - // "Normalize" datatype (so that rgb/complex become several normal floats rather than compound types, possibly also do something about bits) - // Note that there is actually both an rgb datatype and an rgb intent... (My guess is that the datatype corresponds to sizes = [3,dim[0],...], while the intent might correspond to sizes = [dim[0],...,dim[5]=3].) - - // Convert to NRRD-compatible structure - ret.dimension = dim[0] - ret.type = datatype // TODO: Check that we do not feed anything incompatible? - ret.encoding = 'raw' - ret.endian = littleEndian ? 'little' : 'big' - ret.sizes = dim.slice(1) // Note that both NRRD and NIfTI use the convention that the fastest axis comes first! - - if (scl_slope == 0) scl_slope = 1; - - ret.cal_max = cal_max; - ret.cal_min = cal_min; - ret.scl_inter = scl_inter; - ret.scl_slope = scl_slope; - - // this is for convenience use - ret.datascaling = - { - slope:scl_slope, - offset:scl_inter, - id: function() {return (scl_slope==1 & scl_inter==0) }, - e: function(v) { return v*scl_slope+scl_inter }, - ie: function (v) { return (v-scl_inter)/scl_slope } - }; - - - - if (xyzt_units !== undefined) { - ret.spaceUnits = xyzt_units - while(ret.spaceUnits.length < ret.dimension) { // Pad if necessary - ret.spaceUnits.push("") - } - ret.spaceUnits.length = ret.dimension // Shrink if necessary - } - - if (qform_code === 0) { // "method 1" - ret.spacings = pixdim.slice(1) - while(ret.spacings.length < ret.dimension) { - ret.spacings.push(NaN) - } - ret.spaceDimension = Math.min(ret.dimension, 3) // There might be non-3D data sets? (Although the NIfTI format does seem /heavily/ reliant on assuming a 3D space.) - } else if (qform_code > 0) { // "method 2" - // TODO: Figure out exactly what to do with the different qform codes. - ret.space = "right-anterior-superior" // Any method for orientation (except for "method 1") uses this, apparently. - var qfac = pixdim[0] === 0.0 ? 1 : pixdim[0] - var a = Math.sqrt(Math.max(0.0,1.0-(quatern_b*quatern_b+quatern_c*quatern_c+quatern_d*quatern_d))) - var b = quatern_b - var c = quatern_c - var d = quatern_d - ret.spaceDirections = [ - [pixdim[1]*(a*a+b*b-c*c-d*d),pixdim[1]*(2*b*c+2*a*d),pixdim[1]*(2*b*d-2*a*c)], - [pixdim[2]*(2*b*c-2*a*d),pixdim[2]*(a*a+c*c-b*b-d*d),pixdim[2]*(2*c*d+2*a*b)], - [qfac*pixdim[3]*(2*b*d+2*a*c),qfac*pixdim[3]*(2*c*d-2*a*b),qfac*pixdim[3]*(a*a+d*d-c*c-b*b)]] - ret.spaceOrigin = [qoffset_x,qoffset_y,qoffset_z] - } else { - console.warn("Invalid qform_code: " + qform_code + ", orientation is probably messed up.") - } - // TODO: Here we run into trouble, because in NRRD we cannot expose two DIFFERENT (not complementary, different!) transformations. Even more frustrating is that sform transformations are actually more compatible with NRRD than the qform methods. - //console.warn("sform " + sform_code); - // RGB niftis from dcm2nii have sform_code 0, but still have the srow ... so this should always be tried ...? - if (sform_code != 0) - { // "method 3" - ret.space = "right-anterior-superior" // Any method for orientation (except for "method 1") uses this, apparently. - - // Nifit format convention is: row-wise storage of matric (x,x,x offsx, y,y,y, offsy, z,z,z,offsz) - // Therefore, must transpose for column wise storage. - // However, in javascipt array multiplicaton assums row-wise storage. Therefore, edges are created as transposed in MedImageViewer prepare data - ret.spaceDirections = [ - [srow[0*4 + 0],srow[1*4 + 0],srow[2*4 + 0]], - [srow[0*4 + 1],srow[1*4 + 1],srow[2*4 + 1]], - [srow[0*4 + 2],srow[1*4 + 2],srow[2*4 + 2]]] - ret.spaceOrigin = [srow[0*4 + 3],srow[1*4 + 3],srow[2*4 + 3]] - } - else - { - console.warn("sform transformation are currently ignored.") - ret.spaceDirections = [ [1,0,0], [0,1,0], [0,0,1]]; - ret.spaceOrigin = [ 0,0,0]; - } - // TODO: Enforce that spaceDirections and so on have the correct size. - - - // to avoid numerical problems in math.js - // ret.spaceDirections = math.add(math.matrix(ret.spaceDirections),0.000000000001)._data; - - - // TODO: We're still missing an awful lot of info! - - // Read data if it is here - if (magic === "n+1\0") { - if (vox_offset<352 || vox_offset>buffer.byteLength) { - throw new Error("Illegal vox_offset!") - } - - ret.hdroffset = Math.floor(vox_offset); - ret.buffer = buffer; - - - - if (datatype !== 0) { - // TODO: It MIGHT make sense to equate DT_UNKNOWN (0) to 'block', with bitpix giving the block size in bits - ret.data = parseNIfTIRawData(ret.buffer, datatype, dim, {endianFlag: littleEndian},Math.floor(vox_offset)) - } - } - - ret.filetype='nifti'; - - return ret -} - -function parseNIfTIRawData(buffer, type, dim, options,hdroffs) { - var i, arr, view, totalLen = 1, endianFlag = options.endianFlag, endianness = endianFlag ? 'little' : 'big' - for(i=1; i 0) - { - for(var k=0; k < args.length; k+=2) - { - if(args[k].substr(0,2) !="--") - { - console.log("Error parsing input `"+ args[k] +"`. Must be given as [--key value] pair") - - - //process.exit(1); - //return; - } - else - { - if(args[k] =="--help") - { - printhelp(); - //return; - } - params[args[k].substr(2)] = parseInt(args[k+1]); - } - - } - } - else - { - printhelp(); - } - - function printhelp() - { - var nl = "\n\t\t\t "; - var msg = ""; - msg += "Usage: nodejs unring.js"; - msg += " --in "; - msg += (nl + "--out (default: _unring)"); - msg += (nl + "--nshifts x (default: 20)"); - msg += (nl + "--minW x (default: 1)"); - msg += (nl + "--maxW x (default: 3)"); - - msg += (nl + " ===== test / debug params ====="); - msg += (nl + "--maxnumslices x (default: -1)"); - msg += (nl + "--maxnumtimepoints x (default: -1)"); - msg += (nl + "--interleaved x (default: 0)"); - console.log(msg) - return; - } - - if(params.in == undefined) - params.in = 't2zoom_test.nii'; - - if(params.out == undefined) - params.out = params.in.substr(0, params.in.length-3) + "_unring.nii"; - - console.log('Unringing file ... `' + params.in +"`"); - - unring_file(params, function(){} ); - - console.log('Finished. Results written to `' + params.out + '`'); - -} - - - - -////////////////////////////////////////////////// -// command line wrapper (nodejs) -////////////////////////////////////////////////// -function unring_file(params) -{ - var raw = fs.readFileSync(params.in); - raw.buffer = raw.buffer || raw; - var nii = parse(raw.buffer); - - unring_nifti(nii, params) - - fs.writeFileSync(params.out, raw); - -} - - - -////////////////////////////////////////////////// -// main function -////////////////////////////////////////////////// -function unring_nifti(nii, params_in) -{ - var params = {}; - - - // ********** main params - params.nshifts = 20; - params.minW = 1; - params.maxW = 2; - - // ********** debug / test params - params.maxnumslices = -1; - params.maxnumtimepoints = -1; - params.interleaved = false; - - params.whendone = function(){}; - params.onprogress = console.log; - - - - - // *********** extend with the input params - if(params_in !=undefined) - { - for(var p in params) - { - if(params_in[p] != undefined) - if( typeof(params_in[p]) != "function" && typeof params_in[p] != "boolean" ) - params[p] = parseInt( params_in[p] ); - else - params[p] = ( params_in[p] ); - } - } - - - // nifti buffer will be overwritten, so give this function a copy of a nifti, if desired - - var data = nii.data; - var sz = nii.sizes; - - var raw_slice = new Float64Array(sz[0]*sz[1]); - var unrung_slice = new Float64Array(sz[0]*sz[1]*2); - var unrung_int16 = new Int16Array(sz[0]*sz[1]); - - if(sz[3] == undefined) - sz[3] = 1; - - var maxtp = params.maxnumtimepoints==-1?sz[3]:params.maxnumtimepoints; - if(maxtp > sz[3]) - maxtp = sz[3]; - - var maxslices = params.maxnumslices==-1?sz[2]:params.maxnumslices; - if(maxslices > sz[2]) - maxslices = sz[2]; - - // time measure nodejs /javascript - if(typeof performance != "undefined") - { - var gettime = function(){ return performance.now()}; - } - else - { - var gettime = function(){ return new Date().getTime()}; - } - - console.log(" : Parameters: nshifts " + params.nshifts + ", maxW " + params.minW + ", maxW " + params.maxW + ", maxnumslices " + maxslices + ", maxnumtimepoints " + maxtp ); - - //test / debug: unring only each second slice and interleave with original - if(params.interleaved) - { - //**** outermost loop ist timepoint (b-vals for diffusion data) - for( var timepoint=0; timepoint < maxtp; timepoint++) - { - for(var slice = 1; slice < maxslices; slice +=2 ) - { - - var st = gettime(); - var offsetbefore = (slice -1)*sz[0]*sz[1] + timepoint*sz[0]*sz[1]*sz[2]; - var offset = (slice)*sz[0]*sz[1] + timepoint*sz[0]*sz[1]*sz[2]; - - raw_slice = nii.data.slice(offsetbefore, offset + sz[0]*sz[1]); - unring2d(raw_slice,false,unrung_slice,sz, params.nshifts, params.minW, params.maxW); - - //convert unrung data to int16 for output - for(var i = 0; i < unrung_int16.length; i++) - { - nii.data[i+offset] = unrung_slice[2*i] + .5; - } - - var en = gettime(); - - var msg =""; - if(sz[3] > 1) - msg += "Unringing volume " +timepoint + "/" +sz[3] + " | "; - msg += "slice " +slice + "/" +sz[2] + ' in ' + Math.round(en-st) + 'ms.' ; - params.onprogress( msg ); - - }//for slice - }// for time - - } - else // normal mode - { - //**** outermost loop ist timepoint (b-vals for diffusion data) - for( var timepoint=0; timepoint < maxtp; timepoint++) - { - for(var slice = 0; slice < maxslices; slice++) - { - var st = gettime(); - var offset = slice*sz[0]*sz[1] + timepoint*sz[0]*sz[1]*sz[2]; - - //selslice = 4* sz[0]*sz[1]; - - raw_slice = nii.data.slice(offset, offset + sz[0]*sz[1]); - - unring2d(raw_slice,false,unrung_slice,sz, params.nshifts, params.minW, params.maxW); - - //convert unrung data to int16 for output - for(var i = 0; i < unrung_int16.length; i++) - { - nii.data[i+offset] = unrung_slice[2*i] + .5; - } - - var en = gettime(); - - var msg =""; - if(sz[3] > 1) - msg += "Unringing volume " +timepoint + "/" +sz[3] + " | "; - msg += "slice " +slice + "/" +sz[2] + ' in ' + Math.round(en-st) + 'ms.' ; - params.onprogress( msg ); - - }//for slice - }// for time - } - - - // final callback - params.whendone(); - console.log(" Unringing done." ); - - return nii; -} - - - -/* - img_in: 2D image, with possible ringing, stored as 1D Float64Array - img_out: 2D image stored as 1D Float64Array which will store the unrung image - dim: 2-elt array with the dimensions of the input image - nshifts: number of shifts to try - minW: minimum of the shift window - maxW: maximum of the shift window -*/ -function unring2d(img_in, is_cplx, img_out, dim, nshifts, minW,maxW) -{ - - //create the fourier transforms of the image and its transpose - var fac = 2; - if(is_cplx) - { - fac = 1; - } - var img_in_ft = new Float64Array(img_in.length*fac); - var img_in_t_ft = new Float64Array(img_in.length*fac); - - fft_2d(img_in,dim,img_in_ft,is_cplx); - transpose_cplx(img_in_ft,dim,img_in_t_ft); - //(the 2d fft of the transpose of X i the hermitian transpose of the 2d fft of x) - - //create and apply saddle filter - for(var j = 0; j < dim[1]; j++) - { - var cj = (1+Math.cos(2*Math.PI*j/dim[1]))*0.5; - for(var i = 0; i < dim[0]; i++){ - var ci = (1+Math.cos(2*Math.PI*i/dim[0]))*0.5; - var eps = .000000000000001 - var scale = 1/(ci+cj+eps);//the denominator of the filter value, eps to avoid /0 error - img_in_ft[2*(i+j*dim[0])] = img_in_ft[2*(i+j*dim[0])] * cj * scale; - img_in_ft[2*(i+j*dim[0]) + 1] = img_in_ft[2*(i+j*dim[0]) + 1] * cj * scale; - img_in_t_ft[2*(j + i*dim[1])] = img_in_t_ft[2*(j + i*dim[1])] * ci * scale; - img_in_t_ft[2*(j + i*dim[1]) + 1] = img_in_t_ft[2*(j + i*dim[1]) + 1] * ci * scale; - }//for i - }//for j - - //convert the filtered images back to spatial domain - var filt1 = new Float64Array(img_in.length*2); - var filt2 = new Float64Array(img_in.length*2); - ifft_2d(img_in_ft,dim,filt1); - ifft_2d(img_in_t_ft,dim_t,filt2); - - //unring the filtered images - unring1d(filt1,dim[0],dim[1],nshifts,minW,maxW,function(){}); - unring1d(filt2,dim[1],dim[0],nshifts,minW,maxW,function(){}); - - //add the two filtered images together and store them in img_out - for(var i = 0; i < dim[0]; i++) - { - for(var j = 0; j < dim[1]; j++){ - img_out[2*(i+j*dim[0])] = filt1[2*(i+j*dim[0])] + filt2[2*(j + i*dim[1])]; - img_out[2*(i+j*dim[0]) + 1] = filt1[2*(i+j*dim[0]) + 1] + filt2[2*(j + i*dim[1]) + 1]; - } - } -}//unring2d - -/* - transpose a real-valued 2-d image - img: 1-D vector storing the original image - dim: the dimensions of the 2-d image stored in img vector - img_t: 1-D vector that will hold the transposed image -*/ -function transpose_re(img,dim,img_t) -{ - for(var i = 0; i < dim[0]; i++){ - for(var j = 0; j < dim[1]; j++){ - img_t[j+i*dim[1]] = img[i+j*dim[0]]; - } - } -} - -/* - transpose a real-valued 2-d image - img: 1-D vector storing the original image - in the form [real0 imag0 real1 imag1 ... ] - dim: the dimensions of the 2-d image stored in img vector - img_t: 1-D vector that will hold the transposed image -*/ -function transpose_cplx(img,dim,img_t) -{ - for(var i = 0; i < dim[0]; i++) - { - for(var j = 0; j < dim[1]; j++) - { - img_t[2*(j+i*dim[1])] = img[2*(i+j*dim[0])]; - img_t[2*(j+i*dim[1]) + 1] = img[2*(i+j*dim[0]) + 1]; - } - } -} - -/* - insert a source vector into a destination vector - src: the vector to be inserted - dest: the vector that src is inserted into - n: number of elements of src to insert - offset: the position in dest that src is inserted into -*/ -function copy_into(src,dest,n,offset) -{ - for(var i = 0; i < n; i++) - { - dest[offset+i] = src[i]; - } -} - -/* - perform a 2-dimensional fourier transform - img: the image to be transformed, stored as a 1D vector. - can be real or complex, stored as [real0 imag0 real1 imag1 ...] - dim: the dimensions of the 2D image that 'img' represents - img_ft: the vector that will hold the fourier transform of img - is_cplx: boolean flag for type of img -*/ -function fft_2d(img, dim, img_ft, is_cplx) -{ - //create fft objects - //fft0 = new FFT.complex(dim[0],false); - //fft1 = new FFT.complex(dim[1],false); - - var kissFFT0 = new KissFFT.FFT(dim[0]); - var kissFFT1 = new KissFFT.FFT(dim[1]); - - - //create vectors that will store intermediate steps - var frow = new Float64Array(2*dim[0]); - var intermed = new Float64Array(2*dim[0]*dim[1]); - var intermed_t = new Float64Array(2*dim[0]*dim[1]); - var fft_trans = new Float64Array(2*dim[0]*dim[1]); - - - // make image complex if not already, makes it easier, only complex fft - if(!is_cplx) - { - var img2 = new Float64Array(dim[0]*dim[1]*2); - - // not working in all nodejs versions ... so zero fill manually - //img2.fill(0); - for(var k=0; k< img2.length; k++) - img2[k] = 0; - - for(var k=0; k< img.length; k++) - img2[2*k] = img[k]; - img = img2; - var fft_type = 'complex'; - } - - //perform 1D fft on each of the rows of img - var row_len = 2*dim[0]; - for(var i = 0; i < dim[1]; i++) - { - //fft0.simple(frow,img.slice(i*row_len,(i+1)*row_len),fft_type); - frow = kissFFT0.forward(img.slice(i*row_len,(i+1)*row_len)); - copy_into(frow,intermed,2*dim[0],i*2*dim[0]); - } - - //transpose the row transformed array - transpose_cplx(intermed,dim,intermed_t); - - //fft each of the rows (which are columns from the original image) - var col_len = 2*dim[1]; - var fcol = new Float64Array(col_len); - for(var i = 0; i < dim[0]; i++) - { - //fft1.simple(fcol,intermed_t.slice(i*col_len,(i+1)*col_len),'complex'); - fcol = kissFFT1.forward(intermed_t.slice(i*col_len,(i+1)*col_len)); - copy_into(fcol,fft_trans,col_len,i*col_len); - } - - //transpose back to original dimentions - dim_t = new Float64Array([dim[1], dim[0]]); - transpose_cplx(fft_trans,dim_t,img_ft); -} - -//inverse fourier transform -//same as fft_2d but all of the 1D ffts are inverse DFTs -function ifft_2d(kspace, dim, img_space) -{ -// fft0 = new FFT.complex(dim[0],true); -// fft1 = new FFT.complex(dim[1],true); - - var ikissFFT0 = new KissFFT.FFT(dim[0]); - var ikissFFT1 = new KissFFT.FFT(dim[1]); - - //fft each of the rows - var frow = new Float64Array(2*dim[0]); - var intermed = new Float64Array(2*dim[0]*dim[1]); - var intermed_t = new Float64Array(2*dim[0]*dim[1]); - var fft_trans = new Float64Array(2*dim[0]*dim[1]); - - var fft_type = 'complex'; - var row_len = 2*dim[0]; - - for(var i = 0; i < dim[1]; i++) - { - //fft0.simple(frow,kspace.slice(i*row_len,(i+1)*row_len),fft_type); - frow = ikissFFT0.inverse( kspace.slice(i*row_len,(i+1)*row_len) ); - copy_into(frow,intermed,2*dim[0],i*2*dim[0]); - - } - - //transpose the row transformed - transpose_cplx(intermed,dim,intermed_t); - - //fft each of the rows (which are columns from the original image) - var col_len = 2*dim[1]; - var fcol = new Float64Array(col_len); - for(var i = 0; i < dim[0]; i++) - { - //fft1.simple(fcol,intermed_t.slice(i*col_len,(i+1)*col_len),'complex'); - fcol = ikissFFT1.inverse(intermed_t.slice(i*col_len,(i+1)*col_len) ) - copy_into(fcol,fft_trans,col_len,i*col_len); - } - //transpose back to original dimentions - dim_t = new Float64Array([dim[1], dim[0]]); - transpose_cplx(fft_trans,dim_t,img_space); - - //perform scaling - scale = 1/(dim[0]*dim[1]); - for(var i = 0; i < img_space.length; i++) - { - img_space[i] = img_space[i]*scale; - } -} - - - -/* -perform the unringing algorithm on each row of a 2-d array -ARGS: - data - the numlines-by-n image array - n - number of pixels per row - numlines - number of rows to analzye - nshifts - number of subvoxel shift values to try in one direction (total # shifts will be 2*nshifts+1) - minW - min of window - maxW - max of window - callback - callback function -*/ -function unring1d(data, n, numlines, nshifts, minW, maxW, callback) -{ - - - //create the length variables - var totalShifts = 2*nshifts+1; - var totalSamps = 2*n; - - //create the necessary variables -// var fft = new FFT.complex(n,false); -// var ifft = new FFT.complex(n,true); - - var kissFFT = new KissFFT.FFT(totalSamps/2); - var kissFFTi = new KissFFT.FFT(totalSamps/2); - - - //this variable holds the frequencydomain version of a row, so that it can be shifted - var rowFreq = new Float64Array(totalSamps); - var rowFreqShift = new Float64Array(totalSamps); - var rowTimeShift = new Float64Array(totalSamps); - - //these variables hold the rows shifted in time and freq domains - var timeShifts = new Float64Array(totalSamps*totalShifts); - //var freqShifts = new Float64Array(totalSamps*totalShifts); - - //these arrays hold the measure of ringing at successive shifts to the right and leftDiffs - //ringing is measured as the sum of the pairwise differences of adjacent pixels - var rightDiffs = new Float64Array(totalShifts); - var leftDiffs = new Float64Array(totalShifts); - - - //create the shift array - var shifts = new Float64Array(totalShifts); - shifts[0] = 0; - for(var i = 0; i < nshifts; i++) - { - shifts[i+1] = (i+1); - shifts[i+1+nshifts] = 0-(i+1); - } - - //the angle corresponding to a certain linear shift - var phi = new Float64Array(2); - //the angle that increases for each successive frequencz - var ang = new Float64Array(2); - - - //var maxn; - if(n%2 == 1) - { - var maxn = (n-1)/2; - } - else - { - var maxn = n/2-1; - } - - //generate the frequency ramp - var freqRamps = new Float64Array(2*maxn*shifts.length); - var ramplen = 2*maxn; - for(s = 1; s < shifts.length; s++) - { - var p = shifts[s] * Math.PI / (n*nshifts); - phi[0] = Math.cos(p); - phi[1] = Math.sin(p); - ang[0] = 1; - ang[1] = 0; - for(var i =0; i < maxn; i++) - { - var tmp = ang[0]; - ang[0] = phi[0]*ang[0] - phi[1]*ang[1]; - ang[1] = tmp*phi[1] + phi[0]*ang[1]; - freqRamps[s*ramplen + 2*i] = ang[0]; - freqRamps[s*ramplen + 2*i + 1] = ang[1]; - } - } - - - //apply shift in frequency domain, then in time domain - for (var line = 0; line < numlines; line++) - { - var line_idx = line*totalSamps; - - var currentline = data.slice(line_idx,line_idx+totalSamps); - - //DEBUG - //start_time = performance.now(); - for(var i = 0; i < totalSamps; i++) - timeShifts[i] = data[line_idx+i]; - - - - //fft.simple(rowFreq,currentline,'complex'); - rowFreq = kissFFT.forward( currentline );// / totalSamps; - - //shift the frequency data by each value in shifts - //s is shift number - //var angle_scale = Math.PI /(n*nshifts); - // start from 1 -> leave first image untouched - for(var s = 1; s < shifts.length; s++) - { - for(var j = 1; j < rowFreq.length; j++) - rowFreqShift[j] = rowFreq[j]; - - - //set the dc term and nyquist frequency - rowFreqShift[0] = rowFreq[0]; - rowFreqShift[1] = rowFreq[1]; - - //if the Nquist frequency is included, set it to 0 - if(n%2==0) - { - rowFreqShift[n] = 0; - rowFreqShift[ n + 1] = 0; - } - - var tmp; - for(var i =0; i < maxn; i++) - { - var L = (i+1); - var FR = 2*i; - - rowFreqShift[2*L] = freqRamps[s*ramplen + FR]*rowFreq[2*L] - freqRamps[s*ramplen + FR + 1]*rowFreq[2*L+1]; - rowFreqShift[2*L+1] = freqRamps[s*ramplen + FR]*rowFreq[2*L+1] + freqRamps[s*ramplen + FR + 1]*rowFreq[2*L]; - - L = (n-1-i); - rowFreqShift[2*L] = freqRamps[s*ramplen + FR]*rowFreq[2*L] + freqRamps[s*ramplen + FR + 1]*rowFreq[2*L+1]; - rowFreqShift[2*L+1] = freqRamps[s*ramplen + FR]*rowFreq[2*L+1] - freqRamps[s*ramplen + FR + 1]*rowFreq[2*L]; - - }//for i (freq bin to shift) - - - //perform the inverse fft to get signal shifted in time domain - //ifft.simple(rowTimeShift,rowFreqShift,'complex'); - rowTimeShift = kissFFTi.inverse( rowFreqShift ) ; - - //copy the time shifted array into the dictionary of shifted values - for(var i = 0; i < totalSamps; i++) - timeShifts[s*totalSamps + i] = rowTimeShift[i] / n; - - }//for s (shift number) - - - // calc the first pixel. For each following pixel, simple subtract tail and add new head. - // Only two operations instead of a loop - for(var s = 0; s0) - rightDiffs[s] += diff; - else - rightDiffs[s] -=diff; - - - diff = timeShifts[offset + leftIdx1] - timeShifts[offset + leftIdx2]; - if (diff>0) - leftDiffs[s] += diff; - else - leftDiffs[s] -= diff; - - }//for d - - }//for s - - - var oldRight1, oldRight2, oldLeft1, oldLeft2, newRight1, newRight2, newLeft1, newLeft2, diff; - //for each pixel find the minimal ringing measure & shift to that ringing measure - for(var pix = 0; pix < n; pix++) - { - var minDiff = 99999999999; - var minIndex = 0; - - for(var s = 0; s< totalShifts; s++) - { - - var offset = s*totalSamps; - - if (rightDiffs[s] < minDiff) - { - minDiff = rightDiffs[s]; - minIndex = s; - } - if (leftDiffs[s] < minDiff) - { - minDiff = leftDiffs[s]; - minIndex = s; - } - - //get the ringing measure for the successive pixel by removing the distance measure on one end and adding the distance measure on the other end. - oldRight1 = (2*(pix+minW)+totalSamps) % totalSamps; - oldRight2 = (oldRight1 + 2) % totalSamps; - newRight1 = (2*(pix+maxW+1) + totalSamps)% totalSamps; - newRight2 = (newRight1 + 2) % totalSamps; - - oldLeft1 = (2*(pix - maxW) + totalSamps) %totalSamps; - oldLeft2 = (oldLeft1 -2 + totalSamps) %totalSamps; - newLeft1 = (2*(pix-minW+1) + totalSamps) %totalSamps; - newLeft2 = (newLeft1-2 + totalSamps ) %totalSamps; - - diff = timeShifts[offset + oldRight1] - timeShifts[offset + oldRight2]; - if(diff > 0) - rightDiffs[s] -= diff; - else - rightDiffs[s] += diff; - - diff = timeShifts[offset + oldLeft1] - timeShifts[offset + oldLeft2]; - if(diff > 0) - leftDiffs[s] -= diff; - else - leftDiffs[s] += diff; - - diff = timeShifts[offset + newRight1] - timeShifts[offset + newRight2]; - if(diff > 0) - rightDiffs[s] += diff; - else - rightDiffs[s] -= diff; - - diff = timeShifts[offset + newLeft1] - timeShifts[offset + newLeft2]; - if(diff > 0) - leftDiffs[s] += diff; - else - leftDiffs[s] -= diff; - - }//for s - - var sh = shifts[minIndex]/(2*nshifts); - var shift_offset = minIndex*totalSamps; - if(sh>0) - { - var dif0re = timeShifts[shift_offset + (2*(pix - 1) + totalSamps)%totalSamps]; - var dif1re = timeShifts[shift_offset + (2*pix + totalSamps)%totalSamps]; - data[line_idx+2*pix] = (dif1re*(1-sh) + dif0re*sh) ; - } - else - { - var dif1re = timeShifts[shift_offset + (2*pix + totalSamps)%totalSamps]; - var dif2re = timeShifts[shift_offset + (2*(pix + 1) + totalSamps)%totalSamps]; - data[line_idx+2*pix] = (dif1re*(1+sh) - dif2re*sh) ; - } - // remove negative values, (we are at uint16 at the end) - if(data[line_idx+2*pix] < 0) - { - data[line_idx+2*pix] = 0; - } - - - }//for pix - }//for line - -} - -function exportnii(vec,filename) -{ - fs.writeFileSync(filename,vec.toString()); -} diff --git a/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.cpp b/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.cpp deleted file mode 100644 index 44fa8cb..0000000 --- a/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.cpp +++ /dev/null @@ -1,639 +0,0 @@ - -/* - LICENCE - - The Software remains the property of the University Medical Center - Freiburg ("the University"). - - The Software is distributed "AS IS" under this Licence solely for - non-commercial use in the hope that it will be useful, but in order - that the University as a charitable foundation protects its assets for - the benefit of its educational and research purposes, the University - makes clear that no condition is made or to be implied, nor is any - warranty given or to be implied, as to the accuracy of the Software, - or that it will be suitable for any particular purpose or for use - under any specific conditions. Furthermore, the University disclaims - all responsibility for the use which is made of the Software. It - further disclaims any liability for the outcomes arising from using - the Software. - - The Licensee agrees to indemnify the University and hold the - University harmless from and against any and all claims, damages and - liabilities asserted by third parties (including claims for - negligence) which arise directly or indirectly from the use of the - Software or the sale of any products based on the Software. - - No part of the Software may be reproduced, modified, transmitted or - transferred in any form or by any means, electronic or mechanical, - without the express permission of the University. The permission of - the University is not required if the said reproduction, modification, - transmission or transference is done without financial return, the - conditions of this Licence are imposed upon the receiver of the - product, and all original and amended source code is included in any - transmitted product. You may be held legally responsible for any - copyright infringement that is caused or encouraged by your failure to - abide by these terms and conditions. - - You are not permitted under this Licence to use this Software - commercially. Use for which any financial return is received shall be - defined as commercial use, and includes (1) integration of all or part - of the source code or the Software into a product for sale or license - by or on behalf of Licensee to third parties or (2) use of the - Software or any derivative of it for research with the final aim of - developing software products for sale or license to a third party or - (3) use of the Software or any derivative of it for research with the - final aim of developing non-software products for sale or license to a - third party, or (4) use of the Software to provide any service to an - external organisation for which payment is received. */ - - - - -#include -#include -#include -#include -#include -#include - -#include "fftw3.h" - -using namespace std; - -#define PI 3.1416 - - - -void unring_1D(fftw_complex *data,int n, int numlines,int nsh,int minW, int maxW) -{ - - - fftw_complex *in, *out; - fftw_plan p,pinv; - - in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n); - out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n); - p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE); - pinv = fftw_plan_dft_1d(n, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); - - fftw_complex *sh = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n *(2*nsh+1)); - fftw_complex *sh2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * n *(2*nsh+1)); - - - double nfac = 1/double(n); - - int *shifts = (int*) malloc(sizeof(int)*(2*nsh+1)); - shifts[0] = 0; - for (int j = 0; j < nsh;j++) - { - shifts[j+1] = j+1; - shifts[1+nsh+j] = -(j+1); - } - - double TV1arr[2*nsh+1]; - double TV2arr[2*nsh+1]; - - for (int k = 0; k < numlines; k++) - { - - - fftw_execute_dft(p,&(data[n*k]),sh); - - int maxn = (n%2 == 1)? (n-1)/2 : n/2 -1; - - for (int j = 1; j < 2*nsh+1; j++) - { - double phi = PI/double(n) * double(shifts[j])/double(nsh); - fftw_complex u = {cos(phi),sin(phi)}; - fftw_complex e = {1,0}; - - sh[j*n ][0] = sh[0][0]; - sh[j*n ][1] = sh[0][1]; - - if (n%2 == 0) - { - sh[j*n + n/2][0] = 0; - sh[j*n + n/2][1] = 0; - } - - for (int l = 0; l < maxn; l++) - { - - double tmp = e[0]; - e[0] = u[0]*e[0] - u[1]*e[1]; - e[1] = tmp*u[1] + u[0]*e[1]; - - int L ; - L = l+1; - sh[j*n +L][0] = (e[0]*sh[L][0] - e[1]*sh[L][1]); - sh[j*n +L][1] = (e[0]*sh[L][1] + e[1]*sh[L][0]); - L = n-1-l; - sh[j*n +L][0] = (e[0]*sh[L][0] + e[1]*sh[L][1]); - sh[j*n +L][1] = (e[0]*sh[L][1] - e[1]*sh[L][0]); - - } - } - - - for (int j = 0; j < 2*nsh+1; j++) - { - fftw_execute_dft(pinv,&(sh[j*n]),&sh2[j*n]); - } - - for (int j=0;j < 2*nsh+1;j++) - { - TV1arr[j] = 0; - TV2arr[j] = 0; - const int l = 0; - for (int t = minW; t <= maxW;t++) - { - TV1arr[j] += fabs(sh2[j*n + (l-t+n)%n ][0] - sh2[j*n + (l-(t+1)+n)%n ][0]); - TV1arr[j] += fabs(sh2[j*n + (l-t+n)%n ][1] - sh2[j*n + (l-(t+1)+n)%n ][1]); - TV2arr[j] += fabs(sh2[j*n + (l+t+n)%n ][0] - sh2[j*n + (l+(t+1)+n)%n ][0]); - TV2arr[j] += fabs(sh2[j*n + (l+t+n)%n ][1] - sh2[j*n + (l+(t+1)+n)%n ][1]); - } - } - - - - - for(int l=0; l < n; l++) - { - double minTV = 999999999999; - int minidx= 0; - for (int j=0;j < 2*nsh+1;j++) - { - -// double TV1 = 0; -// double TV2 = 0; -// for (int t = minW; t <= maxW;t++) -// { -// TV1 += fabs(sh2[j*n + (l-t)%n ][0] - sh2[j*n + (l-(t+1))%n ][0]); -// TV1 += fabs(sh2[j*n + (l-t)%n ][1] - sh2[j*n + (l-(t+1))%n ][1]); -// TV2 += fabs(sh2[j*n + (l+t)%n ][0] - sh2[j*n + (l+(t+1))%n ][0]); -// TV2 += fabs(sh2[j*n + (l+t)%n ][1] - sh2[j*n + (l+(t+1))%n ][1]); -// -// } -// -// -// if (TV1 < minTV) -// { -// minTV = TV1; -// minidx = j; -// } -// if (TV2 < minTV) -// { -// minTV = TV2; -// minidx = j; -// } - - - if (TV1arr[j] < minTV) - { - minTV = TV1arr[j]; - minidx = j; - } - if (TV2arr[j] < minTV) - { - minTV = TV2arr[j]; - minidx = j; - } - - TV1arr[j] += fabs(sh2[j*n + (l-minW+1+n)%n ][0] - sh2[j*n + (l-(minW)+n)%n ][0]); - TV1arr[j] -= fabs(sh2[j*n + (l-maxW+n)%n ][0] - sh2[j*n + (l-(maxW+1)+n)%n ][0]); - TV2arr[j] += fabs(sh2[j*n + (l+maxW+1+n)%n ][0] - sh2[j*n + (l+(maxW+2)+n)%n ][0]); - TV2arr[j] -= fabs(sh2[j*n + (l+minW+n)%n ][0] - sh2[j*n + (l+(minW+1)+n)%n ][0]); - - TV1arr[j] += fabs(sh2[j*n + (l-minW+1+n)%n ][1] - sh2[j*n + (l-(minW)+n)%n ][1]); - TV1arr[j] -= fabs(sh2[j*n + (l-maxW+n)%n ][1] - sh2[j*n + (l-(maxW+1)+n)%n ][1]); - TV2arr[j] += fabs(sh2[j*n + (l+maxW+1+n)%n ][1] - sh2[j*n + (l+(maxW+2)+n)%n ][1]); - TV2arr[j] -= fabs(sh2[j*n + (l+minW+n)%n ][1] - sh2[j*n + (l+(minW+1)+n)%n ][1]); - - } - - - double a0r = sh2[minidx*n + (l-1+n)%n ][0]; - double a1r = sh2[minidx*n + l][0]; - double a2r = sh2[minidx*n + (l+1+n)%n ][0]; - double a0i = sh2[minidx*n + (l-1+n)%n ][1]; - double a1i = sh2[minidx*n + l][1]; - double a2i = sh2[minidx*n + (l+1+n)%n ][1]; - double s = double(shifts[minidx])/nsh/2; - - //data[k*n + l][0] = (a1r - 0.5*(a2r-a0r)*s + (0.5*(a2r+a0r) - a1r)*s*s)*nfac; - //data[k*n + l][1] = (a1i - 0.5*(a2i-a0i)*s + (0.5*(a2i+a0i) - a1i)*s*s)*nfac; - - - if (s>0) - { - data[k*n + l][0] = (a1r*(1-s) + a0r*s)*nfac; - data[k*n + l][1] = (a1i*(1-s) + a0i*s)*nfac; - } - else - { - s = -s; - data[k*n + l][0] = (a1r*(1-s) + a2r*s)*nfac; - data[k*n + l][1] = (a1i*(1-s) + a2i*s)*nfac; - } - - } - - - - } - - - - free(shifts); - fftw_destroy_plan(p); - fftw_destroy_plan(pinv); - fftw_free(in); - fftw_free(out); - fftw_free(sh); - fftw_free(sh2); - - - - -} - - -void unring_2d(fftw_complex *data1,fftw_complex *tmp2, const int *dim_sz, int nsh, int minW, int maxW) -{ - - - double eps = 0; - fftw_complex *tmp1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - fftw_complex *data2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - - fftw_plan p,pinv,p_tr,pinv_tr; - p = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_FORWARD, FFTW_ESTIMATE); - pinv = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_BACKWARD, FFTW_ESTIMATE); - p_tr = fftw_plan_dft_2d(dim_sz[0],dim_sz[1], data2, tmp2, FFTW_FORWARD, FFTW_ESTIMATE); - pinv_tr = fftw_plan_dft_2d(dim_sz[0],dim_sz[1], data2, tmp2, FFTW_BACKWARD, FFTW_ESTIMATE); - double nfac = 1/double(dim_sz[0]*dim_sz[1]); - - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data2[j*dim_sz[1]+k][0] = data1[k*dim_sz[0]+j][0]; - data2[j*dim_sz[1]+k][1] = data1[k*dim_sz[0]+j][1]; - } - - fftw_execute_dft(p,data1,tmp1); - fftw_execute_dft(p_tr,data2,tmp2); - - for (int k = 0 ; k < dim_sz[1];k++) - { - double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5 +eps; - for (int j = 0 ; j < dim_sz[0];j++) - { - double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5 +eps; - tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] * ck) / (ck+cj); - tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] * ck) / (ck+cj); - tmp2[j*dim_sz[1]+k][0] = nfac*(tmp2[j*dim_sz[1]+k][0] * cj) / (ck+cj); - tmp2[j*dim_sz[1]+k][1] = nfac*(tmp2[j*dim_sz[1]+k][1] * cj) / (ck+cj); - } - } - - fftw_execute_dft(pinv,tmp1,data1); - fftw_execute_dft(pinv_tr,tmp2,data2); - - unring_1D(data1,dim_sz[0],dim_sz[1],nsh,minW,maxW); - unring_1D(data2,dim_sz[1],dim_sz[0],nsh,minW,maxW); - - - fftw_execute_dft(p,data1,tmp1); - fftw_execute_dft(p_tr,data2,tmp2); - - - for (int k = 0 ; k < dim_sz[1];k++) - { - double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5 +eps; - for (int j = 0 ; j < dim_sz[0];j++) - { - double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5 +eps; - tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] + tmp2[j*dim_sz[1]+k][0] ) ; - tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] + tmp2[j*dim_sz[1]+k][1] ) ; - // tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] + tmp2[j*dim_sz[1]+k][0] ) /(ck+cj); - // tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] + tmp2[j*dim_sz[1]+k][1] ) /(ck+cj); -// tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0]*ck + tmp2[j*dim_sz[1]+k][0]*cj ) /(ck+cj); -// tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1]*ck + tmp2[j*dim_sz[1]+k][1]*cj ) /(ck+cj); - } - } - - fftw_execute_dft(pinv,tmp1,tmp2); - - fftw_free(data2); - fftw_free(tmp1); -} - - -/* -void unring_2d(fftw_complex *data1,fftw_complex *tmp2, const int *dim_sz, int nsh) -{ - - fftw_complex *data2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data2[j*dim_sz[1]+k][0] = data1[k*dim_sz[0]+j][0]; - data2[j*dim_sz[1]+k][1] = data1[k*dim_sz[0]+j][1]; - } - - unring_1D(data1,dim_sz[0],dim_sz[1],nsh); - unring_1D(data2,dim_sz[1],dim_sz[0],nsh); - - fftw_complex *tmp1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - - fftw_plan p,pinv,p_tr; - p = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_FORWARD, FFTW_ESTIMATE); - pinv = fftw_plan_dft_2d(dim_sz[1],dim_sz[0], data1, tmp1, FFTW_BACKWARD, FFTW_ESTIMATE); - p_tr = fftw_plan_dft_2d(dim_sz[0],dim_sz[1], data2, tmp2, FFTW_FORWARD, FFTW_ESTIMATE); - - fftw_execute_dft(p,data1,tmp1); - fftw_execute_dft(p_tr,data2,tmp2); - - double nfac = 1/double(dim_sz[0]*dim_sz[1]); - - for (int k = 0 ; k < dim_sz[1];k++) - { - double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5; - for (int j = 0 ; j < dim_sz[0];j++) - { - double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5; - tmp1[k*dim_sz[0]+j][0] = nfac*(tmp1[k*dim_sz[0]+j][0] * ck + tmp2[j*dim_sz[1]+k][0] * cj) /(ck+cj); - tmp1[k*dim_sz[0]+j][1] = nfac*(tmp1[k*dim_sz[0]+j][1] * ck + tmp2[j*dim_sz[1]+k][1] * cj) /(ck+cj); - } - } - - fftw_execute_dft(pinv,tmp1,tmp2); - - fftw_free(data2); - fftw_free(tmp1); -} - -*/ -// -// -// void unring_3d(fftw_complex *data1,fftw_complex *tmp2, const int *dim_sz, int nsh) -// { -// -// fftw_complex *data2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// fftw_complex *data3 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// for (int i = 0 ; i < dim_sz[2];i++) -// for (int k = 0 ; k < dim_sz[1];k++) -// for (int j = 0 ; j < dim_sz[0];j++) -// { -// data2[i*dim_sz[1]*dim_sz[0]+j*dim_sz[1]+k][0] = data1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][0]; -// data2[i*dim_sz[1]*dim_sz[0]+j*dim_sz[1]+k][1] = data1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][1]; -// -// data3[j*dim_sz[1]*dim_sz[2]+k*dim_sz[2]+i][0] = data1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][0]; -// data3[j*dim_sz[1]*dim_sz[2]+k*dim_sz[2]+i][1] = data1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][1]; -// } -// -// unring_1D(data1,dim_sz[0],dim_sz[1]*dim_sz[2],nsh); -// unring_1D(data2,dim_sz[1],dim_sz[0]*dim_sz[2],nsh); -// unring_1D(data3,dim_sz[2],dim_sz[1]*dim_sz[0],nsh); -// -// fftw_complex *tmp1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// fftw_complex *tmp3 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// -// fftw_plan p,pinv,p_tr,p_tr2; -// p = fftw_plan_dft_3d(dim_sz[2],dim_sz[1],dim_sz[0], data1, tmp1, FFTW_FORWARD, FFTW_ESTIMATE); -// p_tr = fftw_plan_dft_3d(dim_sz[2],dim_sz[0],dim_sz[1], data2, tmp2, FFTW_FORWARD, FFTW_ESTIMATE); -// p_tr2 = fftw_plan_dft_3d(dim_sz[0],dim_sz[1],dim_sz[2], data2, tmp2, FFTW_FORWARD, FFTW_ESTIMATE); -// -// pinv = fftw_plan_dft_3d(dim_sz[2],dim_sz[1],dim_sz[0], data1, tmp1, FFTW_BACKWARD, FFTW_ESTIMATE); -// -// fftw_execute_dft(p,data1,tmp1); -// fftw_execute_dft(p_tr,data2,tmp2); -// fftw_execute_dft(p_tr2,data3,tmp3); -// -// for (int i = 0 ; i < dim_sz[2];i++) -// { -// double ci = (1+cos(2*PI*(double(i)/dim_sz[2])))*0.5; -// for (int k = 0 ; k < dim_sz[1];k++) -// { -// double ck = (1+cos(2*PI*(double(k)/dim_sz[1])))*0.5; -// for (int j = 0 ; j < dim_sz[0];j++) -// { -// double cj = (1+cos(2*PI*(double(j)/dim_sz[0])))*0.5; -// tmp1[i*dim_sz[0]*dim_sz[1] + k*dim_sz[0]+j][0] = (tmp1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][0] * (ck*ci) -// + tmp2[ i*dim_sz[1]*dim_sz[0] + j*dim_sz[1] + k][0] * (cj*ci) -// + tmp3[ j*dim_sz[1]*dim_sz[2] + k*dim_sz[2] + i][0] * (cj*ck) ) / (ck*ci + cj*ci + cj*ck); -// tmp1[i*dim_sz[0]*dim_sz[1] + k*dim_sz[0]+j][1] = (tmp1[ i*dim_sz[1]*dim_sz[0] + k*dim_sz[0] + j][1] * (ck*ci) -// + tmp2[ i*dim_sz[1]*dim_sz[0] + j*dim_sz[1] + k][1] * (cj*ci) -// + tmp3[ j*dim_sz[1]*dim_sz[2] + k*dim_sz[2] + i][1] * (cj*ck) ) / (ck*ci + cj*ci + cj*ck); -// } -// } -// } -// fftw_execute_dft(pinv,tmp1,tmp2); -// -// fftw_free(data2); -// fftw_free(data3); -// fftw_free(tmp1); -// fftw_free(tmp3); -// } -// -// -// -// - - - -void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) -{ - -// if(nrhs != 8 && nrhs != 9) { -// -// printf(" wrong usage!!!.\n\n"); -// return; -// } else if(nlhs>4) { -// printf("Too many output arguments\n"); -// return; -// } -// - - int pcnt = 0; - - //////////////////////////// get all the arguments from MATLAB - - const mxArray *Img = prhs[pcnt++]; - const int numdim = mxGetNumberOfDimensions(Img); - const int *dim_sz = mxGetDimensions(Img); - double *data = (double*) mxGetData(Img); - double *data_i = (double*) mxGetImagData(Img); - - const mxArray *Params = prhs[pcnt++]; - double *params = mxGetPr(Params); - - - int nsh = int(params[2]); - int minW = int(params[0]); - int maxW = int(params[1]); - - if (numdim == 2) - { - - fftw_complex *data_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - fftw_complex *res_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]); - if (data_i == 0) - { - plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxREAL); - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data_complex[k*dim_sz[0]+j][0] = data[k*dim_sz[0]+j]; - data_complex[k*dim_sz[0]+j][1] = 0; - } - } - else - { - plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxCOMPLEX); - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data_complex[k*dim_sz[0]+j][0] = data[k*dim_sz[0]+j]; - data_complex[k*dim_sz[0]+j][1] = data_i[k*dim_sz[0]+j]; - } - } - - unring_2d(data_complex,res_complex, dim_sz,nsh,minW,maxW); - - double *res = (double*) mxGetData(plhs[0]); - double *res_i = (double*) mxGetImagData(plhs[0]); - - if (res_i == 0) - { - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - res[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][0]; - } - else - { - for (int k = 0 ; k < dim_sz[1];k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - res[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][0]; - res_i[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][1]; - } - } - - fftw_free(data_complex); - fftw_free(res_complex); - } - else if (numdim >= 3) - { - int prodsz = 1; - for (int k = 2; k < numdim;k++) - prodsz *= dim_sz[k]; - - - fftw_complex *data_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*prodsz); - fftw_complex *res_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*prodsz); - if (data_i == 0) - { - plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxREAL); - for (int k = 0 ; k < dim_sz[1]*prodsz;k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data_complex[k*dim_sz[0]+j][0] = data[k*dim_sz[0]+j]; - data_complex[k*dim_sz[0]+j][1] = 0; - } - } - else - { - plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxCOMPLEX); - for (int k = 0 ; k < dim_sz[1]*prodsz;k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - data_complex[k*dim_sz[0]+j][0] = data[k*dim_sz[0]+j]; - data_complex[k*dim_sz[0]+j][1] = data_i[k*dim_sz[0]+j]; - } - } - - for (int k = 0; k < prodsz; k++) - unring_2d(&(data_complex[k*dim_sz[0]*dim_sz[1]]),&(res_complex[k*dim_sz[0]*dim_sz[1]]), dim_sz,nsh,minW,maxW); - - double *res = (double*) mxGetData(plhs[0]); - double *res_i = (double*) mxGetImagData(plhs[0]); - - if (res_i == 0) - { - for (int k = 0 ; k < dim_sz[1]*prodsz;k++) - for (int j = 0 ; j < dim_sz[0];j++) - res[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][0]; - } - else - { - for (int k = 0 ; k < dim_sz[1]*prodsz;k++) - for (int j = 0 ; j < dim_sz[0];j++) - { - res[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][0]; - res_i[k*dim_sz[0]+j] = res_complex[k*dim_sz[0]+j][1]; - } - } - - fftw_free(data_complex); - fftw_free(res_complex); - } -// else if (numdim == 3) -// { -// -// fftw_complex *data_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// fftw_complex *res_complex = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * dim_sz[0]*dim_sz[1]*dim_sz[2]); -// if (data_i == 0) -// { -// plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxREAL); -// for (int i = 0 ; i < dim_sz[2];i++) -// for (int k = 0 ; k < dim_sz[1];k++) -// for (int j = 0 ; j < dim_sz[0];j++) -// { -// data_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][0] = data[i*dim_sz[0]*dim_sz[1]+k*dim_sz[0]+j]; -// data_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][1] = 0; -// } -// } -// else -// { -// plhs[0] = mxCreateNumericArray(numdim,dim_sz,mxGetClassID(Img),mxCOMPLEX); -// for (int i = 0 ; i < dim_sz[2];i++) -// for (int k = 0 ; k < dim_sz[1];k++) -// for (int j = 0 ; j < dim_sz[0];j++) -// { -// data_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][0] = data[i*dim_sz[0]*dim_sz[1]+k*dim_sz[0]+j]; -// data_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][1] = data_i[i*dim_sz[0]*dim_sz[1]+k*dim_sz[0]+j]; -// } -// } -// -// unring_3d(data_complex,res_complex, dim_sz,nsh); -// -// double *res = (double*) mxGetData(plhs[0]); -// double *res_i = (double*) mxGetImagData(plhs[0]); -// -// if (res_i == 0) -// { -// for (int i = 0 ; i < dim_sz[2];i++) -// for (int k = 0 ; k < dim_sz[1];k++) -// for (int j = 0 ; j < dim_sz[0];j++) -// res[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j] = res_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][0]; -// } -// else -// { -// for (int i = 0 ; i < dim_sz[2];i++) -// for (int k = 0 ; k < dim_sz[1];k++) -// for (int j = 0 ; j < dim_sz[0];j++) -// { -// res[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j] = res_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][0]; -// res_i[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j] = res_complex[i*dim_sz[0]*dim_sz[1]+ k*dim_sz[0]+j][1]; -// } -// } -// -// fftw_free(data_complex); -// fftw_free(res_complex); -// } - - -} - - diff --git a/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.mexa64 b/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.mexa64 deleted file mode 100644 index f89ac0f..0000000 Binary files a/func/utils/reisert-unring-ddd43da65219/matlab/ringRm.mexa64 and /dev/null differ diff --git a/func/utils/reisert-unring-ddd43da65219/matlab/unring.m b/func/utils/reisert-unring-ddd43da65219/matlab/unring.m deleted file mode 100644 index 0530210..0000000 --- a/func/utils/reisert-unring-ddd43da65219/matlab/unring.m +++ /dev/null @@ -1,19 +0,0 @@ -%%%%%%%% -% -% unring - tool for removal of the Gibbs ringing artefact -% Usage: outvol = unring(invol,params) -% Options: invol - input volume -% params - 3x1 array with [minW maxW nsh] -% nsh discretization of subpixel spaceing (default 20) -% minW left border of window used for TV computation (default 1) -% maxW right border of window used for TV computation (default 3) - - -function v = unring(v,params) - -if nargin == 1, - params = [1 3 20]; -end; - -v = double(v); -v = ringRm(v,params); \ No newline at end of file diff --git a/func/utils/smooth3D.m b/func/utils/smooth3D.m deleted file mode 100644 index f7760e6..0000000 --- a/func/utils/smooth3D.m +++ /dev/null @@ -1,56 +0,0 @@ -function S=smooth3D(X,FWHM,vox) - -% will apply a 3D gaussian smoothing filter to a 3D image, call with -% S=smooth(X,FWFHM,voxdims) -% FWHM is in mm - -%zero fill to required size -dimsorig=size(X); -if length(dimsorig)>=3 - vol=1 -else - vol=0; - if dimsorig(1)==1 - X=repmat(X,[8 1 8]); - end; - if dimsorig(2)==1 - X=repmat(X,[1 8 8]); - end; -end; - - -dim=size(X); -%create gaussian smoothing matrix - -x1=((-dim(1)/2:dim(1)/2-1))*vox(1); -x2=((-dim(2)/2:dim(2)/2-1))*vox(2); -x3=((-dim(3)/2:dim(3)/2-1))*vox(3); - - -[X1,X2,X3]=ndgrid(x1,x2,x3); - -dev=(FWHM/2.35); - -GAUSS=exp(-(X1.^2+X2.^2+X3.^2)/(2*dev^2)); - GAUSS=GAUSS/(sum(abs(GAUSS(:)))); - - -S=zeros(dim); - -S=(ifft3s(bsxfun(@times,fft3s(X),fft3s(GAUSS)))); - - -if length(dimsorig)<3 - if dimsorig(1)==1 - S=S(end/2,:,end/2); - end; - if dimsorig(2)==1 - S=S(:,end/2,end/2); - end; - -end - - - - - diff --git a/func/utils/sos.m b/func/utils/sos.m deleted file mode 100644 index 1d68af8..0000000 --- a/func/utils/sos.m +++ /dev/null @@ -1,18 +0,0 @@ -function res = sos(x ,dim, pnorm) -% res = sos(x [,dim, pnorm]) -% -% function computes the square root of sum of squares along dimension dim. -% If dim is not specified, it computes it along the last dimension. -% -% (c) Michael Lustig 2009 - -if nargin < 2 - dim = size(size(x),2); -end - -if nargin < 3 - pnorm = 2; -end - - -res = (sum(abs(x.^pnorm),dim)).^(1/pnorm); diff --git a/func/utils/subplot1.m b/func/utils/subplot1.m deleted file mode 100644 index e839db6..0000000 --- a/func/utils/subplot1.m +++ /dev/null @@ -1,228 +0,0 @@ -function subplot1(M,N,varargin); -%------------------------------------------------------------------------- -% subplot1 function An mproved subplot function -% Input : - If more than one input argumenst are given, -% then the first parameter is the number of rows. -% If single input argument is given, then this is the -% subplot-number for which to set focus. -% This could a scalar or two element vector (I,J). -% - Number of columns. -% * variable number of parameters -% (in pairs: ...,Keywoard, Value,...) -% - 'Min' : X, Y lower position of lowest subplot, -% default is [0.10 0.10]. -% - 'Max' : X, Y largest position of highest subplot, -% default is [0.95 0.95]. -% - 'Gap' : X,Y gaps between subplots, -% default is [0.01 0.01]. -% - 'XTickL' : x ticks labels option, -% 'Margin' : plot only XTickLabels in the -% subplot of the lowest row (default). -% 'All' : plot XTickLabels in all subplots. -% 'None' : don't plot XTickLabels in subplots. -% - 'YTickL' : y ticks labels option, -% 'Margin' : plot only YTickLabels in the -% subplot of the lowest row (defailt). -% 'All' : plot YTickLabels in all subplots. -% 'None' : don't plot YTickLabels in subplots. -% - 'FontS' : axis font size, default is 10. -% 'XScale' : scale of x axis: -% 'linear', default. -% 'log' -% - 'YScale' : scale of y axis: -% 'linear', default. -% 'log' -% Example: subplot1(2,2,'Gap',[0.02 0.02]); -% subplot1(2,3,'Gap',[0.02 0.02],'XTickL','None','YTickL','All','FontS',16); -% See also : subplot1c.m -% Tested : Matlab 5.3 -% By : Eran O. Ofek June 2002 -% URL : http://wise-obs.tau.ac.il/~eran/matlab.html -%------------------------------------------------------------------------- -MinDef = [0.10 0.10]; -MaxDef = [0.95 0.95]; -GapDef = [0.01 0.01]; -XTickLDef = 'Margin'; -YTickLDef = 'Margin'; -FontSDef = 10; -XScaleDef = 'linear'; -YScaleDef = 'linear'; - -% set default parameters -Min = MinDef; -Max = MaxDef; -Gap = GapDef; -XTickL = XTickLDef; -YTickL = YTickLDef; -FontS = FontSDef; -XScale = XScaleDef; -YScale = YScaleDef; - - -MoveFoc = 0; -if (nargin==1), - %--- move focus to subplot # --- - MoveFoc = 1; -elseif (nargin==2), - % do nothing -elseif (nargin>2), - Narg = length(varargin); - if (0.5.*Narg==floor(0.5.*Narg)), - - for I=1:2:Narg-1, - switch varargin{I}, - case 'Min' - Min = varargin{I+1}; - case 'Max' - Max = varargin{I+1}; - case 'Gap' - Gap = varargin{I+1}; - case 'XTickL' - XTickL = varargin{I+1}; - case 'YTickL' - YTickL = varargin{I+1}; - case 'FontS' - FontS = varargin{I+1}; - case 'XScale' - XScale = varargin{I+1}; - case 'YScale' - YScale = varargin{I+1}; - otherwise - error('Unknown keyword'); - end - end - else - error('Optional arguments should given as keyword, value'); - end -else - error('Illegal number of input arguments'); -end - - - - - - - - -switch MoveFoc - case 1 - %--- move focus to subplot # --- - H = get(gcf,'Children'); - Ptot = length(H); - if (length(M)==1), - M = Ptot - M + 1; - elseif (length(M)==2), - %--- check for subplot size --- - Pos1 = get(H(1),'Position'); - Pos1x = Pos1(1); - for Icheck=2:1:Ptot, - PosN = get(H(Icheck),'Position'); - PosNx = PosN(1); - if (PosNx==Pos1x), - NumberOfCol = Icheck - 1; - break; - end - end - NumberOfRow = Ptot./NumberOfCol; - - Row = M(1); - Col = M(2); - - M = (Row-1).*NumberOfCol + Col; - M = Ptot - M + 1; - else - error('Unknown option, undefined subplot index'); - end - - set(gcf,'CurrentAxes',H(M)); - - case 0 - %--- open subplots --- - - Xmin = Min(1); - Ymin = Min(2); - Xmax = Max(1); - Ymax = Max(2); - Xgap = Gap(1); - Ygap = Gap(2); - - - Xsize = (Xmax - Xmin)./N; - Ysize = (Ymax - Ymin)./M; - - Xbox = Xsize - Xgap; - Ybox = Ysize - Ygap; - - - Ptot = M.*N; - - Hgcf = gcf; - clf; - figure(Hgcf); - for Pi=1:1:Ptot, - Row = ceil(Pi./N); - Col = Pi - (Row - 1)*N; - - Xstart = Xmin + Xsize.*(Col - 1); - Ystart = Ymax - Ysize.*Row; - -% subplot(M,N,Pi); -% hold on; - axes('position',[Xstart,Ystart,Xbox,Ybox]); - %set(gca,'position',[Xstart,Ystart,Xbox,Ybox]); - set(gca,'FontSize',FontS); - box on; - hold on; - - switch XTickL - case 'Margin' - if (Row~=M), - %--- erase XTickLabel --- - set(gca,'XTickLabel',[]); - end - case 'All' - % do nothing - case 'None' - set(gca,'XTickLabel',[]); - otherwise - error('Unknown XTickL option'); - end - - switch YTickL - case 'Margin' - if (Col~=1), - %--- erase YTickLabel --- - set(gca,'YTickLabel',[]); - end - case 'All' - % do nothing - case 'None' - set(gca,'YTickLabel',[]); - otherwise - error('Unknown XTickL option'); - end - - switch XScale - case 'linear' - set(gca,'XScale','linear'); - case 'log' - set(gca,'XScale','log'); - otherwise - error('Unknown XScale option'); - end - - switch YScale - case 'linear' - set(gca,'YScale','linear'); - case 'log' - set(gca,'YScale','log'); - otherwise - error('Unknown YScale option'); - end - - end - - otherwise - error('Unknown MoveFoc option'); -end \ No newline at end of file