char * STAVG_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; /* input dataset idcode */ THD_3dim_dataset * old_dset , * new_dset ; /* input and output datasets */ char * new_prefix , * str , * str2; /* strings from user */ int meth; /* chosen computation method */ int new_datum , /* control parameters */ old_datum , ntime ; int te, ne, tinc, kim, nia; int numepochs, minlength, maxlength, lastindex, navgpts; int nvox , perc , new_units, old_units ; int ii, ibot,itop , kk, jj; int no1, user_maxlength, delta; int *pEpochLength, *pTimeIndex; int nx, ny, nz, npix; float *pNumAvg; float old_dtime; MRI_IMAGE * stimim; MRI_IMARR *avgimar; byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ float * fxar = NULL ; /* array loaded from input dataset */ float * stimar = NULL ; float ** fout = NULL ; /* will be array of output floats */ float * tar = NULL ; /* will be array of taper coefficients */ float * nstimar; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ /*--------- go to first input line ---------*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; /* get dataset item */ old_dset = PLUTO_find_dset(idc) ; /* get ptr to dataset */ if( old_dset == NULL ) return "*************************\n" "Cannot find Input Dataset\n" "*************************" ; ntime = DSET_NUM_TIMES(old_dset) ; if( ntime < 2 ) return "*****************************\n" "Dataset has only 1 time point\n" "*****************************" ; ii = DSET_NVALS_PER_TIME(old_dset) ; if( ii > 1 ) return "************************************\n" "Dataset has > 1 value per time point\n" "************************************" ; old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum type */ new_datum = old_datum; old_dtime = DSET_TIMESTEP(old_dset); old_units = DSET_TIMEUNITS(old_dset); nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz; npix = old_dset->daxes->nxx * old_dset->daxes->nyy; nx = old_dset->daxes->nxx; new_prefix = PLUTO_get_string(plint) ; /* get string item (the output prefix) */ if( ! PLUTO_prefix_ok(new_prefix) ) /* check if it is OK */ return "************************\n" "Output Prefix is illegal\n" "************************" ; /*--------- go to next input line ---------*/ PLUTO_next_option(plint); stimim = PLUTO_get_timeseries(plint); if( stimim == NULL ) return "Please specify stimulus timing"; if( stimim->nx < ntime ){ return "**************************************\n" "Not enough pts in stimulus time-series\n" "**************************************"; } stimar = MRI_FLOAT_PTR(stimim); delta = PLUTO_get_number(plint); if( abs(delta) > ntime ){ return "************************\n" "Delta shift is too large\n" "************************"; } /*initialize variables if not user specified */ user_maxlength = ntime; no1 = 0; /*--------- go to next input line ---------*/ PLUTO_next_option(plint); str = PLUTO_get_string(plint) ; /* get string item (the method) */ meth = PLUTO_string_index( str , /* find it in list it is from */ _STAVG_NUM_METHODS , method_strings ) ; /*--------- see if the 4th option line is present --------*/ str = PLUTO_get_optiontag( plint ) ; if( str != NULL ){ user_maxlength = (int) PLUTO_get_number(plint) ; str2 = PLUTO_get_string(plint) ; /* get string item (the method) */ no1 = PLUTO_string_index( str2 , /* find it in list it is from */ 2 , yes_no_strings) ; } /*------------------------------------------------------*/ /*---------- At this point, the inputs are OK ----------*/ PLUTO_popup_meter( plint ) ; /* popup a progress meter */ /*________________[ Main Code ]_________________________*/ fout = avg_epochs( old_dset, stimar, user_maxlength, 1, meth, plint ); if( fout == NULL ) return " \nError in avg_epochs() function!\n " ; if( RMB_DEBUG ) fprintf(stderr, "Done with avg_epochs\n"); maxlength = M_maxlength; /*______________________________________________________*/ new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */ { char * his = PLUTO_commandstring(plint) ; tross_Copy_History( old_dset , new_dset ) ; tross_Append_History( new_dset , his ) ; free( his ) ; } /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , maxlength , /* # sub-bricks */ ADN_ntt , maxlength , /* # time points */ /* ADN_ttorg , old_dtime , */ /* time origin */ /* ADN_ttdel , old_dtime , */ /* time step */ /* ADN_ttdur , old_dtime , */ /* time duration */ /* ADN_nsl , 0 , */ /* z-axis time slicing */ /* ADN_tunits , old_units , */ /* time units */ ADN_none ) ; if( ii != 0 ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return "***********************************\n" "Error while creating output dataset\n" "***********************************" ; } /*------------------------------------------------------------*/ /*------- The output is now in fout[kk][ii], for kk=0..maxlength-1 , ii=0..nvox-1. We must now put this into the output dataset -------*/ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout bricks to the dataset ***/ case MRI_float: for( kk=0 ; kk < maxlength ; kk++ ) EDIT_substitute_brick( new_dset , kk , MRI_float , fout[kk] ) ; break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * bout ; float fac ; for( kk=0 ; kk < maxlength ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ bout = (short *) malloc( sizeof(short) * nvox ) ; if( bout == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_stavg!\n\a") ; return("Final malloc error in plug_stavg!"); ; /* exit(1) ;*/ } /*-- find scaling and then scale --*/ /*fac = MCW_vol_amax( nvox,1,1 , MRI_float , fout[kk] ) ;*/ fac = 1.0; EDIT_coerce_scale_type( nvox,fac , MRI_float,fout[kk] , MRI_short,bout ) ; free( fout[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , kk , MRI_short , bout ) ; } } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * bout ; float fac ; for( kk=0 ; kk < maxlength ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ bout = (byte *) malloc( sizeof(byte) * nvox ) ; if( bout == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_stavg!\n\a") ; return("Final malloc error in plug_stavg!"); ; /* exit(1) ;*/ } /*-- find scaling and then scale --*/ fac = 1.0; EDIT_coerce_scale_type( nvox,fac , MRI_float,fout[kk] , MRI_byte,bout ) ; free( fout[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , kk , MRI_byte , bout ) ; } } break ; } /* end of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ PLUTO_set_meter( plint , 100 ) ; /* set progress meter to 100% */ PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ; FREE_WORKSPACE ; return NULL ; /* null string returned means all was OK */ }
static int * PLUTO_4D_to_nothing (THD_3dim_dataset * old_dset , int ignore , int detrend , generic_func * user_func, void * user_data ) { byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * dtr = NULL ; /* will be array of detrending coeff */ float val , d0fac , d1fac , x0,x1; double tzero=0.0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox ; static int retval; register int kk ; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( user_func == NULL ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ if( nuse < 2 ) return NULL ; DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ ZFREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ ZFREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) ZFREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ ZFREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data ) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( 0.0l,0.0l , nvox , NULL , 0.0l,0.0l , user_data ) ; } #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ /* The info computed here is not being used in this version*/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** Send data to user function ***/ #if 0 user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ; } #endif } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data ) ; #else { void (*uf)(double,double,int,float *,double,double,void *) = (void (*)(double,double,int,float *,double,double,void *))(user_func) ; uf( 0.0l,0.0l, 0 , NULL,0.0l,0.0l, user_data ) ; } #endif /*-------------- Cleanup and go home ----------------*/ ZFREE_WORKSPACE ; retval = 0; return &retval; /* this value is not used for now .... */ }
int main( int argc , char *argv[] ) { THD_3dim_dataset *old_dset , *new_dset ; /* input and output datasets */ THD_3dim_dataset *mask_dset=NULL ; float mask_bot=666.0 , mask_top=-666.0 ; byte *cmask=NULL ; int ncmask=0 ; byte *mmm = NULL ; int mcount=0, verb=0; int nopt, nbriks, ii ; int addBriks = 0 ; /* n-1 sub-bricks out */ int fullBriks = 0 ; /* n sub-bricks out */ int tsout = 0 ; /* flag to output a time series (not a stat bucket) */ int numMultBriks,methIndex,brikIndex; /*----- Help the pitiful user? -----*/ /* bureaucracy */ mainENTRY("3dTstat main"); machdep(); AFNI_logger("3dTstat",argc,argv); PRINT_VERSION("3dTstat"); AUTHOR("KR Hammett & RW Cox"); /*--- scan command line for options ---*/ if (argc == 1) { usage_3dTstat(1); exit(0); } /* Bob's help shortcut */ nopt = 1 ; nbriks = 0 ; nmeths = 0 ; verb = 0; while( nopt < argc && argv[nopt][0] == '-' ){ if (strcmp(argv[nopt], "-h") == 0 || strcmp(argv[nopt], "-help") == 0) { usage_3dTstat(strlen(argv[nopt]) > 3 ? 2:1); exit(0); } if( strcmp(argv[nopt],"-verb") == 0 ){ verb++ ; nopt++ ; continue ; } /*-- methods --*/ if( strcasecmp(argv[nopt],"-centromean") == 0 ){ /* 01 Nov 2010 */ meth[nmeths++] = METH_CENTROMEAN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-bmv") == 0 ){ meth[nmeths++] = METH_BMV ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-median") == 0 ){ meth[nmeths++] = METH_MEDIAN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-nzmedian") == 0 ){ meth[nmeths++] = METH_NZMEDIAN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-DW") == 0 ){ meth[nmeths++] = METH_DW ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-zcount") == 0 ){ meth[nmeths++] = METH_ZCOUNT ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-nzcount") == 0 ){ meth[nmeths++] = METH_NZCOUNT ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-MAD") == 0 ){ meth[nmeths++] = METH_MAD ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-mean") == 0 ){ meth[nmeths++] = METH_MEAN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-sum") == 0 ){ meth[nmeths++] = METH_SUM ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-sos") == 0 ){ meth[nmeths++] = METH_SUM_SQUARES ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-abssum") == 0 ){ meth[nmeths++] = METH_ABSSUM ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-slope") == 0 ){ meth[nmeths++] = METH_SLOPE ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-stdev") == 0 || strcasecmp(argv[nopt],"-sigma") == 0 ){ meth[nmeths++] = METH_SIGMA ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-cvar") == 0 ){ meth[nmeths++] = METH_CVAR ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-cvarinv") == 0 ){ meth[nmeths++] = METH_CVARINV ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-stdevNOD") == 0 || strcasecmp(argv[nopt],"-sigmaNOD") == 0 ){ /* 07 Dec 2001 */ meth[nmeths++] = METH_SIGMA_NOD ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-cvarNOD") == 0 ){ /* 07 Dec 2001 */ meth[nmeths++] = METH_CVAR_NOD ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-cvarinvNOD") == 0 ){ meth[nmeths++] = METH_CVARINVNOD ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-min") == 0 ){ meth[nmeths++] = METH_MIN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-max") == 0 ){ meth[nmeths++] = METH_MAX ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-absmax") == 0 ){ meth[nmeths++] = METH_ABSMAX ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-signed_absmax") == 0 ){ meth[nmeths++] = METH_SIGNED_ABSMAX ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argmin") == 0 ){ meth[nmeths++] = METH_ARGMIN ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argmin1") == 0 ){ meth[nmeths++] = METH_ARGMIN1 ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argmax") == 0 ){ meth[nmeths++] = METH_ARGMAX ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argmax1") == 0 ){ meth[nmeths++] = METH_ARGMAX1 ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argabsmax") == 0 ){ meth[nmeths++] = METH_ARGABSMAX ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-argabsmax1") == 0 ){ meth[nmeths++] = METH_ARGABSMAX1; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-duration") == 0 ){ meth[nmeths++] = METH_DURATION ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-onset") == 0 ){ meth[nmeths++] = METH_ONSET ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-offset") == 0 ){ meth[nmeths++] = METH_OFFSET ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-centroid") == 0 ){ meth[nmeths++] = METH_CENTROID ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-centduration") == 0 ){ meth[nmeths++] = METH_CENTDURATION ; nbriks++ ; nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-nzmean") == 0 ){ meth[nmeths++] = METH_NZMEAN ; nbriks++ ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-mask",5) == 0 ){ if( mask_dset != NULL ) ERROR_exit("Cannot have two -mask options!\n") ; if( nopt+1 >= argc ) ERROR_exit("-mask option requires a following argument!\n"); mask_dset = THD_open_dataset( argv[++nopt] ) ; if( mask_dset == NULL ) ERROR_exit("Cannot open mask dataset!\n") ; if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex ) ERROR_exit("Cannot deal with complex-valued mask dataset!\n"); nopt++ ; continue ; } if( strncmp(argv[nopt],"-mrange",5) == 0 ){ if( nopt+2 >= argc ) ERROR_exit("-mrange option requires 2 following arguments!\n"); mask_bot = strtod( argv[++nopt] , NULL ) ; mask_top = strtod( argv[++nopt] , NULL ) ; if( mask_top < mask_top ) ERROR_exit("-mrange inputs are illegal!\n") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-cmask") == 0 ){ /* 16 Mar 2000 */ if( nopt+1 >= argc ) ERROR_exit("-cmask option requires a following argument!\n"); cmask = EDT_calcmask( argv[++nopt] , &ncmask, 0 ) ; if( cmask == NULL ) ERROR_exit("Can't compute -cmask!\n"); nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-autocorr") == 0 ){ meth[nmeths++] = METH_AUTOCORR ; if( ++nopt >= argc ) ERROR_exit("-autocorr needs an argument!\n"); meth[nmeths++] = atoi(argv[nopt++]); if (meth[nmeths - 1] == 0) { addBriks++; } else { nbriks+=meth[nmeths - 1] ; } continue ; } if( strcasecmp(argv[nopt],"-autoreg") == 0 ){ meth[nmeths++] = METH_AUTOREGP ; if( ++nopt >= argc ) ERROR_exit("-autoreg needs an argument!\n"); meth[nmeths++] = atoi(argv[nopt++]); if (meth[nmeths - 1] == 0) { addBriks++; } else { nbriks+=meth[nmeths - 1] ; } continue ; } if( strcasecmp(argv[nopt],"-accumulate") == 0 ){ /* 4 Mar 2008 [rickr] */ meth[nmeths++] = METH_ACCUMULATE ; meth[nmeths++] = -1; /* flag to add N (not N-1) output bricks */ fullBriks++; tsout = 1; /* flag to output a timeseries */ nopt++ ; continue ; } if( strcasecmp(argv[nopt],"-l2norm") == 0 ){ /* 07 Jan 2013 [rickr] */ meth[nmeths++] = METH_L2_NORM ; nbriks++ ; nopt++ ; continue ; } /*-- prefix --*/ if( strcasecmp(argv[nopt],"-prefix") == 0 ){ if( ++nopt >= argc ) ERROR_exit("-prefix needs an argument!\n"); MCW_strncpy(prefix,argv[nopt],THD_MAX_PREFIX) ; if( !THD_filename_ok(prefix) ) ERROR_exit("%s is not a valid prefix!\n",prefix); nopt++ ; continue ; } /*-- tdiff --*/ if( strcasecmp(argv[nopt],"-tdiff") == 0 ){ /* 25 May 2011 */ do_tdiff = 1 ; nopt++ ; continue ; } /*-- nscale --*/ if( strcasecmp(argv[nopt],"-nscale") == 0 ){ /* 25 May 2011 */ nscale = 1 ; nopt++ ; continue ; } /*-- datum --*/ if( strcasecmp(argv[nopt],"-datum") == 0 ){ if( ++nopt >= argc ) ERROR_exit("-datum needs an argument!\n"); if( strcasecmp(argv[nopt],"short") == 0 ){ datum = MRI_short ; } else if( strcasecmp(argv[nopt],"float") == 0 ){ datum = MRI_float ; } else if( strcasecmp(argv[nopt],"byte") == 0 ){ datum = MRI_byte ; } else { ERROR_exit("-datum of type '%s' is not supported!\n", argv[nopt] ) ; } nopt++ ; continue ; } /* base percentage for duration calcs */ if (strcasecmp (argv[nopt], "-basepercent") == 0) { if( ++nopt >= argc ) ERROR_exit("-basepercent needs an argument!\n"); basepercent = strtod(argv[nopt], NULL); if(basepercent>1) basepercent /= 100.0; /* assume integer percent if >1*/ nopt++; continue; } /*-- Quien sabe'? --*/ ERROR_message("Unknown option: %s\n",argv[nopt]) ; suggest_best_prog_option(argv[0], argv[nopt]); exit(1); } if (argc < 2) { ERROR_message("Too few options, use -help for details"); exit(1); } /*--- If no options selected, default to single stat MEAN -- KRH ---*/ if (nmeths == 0) nmeths = 1; if (nbriks == 0 && addBriks == 0 && fullBriks == 0) nbriks = 1; /*----- read input dataset -----*/ if( nopt >= argc ) ERROR_exit(" No input dataset!?") ; old_dset = THD_open_dataset( argv[nopt] ) ; if( !ISVALID_DSET(old_dset) ) ERROR_exit("Can't open dataset %s\n",argv[nopt]); nopt++ ; if( nopt < argc ) WARNING_message("Trailing datasets on command line ignored: %s ...",argv[nopt]) ; if( DSET_NVALS(old_dset) == 1 ){ WARNING_message("Input dataset has 1 sub-brick ==> -tdiff is turned off") ; do_tdiff = 0 ; } /* no input volumes is bad, 1 volume applies to only certain methods */ /* 2 Nov 2010 [rickr] */ if( DSET_NVALS(old_dset) == 0 ) { ERROR_exit("Time series is of length 0?\n") ; } else if( DSET_NVALS(old_dset) == 1 || (do_tdiff && DSET_NVALS(old_dset)==2) ) { int methOK, OK = 1; /* see if each method is valid for nvals == 1 */ for( methIndex = 0; methIndex < nmeths; methIndex++ ) { methOK = 0; for( ii = 0; ii < NUM_1_INPUT_METHODS; ii++ ) { if( meth[methIndex] == valid_1_input_methods[ii] ) { methOK = 1; break; } } if( ! methOK ) ERROR_exit("Can't use dataset with %d values per voxel!" , DSET_NVALS(old_dset) ) ; } /* tell the library function that this case is okay */ g_thd_maker_allow_1brick = 1; } if( DSET_NUM_TIMES(old_dset) < 2 ){ WARNING_message("Input dataset is not 3D+time; assuming TR=1.0") ; EDIT_dset_items( old_dset , ADN_ntt , DSET_NVALS(old_dset) , ADN_ttorg , 0.0 , ADN_ttdel , 1.0 , ADN_tunits , UNITS_SEC_TYPE , NULL ) ; } /* If one or more of the -autocorr/-autoreg options was called with */ /* an argument of 0, then I'll now add extra BRIKs for the N-1 data */ /* output points for each. */ nbriks += ((DSET_NVALS(old_dset)-1) * addBriks); nbriks += ((DSET_NVALS(old_dset) ) * fullBriks); /* ------------- Mask business -----------------*/ if( mask_dset == NULL ){ mmm = NULL ; if( verb ) INFO_message("%d voxels in the entire dataset (no mask)\n", DSET_NVOX(old_dset)) ; } else { if( DSET_NVOX(mask_dset) != DSET_NVOX(old_dset) ) ERROR_exit("Input and mask datasets are not same dimensions!\n"); mmm = THD_makemask( mask_dset , 0 , mask_bot, mask_top ) ; mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ; if( mcount <= 0 ) ERROR_exit("No voxels in the mask!\n") ; if( verb ) INFO_message("%d voxels in the mask\n",mcount) ; DSET_delete(mask_dset) ; } if( cmask != NULL ){ if( ncmask != DSET_NVOX(old_dset) ) ERROR_exit("Input and cmask datasets are not same dimensions!\n"); if( mmm != NULL ){ for( ii=0 ; ii < DSET_NVOX(old_dset) ; ii++ ) mmm[ii] = (mmm[ii] && cmask[ii]) ; free(cmask) ; mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ; if( mcount <= 0 ) ERROR_exit("No voxels in the mask+cmask!\n") ; if( verb ) INFO_message("%d voxels in the mask+cmask\n",mcount) ; } else { mmm = cmask ; mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ; if( mcount <= 0 ) ERROR_exit("No voxels in the cmask!\n") ; if( verb ) INFO_message("%d voxels in the cmask\n",mcount) ; } } /*------------- ready to compute new dataset -----------*/ new_dset = MAKER_4D_to_typed_fbuc( old_dset , /* input dataset */ prefix , /* output prefix */ datum , /* output datum */ 0 , /* ignore count */ 0 , /* can't detrend in maker function KRH 12/02*/ nbriks , /* number of briks */ STATS_tsfunc , /* timeseries processor */ NULL, /* data for tsfunc */ mmm, nscale ) ; if( new_dset != NULL ){ tross_Copy_History( old_dset , new_dset ) ; tross_Make_History( "3dTstat" , argc,argv , new_dset ) ; for (methIndex = 0,brikIndex = 0; methIndex < nmeths; methIndex++, brikIndex++) { if ((meth[methIndex] == METH_AUTOCORR) || (meth[methIndex] == METH_ACCUMULATE) || (meth[methIndex] == METH_AUTOREGP)) { numMultBriks = meth[methIndex+1]; /* note: this looks like it should be NV-1 4 Mar 2008 [rickr] */ if (numMultBriks == 0) numMultBriks = DSET_NVALS(old_dset)-1; /* new flag for NVALS [rickr] */ if (numMultBriks == -1) numMultBriks = DSET_NVALS(old_dset); for (ii = 1; ii <= numMultBriks; ii++) { char tmpstr[25]; if (meth[methIndex] == METH_AUTOREGP) { sprintf(tmpstr,"%s[%d](%d)",meth_names[meth[methIndex]], numMultBriks,ii); } else { sprintf(tmpstr,"%s(%d)",meth_names[meth[methIndex]],ii); } EDIT_BRICK_LABEL(new_dset, (brikIndex + ii - 1), tmpstr) ; } methIndex++; brikIndex += numMultBriks - 1; } else { EDIT_BRICK_LABEL(new_dset, brikIndex, meth_names[meth[methIndex]]) ; } } if( tsout ) /* then change output to a time series */ EDIT_dset_items( new_dset , ADN_ntt , brikIndex , ADN_ttorg , DSET_TIMEORIGIN(old_dset) , ADN_ttdel , DSET_TIMESTEP(old_dset) , ADN_tunits , DSET_TIMEUNITS(old_dset) , NULL ) ; DSET_write( new_dset ) ; WROTE_DSET( new_dset ) ; } else { ERROR_exit("Unable to compute output dataset!\n") ; } exit(0) ; }
THD_3dim_dataset * MAKER_4D_to_typed_fim( THD_3dim_dataset * old_dset , char * new_prefix , int new_datum , int ignore , int detrend , generic_func * user_func , void * user_data ) { THD_3dim_dataset * new_dset ; /* output dataset */ byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * fout = NULL ; /* will be array of output floats */ float * dtr = NULL ; /* will be array of detrending coeff */ float val , d0fac , d1fac , x0,x1; double tzero=0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , nbad ; register int kk ; void (*ufunc)(double,double,int,float *,double,double,void *,float *) = (void (*)(double,double,int,float *,double,double,void *,float *)) user_func ; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( new_datum >= 0 && new_datum != MRI_byte && new_datum != MRI_short && new_datum != MRI_float ) return NULL ; if( user_func == NULL ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ if( nuse < 2 ) return NULL ; if( new_datum < 0 ) new_datum = old_datum ; /* output datum = input */ if( new_datum == MRI_complex ) return NULL ; /* but complex = bad news */ DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) FREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*---------------------- make a new dataset ----------------------*/ new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */ /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , 1 , /* # sub-bricks */ ADN_ntt , 0 , /* # time points */ ADN_type , ISHEAD(old_dset) /* dataset type */ ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_FIM_TYPE , /* function type */ ADN_none ) ; if( ii != 0 ){ ERROR_message("Error creating dataset '%s'",new_prefix) ; THD_delete_3dim_dataset( new_dset , False ) ; /* some error above */ FREE_WORKSPACE ; return NULL ; } /*------ make floating point output brick (only at the end will scale to byte or shorts) ------*/ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; fout = (float *) malloc( sizeof(float) * nvox ) ; /* ptr to brick */ if( fout == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** compute output ***/ #if 0 user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #else ufunc( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #endif } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* don't need this no more */ /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #endif nbad = thd_floatscan( nvox , fout ) ; /* 08 Aug 2000 */ if( nbad > 0 ) fprintf(stderr, "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fim\n\a", nbad ) ; /*------------------------------------------------------------*/ /*------- The output is now in fout[ii], ii=0..nvox-1. We must now put this into the output dataset -------*/ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout brick to the dataset ***/ case MRI_float: EDIT_substitute_brick( new_dset , 0 , MRI_float , fout ) ; fout = NULL ; /* so it won't be freed later */ break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (short *) malloc( sizeof(short) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 32767.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_short,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_short , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (byte *) malloc( sizeof(byte) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 255.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_byte,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_byte , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; } /* end of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ FREE_WORKSPACE ; return new_dset ; }
int main( int argc , char *argv[] ) { char *aname ; THD_3dim_dataset *dset ; int ii , scl ; MRI_IMAGE *im , *qim ; char *fname ; float fac ; int do_4D=0 , iarg=1 ; /* 30 Sep 2002 */ FILE *ifp=NULL ; int xxor=-1,yyor=0,zzor=0 , xdir=0,ydir=0,zdir=0; /* 19 Mar 2003 */ float xdel=0.0 ,ydel=0.0,zdel=0.0; char orient_code[4] ; /*-- help me if you can --*/ WARNING_message("This program (3dAFNItoANALYZE) is old, not maintained, and probably useless!") ; if( argc < 3 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dAFNItoANALYZE [-4D] [-orient code] aname dset\n" "Writes AFNI dataset 'dset' to 1 or more ANALYZE 7.5 format\n" ".hdr/.img file pairs (one pair for each sub-brick in the\n" "AFNI dataset). The ANALYZE files will be named\n" " aname_0000.hdr aname_0000.img for sub-brick #0\n" " aname_0001.hdr aname_0001.img for sub-brick #1\n" "and so forth. Each file pair will contain a single 3D array.\n" "\n" "* If the AFNI dataset does not include sub-brick scale\n" " factors, then the ANALYZE files will be written in the\n" " datum type of the AFNI dataset.\n" "* If the AFNI dataset does have sub-brick scale factors,\n" " then each sub-brick will be scaled to floating format\n" " and the ANALYZE files will be written as floats.\n" "* The .hdr and .img files are written in the native byte\n" " order of the computer on which this program is executed.\n" "\n" "Options\n" "-------\n" "-4D [30 Sep 2002]:\n" " If you use this option, then all the data will be written to\n" " one big ANALYZE file pair named aname.hdr/aname.img, rather\n" " than a series of 3D files. Even if you only have 1 sub-brick,\n" " you may prefer this option, since the filenames won't have\n" " the '_0000' appended to 'aname'.\n" "\n" "-orient code [19 Mar 2003]:\n" " This option lets you flip the dataset to a different orientation\n" " when it is written to the ANALYZE files. The orientation code is\n" " formed as follows:\n" " The code must be 3 letters, one each from the\n" " pairs {R,L} {A,P} {I,S}. The first letter gives\n" " the orientation of the x-axis, the second the\n" " orientation of the y-axis, the third the z-axis:\n" " R = Right-to-Left L = Left-to-Right\n" " A = Anterior-to-Posterior P = Posterior-to-Anterior\n" " I = Inferior-to-Superior S = Superior-to-Inferior\n" " For example, 'LPI' means\n" " -x = Left +x = Right\n" " -y = Posterior +y = Anterior\n" " -z = Inferior +z = Superior\n" " * For display in SPM, 'LPI' or 'RPI' seem to work OK.\n" " Be careful with this: you don't want to confuse L and R\n" " in the SPM display!\n" " * If you DON'T use this option, the dataset will be written\n" " out in the orientation in which it is stored in AFNI\n" " (e.g., the output of '3dinfo dset' will tell you this.)\n" " * The dataset orientation is NOT stored in the .hdr file.\n" " * AFNI and ANALYZE data are stored in files with the x-axis\n" " varying most rapidly and the z-axis most slowly.\n" " * Note that if you read an ANALYZE dataset into AFNI for\n" " display, AFNI assumes the LPI orientation, unless you\n" " set environment variable AFNI_ANALYZE_ORIENT.\n" ) ; PRINT_COMPILE_DATE; exit(0) ; } mainENTRY("3dAFNItoANALYZE main"); machdep(); PRINT_VERSION("3dAFNItoANALYZE"); /*-- read inputs --*/ while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-4D") == 0 ){ /* 30 Sep 2002 */ do_4D = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-orient") == 0 ){ /* 19 Mar 2003 */ char acod ; if( iarg+1 >= argc ){ fprintf(stderr,"** Need something after -orient!\n"); exit(1); } MCW_strncpy(orient_code,argv[++iarg],4) ; if( strlen(orient_code) != 3 ){ fprintf(stderr,"** Illegal code '%s' after -orient!\n",argv[iarg]); exit(1); } acod = toupper(orient_code[0]) ; xxor = ORCODE(acod) ; acod = toupper(orient_code[1]) ; yyor = ORCODE(acod) ; acod = toupper(orient_code[2]) ; zzor = ORCODE(acod) ; if( xxor<0 || yyor<0 || zzor<0 || !OR3OK(xxor,yyor,zzor) ){ fprintf(stderr,"** Unusable code after -orient!\n"); exit(1); } iarg++ ; continue ; } fprintf(stderr,"** Illegal option: %s\n",argv[iarg]); exit(1); } if( iarg >= argc-1 ){ fprintf(stderr,"** Not enough arguments on command line!\n"); exit(1); } aname = argv[iarg++] ; if( !THD_filename_ok(aname) ){ fprintf(stderr,"** Illegal aname string %s\n",aname) ; exit(1) ; } fname = malloc( strlen(aname)+16 ) ; dset = THD_open_dataset( argv[iarg++] ); CHECK_OPEN_ERROR(dset,argv[iarg-1]); if( xxor >= 0 ){ /* 19 Mar 2003: figure how to flip */ xdir = THD_get_axis_direction( dset->daxes , xxor ) ; ydir = THD_get_axis_direction( dset->daxes , yyor ) ; zdir = THD_get_axis_direction( dset->daxes , zzor ) ; if( ydir == 0 || zdir == 0 ) xdir = 0 ; if( xdir == 1 && ydir == 2 && zdir == 3 ) xdir = 0 ; } if( xdir != 0 ){ float dx=fabs(DSET_DX(dset)) , dy=fabs(DSET_DY(dset)) , dz=fabs(DSET_DZ(dset)) ; DSET_mallocize(dset) ; switch( xdir ){ case 1: case -1: xdel = dx ; break ; case 2: case -2: xdel = dy ; break ; case 3: case -3: xdel = dz ; break ; } switch( ydir ){ case 1: case -1: ydel = dx ; break ; case 2: case -2: ydel = dy ; break ; case 3: case -3: ydel = dz ; break ; } switch( zdir ){ case 1: case -1: zdel = dx ; break ; case 2: case -2: zdel = dy ; break ; case 3: case -3: zdel = dz ; break ; } } else { xdel = fabs(DSET_DX(dset)) ; ydel = fabs(DSET_DY(dset)) ; zdel = fabs(DSET_DZ(dset)) ; } DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; /* determine if we scale to floats */ scl = THD_need_brick_factor( dset ) ; /* 30 Sep 2002: if doing a 4D file, write single .hdr now */ if( do_4D ){ im = mri_empty_conforming( DSET_BRICK(dset,0) , (scl) ? MRI_float : DSET_BRICK_TYPE(dset,0) ) ; if( xdir != 0 ){ qim = mri_flip3D( xdir,ydir,zdir , im ) ; if( qim == NULL){ fprintf(stderr,"mri_flip3D fails?!\n"); exit(1); } mri_free(im); im = qim; } im->dx = xdel ; /* load voxel sizes */ im->dy = ydel ; im->dz = zdel ; im->dw = 1.0 ; if( AFNI_yesenv("AFNI_ANALYZE_ORIGINATOR") ){ im->xo = dset->daxes->xxorg ; /* load voxel origin */ im->yo = dset->daxes->yyorg ; /* 03/11/04 KRH added this bit for SPM */ im->zo = dset->daxes->zzorg ; if( ORIENT_sign[dset->daxes->xxorient] == '-' ){ im->dx = -im->dx ; /* im->xo = -im->xo ; */ } if( ORIENT_sign[dset->daxes->yyorient] == '-' ){ im->dy = -im->dy ; /* im->yo = -im->yo ; */ } if( ORIENT_sign[dset->daxes->zzorient] == '-' ){ im->dz = -im->dz ; /* im->zo = -im->zo ; */ } } im->nt = DSET_NVALS(dset) ; /* add a time axis */ im->dt = DSET_TR(dset) ; if( im->dt <= 0.0 ) im->dt = 1.0 ; if( DSET_TIMEUNITS(dset) == UNITS_MSEC_TYPE ) im->dt *= 0.001 ; /* 05 Jul 2005 */ mri_write_analyze( aname , im ) ; /* output 4D .hdr file */ mri_free(im) ; sprintf(fname,"%s.img",aname) ; /* open output .img file */ ifp = fopen( fname , "wb" ) ; if( ifp == NULL ){ fprintf(stderr,"** Can't open file %s for output!\n",fname) ; exit(1) ; } } /* loop over sub-bricks */ for( ii=0 ; ii < DSET_NVALS(dset) ; ii++ ){ im = DSET_BRICK(dset,ii) ; /* get the sub-brick */ if( scl ){ /* scale it to floats */ fac = DSET_BRICK_FACTOR(dset,ii) ; if( fac == 0.0 ) fac = 1.0 ; qim = mri_scale_to_float( fac , im ) ; } else { qim = im ; } if( xdir != 0 ){ /* 19 Mar 2003: flip it */ MRI_IMAGE *fim ; fim = mri_flip3D( xdir,ydir,zdir , qim ) ; if( fim == NULL ){ fprintf(stderr,"mri_flip3D fails at ii=%d ?!\n",ii); exit(1); } if( qim != im ) mri_free(qim) ; qim = fim ; } if( do_4D ){ /* 30 Sep 2002: write into 4D .img file */ fwrite( mri_data_pointer(qim) , qim->nvox , qim->pixel_size , ifp ) ; } else { /* write separate 3D .hdr/.img files */ qim->dx = xdel ; /* load voxel sizes */ qim->dy = ydel ; qim->dz = zdel ; qim->dw = 1.0 ; if( AFNI_yesenv("AFNI_ANALYZE_ORIGINATOR") ){ qim->xo = dset->daxes->xxorg ; /* load voxel origin */ qim->yo = dset->daxes->yyorg ; /* 03/11/04 KRH added this bit for SPM */ qim->zo = dset->daxes->zzorg ; if( ORIENT_sign[dset->daxes->xxorient] == '-' ){ qim->dx = -qim->dx ; /* qim->xo = -qim->xo ; */ } if( ORIENT_sign[dset->daxes->yyorient] == '-' ){ qim->dy = -qim->dy ; /* qim->yo = -qim->yo ; */ } if( ORIENT_sign[dset->daxes->zzorient] == '-' ){ qim->dz = -qim->dz ; /* qim->zo = -qim->zo ; */ } } sprintf(fname,"%s_%04d",aname,ii) ; /* make up a filename */ mri_write_analyze( fname , qim ) ; /* do the real work */ } if( qim != im ) mri_free(qim) ; DSET_unload_one(dset,ii) ; /* clean up the trash */ } if( ifp != NULL ) fclose(ifp) ; /* 30 Sep 2002 */ free(fname) ; exit(0) ; }
static char *Fourier_Filter_Driver(PLUGIN_interface *plint, THD_3dim_dataset *input, float low_fc, float high_fc, int ignore, int autocorr, int retrend, char *output_prefix) { #else static char *Fourier_Filter_Driver(THD_3dim_dataset *input, float low_fc, float high_fc, int ignore, int autocorr, int retrend, char *output_prefix) { #endif int i, j; int ntimes, nvox; float **out_data, *out_temp, *scale, *input_data_f, period; byte *input_data_b; short *input_data_s; THD_3dim_dataset *output=NULL; char *err; /* should be a valid 3d+time input */ DSET_load(input); ntimes = DSET_NUM_TIMES(input); nvox = DSET_NVOX(input); /* Create a float array for the output */ out_data = (float **)My_Malloc(ntimes * sizeof(float *)); for (i=0; i<ntimes; out_data[i++] = (float *)My_Malloc(nvox * sizeof(float))); /* Create the tempory float array */ out_temp = (float *)My_Malloc(ntimes*sizeof(float)); /* Get the scale factors for later */ scale = (float *)My_Malloc(ntimes*sizeof(float)); for (i=0; i<ntimes; i++) { if (!DSET_BRICK_FACTOR(input,i)) scale[i] = 1.0; else scale[i] = DSET_BRICK_FACTOR(input,i); } /* get the sampling period */ period = DSET_TIMESTEP(input); switch (DSET_TIMEUNITS(input)) { case UNITS_MSEC_TYPE: {period/=1000; break; } case UNITS_SEC_TYPE: break; case UNITS_HZ_TYPE: return ("FIlter_Driver Error:\nHmm, you would think I could handle a 3d+time that is already\nfrequency, but Im lame"); default: return("Filter_Driver Error:\nI dont understand the units of the 3d+time"); } #ifdef IN_FOURIER_PLUGIN PLUTO_popup_meter(plint); #endif /* Loop over voxels, pull out the time series and filter */ for (i=0; i< nvox; i++) { for (j=0; j<ntimes; j++) { switch(DSET_BRICK_TYPE(input,j)) { case MRI_byte: { input_data_b = (byte *)DSET_ARRAY(input,j); out_temp[j] = scale[j] * (float)input_data_b[i]; break; } case MRI_short: { input_data_s = (short *)DSET_ARRAY(input,j); out_temp[j] = scale[j] * (float)input_data_s[i]; break; } case MRI_float: { input_data_f = (float *)DSET_ARRAY(input,j); out_temp[j] = scale[j] * input_data_f[i]; break; } default : { return("FIlter_Driver Error:\nInvalid data type for one of the sub-bricks"); } } } err = filter(out_temp, low_fc, high_fc, ntimes, period, ignore, retrend, FALSE); if (err != NULL) return err; for(j=0; j<ntimes; j++) out_data[j][i] = out_temp[j]; #ifdef IN_FOURIER_PLUGIN PLUTO_set_meter(plint, (int)(100.0*((float)i/(float)nvox))); #endif } /* create new dataset and convert, etc. */ output = EDIT_empty_copy(input); tross_Copy_History(output,input) ; /* Jul 2010 */ #if defined(ARGC) && defined(ARGV) tross_Make_History( "3dFourier" , ARGC,ARGV , output ) ; #endif j=EDIT_dset_items(output, ADN_prefix, output_prefix, ADN_none); for (j=0; j<ntimes; j++) { switch(DSET_BRICK_TYPE(input,j)) { case MRI_byte: { input_data_b = (byte *)My_Malloc(nvox*sizeof(byte)); for (i=0; i<nvox; i++) input_data_b[i] = (byte)(out_data[j][i] / scale[j]); EDIT_substitute_brick(output, j, MRI_byte, (byte *)input_data_b); break; } case MRI_short: { input_data_s = (short *)My_Malloc(nvox*sizeof(short)); for (i=0; i<nvox; i++) input_data_s[i] = (short)(out_data[j][i] / scale[j]); EDIT_substitute_brick(output, j, MRI_short, (short *)input_data_s); break; } case MRI_float: { input_data_f = (float *)My_Malloc(nvox*sizeof(float)); for (i=0; i<nvox; i++) input_data_f[i] = (float)(out_data[j][i] / scale[j]); EDIT_substitute_brick(output, j, MRI_float, (float *)input_data_f); break; } } #ifdef IN_FOURIER_PLUGIN PLUTO_set_meter(plint, (int)(100.0*((float)j/(float)ntimes))); #endif } /* Write out the new brick at let the memory be free */ #ifdef IN_FOURIER_PLUGIN PLUTO_add_dset(plint, output, DSET_ACTION_MAKE_CURRENT); #else DSET_write(output); #endif DSET_unload(input); DSET_unload(output); for (i=0; i<ntimes; free(out_data[i++])); free (out_data); free (scale); free (out_temp); #ifdef IN_FOURIER_PLUGIN PLUTO_popdown_meter(plint); #endif return NULL; }