/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
#include "mrilib.h"
#include <string.h>
double DSET_cor( THD_3dim_dataset *, THD_3dim_dataset *, byte *, int , double *) ;
int main( int argc , char * argv[] )
{
double dxy , sxy;
int narg , ndset , nvox , demean=0 , DoDot = 0;
THD_3dim_dataset * xset , * yset , * mask_dset=NULL ;
float mask_bot=666.0 , mask_top=-666.0 ;
byte * mmm=NULL ;
/*-- read command line arguments --*/
if( argc < 3 || strncmp(argv[1],"-help",5) == 0 ){
printf("Usage: 3ddot [options] dset1 dset2\n"
"Output = correlation coefficient between 2 dataset bricks\n"
" - you can use sub-brick selectors on the dsets\n"
" - the result is a number printed to stdout"
"Options:\n"
" -mask mset Means to use the dataset 'mset' as a mask:\n"
" Only voxels with nonzero values in 'mset'\n"
" will be averaged from 'dataset'. Note\n"
" that the mask dataset and the input dataset\n"
" must have the same number of voxels.\n"
" -mrange a b Means to further restrict the voxels from\n"
" 'mset' so that only those mask values\n"
" between 'a' and 'b' (inclusive) will\n"
" be used. If this option is not given,\n"
" all nonzero values from 'mset' are used.\n"
" Note that if a voxel is zero in 'mset', then\n"
" it won't be included, even if a < 0 < b.\n"
" -demean Means to remove the mean from each volume\n"
" prior to computing the correlation.\n"
" -dodot Return the dot product.\n"
) ;
printf("\n" MASTER_SHORTHELP_STRING ) ;
exit(0) ;
}
narg = 1 ;
while( narg < argc && argv[narg][0] == '-' ){
if( strncmp(argv[narg],"-demean",5) == 0 ){
demean++ ;
narg++ ; continue ;
}
if( strncmp(argv[narg],"-dodot",4) == 0 ){
DoDot++ ;
narg++ ; continue ;
}
if( strncmp(argv[narg],"-mask",5) == 0 ){
if( mask_dset != NULL ){
fprintf(stderr,"*** Cannot have two -mask options!\n") ; exit(1) ;
}
if( narg+1 >= argc ){
fprintf(stderr,"*** -mask option requires a following argument!\n");
exit(1) ;
}
mask_dset = THD_open_dataset( argv[++narg] ) ;
if( mask_dset == NULL ){
fprintf(stderr,"*** Cannot open mask dataset!\n") ; exit(1) ;
}
if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex ){
fprintf(stderr,"*** Cannot deal with complex-valued mask dataset!\n");
exit(1) ;
}
narg++ ; continue ;
}
if( strncmp(argv[narg],"-mrange",5) == 0 ){
if( narg+2 >= argc ){
fprintf(stderr,"*** -mrange option requires 2 following arguments!\n")
;
exit(1) ;
}
mask_bot = strtod( argv[++narg] , NULL ) ;
mask_top = strtod( argv[++narg] , NULL ) ;
if( mask_top < mask_top ){
fprintf(stderr,"*** -mrange inputs are illegal!\n") ; exit(1) ;
}
narg++ ; continue ;
}
fprintf(stderr,"*** Unknown option: %s\n",argv[narg]) ; exit(1) ;
}
/* should have at least 2 more arguments */
ndset = argc - narg ;
if( ndset <= 1 ){
fprintf(stderr,"*** No input datasets!?\n") ; exit(1) ;
}
xset = THD_open_dataset( argv[narg++] ) ;
yset = THD_open_dataset( argv[narg++] ) ;
if( xset == NULL || yset == NULL ){
fprintf(stderr,"*** cannot open both input datasets!\n") ; exit(1) ;
}
if( DSET_NUM_TIMES(xset) > 1 || DSET_NUM_TIMES(yset) > 1 ){
fprintf(stderr,"*** cannot use time-dependent datasets!\n") ; exit(1) ;
}
nvox = DSET_NVOX(xset) ;
if( nvox != DSET_NVOX(yset) ){
fprintf(stderr,"*** input datasets dimensions don't match!\n");exit(1);
}
/* make a byte mask from mask dataset */
if( mask_dset != NULL ){
int mcount ;
if( DSET_NVOX(mask_dset) != nvox ){
fprintf(stderr,"*** Input and mask datasets are not same dimensions!\n");
exit(1) ;
}
mmm = THD_makemask( mask_dset , 0 , mask_bot,mask_top ) ;
mcount = THD_countmask( nvox , mmm ) ;
fprintf(stderr,"+++ %d voxels in the mask\n",mcount) ;
if( mcount <= 5 ){
fprintf(stderr,"*** Mask is too small!\n");exit(1);
}
DSET_delete(mask_dset) ;
}
dxy = DSET_cor( xset , yset , mmm , demean, &sxy ) ;
if (DoDot) {
printf("%g\n",dxy*sxy) ;
} else {
printf("%g\n",dxy) ;
}
exit(0) ;
}
double DSET_cor( THD_3dim_dataset *xset,
THD_3dim_dataset *yset, byte *mmm , int dm, double *sxyr)
{
double sumxx , sumyy , sumxy , tx,ty , dxy ;
void * xar , * yar ;
float * fxar , * fyar ;
int ii , nxyz , ivx,ivy , itypx,itypy , fxar_new,fyar_new , nnn ;
nxyz = DSET_NVOX(xset) ;
if (sxyr) *sxyr = 0.0;
/* load bricks */
DSET_load(xset); CHECK_LOAD_ERROR(xset);
ivx = 0 ;
itypx = DSET_BRICK_TYPE(xset,ivx) ;
xar = DSET_ARRAY(xset,ivx) ; if( xar == NULL ) return 0.0 ;
if( itypx == MRI_float ){
fxar = (float *) xar ; fxar_new = 0 ;
} else {
fxar = (float *) malloc( sizeof(float) * nxyz ) ; fxar_new = 1 ;
EDIT_coerce_type( nxyz , itypx,xar , MRI_float,fxar ) ;
PURGE_DSET( xset ) ;
}
DSET_load(yset); CHECK_LOAD_ERROR(yset);
ivy = 0 ;
itypy = DSET_BRICK_TYPE(yset,ivy) ;
yar = DSET_ARRAY(yset,ivy) ; if( yar == NULL ) return 0.0 ;
if( itypy == MRI_float ){
fyar = (float *) yar ; fyar_new = 0 ;
} else {
fyar = (float *) malloc( sizeof(float) * nxyz ) ; fyar_new = 1 ;
EDIT_coerce_type( nxyz , itypy,yar , MRI_float,fyar ) ;
PURGE_DSET( yset ) ;
}
/* 29 Feb 2000: remove mean? */
if( dm ){
sumxx = sumyy = 0.0 ;
for( nnn=ii=0 ; ii < nxyz ; ii++ ){
if( mmm == NULL || mmm[ii] ){
sumxx += fxar[ii] ; sumyy += fyar[ii] ; nnn++ ;
}
}
if( nnn < 5 ) return 0.0 ; /* ERROR */
sumxx /= nnn ; sumyy /= nnn ;
for( ii=0 ; ii < nxyz ; ii++ ){
if( mmm == NULL || mmm[ii] ){
fxar[ii] -= sumxx ; fyar[ii] -= sumyy ;
}
}
}
/* compute sums */
sumxx = sumyy = sumxy = 0.0 ;
for( ii=0 ; ii < nxyz ; ii++ ){
if( mmm == NULL || mmm[ii] ){
tx = fxar[ii] ; ty = fyar[ii] ;
sumxx += tx * tx ;
sumyy += ty * ty ;
sumxy += tx * ty ;
}
}
/* toss trash */
if( fxar_new ) free( fxar ) ;
if( fyar_new ) free( fyar ) ;
/* compute result */
dxy = sumxx * sumyy ; if( dxy <= 0.0 ) return 0.0 ;
if (sxyr) *sxyr = sqrt(dxy);
dxy = sumxy / sqrt(dxy) ;
return dxy ;
}
syntax highlighted by Code2HTML, v. 0.9.1