#include "afni_warp.h"
#define NPER 10
static int nper = NPER ;
int_triple THD_orient_guess( MRI_IMAGE *imm )
{
int nvox , ii , nx,ny,nxy,nz , ix,jy,kz , icm,jcm,kcm , nbar ;
byte *bar , bp,bm ;
float xcm , ycm , zcm , ff , dx,dy,dz ;
float xx,yy,zz ;
int ni,nj,nk , itop,jtop,ktop , im,ip , jm,jp , km,kp ;
float axx,ayy,azz , clip , qx,qy,qz , arr[3] ;
int d_LR , d_AP , d_IS ;
int_triple it = {-1,-1,-1} ;
/*-- check for bad input --*/
if( imm == NULL || imm->nx < 5 || imm->ny < 5 || imm->nz < 5 ) return it ;
nx = imm->nx; ny = imm->ny; nz = imm->nz; nxy = nx*ny; nvox = nx*ny*nz;
dx = fabs(imm->dx) ; if( dx == 0.0 ) dx = 1.0 ;
dy = fabs(imm->dy) ; if( dy == 0.0 ) dy = 1.0 ;
dz = fabs(imm->dz) ; if( dz == 0.0 ) dz = 1.0 ;
/*-- make mask of NPER levels --*/
bar = (byte *) malloc( sizeof(byte) * nvox ) ;
clip = THD_cliplevel( imm , 0.5 ) ;
/* start with a binary mask */
switch( imm->kind ){
case MRI_float:{
float *ar = MRI_FLOAT_PTR(imm) ;
for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip);
}
break ;
case MRI_short:{
short *ar = MRI_SHORT_PTR(imm) ;
for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip);
}
break ;
case MRI_byte:{
byte *ar = MRI_BYTE_PTR(imm) ;
for( ii=0 ; ii < nvox ; ii++ ) bar[ii] = (ar[ii] >= clip);
}
break ;
}
nbar = THD_countmask(nvox,bar) ;
printf("%d voxels in initial binary mask\n",nbar) ;
if( nbar == 0 ){ free(bar); return it; } /* bad */
THD_mask_clust( nx,ny,nz , bar ) ; /* take biggest cluster */
nbar = THD_countmask(nvox,bar) ;
printf("%d voxels in final binary mask\n",nbar) ;
#ifdef NPER
if( nper > 1 ){
float per[NPER+1] ; MRI_IMAGE *qim ; int jj ;
qim = mri_new( nbar , 1 , imm->kind ) ;
switch(imm->kind){
case MRI_float:{
float *ar=MRI_FLOAT_PTR(imm) , *qar=MRI_FLOAT_PTR(qim) ;
for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ;
}
break ;
case MRI_short:{
short *ar=MRI_SHORT_PTR(imm) , *qar=MRI_SHORT_PTR(qim) ;
for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ;
}
break ;
case MRI_byte:{
byte *ar=MRI_BYTE_PTR(imm) , *qar=MRI_BYTE_PTR(qim) ;
for( jj=ii=0 ; ii < nvox ; ii++ ) if( bar[ii] ) qar[jj++] = ar[ii] ;
}
break ;
}
printf("call mri_percents\n") ;
mri_percents( qim , nper , per ) ; /* compute nper break points */
mri_free(qim) ;
printf("per:") ;
for( ii=0 ; ii <= nper ; ii++ ) printf(" %g",per[ii]) ;
printf("\n") ;
switch( imm->kind ){
case MRI_float:{
float *ar = MRI_FLOAT_PTR(imm) , val ;
for( ii=0 ; ii < nvox ; ii++ ){
if( bar[ii] ){
val = ar[ii] ;
for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/
bar[ii] = jj ;
}
}
}
break ;
case MRI_short:{
short *ar = MRI_SHORT_PTR(imm) , val ;
for( ii=0 ; ii < nvox ; ii++ ){
if( bar[ii] ){
val = ar[ii] ;
for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/
bar[ii] = jj ;
}
}
}
break ;
case MRI_byte:{
byte *ar = MRI_BYTE_PTR(imm) , val ;
for( ii=0 ; ii < nvox ; ii++ ){
if( bar[ii] ){
val = ar[ii] ;
for( jj=1 ; jj <= nper && val >= per[jj] ; jj++ ) ; /*spin*/
bar[ii] = jj ;
}
}
}
break ;
}
}
#endif /* NPER */
/* find center of mass of mask */
xcm = ycm = zcm = ff = 0.0 ;
for( ii=0 ; ii < nvox ; ii++ ){
if( bar[ii] ){
ix = (ii % nx) ; xx = ix*dx ; xcm += xx*bar[ii] ;
jy = (ii / nx) % ny ; yy = jy*dy ; ycm += yy*bar[ii] ;
kz = (ii /nxy) ; zz = kz*dz ; zcm += zz*bar[ii] ;
ff += bar[ii] ;
}
}
xcm /= ff ; ycm /= ff ; zcm /= ff ;
icm = rint(xcm/dx) ;
itop = 2*icm ; if( itop >= nx ) itop = nx-1 ;
ni = itop-icm ;
jcm = rint(ycm/dy) ;
jtop = 2*jcm ; if( jtop >= ny ) jtop = ny-1 ;
nj = jtop-jcm ;
kcm = rint(zcm/dz) ;
ktop = 2*kcm ; if( ktop >= nz ) ktop = nz-1 ;
nk = ktop-kcm ;
printf("Mask count = %d\n"
"icm = %d jcm = %d kcm = %d\n"
"ni = %d nj = %d nk = %d\n",
(int)ff , icm,jcm,kcm , ni,nj,nk ) ;
/** compute asymmetry measures about CM voxel **/
#define BAR(i,j,k) bar[(i)+(j)*nx+(k)*nxy]
axx = 0.0 ;
for( ix=1 ; ix <= ni ; ix++ ){
im = icm-ix ; ip = icm+ix ;
for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){
for( jy=jcm-nj ; jy <= jcm+nj ; jy++ )
axx += abs(BAR(ip,jy,kz) - BAR(im,jy,kz)) ;
}
}
axx /= (ni*nj*nk) ; printf("axx = %g\n",axx) ;
ayy = 0.0 ;
for( jy=1 ; jy <= nj ; jy++ ){
jm = jcm-jy ; jp = jcm+jy ;
for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){
for( ix=icm-ni ; ix <= icm+ni ; ix++ )
ayy += abs(BAR(ix,jp,kz) - BAR(ix,jm,kz)) ;
}
}
ayy /= (ni*nj*nk) ; printf("ayy = %g\n",ayy) ;
azz = 0.0 ;
for( kz=1 ; kz <= nk ; kz++ ){
km = kcm-kz ; kp = kcm+kz ;
for( jy=jcm-nj ; jy <= jcm+nj ; jy++ ){
for( ix=icm-ni ; ix <= icm+ni ; ix++ )
azz += abs(BAR(ix,jy,kp) - BAR(ix,jy,km)) ;
}
}
azz /= (ni*nj*nk) ; printf("azz = %g\n",azz) ;
/** least asymettric is L-R direction **/
if( axx < ayy ){
if( axx < azz ) d_LR = 1 ;
else d_LR = 3 ;
} else {
if( ayy < azz ) d_LR = 2 ;
else d_LR = 3 ;
}
printf("axis %d is L-R\n",d_LR) ;
arr[0] = axx ; arr[1] = ayy ; arr[2] = azz ; ff = arr[d_LR-1] ;
arr[0] /= ff ;
arr[1] /= ff ;
arr[2] /= ff ;
printf("a ratios = %g %g %g\n",arr[0],arr[1],arr[2]) ;
/** find asymmetry measures in 1/2 spaces perp to L-R **/
switch( d_LR ){
case 3:{ /* L-R is z-axis */
float axx_jp=0.0, axx_jm=0.0, ayy_ip=0.0, ayy_im=0.0 ;
for( ix=1 ; ix <= ni ; ix++ ){
im = icm-ix ; ip = icm+ix ;
for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){
for( jy=1 ; jy <= nj ; jy++ ){
axx_jp += abs(BAR(ip,jcm+jy,kz) - BAR(im,jcm+jy,kz)) ;
axx_jm += abs(BAR(ip,jcm-jy,kz) - BAR(im,jcm-jy,kz)) ;
}
}
}
for( jy=1 ; jy <= nj ; jy++ ){
jm = jcm-jy ; jp = jcm+jy ;
for( kz=kcm-nk ; kz <= kcm+nk ; kz++ ){
for( ix=1 ; ix <= ni ; ix++ ){
ayy_ip += abs(BAR(icm+ix,jp,kz) - BAR(icm+ix,jm,kz)) ;
ayy_im += abs(BAR(icm-ix,jp,kz) - BAR(icm-ix,jm,kz)) ;
}
}
}
axx_jp /= (ni*nj*nk) ; axx_jm /= (ni*nj*nk) ;
ayy_ip /= (ni*nj*nk) ; ayy_im /= (ni*nj*nk) ;
printf("axx_jp=%g axx_jm=%g ayy_ip=%g ayy_im=%g\n",
axx_jp,axx_jm , ayy_ip,ayy_im ) ;
} /* end of case 3 */
break ;
}
return it ;
}
int main( int argc , char *argv[] )
{
THD_3dim_dataset *dset ;
MRI_IMAGE *im ;
int iarg=1 ;
if( strcmp(argv[1],"-nper") == 0 ){
nper = strtol( argv[2] , NULL , 10 ) ;
iarg = 3 ;
}
for( ; iarg < argc ; iarg++ ){
printf("======= dataset %s nper=%d ========\n",argv[iarg],nper) ;
dset = THD_open_dataset(argv[iarg]) ;
if( dset == NULL ) continue ;
DSET_load(dset) ;
im = DSET_BRICK(dset,0) ;
im->dx = DSET_DX(dset) ;
im->dy = DSET_DY(dset) ;
im->dz = DSET_DZ(dset) ;
(void) THD_orient_guess( im ) ;
printf( "Data Axes Orientation:\n"
" first (x) = %s\n"
" second (y) = %s\n"
" third (z) = %s\n" ,
ORIENT_typestr[dset->daxes->xxorient] ,
ORIENT_typestr[dset->daxes->yyorient] ,
ORIENT_typestr[dset->daxes->zzorient] ) ;
DSET_delete(dset) ;
}
exit(0) ;
}
syntax highlighted by Code2HTML, v. 0.9.1