function invol=intrinsicvol(tet_file, mask_file, mask_thresh) %INTRINSICVOL intrinsic volumes for a non-isotropic field. % % INTRINSICVOL( TET_FILE, MASK_FILE, MASK_THRESH) % % TET_FILE: Tetrehedral mesh file created by mesh_tet - % see help of mesh_tet. % % MASK_FILE: A continuous volume to define the mask. If it has multiple % frames, then the first frame is used. % % MASK_THRESH: Mask is all voxels where MASK_FILE > MASK_THRESH. % % INVOL: Intrinsic volumes for dimensions 0:3. Note that % resels = invol ./ sqrt(4*log(2)).^(0:3) % % For fMRI data, get whitened residuals from fmrilm by which_stats(7)=1, % which will create a file base_wresid.ext (ext = mnc or img). Then: % % mask_mesh(base_wresid.ext, base, mask_file) % mesh_tet(base_mesh.ext, base) % intrinsicvol(base_tet.ext, base_mask.ext, 0.5) d=fmris_read_image(tet_file,0,0); d.dim numslices=d.dim(3); J=d.dim(2); I=d.dim(1); IJ=I*J; % Set up: i=kron(ones(1,J),1:I); j=kron(1:J,ones(1,I)); ex=find(i1); find(i>1)+IJ]'; ey=find(j1); find(j>1)+IJ]'; ez=1:(IJ); ez1=ez; ez2=ez+IJ; exye=find((rem(i+j,2)==0)&(imask_thresh); flip=2; mink=zeros(1,4); for slice=1:numslices slice flip=3-flip; if slicemask_thresh); else mask(:,flip)=zeros(IJ,1); end % Intrinsic volume for points: pc=IJ*(2-flip); pf=(1+pc):(IJ+pc); mink00=sum(mask(pf)); % Intrinsic volume for edges: ec=(3*IJ-2*I-2*J+1)*(2-flip); ef=(1+ec):(6*IJ-3*I-3*J+1+ec); edge=find(mask(edge1(ef)) & mask(edge2(ef)))+ec; mink10=length(edge); mink11=sum(psqrt(lams(node(edge)))); % Intrinsic volume for tringles: tc=2*(IJ-I-J+1)*(2-flip); tf=(1+tc):(10*IJ-8*I-8*J+6+tc); tri=find(mask(tri1(tf)) & mask(tri2(tf)) & mask(tri3(tf)))+tc; l12=lams(spnode(tri1(tri)+2*IJ*(tri2(tri)-1))); l13=lams(spnode(tri1(tri)+2*IJ*(tri3(tri)-1))); l23=lams(spnode(tri2(tri)+2*IJ*(tri3(tri)-1))); mink20=length(tri); mink21=0.5*sum(psqrt([l12 l13 l23])); mink22=sum(psqrt(4*l12.*l13-(l12+l13-l23).^2))/4; % Intrinsic volume for tetrahedra: tet=find(mask(tet1) & mask(tet2) & mask(tet3) & mask(tet4)); l12=lams(spnode(tet1(tet)+2*IJ*(tet2(tet)-1))); l13=lams(spnode(tet1(tet)+2*IJ*(tet3(tet)-1))); l14=lams(spnode(tet1(tet)+2*IJ*(tet4(tet)-1))); l23=lams(spnode(tet2(tet)+2*IJ*(tet3(tet)-1))); l24=lams(spnode(tet2(tet)+2*IJ*(tet4(tet)-1))); l34=lams(spnode(tet3(tet)+2*IJ*(tet4(tet)-1))); d12=4*l12.*l34-(l13+l24-l23-l14).^2; d13=4*l13.*l24-(l12+l34-l23-l14).^2; d14=4*l14.*l23-(l12+l34-l24-l13).^2; a1=4*l24.*l34-(l24+l34-l23).^2; a2=4*l14.*l34-(l14+l34-l13).^2; a3=4*l14.*l24-(l14+l24-l12).^2; a4=4*l13.*l23-(l13+l23-l12).^2; h=(a1<=0)|(a2<=0); delta12=sum(psqrt(l34).*pacos((d12-a1-a2)./psqrt(a1.*a2+h)/2.*(1-h)+h)); h=(a1<=0)|(a3<=0); delta13=sum(psqrt(l24).*pacos((d13-a1-a3)./psqrt(a1.*a3+h)/2.*(1-h)+h)); h=(a1<=0)|(a4<=0); delta14=sum(psqrt(l23).*pacos((d14-a1-a4)./psqrt(a1.*a4+h)/2.*(1-h)+h)); h=(a2<=0)|(a3<=0); delta23=sum(psqrt(l14).*pacos((d14-a2-a3)./psqrt(a2.*a3+h)/2.*(1-h)+h)); h=(a2<=0)|(a4<=0); delta24=sum(psqrt(l13).*pacos((d13-a2-a4)./psqrt(a2.*a4+h)/2.*(1-h)+h)); h=(a3<=0)|(a4<=0); delta34=sum(psqrt(l12).*pacos((d12-a3-a4)./psqrt(a3.*a4+h)/2.*(1-h)+h)); mink30=length(tet); mink31=(delta12+delta13+delta14+delta23+delta24+delta34)/(2*pi); mink32=sum(psqrt(a1)+psqrt(a2)+psqrt(a3)+psqrt(a4))/8; mink33=sum(psqrt((4*a1.*a2-(a1+a2-d12).^2)./ ... (l34+(l34<=0)).*(l34>0)))/48; % Intrinsic volume for mask: mink(1)=mink(1)+mink00-mink10+mink20-mink30; mink(2)=mink(2)+mink11-mink21+mink31; mink(3)=mink(3)+mink22-mink32; mink(4)=mink(4)+mink33; end invol=mink return function y=psqrt(x) y=sqrt(max(x,0)); return function y=pacos(x) y=acos(min(abs(x),1).*sign(x)); return %End