int SUMA_ShortizeDset(THD_3dim_dataset **dsetp, float thisfac) { static char FuncName[]={"SUMA_ShortizeDset"}; char sprefix[THD_MAX_PREFIX+10]; int i, j; byte *bb=NULL; short *sb=NULL; float bbf=0.0; THD_3dim_dataset *cpset=NULL, *dset=*dsetp; SUMA_ENTRY; if (!dset) { SUMA_S_Err("NULL *dsetp at input!"); SUMA_RETURN(0); } sprintf(sprefix, "%s.s", dset->dblk->diskptr->prefix); NEW_SHORTY(dset, DSET_NVALS(dset), "ss.cp", cpset); for (i=0; i<DSET_NVALS(dset); ++i) { if (DSET_BRICK_TYPE(dset,i) == MRI_byte) { bb = (byte *)DSET_ARRAY(dset,i); sb = (short *)DSET_ARRAY(cpset,i); if (thisfac <= 0.0) { for (j=0; j<DSET_NVOX(dset); ++j) { sb[j] = (short)bb[j]; } thisfac = DSET_BRICK_FACTOR(dset,i); } else { bbf = DSET_BRICK_FACTOR(dset,i); if (bbf == 0.0f) bbf = 1.0; bbf = bbf/thisfac; for (j=0; j<DSET_NVOX(dset); ++j) { sb[j] = SHORTIZE((((float)bb[j])*bbf)); } } EDIT_BRICK_FACTOR( cpset,i,thisfac ) ; } else { EDIT_substscale_brick(cpset, i, DSET_BRICK_TYPE(dset,i), DSET_ARRAY(dset,i), MRI_short, thisfac); if (DSET_BRICK_TYPE(dset,i) != MRI_short) { DSET_FREE_ARRAY(dset, i); } else { DSET_NULL_ARRAY(dset, i); } } } /* preserve tables, if any */ THD_copy_labeltable_atr( cpset->dblk, dset->dblk); DSET_delete(dset); dset = NULL; *dsetp=cpset; SUMA_RETURN(1); }
float THD_get_float_value( int ind , int ival , THD_3dim_dataset *dset ) { MRI_TYPE typ ; float val=0.0f ; if( ind < 0 || ival < 0 || !ISVALID_DSET(dset) || ival >= DSET_NVALS(dset) || ind >= DSET_NVOX(dset) ) return val ; typ = DSET_BRICK_TYPE(dset,ival) ; /* raw data type */ switch( typ ){ default: /* don't know what to do --> return nada */ return(-1); break ; case MRI_byte:{ byte *bar ; bar = (byte *) DSET_ARRAY(dset,ival) ; if( bar != NULL ) val = (float)bar[ind] ; } break ; case MRI_short:{ short *bar ; bar = (short *) DSET_ARRAY(dset,ival) ; if( bar != NULL ) val = (float)bar[ind] ; } break ; case MRI_float:{ float *bar ; bar = (float *) DSET_ARRAY(dset,ival) ; if( bar != NULL ) val = bar[ind] ; } break ; case MRI_complex:{ complex *bar ; bar = (complex *) DSET_ARRAY(dset,ival) ; if( bar != NULL ) val = CABS(bar[ind]) ; } break ; } if( DSET_BRICK_FACTOR(dset,ival) > 0.0f ) val *= DSET_BRICK_FACTOR(dset,ival) ; return val ; }
int THD_subbrick_minmax (THD_3dim_dataset *dset, int isb, int scl, float *min, float *max) { float tf = 1.0; *min = 0.0; *max = 0.0; if (!dset) return(0); RELOAD_STATS(dset); if( ISVALID_STATISTIC(dset->stats) ) { *min = dset->stats->bstat[isb].min; *max = dset->stats->bstat[isb].max; } else { /* the slow way */ THD_slow_minmax_dset(dset, min, max, isb, isb); } /* values are already scaled, remove it */ if (!scl) { tf = DSET_BRICK_FACTOR(dset,isb) ; if (tf == 0.0) tf = 1.0; *min /= tf; *max /= tf; } return(1); }
void process_subbrick (THD_3dim_dataset * dset, int ibrick) { const float EPSILON = 1.0e-10; float factor; /* factor is new scale factor for this sub-brick */ void * vfim = NULL; /* sub-brick data pointer */ float * ffim = NULL; /* sub-brick data in floating point format */ char brick_label[THD_MAX_NAME]; /* sub-brick label */ ENTRY("process_subbrick") ; if (!FDR_quiet) printf ("Processing sub-brick #%d \n", ibrick); /*----- Allocate memory for float data -----*/ ffim = (float *) malloc (sizeof(float) * FDR_nxyz); MTEST (ffim); /*----- Convert sub-brick to float stats -----*/ SUB_POINTER (dset, ibrick, 0, vfim); EDIT_coerce_scale_type (FDR_nxyz, DSET_BRICK_FACTOR(dset,ibrick), DSET_BRICK_TYPE(dset,ibrick), vfim, /* input */ MRI_float , ffim); /* output */ /*----- Calculate FDR z-scores for all voxels within this volume -----*/ process_volume (ffim, DSET_BRICK_STATCODE(dset,ibrick), DSET_BRICK_STATAUX (dset,ibrick)); /*----- Replace old sub-brick with new z-scores -----*/ if( !FDR_float || DSET_BRICK_TYPE(dset,ibrick)==MRI_float ){ SUB_POINTER (dset, ibrick, 0, vfim); factor = EDIT_coerce_autoscale_new (FDR_nxyz, MRI_float, ffim, DSET_BRICK_TYPE(dset,ibrick), vfim); if (factor < EPSILON) factor = 0.0; else factor = 1.0 / factor; if( DSET_BRICK_TYPE(dset,ibrick) == MRI_short ) EDIT_misfit_report( DSET_FILECODE(dset) , ibrick , FDR_nxyz , factor , vfim , ffim ) ; } else { /*** if -float was given ***/ EDIT_substitute_brick( dset , ibrick , MRI_float , ffim ) ; ffim = NULL ; factor = 0.0f ; } /*----- edit the sub-brick -----*/ if( FDR_qval ) strcpy (brick_label, "FDRq:"); else strcpy (brick_label, "FDRz:"); strcat (brick_label, DSET_BRICK_LABEL(dset, ibrick)); EDIT_BRICK_LABEL (dset, ibrick, brick_label); EDIT_BRICK_FACTOR (dset, ibrick, factor); if( !FDR_qval ) EDIT_BRICK_TO_FIZT (dset,ibrick); else EDIT_BRICK_TO_NOSTAT(dset,ibrick); /*----- Deallocate memory -----*/ if (ffim != NULL) { free (ffim); ffim = NULL; } EXRETURN ; }
/* - moved from 3dhistog.c 18 Dec 2012 [rickr] */ int THD_slow_minmax_dset(THD_3dim_dataset *dset, float *dmin, float *dmax, int iv_bot, int iv_top) { int iv_fim; float fimfac; float vbot , vtop, temp_fbot=1.0, temp_ftop=0.0 ; DSET_load(dset); for( iv_fim=iv_bot ; iv_fim <= iv_top ; iv_fim++ ){ /* minimum and maximum for sub-brick */ vbot = mri_min( DSET_BRICK(dset,iv_fim) ) ; vtop = mri_max( DSET_BRICK(dset,iv_fim) ) ; fimfac = DSET_BRICK_FACTOR(dset,iv_fim) ; if (fimfac == 0.0) fimfac = 1.0; vbot *= fimfac ; vtop *= fimfac ; /* update global min and max */ if ( temp_fbot > temp_ftop ) { /* first time, just copy */ temp_fbot = vbot; temp_ftop = vtop; } else { if( vbot < temp_fbot ) temp_fbot = vbot; if( vtop > temp_ftop ) temp_ftop = vtop; } } *dmin = temp_fbot; *dmax = temp_ftop; return(0); }
MRI_IMAGE * THD_median_brick( THD_3dim_dataset *dset ) { int nvox , nvals , ii ; MRI_IMAGE *tsim , *medim ; float *medar ; float *tsar ; /* 05 Nov 2001 */ ENTRY("THD_median_brick") ; if( !ISVALID_DSET(dset) ) RETURN(NULL) ; DSET_load(dset) ; if( !DSET_LOADED(dset) ) RETURN(NULL) ; nvals = DSET_NVALS(dset) ; tsim = DSET_BRICK(dset,0) ; if( nvals == 1 ){ medim = mri_scale_to_float( DSET_BRICK_FACTOR(dset,0), tsim ) ; RETURN(medim) ; } medim = mri_new_conforming( tsim , MRI_float ) ; medar = MRI_FLOAT_PTR(medim) ; nvox = DSET_NVOX(dset) ; tsar = (float *) calloc( sizeof(float),nvals+1 ) ; /* 05 Nov 2001 */ for( ii=0 ; ii < nvox ; ii++ ){ THD_extract_array( ii , dset , 0 , tsar ) ; /* 05 Nov 2001 */ medar[ii] = qmed_float( nvals , tsar ) ; } free(tsar) ; RETURN(medim) ; }
MRI_IMAGE * THD_rms_brick( THD_3dim_dataset *dset ) { int nvox , nvals , ii , jj ; MRI_IMAGE *tsim , *medim ; float *medar , sum,fac ; float *tsar ; ENTRY("THD_rms_brick") ; if( !ISVALID_DSET(dset) ) RETURN(NULL) ; DSET_load(dset) ; if( !DSET_LOADED(dset) ) RETURN(NULL) ; nvals = DSET_NVALS(dset) ; fac = 1.0 / nvals ; tsim = DSET_BRICK(dset,0) ; if( nvals == 1 ){ medim = mri_scale_to_float( DSET_BRICK_FACTOR(dset,0), tsim ) ; RETURN(medim) ; } medim = mri_new_conforming( tsim , MRI_float ) ; medar = MRI_FLOAT_PTR(medim) ; nvox = DSET_NVOX(dset) ; tsar = (float *) calloc( sizeof(float),nvals+1 ) ; for( ii=0 ; ii < nvox ; ii++ ){ THD_extract_array( ii , dset , 0 , tsar ) ; for( sum=0.0,jj=0 ; jj < nvals ; jj++ ) sum += tsar[jj]*tsar[jj] ; medar[ii] = sqrtf(fac * sum) ; } free(tsar) ; RETURN(medim) ; }
/*---------------------------------------------------------------------- ** ** Subtract hemispheres. ** ** Check if we need to create or change the factor. ** **---------------------------------------------------------------------- */ static char * process_data( THD_3dim_dataset * dset, hemi_s * hs ) { int count, nx, ny, nz, cx, cx2; int type, diff, floats = ( DSET_BRICK_FACTOR( dset, 0 ) != 0.0 ); short * data, * sp, * sp2; nx = dset->daxes->nxx; ny = dset->daxes->nyy; nz = dset->daxes->nzz; type = hs->thresh_type; data = (short *)DSET_ARRAY( dset, 0 ); for ( count = 0; ! floats && count < ny*nz; count++ ) { sp = data; sp2 = data + nx - 1; for ( cx = 0; cx < (nx+1)/2; cx++ ) { if ( type == 1 ) /* positives only */ { if ( *sp < 0 ) *sp = 0; if ( *sp2 < 0 ) *sp2 = 0; } else if ( type == 2 ) /* negatives only */ { if ( *sp > 0 ) *sp = 0; if ( *sp2 > 0 ) *sp2 = 0; } diff = *sp - *sp2; /* if out of short range */ if ( ( diff > 32767 ) || ( diff < -32768 ) ) floats = 1; else { *sp = diff; *sp2 = -diff; } sp++; sp2--; } data += nx; } if ( floats ) return process_as_floats( dset, hs ); return NULL; /* success */ }
/* Calculates the average value for each voxel in dset across all timepoints. PRE: dset is a valid 3D+T dataset with at least 1 timepoint; ignore is the number of timepoints to ignore at the beginning of dset; 0 <= ignore < number of timepoints in dset; POST: return value is NULL on error, else, return value is an array of floats with the same dimensions as the subbricks of dset, containing the voxel value averages; Note: The caller is responsible for free()ing the returned block of memory when done. Note2: The complex datatype is not supported, and any such bricks will result in an error (NULL return value). */ double * RIC_CalcVoxelMeans(const THD_3dim_dataset * dset, int ignore) { double * avg; /* The voxel averages to be returned */ float scalefactor; /* Current dset brick scaling factor */ int ival, nvals; /* Current, number of dset timepoints */ int ivox, nvoxs; /* Current, number of dset brick voxels */ /* Quick check of arguments */ if (!ISVALID_3DIM_DATASET(dset) || DSET_NVALS(dset) < 1 || ignore < 0 || ignore >= DSET_NVALS(dset)) { return NULL; } /* Initialize */ DSET_load(dset); nvals = DSET_NVALS(dset); nvoxs = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz; avg = malloc(sizeof(double) * nvoxs); if (avg == NULL) { return NULL; } /* Calculate the voxel averages; treat matrices as 1-D arrays */ /* Zero the voxel sums */ for (ivox = 0; ivox < nvoxs; ivox += 1) { avg[ivox] = 0.0; } /* Sum each voxel across time (and hope there are not too many points) */ for (ival = ignore; ival < nvals; ival += 1) { scalefactor = DSET_BRICK_FACTOR(dset, ival); switch (DSET_BRICK_TYPE(dset, ival)) { case MRI_short: RIC_CALCVOXELMEANS__DO_VOXSUM(short); break; case MRI_byte: RIC_CALCVOXELMEANS__DO_VOXSUM(byte); break; case MRI_float: RIC_CALCVOXELMEANS__DO_VOXSUM(float); break; default: /* Unsupported datatype */ free(avg); return NULL; } } /* Divide by number of timepoints to get average */ nvals -= ignore; /* We do not average over the ignored timepoints */ for (ivox = 0; ivox < nvoxs; ivox += 1) { avg[ivox] /= nvals; } return avg; }
int is_integral_sub_brick ( THD_3dim_dataset *dset, int isb, int check_values) { float mfac = 0.0; void *vv=NULL; if( !ISVALID_DSET(dset) || isb < 0 || isb >= DSET_NVALS(dset) ) { fprintf(stderr,"** Bad dset or sub-brick index.\n"); return (0) ; } if( !DSET_LOADED(dset) ) DSET_load(dset); switch( DSET_BRICK_TYPE(dset,isb) ){ case MRI_short: case MRI_byte: if (check_values) { mfac = DSET_BRICK_FACTOR(dset,isb) ; if (mfac != 0.0f && mfac != 1.0f) return(0); } break; case MRI_double: case MRI_complex: case MRI_float: vv = (void *)DSET_ARRAY(dset,isb); mfac = DSET_BRICK_FACTOR(dset,isb) ; if (mfac != 0.0f && mfac != 1.0f) return(0); if (!vv) { fprintf(stderr,"** NULL array!\n"); return(0); } return(is_integral_data(DSET_NVOX(dset), DSET_BRICK_TYPE(dset,isb), DSET_ARRAY(dset,isb) ) ); break; default: return(0); } return(1); }
void THD_load_tcat( THD_datablock *dblk ) { int ivout , dd , iv ; THD_3dim_dataset *dset_in , *dset_out ; NI_str_array *sar ; ENTRY("THD_load_tcat") ; if( !ISVALID_DBLK(dblk) ) EXRETURN ; dset_out = (THD_3dim_dataset *)dblk->parent ; if( !ISVALID_DSET(dset_out) ) EXRETURN ; sar = NI_decode_string_list( dset_out->tcat_list , "~" ) ; if( sar == NULL ) EXRETURN ; if( sar->num != dset_out->tcat_num ){ NI_delete_str_array(sar); EXRETURN; } ivout = 0 ; for( dd=0 ; dd < sar->num ; dd++ ){ dset_in = THD_open_dataset( sar->str[dd] ) ; if( dset_in == NULL ){ NI_delete_str_array(sar) ; DSET_unload(dset_out) ; EXRETURN ; } DSET_mallocize(dset_in) ; DSET_load(dset_in) ; if( !DSET_LOADED(dset_in) ){ NI_delete_str_array(sar) ; DSET_unload(dset_out) ; DSET_delete(dset_in) ; EXRETURN ; } for( iv=0 ; iv < DSET_NVALS(dset_in) ; iv++ ){ EDIT_substitute_brick( dset_out , ivout , DSET_BRICK_TYPE(dset_in,iv), DSET_ARRAY(dset_in,iv) ); mri_fix_data_pointer( NULL , DSET_BRICK(dset_in,iv) ) ; EDIT_BRICK_FACTOR( dset_out , ivout , DSET_BRICK_FACTOR(dset_in,iv) ) ; EDIT_BRICK_LABEL(dset_out, ivout, DSET_BRICK_LABEL(dset_in, iv)); /* ZSS Aug. 27 2012 */ ivout++ ; } DSET_delete(dset_in) ; } NI_delete_str_array(sar) ; EXRETURN ; }
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 .... */ }
void initialize_program (int argc, char * argv[]) { int iv; /* index number of sub-brick */ void * vfim = NULL; /* sub-brick data pointer */ float * ffim = NULL; /* sub-brick data in floating point format */ int ixyz; /* voxel index */ int nx, ny, nz, nxyz; /* numbers of voxels in input dataset */ int mx=0, my=0, mz=0, mxyz; /* numbers of voxels in mask dataset */ int nthr=0; /* number of voxels above mask threshold */ char message[80]; /* error message */ int ibin; /* p-value bin index */ /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ machdep() ; { int new_argc ; char ** new_argv ; addto_args( argc , argv , &new_argc , &new_argv ) ; if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; } } /*----- Save command line for history notes -----*/ commandline = tross_commandline( PROGRAM_NAME , argc,argv ) ; /*----- Does user request help menu? -----*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ) FDR_Syntax() ; /*----- Add to program log -----*/ AFNI_logger (PROGRAM_NAME,argc,argv); /*----- Read input options -----*/ read_options( argc , argv ) ; /*----- Open the mask dataset -----*/ if (FDR_mask_filename != NULL) { if (!FDR_quiet) printf ("Reading mask dataset: %s \n", FDR_mask_filename); DOPEN (FDR_dset, FDR_mask_filename); if (FDR_dset == NULL) { sprintf (message, "Cannot open mask dataset %s", FDR_mask_filename); FDR_error (message); } if (DSET_NVALS(FDR_dset) != 1) WARNING_message("Mask dataset: using sub-brick #0") ; /*----- Get dimensions of mask dataset -----*/ mx = DSET_NX(FDR_dset); my = DSET_NY(FDR_dset); mz = DSET_NZ(FDR_dset); mxyz = mx*my*mz; /*----- Allocate memory for float data -----*/ ffim = (float *) malloc (sizeof(float) * mxyz); MTEST (ffim); /*----- Convert mask dataset sub-brick to floats (in ffim) -----*/ iv = 0 ; SUB_POINTER (FDR_dset, iv, 0, vfim); EDIT_coerce_scale_type (mxyz, DSET_BRICK_FACTOR(FDR_dset,iv), DSET_BRICK_TYPE(FDR_dset,iv), vfim, /* input */ MRI_float , ffim); /* output */ /*----- Allocate memory for mask volume -----*/ FDR_mask = (byte *) malloc (sizeof(byte) * mxyz); MTEST (FDR_mask); /*----- Create mask of voxels above mask threshold -----*/ nthr = 0; for (ixyz = 0; ixyz < mxyz; ixyz++){ if (fabs(ffim[ixyz]) >= FDR_mask_thr){ FDR_mask[ixyz] = 1; nthr++; } else FDR_mask[ixyz] = 0; } if (!FDR_quiet) printf ("Number of voxels above mask threshold = %d \n", nthr); if (nthr < 1) FDR_error ("No voxels above mask threshold. Cannot continue."); /*----- Delete floating point sub-brick -----*/ if (ffim != NULL) { free (ffim); ffim = NULL; } /*----- Delete mask dataset -----*/ THD_delete_3dim_dataset (FDR_dset, False); FDR_dset = NULL ; } /*----- Get the input data -----*/ if (FDR_input1D_filename != NULL) { /*----- Read the input .1D file -----*/ if (!FDR_quiet) printf ("Reading input data: %s \n", FDR_input1D_filename); FDR_input1D_data = read_time_series (FDR_input1D_filename, &nxyz); if (FDR_input1D_data == NULL) { sprintf (message, "Unable to read input .1D data file: %s", FDR_input1D_filename); FDR_error (message); } if (nxyz < 1) { sprintf (message, "No p-values in input .1D data file: %s", FDR_input1D_filename); FDR_error (message); } FDR_nxyz = nxyz; FDR_nthr = nxyz; } else { /*----- Open the input 3D dataset -----*/ if (!FDR_quiet) printf ("Reading input dataset: %s \n", FDR_input_filename); FDR_dset = THD_open_dataset(FDR_input_filename); CHECK_OPEN_ERROR(FDR_dset,FDR_input_filename); /*----- Get dimensions of input dataset -----*/ nx = DSET_NX(FDR_dset); ny = DSET_NY(FDR_dset); nz = DSET_NZ(FDR_dset); nxyz = nx*ny*nz; /*----- Check for compatible dimensions -----*/ if (FDR_mask != NULL) { if ((nx != mx) || (ny != my) || (nz != mz)) FDR_error ("Mask and input dataset have incompatible dimensions"); FDR_nxyz = nxyz; FDR_nthr = nthr; } else { FDR_nxyz = nxyz; FDR_nthr = nxyz; } /*----- Check whether output dataset already exists -----*/ if( THD_deathcon() ) check_one_output_file (FDR_dset, FDR_output_prefix); } /*----- Initialize constant c(N) -----*/ if (FDR_cn < 0.0) { double cn; cn = 0.0; for (ixyz = 1; ixyz <= FDR_nthr; ixyz++) cn += 1.0 / ixyz; FDR_cn = cn; if (!FDR_quiet) printf ("c(N) = %f \n", FDR_cn); } /*----- Initialize voxel pointers -----*/ for (ibin = 0; ibin < FDR_MAX_LL; ibin++) FDR_head_voxel[ibin] = NULL; return ; }
int main( int argc , char *argv[] ) { MRI_IMAGE *xim , *yim ; float *xar , *yar , *war ; int iarg , ndset , nvox , ii , jj, xyall , clip=0 ; THD_3dim_dataset *xset , *yset , * mask_dset=NULL ; float xbot=1.0f,xtop=0.0f , ybot=1.0f,ytop=0.0f , val ; float xsum,ysum , xsig,ysig ; byte *mmm=NULL ; char *save_hist=NULL, *save_hist_1D=NULL ; /*-- read command line arguments --*/ if( argc < 3 || strncmp(argv[1],"-help",5) == 0 ){ printf("Usage: 3dAcost [options] xset yset\n" "Output = 3dAllineate cost functions between 2 dataset bricks\n" " (for debugging purposes, mostly).\n" "\n" "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" " -histpow p Set histogram power to 'p'; number of bins in\n" " histogram (each axis) = n^p (n=# of points).\n" " (Default is p=0.33333.)\n" " -histbin m Set histogram to use 'm' bins (each axis).\n" " (Max number of bins is 255.)\n" " -savehist ss Save 2D histogram to image file 'ss'\n" " (floating point image; read with 'afni -im')\n" " -savehist_1D dd Save original form of 2D histogram to 1D file 'dd'\n" " (-savehist produces the rootogram)\n" " -xrange a b Use only xset values in range a..b.\n" " -yrange c d Use only yset values in range c..d.\n" " (Default is to use all values.)\n" " -clip Use values from min to mri_topclip()\n" ) ; exit(0) ; } iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-xrange") == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("no arguments after '%s'!",argv[iarg-1]) ; xbot = (float)strtod(argv[iarg++],NULL) ; xtop = (float)strtod(argv[iarg++],NULL) ; continue ; } if( strcmp(argv[iarg],"-yrange") == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("no arguments after '%s'!",argv[iarg-1]) ; ybot = (float)strtod(argv[iarg++],NULL) ; ytop = (float)strtod(argv[iarg++],NULL) ; continue ; } if( strcmp(argv[iarg],"-clip") == 0 ){ clip = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-savehist") == 0 ){ if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; if( !THD_filename_ok(argv[iarg]) ) ERROR_exit("badly formed filename: '%s' '%s'",argv[iarg-1],argv[iarg]); save_hist = argv[iarg] ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-savehist_1D") == 0 ){ if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; save_hist_1D= argv[iarg] ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-histpow") == 0 ){ double hist_pow ; if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; hist_pow = strtod(argv[iarg],NULL) ; set_2Dhist_hpower(hist_pow) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-histbin") == 0 ){ int hist_nbin ; if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; hist_nbin = (int)strtod(argv[iarg],NULL) ; set_2Dhist_hbin(hist_nbin) ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-mask",5) == 0 ){ if( mask_dset != NULL ) ERROR_exit("Can't use -mask twice!") ; if( iarg+1 >= argc ) ERROR_exit("-mask needs a filename!") ; mask_dset = THD_open_dataset( argv[++iarg] ) ; CHECK_OPEN_ERROR(mask_dset,argv[iarg]) ; iarg++ ; continue ; } fprintf(stderr,"*** Unknown option: %s\n",argv[iarg]) ; exit(1) ; } /* should have at least 2 more arguments */ ndset = argc - iarg ; if( ndset <= 1 ){ fprintf(stderr,"*** No input datasets!?\n") ; exit(1) ; } xset = THD_open_dataset(argv[iarg++]) ; CHECK_OPEN_ERROR(xset,argv[iarg-1]) ; yset = THD_open_dataset(argv[iarg++]) ; CHECK_OPEN_ERROR(yset,argv[iarg-1]) ; DSET_load(xset) ; DSET_load(yset) ; CHECK_LOAD_ERROR(xset) ; CHECK_LOAD_ERROR(yset) ; if( DSET_NVALS(xset) > 1 || DSET_NVALS(yset) > 1 ) WARNING_message("Using only sub-brick [0] of input datasets") ; nvox = DSET_NVOX(xset) ; if( nvox != DSET_NVOX(yset) ) ERROR_exit("Input datasets dimensions don't match!") ; xim = mri_scale_to_float( DSET_BRICK_FACTOR(xset,0) , DSET_BRICK(xset,0) ); yim = mri_scale_to_float( DSET_BRICK_FACTOR(yset,0) , DSET_BRICK(yset,0) ); xar = MRI_FLOAT_PTR(xim) ; yar = MRI_FLOAT_PTR(yim) ; DSET_unload(xset); DSET_unload(yset); /* make a byte mask from mask dataset */ war = (float *)malloc(sizeof(float)*nvox) ; if( mask_dset != NULL ){ int mcount ; if( DSET_NVOX(mask_dset) != nvox ) ERROR_exit("Input and mask datasets are not same dimensions!"); mmm = THD_makemask( mask_dset , 0 , 666.0,-666.0 ) ; mcount = THD_countmask( nvox , mmm ) ; if( mcount <= 5 ) ERROR_exit("Mask is too small: %d voxels",mcount) ; DSET_delete(mask_dset) ; for( ii=0 ; ii < nvox ; ii++ ) war[ii] = (float)mmm[ii] ; free((void *)mmm) ; } else { for( ii=0 ; ii < nvox ; ii++ ) war[ii] = 1.0f ; } if( clip ){ xbot = mri_min(xim) ; xtop = mri_topclip(xim) ; INFO_message("xbot=%g xclip=%g",xbot,xtop) ; ybot = mri_min(yim) ; ytop = mri_topclip(yim) ; INFO_message("ybot=%g yclip=%g",ybot,ytop) ; } xyall = 0 ; if( xbot >= xtop ){ xbot = 1.e+38 ; xtop = -1.e+38 ; for( ii=0 ; ii < nvox ; ii++ ) if( war[ii] > 0.0f ){ if( xar[ii] < xbot ) xbot = xar[ii] ; else if( xar[ii] > xtop ) xtop = xar[ii] ; } INFO_message("xbot=%g xtop=%g",xbot,xtop) ; if( xbot >= xtop ) ERROR_exit("no x range?!") ; xyall++ ; } if( ybot >= ytop ){ ybot = 1.e+38 ; ytop = -1.e+38 ; for( ii=0 ; ii < nvox ; ii++ ) if( war[ii] > 0.0f ){ if( yar[ii] < ybot ) ybot = yar[ii] ; else if( yar[ii] > ytop ) ytop = yar[ii] ; } INFO_message("ybot=%g ytop=%g",ybot,ytop) ; if( ybot >= ytop ) ERROR_exit("no y range?!") ; xyall++ ; } if( xyall < 2 ){ for( ii=0 ; ii < nvox ; ii++ ) if( xar[ii] < xbot || xar[ii] > xtop || yar[ii] < ybot || yar[ii] > ytop ) war[ii] = 0.0f ; } xyall = 0 ; for( ii=0 ; ii < nvox ; ii++ ) xyall += (war[ii] > 0.0f) ; INFO_message("Processing %d voxels",xyall) ; if( xyall <= 5 ) ERROR_exit("Too few voxels to continue!") ; xsum = ysum = 0.0f ; for( ii=0 ; ii < nvox ; ii++ ){ if( war[ii] > 0.0f ){ xsum += xar[ii]; ysum += yar[ii]; } } xsum /= xyall ; ysum /= xyall ; INFO_message("xmean=%g ymean=%g",xsum,ysum) ; xsig = ysig = 0.0f ; for( ii=0 ; ii < nvox ; ii++ ){ if( war[ii] > 0.0f ){ val = (xar[ii]-xsum) ; xsig += val*val ; val = (yar[ii]-ysum) ; ysig += val*val ; } } xsig = sqrt( xsig/(xyall-1.0) ); ysig = sqrt( ysig/(xyall-1.0) ); INFO_message("xsig =%g ysig =%g",xsig,ysig) ; val = THD_pearson_corr_wt( nvox , xar , yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Correlation = %+.5f\n",val) ; val = -THD_mutual_info_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("-Mutual Info = %+.5f\n",val ) ; val = THD_norm_mutinf_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("Norm Mutual Info = %+.5f\n",val ) ; #if 0 INFO_message("THD_corr_ratio_scl(%d,%g,%g,xar,%g,%g,yar,war)", nvox , xbot,xtop , ybot,ytop ) ; #endif THD_corr_ratio_sym_mul ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio sym* = %+.5f\n",val) ; THD_corr_ratio_sym_add ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio sym+ = %+.5f\n",val) ; THD_corr_ratio_sym_not ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio unsym= %+.5f\n",val) ; val = -THD_hellinger_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("-Hellinger metric = %+.5f\n",val) ; if( save_hist != NULL ){ /* Save 2D histogram */ int nbin ; float *xyc ; nbin = retrieve_2Dhist( &xyc ) ; if( nbin > 0 && xyc != NULL ){ MRI_IMAGE *fim,*qim ; double ftop ; fim = mri_new(nbin,nbin,MRI_float); mri_fix_data_pointer(xyc,fim); #if 0 for( ii=0 ; ii < nbin*nbin ; ii++ ) xyc[ii] = sqrtf(xyc[ii]) ; ftop = mri_max(fim); if( ftop == 0.0 ) ftop = 1.0; qim = mri_to_byte_scl(255.4/ftop,0.0,fim) ; mri_clear_data_pointer(fim); mri_free(fim); fim = mri_flippo(MRI_ROT_180,1,qim); mri_free(qim); mri_write_pnm(save_hist,fim); mri_free(fim); #else qim = mri_flippo(MRI_ROT_180,1,fim); mri_clear_data_pointer(fim); mri_free(fim); mri_write(save_hist,qim); mri_free(qim); #endif INFO_message("- Saved %dx%d histogram to %s",nbin,nbin,save_hist) ; } } if( save_hist_1D != NULL ){ /* Save 2D raw histogram */ int nbin ; float *xyc ; nbin = retrieve_2Dhist( &xyc ) ; if( nbin > 0 && xyc != NULL ){ FILE *fid=fopen(save_hist_1D,"w"); for( ii=0 ; ii < nbin; ii++ ) { for( jj=0 ; jj < nbin; jj++ ) { fprintf(fid,"%.4f\t", xyc[ii*nbin+jj]); } fprintf(fid,"\n"); } fclose(fid); } INFO_message("- Saved %dx%d 1D histogram to %s",nbin,nbin,save_hist_1D) ; } exit(0) ; }
/*---------------------------------------------------------------------- ** ** Subtract hemispheres assuming we need floats. ** **---------------------------------------------------------------------- */ static char * process_as_floats( THD_3dim_dataset * dset, hemi_s * hs ) { int count, cx, type = hs->thresh_type; int nx, ny, nz, nvox; short * sp, * sdata; float * fdata, * fp, * fp2; float factor, maxabs; nx = dset->daxes->nxx; ny = dset->daxes->nyy; nz = dset->daxes->nzz; nvox = nx * ny * nz; sdata = (short *)DSET_ARRAY( dset, 0 ); factor = DSET_BRICK_FACTOR( dset, 0 ); factor = factor == 0.0 ? 1.0 : factor; /* first get the data into a float array */ if ( ( fdata = (float *)malloc( nvox * sizeof( float ) ) ) == NULL ) return "------------------------------\n" "paf: failed allocation of floats" "------------------------------\n"; fp = fdata; sp = sdata; for ( count = 0; count < nvox; count++ ) { *fp = *sdata * factor; if ( ( type == 1 ) && ( *fp < 0 ) ) *fp = 0; else if ( ( type == 2 ) && ( *fp > 0 ) ) *fp = 0; fp++; sp++; } /* now make the subtraction as floats */ for ( count = 0; count < ny*nz; count++ ) { fp = fdata + count * nx; fp2 = fp + nx - 1; for ( cx = 0; cx < (nx+1)/2; cx++ ) { *fp = *fp - *fp2; *fp2 = -*fp; fp++; fp2--; } } /* now make a new factor */ maxabs = MCW_vol_amax( nvox, 1, 1, MRI_float, fdata ); /* result is all zero, let the user worry */ if ( maxabs != 0.0 ) { factor = MRI_TYPE_maxval[MRI_short] /maxabs; /* 32767? / maxabs */ EDIT_coerce_scale_type( nvox, factor, MRI_float, fdata, MRI_short, sdata ); DSET_BRICK_FACTOR( dset, 0 ) = factor == 0.0 ? 0.0 : 1.0 / factor; THD_load_statistics( dset ); } free(fdata); return NULL; /* success */ }
char * MASKAVE_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; THD_3dim_dataset * input_dset , * mask_dset ; int iv , mcount , nvox , ii , sigmait , nvals=0 , doall , ivbot,ivtop ; float mask_bot=666.0 , mask_top=-666.0 ; double sum=0.0 , sigma=0.0 ; float * sumar=NULL , * sigmar=NULL ; char * tag , * str , buf[64] , abuf[32],sbuf[32] ; byte * mmm ; char * cname=NULL ; /* 06 Aug 1998 */ int cdisk=0 ; /* 22 Aug 2000 */ int miv=0 ; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ if( plint == NULL ) return "*************************\n" "MASKAVE_main: NULL input\n" "*************************" ; /*-- read 1st line --*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; input_dset = PLUTO_find_dset(idc) ; if( input_dset == NULL ) return "********************************\n" "MASKAVE_main: bad input dataset\n" "********************************" ; iv = (int) PLUTO_get_number(plint) ; if( iv >= DSET_NVALS(input_dset) ) return "**********************************\n" "MASKAVE_main: bad input sub-brick\n" "**********************************" ; doall = (iv < 0) ; if( doall ){ nvals = DSET_NVALS(input_dset) ; ivbot = 0 ; ivtop = nvals-1 ; } else { ivbot = ivtop = iv ; } DSET_load(input_dset) ; if( DSET_ARRAY(input_dset,ivbot) == NULL ) return "*********************************\n" "MASKAVE_main: can't load dataset\n" "*********************************" ; nvox = DSET_NVOX(input_dset) ; /*-- read 2nd line --*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; mask_dset = PLUTO_find_dset(idc) ; if( mask_dset == NULL ) return "*******************************\n" "MASKAVE_main: bad mask dataset\n" "*******************************" ; if( DSET_NVOX(mask_dset) != nvox ) return "*************************************************************\n" "MASKAVE_main: mask input dataset doesn't match source dataset\n" "*************************************************************" ; miv = (int) PLUTO_get_number(plint) ; /* 06 Aug 1998 */ if( miv >= DSET_NVALS(mask_dset) ) return "*****************************************************\n" "MASKAVE_main: mask dataset sub-brick index is too big\n" "*****************************************************" ; DSET_load(mask_dset) ; if( DSET_ARRAY(mask_dset,0) == NULL ) return "**************************************\n" "MASKAVE_main: can't load mask dataset\n" "**************************************" ; /*-- read optional lines --*/ while( (tag=PLUTO_get_optiontag(plint)) != NULL ){ if( strcmp(tag,"Range") == 0 ){ mask_bot = PLUTO_get_number(plint) ; mask_top = PLUTO_get_number(plint) ; continue ; } if( strcmp(tag,"1D Save") == 0 ){ char * yn ; cname = PLUTO_get_string(plint) ; yn = PLUTO_get_string(plint) ; cdisk = (strcmp(yn,yesno_list[0]) == 0) ; continue ; } } /*------------------------------------------------------*/ /*---------- At this point, the inputs are OK ----------*/ /*-- build a byte mask array --*/ mmm = (byte *) malloc( sizeof(byte) * nvox ) ; if( mmm == NULL ) return "*** Can't malloc workspace! ***" ; /* separate code for each input data type */ switch( DSET_BRICK_TYPE(mask_dset,miv) ){ default: free(mmm) ; return "*** Can't use mask dataset -- illegal data type! ***" ; case MRI_short:{ short mbot , mtop ; short * mar = (short *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = SHORTIZE(mask_bot/mfac) ; mtop = SHORTIZE(mask_top/mfac) ; } else { mbot = (short) -MRI_TYPE_maxval[MRI_short] ; mtop = (short) MRI_TYPE_maxval[MRI_short] ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; case MRI_byte:{ byte mbot , mtop ; byte * mar = (byte *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = BYTEIZE(mask_bot/mfac) ; mtop = BYTEIZE(mask_top/mfac) ; if( mtop == 0 ){ free(mmm) ; return "*** Illegal mask range for mask dataset of bytes. ***" ; } } else { mbot = 0 ; mtop = (byte) MRI_TYPE_maxval[MRI_short] ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; case MRI_float:{ float mbot , mtop ; float * mar = (float *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = (float) (mask_bot/mfac) ; mtop = (float) (mask_top/mfac) ; } else { mbot = -WAY_BIG ; mtop = WAY_BIG ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; } if( mcount == 0 ){ free(mmm) ; return "*** No voxels survive the masking operations! ***" ; } sigmait = (mcount > 1) ; /*-- compute statistics --*/ if( doall ){ sumar = (float *) malloc( sizeof(float) * nvals ) ; sigmar = (float *) malloc( sizeof(float) * nvals ) ; } for( iv=ivbot ; iv <= ivtop ; iv++ ){ sum = sigma = 0.0 ; /* 13 Dec 1999 */ switch( DSET_BRICK_TYPE(input_dset,iv) ){ default: free(mmm) ; if( doall ){ free(sumar) ; free(sigmar) ; } return "*** Can't use source dataset -- illegal data type! ***" ; case MRI_short:{ short * bar = (short *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; case MRI_byte:{ byte * bar = (byte *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; case MRI_float:{ float * bar = (float *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; } if( doall ){ sumar[iv] = sum ; sigmar[iv] = sigma ; } } free(mmm) ; /*-- send report --*/ if( doall ){ str = (char *) malloc( 1024 + 64*nvals ) ; sprintf(str," ****** ROI statistics ****** \n" " Source = %s [all sub-bricks] \n" " Mask = %s [%s]" , DSET_FILECODE(input_dset) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) ) ; if( mask_bot <= mask_top ){ sprintf(buf," [range %g .. %g]" , mask_bot , mask_top ) ; strcat(str,buf) ; } strcat(str," \n") ; sprintf(buf," Count = %d voxels\n",mcount) ; strcat(str,buf) ; for( iv=0 ; iv < nvals ; iv++ ){ AV_fval_to_char( sumar[iv] , abuf ) ; AV_fval_to_char( sigmar[iv] , sbuf ) ; sprintf(buf," Average = %9.9s Sigma = %9.9s [%s] \n", abuf,sbuf , DSET_BRICK_LABEL(input_dset,iv) ) ; strcat(str,buf) ; } PLUTO_popup_textwin( plint , str ) ; /* 06 Aug 1998 */ if( cname != NULL && cname[0] != '\0' ){ MRI_IMAGE * qim = mri_new_vol_empty( nvals,1,1 , MRI_float ) ; mri_fix_data_pointer( sumar , qim ) ; PLUTO_register_timeseries( cname , qim ) ; if( cdisk ){ /* 22 Aug 2000 */ if( PLUTO_prefix_ok(cname) ){ char * cn ; if( strstr(cname,".1D") == NULL ){ cn = malloc(strlen(cname)+8) ; strcpy(cn,cname) ; strcat(cn,".1D") ; } else { cn = cname ; } mri_write_1D( cn , qim ) ; if( cn != cname ) free(cn) ; } else { PLUTO_popup_transient(plint," \n" "** Illegal filename **\n" "** in 'To Disk?' !! **\n" ) ; } } mri_fix_data_pointer( NULL , qim ) ; mri_free(qim) ; } free(str) ; free(sumar) ; free(sigmar) ; } else if( mask_bot <= mask_top ){ str = (char *) malloc( 1024 ) ; sprintf( str , " *** ROI Statistics *** \n" " Source = %s [%s] \n" " Mask = %s [%s] [range %g .. %g] \n" " Count = %d voxels \n" " Average = %g \n" " Sigma = %g " , DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) , mask_bot , mask_top , mcount , sum , sigma ) ; PLUTO_popup_message(plint,str) ; free(str) ; } else { str = (char *) malloc( 1024 ) ; sprintf( str , " *** ROI Statistics *** \n" " Source = %s [%s] \n" " Mask = %s [%s] \n" " Count = %d voxels \n" " Average = %g \n" " Sigma = %g " , DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) , mcount , sum , sigma ) ; PLUTO_popup_message(plint,str) ; free(str) ; } return NULL ; }
/*! Turn float arrays into sub-bricks of a preset type (based on code in 3dMean) dset (THD_3dim_dataset *) new dset to which arrays will be added far (float **) each far[i] is to become one sub-brick in dset nval (int) the number of arrays in far otype (int) the sub-brick type. Supported options are: MRI_float (so far scaleopt (char) scaling options: 'A' scale if needed 'F' do scale each sub-brick 'G' scale all sub-bricks with the same factor 'N' Do not scale verb (int) loquaciousness returns 1 if all is well 0 all hell broke loose */ int EDIT_add_bricks_from_far(THD_3dim_dataset *dset, float **far, int nval, int otype, char scaleopt, int verb) { int ii=0, kk=0, nxyz; ENTRY("EDIT_add_bricks_from_far"); if (scaleopt != 'A' && scaleopt != 'F' && scaleopt != 'G' && scaleopt != 'N'){ ERROR_message("Bad scaleopt value of %c", scaleopt); RETURN(0); } if (!dset) { ERROR_message("NULL input"); RETURN(0); } nxyz = DSET_NVOX(dset); switch( otype ){ default: ERROR_message("Somehow ended up with otype = %d\n",otype) ; RETURN(0) ; case MRI_float:{ for( kk=0 ; kk < nval ; kk++ ){ EDIT_substitute_brick(dset, kk, MRI_float, far[kk]); DSET_BRICK_FACTOR(dset, kk) = 0.0; far[kk] = NULL; } } break ; case MRI_byte: case MRI_short:{ void ** dfim ; float gtop=0.0 , fimfac , gtemp ; if( verb ) fprintf(stderr," ++ Scaling output to type %s brick(s)\n", MRI_TYPE_name[otype] ) ; dfim = (void **) malloc(sizeof(void *)*nval) ; if( scaleopt == 'G' ){ /* allow global scaling */ gtop = 0.0 ; for( kk=0 ; kk < nval ; kk++ ){ gtemp = MCW_vol_amax( nxyz , 1 , 1 , MRI_float, far[kk] ) ; gtop = MAX( gtop , gtemp ) ; if( gtemp == 0.0 ) WARNING_message("output sub-brick %d is all zeros!\n",kk) ; } } for (kk = 0 ; kk < nval ; kk ++ ) { if( scaleopt != 'G' && scaleopt != 'N'){ /* compute max value in this sub-brick */ gtop = MCW_vol_amax( nxyz , 1 , 1 , MRI_float, far[kk] ) ; if( gtop == 0.0 ) WARNING_message("output sub-brick %d is all zeros!\n",kk) ; } if( scaleopt == 'F' || scaleopt == 'G'){ /* scaling needed */ fimfac = (gtop > 0.0) ? MRI_TYPE_maxval[otype] / gtop : 0.0 ; } else if( scaleopt == 'A' ){ /* only if needed */ fimfac = ( gtop > MRI_TYPE_maxval[otype] || (gtop > 0.0 && gtop < 1.0) ) ? MRI_TYPE_maxval[otype]/ gtop : 0.0 ; if( fimfac == 0.0 && gtop > 0.0 ){ /* 14 May 2010 */ float fv,iv ; /* force scaling if */ for( ii=0 ; ii < nxyz ; ii++ ){ /* non-integers are inside */ fv = far[kk][ii] ; iv = rint(fv) ; if( fabsf(fv-iv) >= 0.01 ){ fimfac = MRI_TYPE_maxval[otype] / gtop ; break ; } } } } else if( scaleopt == 'N') { /* no scaling allowed */ fimfac = 0.0 ; } else { ERROR_message("Should not see this one"); RETURN(0); } if( verb ){ if( fimfac != 0.0 ) INFO_message("Sub-brick %d scale factor = %f\n",kk,fimfac) ; else INFO_message("Sub-brick %d: no scale factor\n" ,kk) ; } dfim[kk] = (void *) malloc( mri_datum_size(otype) * nxyz ) ; if( dfim[kk] == NULL ){ ERROR_message("malloc fails at output\n"); exit(1); } EDIT_coerce_scale_type( nxyz , fimfac , MRI_float, far[kk] , otype,dfim[kk] ) ; if( otype == MRI_short ) EDIT_misfit_report( DSET_FILECODE(dset) , kk , nxyz , (fimfac != 0.0f) ? 1.0f/fimfac : 0.0f , dfim[kk] , far[kk] ) ; free( far[kk] ) ; far[kk] = NULL; EDIT_substitute_brick(dset, kk, otype, dfim[kk] ); DSET_BRICK_FACTOR(dset,kk) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; dfim[kk]=NULL; } free(dfim); dfim = NULL; } break ; } RETURN(1); }
int main( int argc , char *argv[] ) { THD_3dim_dataset *dset=NULL; int iarg , verbose = -1 ; char *outbuf, *stmp=NULL; char *labelName = NULL; char *sbdelim = {"|"}; char *NAflag = {"NA"}; char *atrdelim = {"\t"}, *form=NULL; INFO_FIELDS sing[512]; int iis=0, N_sing = 0, isb=0, withhead = 0, itmp=0; int ip=0, needpair = 0, namelen=0, monog_pairs = 0; THD_3dim_dataset *tttdset=NULL, *dsetp=NULL; char *tempstr = NULL; int extinit = 0; float RL_AP_IS[6]; mainENTRY("3dinfo main") ; machdep() ; if( argc < 2) { Syntax(TXT,1) ; RETURN(0); } iarg = 1 ; while (iarg < argc && argv[iarg][0] == '-') { CHECK_HELP(argv[iarg],Syntax); if( strncmp(argv[iarg],"-verb" ,5) == 0 ){ verbose = 0; iarg++; continue; } else if( strncmp(argv[iarg],"-VERB" ,5) == 0 ){ verbose = 1; iarg++; continue; } else if( strncmp(argv[iarg],"-short",5) == 0 ){ verbose = -1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-header_line") == 0 || strcasecmp(argv[iarg],"-hdr") == 0 ){ withhead = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-monog_pairs") == 0 ){ monog_pairs = 1; iarg++; continue; } else if ( strncmp(argv[iarg],"-label2",7) == 0 ) { iarg++; if (iarg >= argc) ERROR_exit( "3dinfo needs an argument after -label2number\n"); labelName = malloc(sizeof(char) * 2048); strcpy(labelName, argv[iarg]); iarg++; continue; } else if( strcasecmp(argv[iarg],"-sb_delim") == 0) { iarg++; if (iarg >= argc) ERROR_exit( "3dinfo needs a string after -sb_delim\n"); sbdelim = argv[iarg]; iarg++; continue; } else if( strcasecmp(argv[iarg],"-NA_flag") == 0) { iarg++; if (iarg >= argc) ERROR_exit( "3dinfo needs a string after -NA_flag\n"); NAflag = argv[iarg]; iarg++; continue; } else if( strcasecmp(argv[iarg],"-atr_delim") == 0) { iarg++; if (iarg >= argc) ERROR_exit( "3dinfo needs a string after -atr_delim\n"); atrdelim = argv[iarg]; iarg++; continue; } else if( strcasecmp(argv[iarg],"-space") == 0) { sing[N_sing++] = DSET_SPACE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-av_space") == 0) { sing[N_sing++] = AV_DSET_SPACE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-gen_space") == 0) { sing[N_sing++] = DSET_GEN_SPACE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-is_nifti") == 0) { sing[N_sing++] = IS_NIFTI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-is_atlas") == 0) { sing[N_sing++] = IS_ATLAS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-exists") == 0) { sing[N_sing++] = DSET_EXISTS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-is_oblique") == 0) { sing[N_sing++] = IS_OBLIQUE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-obliquity") == 0) { sing[N_sing++] = OBLIQUITY; iarg++; continue; } else if( strcasecmp(argv[iarg],"-handedness") == 0) { sing[N_sing++] = HANDEDNESS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-prefix") == 0) { sing[N_sing++] = PREFIX; iarg++; continue; } else if( strcasecmp(argv[iarg],"-prefix_noext") == 0) { sing[N_sing++] = PREFIX_NOEXT; iarg++; continue; } else if( strcasecmp(argv[iarg],"-ni") == 0) { sing[N_sing++] = NI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nj") == 0) { sing[N_sing++] = NJ; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nk") == 0) { sing[N_sing++] = NK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-n4") == 0) { sing[N_sing++] = NI; sing[N_sing++] = NJ; sing[N_sing++] = NK; sing[N_sing++] = NV; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Rextent") == 0) { sing[N_sing++] = EXTENT_R; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Lextent") == 0) { sing[N_sing++] = EXTENT_L; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Aextent") == 0) { sing[N_sing++] = EXTENT_A; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Pextent") == 0) { sing[N_sing++] = EXTENT_P; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Iextent") == 0) { sing[N_sing++] = EXTENT_I; iarg++; continue; } else if( strcasecmp(argv[iarg],"-Sextent") == 0) { sing[N_sing++] = EXTENT_S; iarg++; continue; } else if( strcasecmp(argv[iarg],"-extent") == 0) { sing[N_sing++] = EXTENT_R; sing[N_sing++] = EXTENT_L; sing[N_sing++] = EXTENT_A; sing[N_sing++] = EXTENT_P; sing[N_sing++] = EXTENT_I; sing[N_sing++] = EXTENT_S; iarg++; continue; } else if( strcasecmp(argv[iarg],"-di") == 0) { sing[N_sing++] = DI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dj") == 0) { sing[N_sing++] = DJ; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dk") == 0) { sing[N_sing++] = DK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-d3") == 0) { sing[N_sing++] = DI; sing[N_sing++] = DJ; sing[N_sing++] = DK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-adi") == 0) { sing[N_sing++] = ADI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-adj") == 0) { sing[N_sing++] = ADJ; iarg++; continue; } else if( strcasecmp(argv[iarg],"-adk") == 0) { sing[N_sing++] = ADK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-ad3") == 0) { sing[N_sing++] = ADI; sing[N_sing++] = ADJ; sing[N_sing++] = ADK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-voxvol") == 0) { sing[N_sing++] = VOXVOL; iarg++; continue; } else if( strcasecmp(argv[iarg],"-iname") == 0) { sing[N_sing++] = INAME; iarg++; continue; } else if( strcasecmp(argv[iarg],"-oi") == 0) { sing[N_sing++] = OI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-oj") == 0) { sing[N_sing++] = OJ; iarg++; continue; } else if( strcasecmp(argv[iarg],"-ok") == 0) { sing[N_sing++] = OK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-o3") == 0) { sing[N_sing++] = OI; sing[N_sing++] = OJ; sing[N_sing++] = OK; iarg++; continue; }else if( strcasecmp(argv[iarg],"-nt") == 0) { sing[N_sing++] = NT; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nti") == 0) { sing[N_sing++] = NTI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nv") == 0) { sing[N_sing++] = NV; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nvi") == 0) { sing[N_sing++] = NVI; iarg++; continue; } else if( strcasecmp(argv[iarg],"-ntimes") == 0) { sing[N_sing++] = NTIMES; iarg++; continue; } else if( strcasecmp(argv[iarg],"-max_node") == 0) { sing[N_sing++] = MAX_NODE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-nijk") == 0) { sing[N_sing++] = NIJK; iarg++; continue; } else if( strcasecmp(argv[iarg],"-labeltable") == 0) { sing[N_sing++] = LTABLE; iarg++; continue; } else if( strcasecmp(argv[iarg],"-labeltable_as_atlas_points") == 0) { sing[N_sing++] = LTABLE_AS_ATLAS_POINT_LIST; iarg++; continue; } else if( strcasecmp(argv[iarg],"-atlas_points") == 0) { sing[N_sing++] = ATLAS_POINTS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-fac") == 0) { sing[N_sing++] = FAC; iarg++; continue; } else if( strcasecmp(argv[iarg],"-datum") == 0) { sing[N_sing++] = DATUM; iarg++; continue; } else if( strcasecmp(argv[iarg],"-label") == 0) { sing[N_sing++] = LABEL; iarg++; continue; } else if( strcasecmp(argv[iarg],"-min") == 0) { sing[N_sing++] = MIN; iarg++; continue; } else if( strcasecmp(argv[iarg],"-max") == 0) { sing[N_sing++] = MAX; iarg++; continue; } else if( strcasecmp(argv[iarg],"-minus") == 0) { sing[N_sing++] = MINUS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-maxus") == 0) { sing[N_sing++] = MAXUS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dmin") == 0) { sing[N_sing++] = DMIN; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dmax") == 0) { sing[N_sing++] = DMAX; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dminus") == 0) { sing[N_sing++] = DMINUS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-dmaxus") == 0) { sing[N_sing++] = DMAXUS; iarg++; continue; } else if( strcasecmp(argv[iarg],"-TR") == 0) { sing[N_sing++] = TR; iarg++; continue; } else if( strcasecmp(argv[iarg],"-header_name") == 0) { sing[N_sing++] = HEADER_NAME; iarg++; continue; } else if( strcasecmp(argv[iarg],"-brick_name") == 0) { sing[N_sing++] = BRICK_NAME; iarg++; continue; } else if( strcasecmp(argv[iarg],"-history") == 0) { sing[N_sing++] = HISTORY; iarg++; continue; } else if( strcasecmp(argv[iarg],"-all_names") == 0) { sing[N_sing++] = ALL_NAMES; iarg++; continue; } else if( strcasecmp(argv[iarg],"-orient") == 0) { sing[N_sing++] = ORIENT; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_grid") == 0) { sing[N_sing++] = SAME_GRID; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_dim") == 0) { sing[N_sing++] = SAME_DIM; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_delta") == 0) { sing[N_sing++] = SAME_DELTA; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_orient") == 0) { sing[N_sing++] = SAME_ORIENT; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_center") == 0) { sing[N_sing++] = SAME_CENTER; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_obl") == 0) { sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-slice_timing") == 0) { sing[N_sing++] = SLICE_TIMING; iarg++; continue; } else if( strcasecmp(argv[iarg],"-sval_diff") == 0) { sing[N_sing++] = SVAL_DIFF; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-val_diff") == 0) { sing[N_sing++] = VAL_DIFF; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-same_all_grid") == 0) { sing[N_sing++] = SAME_DIM; sing[N_sing++] = SAME_DELTA; sing[N_sing++] = SAME_ORIENT; sing[N_sing++] = SAME_CENTER; sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue; } else if( strcasecmp(argv[iarg],"-id") == 0) { sing[N_sing++] = ID; iarg++; continue; } else if( strcasecmp(argv[iarg],"-smode") == 0) { sing[N_sing++] = SMODE; iarg++; continue; } else { ERROR_message("Option %s unknown", argv[iarg]); suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } } if (N_sing == 0) { sing[N_sing++] = CLASSIC; } if (sing[iis] == CLASSIC) PRINT_VERSION("3dinfo") ; THD_allow_empty_dataset(1) ; /* 21 Mar 2007 */ if (iarg == argc) { ERROR_message("No dsets on command line? I have nothing to do.\n"); exit(1); } if (needpair && monog_pairs) needpair = 2; /* pair each couple separately */ if (needpair==2 && (argc-iarg) % 2) { ERROR_message("Using options requiring dset pairs but have odd number\n" "of dsets (%d) on command line.\n", (argc-iarg)); exit (1); } else if (needpair==1 && (argc-iarg) < 2) { ERROR_message("Using options requiring dset pairs but have less than\n" "two dsets (%d) on command line.\n", (argc-iarg)); exit (1); } ip = 0; for( ; iarg < argc ; iarg++ ){ if (ip == 0) { int kkk, nml; char *etr; namelen = 0; for (kkk=iarg; kkk<argc; ++kkk) { if ((etr = THD_trailname(argv[kkk],0))) { nml=strlen(etr); if (nml < 48 && nml > namelen) namelen = nml; } } if (namelen < 6) namelen = 6; if (withhead) { int havenew=0; for (iis = 0; iis < N_sing; ++iis) { if (sing[iis] != CLASSIC) { ++havenew; form = PrintForm(sing[iis], namelen, 1); /*fprintf(stderr,"ZSS: %d %s >%s<\n", sing[iis], Field_Names[sing[iis]], form);*/ fprintf(stdout, form, Field_Names[sing[iis]]); } if (havenew) { if (N_sing > 1 && iis < N_sing-1) fprintf(stdout,"%s",atrdelim); else fprintf(stdout,"\n"); } } } } if( argv[iarg][0] == '\0' ) continue ; /* bad filename */ set_obliquity_report(0); /* silence obliquity */ if (!needpair) { if (!(dset = load_3dinfo_dataset(argv[iarg]))) { /* exit(1); */ } } else { if (needpair == 2) { /* Crazy idea of comparing each pair separately */ if (ip % 2 == 0) { if (!(dset = load_3dinfo_dataset(argv[iarg] ))) { /* exit(1); */ } if (iarg+1==argc || argv[iarg+1][0] == '\0') { ERROR_message("Bad dset pair for %s\n", argv[iarg]); exit(1); } if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) { /* exit(1); */ } } else { /* swap the pair - this allows non pair requiring functions to work as before.*/ tttdset = dsetp; dsetp = dset; dset = tttdset; tttdset=NULL; } } else { /* always compare to very first dset */ if (ip==0) { if (!(dset = load_3dinfo_dataset(argv[iarg] ))) { /*exit(1);*/ } if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) { /*exit(1);*/ } } else if (ip==1) { /* switch order of first two */ tttdset = dsetp; dsetp = dset; /* now dsetp is the very first dset */ dset = tttdset; tttdset=NULL; } else { /* pair with very first, which is dsetp */ if (!(dset = load_3dinfo_dataset(argv[iarg] ))) { /*exit(1);*/ } } } } ++ip; if (0 && !dset) { /* allow for DSET_EXISTS option */ ERROR_exit("Should not get here"); } /* we should re-capture this per dataset 5 Feb 2019 [rickr] */ extinit = 0; for (iis = 0; iis < N_sing; ++iis) { if (!dset) { if (sing[iis] == CLASSIC) { if( dset == NULL ){ /* still not open? */ ERROR_exit("Can't open dataset %s\n", argv[iarg]) ; } } else if (sing[iis] != DSET_EXISTS && sing[iis] != INAME) { fprintf(stdout, "NO-DSET"); SPIT_DELIM(iis, N_sing, atrdelim); continue; } } switch (sing[iis]) { case CLASSIC: if (labelName == NULL ) /*** get and output info ***/ { outbuf = THD_dataset_info( dset , verbose ) ; if( outbuf != NULL ){ printf("\n") ; puts(outbuf) ; free(outbuf) ; outbuf = NULL ; } else { ERROR_exit("Can't get info for dataset %s",argv[iarg]) ; } } else /*** get and output label ***/ { int nval_per = dset->dblk->nvals; int foundLabel = 0; int ival=0; for (ival=0 ; ival < nval_per && !foundLabel; ival++ ) { if (strcmp(DSET_BRICK_LAB(dset,ival), labelName) == 0) { printf("%d\n", ival); foundLabel = 1; } } /* end of for (ival=0 ; ival < nval_per ; ival++ ) */ if (!foundLabel) printf("\n"); } THD_delete_3dim_dataset( dset , False ) ; free(labelName); break; case DSET_EXISTS: fprintf(stdout, "%d", dset ? 1:0); break; case DSET_SPACE: tempstr = THD_get_space(dset); if(tempstr==NULL) fprintf(stdout, "-----"); else fprintf(stdout, "%s", tempstr); break; case DSET_GEN_SPACE: tempstr = THD_get_generic_space(dset); if(tempstr==NULL) fprintf(stdout, "-----"); else fprintf(stdout, "%s", tempstr); break; case AV_DSET_SPACE: /* don't allow anything but the three AFNI views */ tempstr = THD_get_view_space(dset); if(tempstr==NULL) fprintf(stdout, "+orig"); else if (!strncasecmp(tempstr,"ORIG",4)) fprintf(stdout, "+orig"); else if (!strncasecmp(tempstr,"ACPC",4)) fprintf(stdout, "+acpc"); else if (!strncasecmp(tempstr,"TLRC",4)) fprintf(stdout, "+tlrc"); else /* shouldn't get here */ fprintf(stdout, "+orig"); break; case IS_NIFTI: if ( dset->dblk->diskptr && dset->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI ) { fprintf(stdout,"1"); } else { fprintf(stdout,"0"); } break; case IS_ATLAS: if ( is_Dset_Atlasy(dset, NULL) ) { fprintf(stdout,"1"); } else { fprintf(stdout,"0"); } break; case IS_OBLIQUE: if (dset_obliquity(dset,NULL) > 0) { fprintf(stdout,"1"); } else { fprintf(stdout,"0"); } break; case HANDEDNESS: if (THD_handedness(dset) > 0) { fprintf(stdout,"R"); } else { fprintf(stdout,"L"); } break; case OBLIQUITY: fprintf(stdout,"%.3f", THD_compute_oblique_angle(dset->daxes->ijk_to_dicom_real, 0)); break; case PREFIX: form = PrintForm(sing[iis], namelen, 1); fprintf(stdout,form, DSET_PREFIX(dset)); break; case PREFIX_NOEXT: { form = PrintForm(sing[iis], namelen, 1); stmp=DSET_prefix_noext(dset); fprintf(stdout,form, stmp); free(stmp); stmp=NULL; } break; case HEADER_NAME: fprintf(stdout,"%s", dset->dblk->diskptr->header_name); break; case BRICK_NAME: fprintf(stdout,"%s", dset->dblk->diskptr->brick_name); break; case ALL_NAMES: THD_show_dataset_names(dset, "FOR_3DINFO", stdout); break; case HISTORY: stmp = tross_Get_History(dset); fprintf(stdout,"%s", stmp ? stmp:NAflag); if (stmp) free(stmp); stmp=NULL; break; case NI: fprintf(stdout,"%d", DSET_NX(dset)); break; case NJ: fprintf(stdout,"%d", DSET_NY(dset)); break; case NK: fprintf(stdout,"%d", DSET_NZ(dset)); break; case NIJK: fprintf(stdout,"%d", DSET_NVOX(dset)); break; case NTIMES: fprintf(stdout,"%d", DSET_NUM_TIMES(dset)); break; case MAX_NODE: DSET_MAX_NODE(dset,itmp); fprintf(stdout,"%d", itmp); break; case NT: case NV: fprintf(stdout,"%d", DSET_NVALS(dset)); break; case NTI: case NVI: fprintf(stdout,"%d", DSET_NVALS(dset)-1); break; case DI: fprintf(stdout,"%f", DSET_DX(dset)); break; case DJ: fprintf(stdout,"%f", DSET_DY(dset)); break; case DK: fprintf(stdout,"%f", DSET_DZ(dset)); break; case OI: fprintf(stdout,"%f", DSET_XORG(dset)); break; case OJ: fprintf(stdout,"%f", DSET_YORG(dset)); break; case OK: fprintf(stdout,"%f", DSET_ZORG(dset)); break; case ADI: fprintf(stdout,"%f", fabs(DSET_DX(dset))); break; case EXTENT_R: case EXTENT_L: case EXTENT_A: case EXTENT_P: case EXTENT_I: case EXTENT_S: { if (!extinit) { THD_dset_extent(dset, '-', RL_AP_IS); extinit = 1; } fprintf(stdout,"%f", RL_AP_IS[sing[iis]-EXTENT_R]); } break; case ADJ: fprintf(stdout,"%f", fabs(DSET_DY(dset))); break; case ADK: fprintf(stdout,"%f", fabs(DSET_DZ(dset))); break; case VOXVOL: fprintf(stdout,"%f", fabs(DSET_DX(dset))* fabs(DSET_DY(dset))*fabs(DSET_DZ(dset))); break; case INAME: fprintf(stdout,"%s", argv[iarg]); break; case LTABLE: { char *str; if ((str = Dtable_to_nimlstring(DSET_Label_Dtable(dset), "VALUE_LABEL_DTABLE"))) { fprintf(stdout,"%s", str); free(str); } else { fprintf(stdout,"NO_LABEL_TABLE"); } } break; case LTABLE_AS_ATLAS_POINT_LIST: { ATLAS_POINT_LIST *apl=NULL; if ((apl = label_table_to_atlas_point_list(DSET_Label_Dtable(dset)))) { atlas_list_to_niml(apl,NULL); free_atlas_point_list(apl); } else { fprintf(stdout,"NO_LABEL_TABLE"); } } break; case ATLAS_POINTS: { ATR_string *atr = THD_find_string_atr( dset->dblk, "ATLAS_LABEL_TABLE"); if (atr) { fprintf(stdout,"%s", atr->ch); } else { fprintf(stdout,"NO_APL"); } } break; case FAC: { for (isb=0; isb<DSET_NVALS(dset); ++isb) { fprintf(stdout,"%f%s", DSET_BRICK_FACTOR(dset,isb), (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } break; } case DATUM: { for (isb=0; isb<DSET_NVALS(dset); ++isb) { fprintf(stdout,"%s%s", MRI_TYPE_name[DSET_BRICK_TYPE(dset,isb)], (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } break; } case LABEL: { for (isb=0; isb<DSET_NVALS(dset); ++isb) { fprintf(stdout,"%s%s", DSET_BRICK_LABEL(dset,isb) ? DSET_BRICK_LABEL(dset,isb):NAflag, (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } break; } case MIN: case MINUS: case MAX: case MAXUS: { float vv=0.0, min, max; for (isb=0; isb<DSET_NVALS(dset); ++isb) { if (!THD_subbrick_minmax(dset, isb, (sing[iis] == MINUS || sing[iis] == MAXUS) ? 0:1, &min, &max)) { fprintf(stdout,"%s%s", NAflag, (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } else { if (sing[iis] == MINUS) vv = min; else if (sing[iis] == MAXUS) vv = max; else if (sing[iis] == MIN) vv = min; else if (sing[iis] == MAX) vv = max; fprintf(stdout,"%g%s", vv, (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } } break; } case DMIN: case DMINUS: case DMAX: case DMAXUS: { float vv=0.0, min, max; if (!THD_dset_minmax(dset, (sing[iis] == DMINUS || sing[iis] == DMAXUS) ? 0:1, &min, &max)) { fprintf(stdout,"%s%s", NAflag, (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } else { if (sing[iis] == DMINUS) vv = min; else if (sing[iis] == DMAXUS) vv = max; else if (sing[iis] == DMIN) vv = min; else if (sing[iis] == DMAX) vv = max; fprintf(stdout,"%g%s", vv, (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim); } break; } case TR: #if 0 fprintf(stdout,"%f", DSET_TR_SEC(dset)); #else fprintf(stdout,"%f", DSET_TR(dset)); #endif break; case ORIENT: { /* fprintf(stdout,"%c%c%c", * ORIENT_typestr[dset->daxes->xxorient][0], ... ); */ char ostr[4]; /* just to show 23 Jan 2013 [rickr] */ THD_fill_orient_str_3(dset->daxes, ostr); fprintf(stdout,"%3s", ostr); } break; case SAME_GRID: fprintf(stdout,"%d", !THD_dataset_mismatch( dset , dsetp )); break; case SAME_DIM: fprintf(stdout,"%d", !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DIMEN)); break; case SAME_DELTA: fprintf(stdout,"%d", !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DELTA)); break; case SAME_ORIENT: fprintf(stdout,"%d", !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_ORIENT)); break; case SAME_CENTER: fprintf(stdout,"%d", !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_CENTER)); break; case SAME_OBL: fprintf(stdout,"%d", !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_OBLIQ)); break; case SLICE_TIMING: /* 6 May 2013 [rickr] */ { if( DSET_HAS_SLICE_TIMING(dset) ) { DSET_UNMSEC(dset); /* make sure times are in seconds */ for (isb=0; isb<dset->taxis->nsl; ++isb) { fprintf(stdout,"%s%f", (isb > 0) ? sbdelim : "", dset->taxis->toff_sl[isb]); } } else { /* all slices times are at t=0.0 */ for (isb=0; isb<DSET_NZ(dset); ++isb) { fprintf(stdout,"%s%f", (isb > 0) ? sbdelim : "", 0.0); } } } break; case SVAL_DIFF: fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 1)); break; case VAL_DIFF: fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 0)); break; case ID: fprintf(stdout,"%s", DSET_IDCODE_STR(dset)); break; case SMODE: fprintf(stdout,"%s", DSET_STORAGE_MODE_STR(dset)); break; default: ERROR_message("Info field not set properly (%d)\n", sing[iis]); exit(1); } if (sing[iis] != CLASSIC) { SPIT_DELIM(iis, N_sing, atrdelim); } } } exit(0) ; }
int main( int argc , char * argv[] ) { THD_3dim_dataset * dset ; THD_dataxes * daxes ; FD_brick ** brarr , * baxi , * bsag , * bcor ; int iarg , ii ; Boolean ok ; MRI_IMAGE * pim , * flim , * slim ; float * flar ; dset_range dr ; float val , fimfac ; int ival,ityp , kk ; float xbot=BIGG,xtop=BIGG , ybot=BIGG,ytop=BIGG , zbot=BIGG,ztop=BIGG ; int xgood=0 , ygood=0 , zgood=0 , proj_code=PROJ_SUM , mirror_code=MIRR_NO , nsize=0 ; char root[THD_MAX_NAME] = "proj." ; char fname[THD_MAX_NAME] ; int ixbot=0,ixtop=0 , jybot=0,jytop=0 , kzbot=0,kztop=0 ; THD_fvec3 fv ; THD_ivec3 iv ; /*--- read command line arguments ---*/ if( argc < 2 || strncmp(argv[1],"-help",6) == 0 ) Syntax() ; INIT_EDOPT( &PRED_edopt ) ; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ DB("new arg:",argv[iarg]) ; /**** check for editing option ****/ ii = EDIT_check_argv( argc , argv , iarg , &PRED_edopt ) ; if( ii > 0 ){ iarg += ii ; continue ; } /**** -sum or -max ****/ if( strncmp(argv[iarg],"-sum",6) == 0 ){ proj_code = PROJ_SUM ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-max",6) == 0 ){ proj_code = PROJ_MMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-amax",6) == 0 ){ proj_code = PROJ_AMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-smax",6) == 0 ){ proj_code = PROJ_SMAX ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-first") == 0 ){ /* 02 Nov 2000 */ proj_code = PROJ_FIRST ; first_thresh = strtod( argv[++iarg] , NULL ) ; iarg++ ; continue ; } /**** -mirror ****/ if( strncmp(argv[iarg],"-mirror",6) == 0 ){ mirror_code = MIRR_YES ; iarg++ ; continue ; } /**** -nsize ****/ if( strncmp(argv[iarg],"-nsize",6) == 0 ){ nsize = 1 ; iarg++ ; continue ; } /**** -output root ****/ if( strncmp(argv[iarg],"-output",6) == 0 || strncmp(argv[iarg],"-root",6) == 0 ){ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } MCW_strncpy( root , argv[++iarg] , THD_MAX_NAME-1 ) ; ii = strlen(root) ; if( ii == 0 ){ fprintf(stderr,"\n*** illegal rootname!\n") ; exit(-1) ; } if( root[ii-1] != '.' ){ root[ii] = '.' ; root[ii+1] = '\0' ; } iarg++ ; continue ; } /**** -ALL ****/ if( strncmp(argv[iarg],"-ALL",6) == 0 || strncmp(argv[iarg],"-all",6) == 0 ){ xgood = ygood = zgood = 1 ; xbot = ybot = zbot = -BIGG ; xtop = ytop = ztop = BIGG ; iarg++ ; continue ; } /**** -RL {all | x1 x2} ****/ if( strncmp(argv[iarg],"-RL",6) == 0 || strncmp(argv[iarg],"-LR",6) == 0 || strncmp(argv[iarg],"-rl",6) == 0 || strncmp(argv[iarg],"-lr",6) == 0 || strncmp(argv[iarg],"-sag",6)== 0 ){ char * cerr ; float tf ; xgood = 1 ; /* mark for x projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ xbot = -BIGG; xtop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } xbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'R' && xbot > 0.0 ) xbot = -xbot ; xtop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'R' && xtop > 0.0 ) xtop = -xtop ; if( xbot > xtop ){ tf = xbot ; xbot = xtop ; xtop = tf ; } iarg +=3 ; continue ; } /**** -AP {all | y1 y2} ****/ if( strncmp(argv[iarg],"-AP",6) == 0 || strncmp(argv[iarg],"-PA",6) == 0 || strncmp(argv[iarg],"-ap",6) == 0 || strncmp(argv[iarg],"-pa",6) == 0 || strncmp(argv[iarg],"-cor",6)== 0 ){ char * cerr ; float tf ; ygood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ ybot = -BIGG ; ytop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } ybot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'A' && ybot > 0.0 ) ybot = -ybot ; ytop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'A' && ytop > 0.0 ) ytop = -ytop ; if( ybot > ytop ){ tf = ybot ; ybot = ytop ; ytop = tf ; } iarg +=3 ; continue ; } /**** -IS {all | z1 z2} ****/ if( strncmp(argv[iarg],"-IS",6) == 0 || strncmp(argv[iarg],"-SI",6) == 0 || strncmp(argv[iarg],"-is",6) == 0 || strncmp(argv[iarg],"-si",6) == 0 || strncmp(argv[iarg],"-axi",6)== 0 ){ char * cerr ; float tf ; zgood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ zbot = -BIGG ; ztop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } zbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'I' && zbot > 0.0 ) zbot = -zbot ; ztop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'I' && ztop > 0.0 ) ztop = -ztop ; if( zbot > ztop ){ tf = zbot ; zbot = ztop ; ztop = tf ; } iarg +=3 ; continue ; } /**** unknown option ****/ fprintf(stderr,"\n*** Unknown option: %s\n",argv[iarg]) ; exit(-1) ; } /* end of loop over input options */ if( ! xgood && ! ygood && ! zgood ){ fprintf(stderr,"\n*** No projections ordered!?\n") ; exit(-1) ; } /*--- open dataset and set up to extract data slices ---*/ dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ){ fprintf(stderr,"\n*** Can't open dataset file %s\n",argv[iarg]) ; exit(-1) ; } if( DSET_NUM_TIMES(dset) > 1 ){ fprintf(stderr,"\n*** Can't project time-dependent dataset!\n") ; exit(1) ; } EDIT_one_dataset( dset, &PRED_edopt ) ; daxes = dset->daxes ; brarr = THD_setup_bricks( dset ) ; baxi = brarr[0] ; bsag = brarr[1] ; bcor = brarr[2] ; /*--- determine index range for each direction ---*/ dr = PR_get_range( dset ) ; if( xgood ){ if( xbot < dr.xbot ) xbot = dr.xbot ; if( xtop > dr.xtop ) xtop = dr.xtop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xbot,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xtop,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixtop = iv.ijk[2] ; if( ixbot > ixtop ) { ii = ixbot ; ixbot = ixtop ; ixtop = ii ; } if( ixbot < 0 ) ixbot = 0 ; if( ixtop >= bsag->n3 ) ixtop = bsag->n3 - 1 ; } if( ygood ){ if( ybot < dr.ybot ) ybot = dr.ybot ; if( ytop > dr.ytop ) ytop = dr.ytop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ybot,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jybot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ytop,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jytop = iv.ijk[2] ; if( jybot > jytop ) { ii = jybot ; jybot = jytop ; jytop = ii ; } if( jybot < 0 ) jybot = 0 ; if( jytop >= bcor->n3 ) jytop = bcor->n3 - 1 ; } if( zgood ){ if( zbot < dr.zbot ) zbot = dr.zbot ; if( ztop > dr.ztop ) ztop = dr.ztop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,zbot) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kzbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,ztop) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kztop = iv.ijk[2] ; if( kzbot > kztop ) { ii = kzbot ; kzbot = kztop ; kztop = ii ; } if( kzbot < 0 ) kzbot = 0 ; if( kztop >= baxi->n3 ) kztop = baxi->n3 - 1 ; } ival = DSET_PRINCIPAL_VALUE(dset) ; /* index to project */ ityp = DSET_BRICK_TYPE(dset,ival) ; /* type of this data */ fimfac = DSET_BRICK_FACTOR(dset,ival) ; /* scale factor of this data */ /*--- project the x direction, if desired ---*/ if( xgood ){ int n1 = bsag->n1 , n2 = bsag->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=ixbot ; ss <= ixtop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bsag ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Sagittal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Sagittal projection min = %g max = %g\n",fmin,fmax) ; strcpy(fname,root) ; strcat(fname,"sag") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the y direction, if desired ---*/ if( ygood ){ int n1 = bcor->n1 , n2 = bcor->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=jybot ; ss <= jytop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bcor ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Coronal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Coronal projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"cor") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the z direction, if desired ---*/ if( zgood ){ int n1 = baxi->n1 , n2 = baxi->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=kzbot ; ss <= kztop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , baxi ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Axial projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Axial projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"axi") ; mri_write( fname, pim ) ; mri_free(pim) ; } exit(0) ; }
MRI_IMAGE * FD_brick_to_mri( int kslice , int ival , FD_brick * br ) { MRI_IMAGE * im ; /* output */ register int ii,di,ei , jj,dj,ej , base , pp ; char * iar ; /* brick in the input */ MRI_TYPE typ ; /** desire a fake image **/ if( ival < 0 ){ im = mri_new( br->n1 , br->n2 , MRI_short ) ; im->dx = br->del1 ; im->dy = br->del2 ; im->dz = br->del3 ; return im ; } /** otherwise, get ready for a real image **/ if( ival >= br->dset->dblk->nvals ) return NULL ; iar = DSET_ARRAY(br->dset,ival) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( br->dset->dblk ) ; iar = DSET_ARRAY(br->dset,ival) ; if( iar == NULL ) return NULL ; } typ = DSET_BRICK_TYPE(br->dset,ival) ; im = mri_new( br->n1 , br->n2 , typ ) ; im->dx = br->del1 ; im->dy = br->del2 ; im->dz = br->del3 ; switch( typ ){ default: /* don't know what to do --> return nada */ mri_free( im ) ; return NULL ; case MRI_byte:{ register byte * ar = MRI_BYTE_PTR(im) ; register byte * bar = (byte *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_short:{ register short * ar = MRI_SHORT_PTR(im) ; register short * bar = (short *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_float:{ register float * ar = MRI_FLOAT_PTR(im) ; register float * bar = (float *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_int:{ register int * ar = MRI_INT_PTR(im) ; register int * bar = (int *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_double:{ register double * ar = MRI_DOUBLE_PTR(im) ; register double * bar = (double *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_complex:{ register complex * ar = MRI_COMPLEX_PTR(im) ; register complex * bar = (complex *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; case MRI_rgb:{ /* 15 Apr 2002 */ register rgbyte * ar = (rgbyte *) MRI_RGB_PTR(im) ; register rgbyte * bar = (rgbyte *) iar ; di = br->d1 ; dj = br->d2 ; /* strides */ ei = br->e1 ; ej = br->e2 ; /* final indices */ base = br->start + kslice * br->d3 ; pp = 0 ; for( jj=0 ; jj != ej ; jj += dj ) for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ; } break ; } if( DSET_BRICK_FACTOR(br->dset,ival) != 0.0 ){ MRI_IMAGE * qim ; STATUS(" scaling to float"); qim = mri_scale_to_float( DSET_BRICK_FACTOR(br->dset,ival) , im ) ; mri_free(im) ; im = qim ; } return im ; }
int main( int argc , char *argv[] ) { THD_3dim_dataset *dset_in=NULL , *dset_out ; int Lxx=-1 , Lyy=-1 , Lzz=-1 , Mode=FFT_ABS , Sign=-1 , do_alt=0 ; char *prefix = "FFTout" ; int iarg ; MRI_IMAGE *inim , *outim ; float fac ; int nx,ny,nz ; THD_ivec3 iv ; if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dFFT [options] dataset\n" "\n" "* Does the FFT of the input dataset in 3 directions (x,y,z) and\n" " produces the output dataset.\n" "\n" "* Why you'd want to do this is an interesting question.\n" "\n" "* Program 3dcalc can operate on complex-valued datasets, but\n" " only on one component at a time (cf. the '-cx2r' option).\n" "\n" "* Most other AFNI programs can only operate on real-valued\n" " datasets.\n" "\n" "* You could use 3dcalc (twice) to split a complex-valued dataset\n" " into two real-valued datasets, do your will on those with other\n" " AFNI programs, then merge the results back into a complex-valued\n" " dataset with 3dTwotoComplex.\n" "\n" "Options\n" "=======\n" " -abs = Outputs the magnitude of the FFT [default]\n" " -phase = Outputs the phase of the FFT (-PI..PI == no unwrapping!)\n" " -complex = Outputs the complex-valued FFT\n" " -inverse = Does the inverse FFT instead of the forward FFT\n" "\n" " -Lx xx = Use FFT of length 'xx' in the x-direction\n" " -Ly yy = Use FFT of length 'yy' in the y-direction\n" " -Lz zz = Use FFT of length 'zz' in the z-direction\n" " * Set a length to 0 to skip the FFT in that direction\n" "\n" " -altIN = Alternate signs of input data before FFT, to bring\n" " zero frequency from edge of FFT-space to center of grid\n" " for cosmetic purposes.\n" " -altOUT = Alternate signs of output data after FFT. If you\n" " use '-altI' on the forward transform, then you should\n" " use '-altO' an the inverse transform, to get the\n" " signs of the recovered image correct.\n" " **N.B.: You cannot use '-altIN' and '-altOUT' in the same run!\n" "\n" " -input dd = Read the input dataset from 'dd', instead of\n" " from the last argument on the command line.\n" "\n" " -prefix pp = Use 'pp' for the output dataset prefix.\n" "\n" "Notes\n" "=====\n" " * In the present avatar, only 1 sub-brick will be processed.\n" "\n" " * The program can only do FFT lengths that are factorable\n" " into a product of powers of 2, 3, and 5, and are even.\n" " + The largest power of 3 that is allowed is 3^3 = 27.\n" " + The largest power of 5 that is allowed is 5^3 = 125.\n" " + e.g., FFT of length 3*5*8=120 is possible.\n" " + e.g., FFT of length 4*31 =124 is not possible.\n" "\n" " * The 'x', 'y', and 'z' axes here refer to the order the\n" " data is stored, not DICOM coordinates; cf. 3dinfo.\n" "\n" " * If you force (via '-Lx' etc.) an FFT length that is not\n" " allowed, the program will stop with an error message.\n" "\n" " * If you force an FFT length that is shorter than an dataset\n" " axis dimension, the program will stop with an error message.\n" "\n" " * If you don't force an FFT length along a particular axis,\n" " the program will pick the smallest legal value that is\n" " greater than or equal to the corresponding dataset dimension.\n" " + e.g., 124 would be increased to 128.\n" "\n" " * If an FFT length is longer than an axis length, then the\n" " input data in that direction is zero-padded at the end.\n" "\n" " * For -abs and -phase, the output dataset is in float format.\n" "\n" " * If you do the forward and inverse FFT, then you should get back\n" " the original dataset, except for roundoff error and except that\n" " the new dataset axis dimensions may be longer than the original.\n" "\n" " * Forward FFT = sum_{k=0..N-1} [ exp(-2*PI*i*k/N) * data(k) ]\n" "\n" " * Inverse FFT = sum_{k=0..N-1} [ exp(+2*PI*i*k/N) * data(k) ] / N\n" "\n" " * Started a long time ago, but only finished in Aug 2009 at the\n" " request of John Butman, because he asked so nicely. (Now pay up!)\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } PRINT_VERSION("3dFFT") ; mainENTRY("3dFFT main") ; machdep() ; AUTHOR("RW Cox") ; AFNI_logger("3dFFT",argc,argv) ; /*--- scan args ---*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncasecmp(argv[iarg],"-altI",5) == 0 ){ do_alt = 1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-altOUT",5) == 0 ){ do_alt = -1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-inverse",4) == 0 ){ Sign = +1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-abs",4) == 0 ){ Mode = FFT_ABS ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-phase",4) == 0 ){ Mode = FFT_PHASE ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-complex",4) == 0 ){ Mode = FFT_COMPLEX ; iarg++ ; continue ; } if( strlen(argv[iarg]) == 3 && strncmp(argv[iarg],"-L",2) == 0 ){ int lll=-1 , mmm ; char *ept ; iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after option %s",argv[iarg-1]) ; lll = strtol( argv[iarg] , &ept , 10 ) ; if( *ept != '\0' ) ERROR_exit("bad argument after option %s",argv[iarg-1]) ; if( lll > 0 && (mmm = csfft_nextup_even(lll)) != lll ) ERROR_exit( "'%s %d' is not a legal FFT length here: next largest legal value = %d" , argv[iarg-1] , lll , mmm ) ; switch( argv[iarg-1][2] ){ case 'x': case 'X': Lxx = lll ; break ; case 'y': case 'Y': Lyy = lll ; break ; case 'z': case 'Z': Lzz = lll ; break ; default: ERROR_exit("unknown option '%s'",argv[iarg-1]) ; } iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-prefix",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; prefix = strdup( argv[iarg] ) ; if( !THD_filename_ok(prefix) ) ERROR_exit("bad argument after %s\n",argv[iarg-1]) ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-input",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); iarg++ ; continue ; } ERROR_exit("unknown option '%s'\n",argv[iarg]) ; } /* check for simple errors */ if( Lxx == 0 && Lyy == 0 && Lzz == 0 ) ERROR_exit("-Lx, -Ly, -Lz all given as zero?!") ; /* open input dataset */ if( dset_in == NULL ){ if( iarg >= argc ) ERROR_exit("no input dataset on command line?!\n") ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); } nx = DSET_NX(dset_in) ; ny = DSET_NY(dset_in) ; nz = DSET_NZ(dset_in) ; if( DSET_NVALS(dset_in) > 1 ) WARNING_message("only 3dFFT-ing sub-brick #0 of input dataset") ; /* establish actual FFT lengths now (0 ==> no FFT) */ if( nx == 1 ) Lxx = 0 ; /* can't FFT if dataset is shrimpy! */ if( ny == 1 ) Lyy = 0 ; if( nz == 1 ) Lzz = 0 ; if( Lxx < 0 ) Lxx = csfft_nextup_even(nx) ; /* get FFT length from */ if( Lyy < 0 ) Lyy = csfft_nextup_even(ny) ; /* dataset dimensions */ if( Lzz < 0 ) Lzz = csfft_nextup_even(nz) ; INFO_message("x-axis length=%d ; FFT length=%d %s",nx,Lxx,(Lxx==0)?"==> none":"\0") ; INFO_message("y-axis length=%d ; FFT length=%d %s",ny,Lyy,(Lyy==0)?"==> none":"\0") ; INFO_message("z-axis length=%d ; FFT length=%d %s",nz,Lzz,(Lzz==0)?"==> none":"\0") ; if( Lxx > 0 && Lxx < nx ) ERROR_exit("x-axis FFT length too short for data!") ; if( Lyy > 0 && Lyy < ny ) ERROR_exit("y-axis FFT length too short for data!") ; if( Lzz > 0 && Lzz < nz ) ERROR_exit("z-axis FFT length too short for data!") ; /* extract sub-brick #0 */ DSET_load(dset_in) ; CHECK_LOAD_ERROR(dset_in) ; inim = mri_to_complex( DSET_BRICK(dset_in,0) ) ; /* convert input to complex */ fac = DSET_BRICK_FACTOR(dset_in,0) ; if( fac > 0.0f && fac != 1.0f ){ /* scale it if needed */ int ii , nvox = nx*ny*nz ; complex *car = MRI_COMPLEX_PTR(inim) ; for( ii=0 ; ii < nvox ; ii++ ){ car[ii].r *= fac ; car[ii].i *= fac ; } } DSET_unload(dset_in) ; /* input data is all copied now */ /* FFT to get output image */ csfft_scale_inverse(1) ; /* scale by 1/N for inverse FFTs */ outim = mri_fft_3D( Sign , inim , Lxx,Lyy,Lzz , do_alt ) ; mri_free(inim) ; /* post-process output? */ switch( Mode ){ case FFT_ABS:{ MRI_IMAGE *qim = mri_complex_abs(outim) ; mri_free(outim) ; outim = qim ; } break ; case FFT_PHASE:{ MRI_IMAGE *qim = mri_complex_phase(outim) ; mri_free(outim) ; outim = qim ; } break ; } /* create and write output dataset */ dset_out = EDIT_empty_copy( dset_in ) ; tross_Copy_History( dset_in , dset_out ) ; tross_Make_History( "3dFFT" , argc,argv , dset_out ) ; LOAD_IVEC3( iv , outim->nx , outim->ny , outim->nz ) ; EDIT_dset_items( dset_out , ADN_prefix , prefix , ADN_nvals , 1 , ADN_ntt , 0 , ADN_nxyz , iv , /* change dimensions, possibly */ ADN_none ) ; EDIT_BRICK_FACTOR( dset_out , 0 , 0.0 ) ; EDIT_substitute_brick( dset_out , 0 , outim->kind , mri_data_pointer(outim) ) ; DSET_write(dset_out) ; WROTE_DSET(dset_out) ; DSET_unload(dset_out) ; exit(0) ; }
int AFNI_vedit( THD_3dim_dataset *dset , VEDIT_settings vednew , byte *mask ) { THD_datablock *dblk ; int ival ; MRI_IMAGE *dim ; ENTRY("AFNI_vedit") ; if( !ISVALID_DSET(dset) ) RETURN(0) ; dblk = dset->dblk ; /*--- check if we are to clear any existing edits, and also set future editing status to 'do nothing' ---*/ if( vednew.code <= 0 || vednew.code > VEDIT_LASTCODE ){ if( dblk->vedim != NULL ){ mri_free(dblk->vedim); dblk->vedim=NULL; } dblk->vedset.code = 0; dblk->vedset.ival = -1; dblk->vedset.exinfo = NULL; RETURN(0) ; } /* if we have existing editing results, and they correspond to the same parameters as before, then are done. otherwise, we clear out the existing results so they can be replaced. */ if( dblk->vedim != NULL && (vednew.flags&1) == 0 ){ if( memcmp(&(dblk->vedset),&vednew,sizeof(VEDIT_settings)) == 0 ) RETURN(0) ; /* exactly the same as before */ mri_free(dblk->vedim); dblk->vedim=NULL; /* clear old results */ } /*--- at this point, must edit dataset brick ---*/ dblk->vedset = vednew ; /* save settings for next time in */ dblk->vedset.flags = 0 ; /*--- create edited volume ---*/ if( vednew.code == VEDIT_CLUST ){ /*----- Clusterize -----*/ MRI_IMAGE *tim=NULL ; float thr,rmm,vmul,thb,tht ; int thrsign,posfunc,ithr ; ival = vednew.ival ; if( ival < 0 || ival > DSET_NVALS(dset) ) RETURN(0) ; dim = DBLK_BRICK(dblk,ival) ; if( dim == NULL || mri_data_pointer(dim) == NULL ){ DSET_load(dset) ; dim = DBLK_BRICK(dblk,ival) ; if( dim == NULL || mri_data_pointer(dim) == NULL ) RETURN(0) ; } dim->dx = fabs(DSET_DX(dset)); dim->dy = fabs(DSET_DY(dset)); dim->dz = fabs(DSET_DZ(dset)); ithr = (int)vednew.param[0] ; thrsign = (int)vednew.param[4] ; posfunc = (int)vednew.param[5] ; if( ithr >= 0 && ithr < DSET_NVALS(dset) ) tim = DBLK_BRICK(dblk,ithr) ; thr = vednew.param[1] ; if( DSET_BRICK_FACTOR(dset,ithr) > 0.0f ) thr /= DSET_BRICK_FACTOR(dset,ithr) ; thb = THBOT(thr) ; tht = THTOP(thr) ; rmm = vednew.param[2] ; vmul = vednew.param[3] ; dblk->vedim = mri_clusterize( rmm,vmul,dim,thb,tht,tim,posfunc , mask ); } /*--- done ---*/ RETURN(1) ; }
int RIC_CorrectDataset(THD_3dim_dataset * dset, MRI_IMAGE * phase, const double * a, const double * b, int M, int ignore) { float scalefactor; /* Scaling factor for current dset brick */ int ival, nvals; /* Current, number of dset timepoints */ int ivox, nvoxs; /* Current, number of voxels in dset subbrick */ float * pdata; /* Phase data */ int m; /* Current order number (1, M) */ double mp, cmp, smp; /* m * phase; cos(mp); sin(mp) */ double sampd; /* Intersample time in ms for phase */ double slicetime; /* Time of current slice in milliseconds */ int slicestart; /* Voxel index of 1st voxel in current slice */ int sliceend; /* End voxel index of current slice */ int icoeff, ncoeffs; /* Current, number of a,b coefficients */ int islice, nslices; /* Current, number of slices in a subbrick */ int nvoxpers; /* The number of voxels per slice */ /* Quick check of arguments */ if (!ISVALID_3DIM_DATASET(dset) || DSET_NVALS(dset) < 1 || !ISVALID_TIMEAXIS(dset->taxis) || phase == NULL || phase->nx < 1 || phase->ny != 1 || a == NULL || b == NULL || M < 1 || ignore < 0 || ignore >= DSET_NVALS(dset)) { return -1; } /* Initialize */ DSET_load(dset); nvals = DSET_NVALS(dset); nvoxpers = dset->daxes->nxx * dset->daxes->nyy; nslices = dset->daxes->nzz; nvoxs = nvoxpers * nslices; ncoeffs = nvoxs * M; sampd = dset->taxis->ttdel * nvals / phase->nx; switch (dset->taxis->units_type) { case UNITS_MSEC_TYPE: break; case UNITS_SEC_TYPE: sampd *= 1000; break; case UNITS_HZ_TYPE: sampd = 1000 / sampd; break; default: return -1; } pdata = MRI_FLOAT_PTR(phase); /* Correct each subbrick in dset */ /* Iterate over dset timepoints (TRs) => BRIK read from disk once */ for (ival = ignore; ival < nvals; ival += 1) { scalefactor = DSET_BRICK_FACTOR(dset, ival); /* Apply each order of correction to each voxel of the subbrick */ switch (DSET_BRICK_TYPE(dset, ival)) { case MRI_short: RIC_CORRECTDATASET__DO_CORRECT(short); break; case MRI_byte: RIC_CORRECTDATASET__DO_CORRECT(byte); break; case MRI_float: RIC_CORRECTDATASET__DO_CORRECT(float); break; default: /* Unsupported datatype */ return -1; } } return 0; }
int RIC_CalcCoeffAB(THD_3dim_dataset * dset, MRI_IMAGE * phase, const double * avg, double ** a, double ** b, int M, int ignore) { float scalefactor; /* Scaling factor for current dset brick */ int ival, nvals; /* Current, number of dset timepoints */ int ivox, nvoxs; /* Current, number of voxels in dset subbrick */ double * newa, * newb; /* Coefficients a and b, to be calculated */ float * pdata; /* Phase data */ int m; /* Current order number (1, M) */ double mp, cmp, smp; /* m * current phase; cos(mp); sin(mp) */ double sampd; /* Intersample time in ms for phase */ double slicetime; /* Time of current slice in milliseconds */ int slicestart; /* Voxel index of 1st voxel in current slice */ int sliceend; /* End voxel index of current slice */ double * denoma, * denomb; /* Coeff denominators for each m and slice */ int idenom, ndenoms; /* Current, number of coeff denominators */ int inumer, nnumers; /* Current, number of coeff numerators */ int islice, nslices; /* Current, number of slices in a subbrick */ int nvoxpers; /* The number of voxels per slice */ /* Quick check of arguments */ if (!ISVALID_3DIM_DATASET(dset) || DSET_NVALS(dset) < 1 || !ISVALID_TIMEAXIS(dset->taxis) || phase == NULL || phase->nx < 1 || phase->ny != 1 || avg == NULL || a == NULL || b == NULL || M < 1 || ignore < 0 || ignore >= DSET_NVALS(dset)) { return -1; } /* Initialize */ DSET_load(dset); nvals = DSET_NVALS(dset); nvoxpers = dset->daxes->nxx * dset->daxes->nyy; nslices = dset->daxes->nzz; nvoxs = nvoxpers * nslices; ndenoms = nslices * M; nnumers = nvoxs * M; sampd = dset->taxis->ttdel * nvals / phase->nx; switch (dset->taxis->units_type) { case UNITS_MSEC_TYPE: break; case UNITS_SEC_TYPE: sampd *= 1000; break; case UNITS_HZ_TYPE: sampd = 1000 / sampd; break; default: return -1; } pdata = MRI_FLOAT_PTR(phase); newa = malloc(sizeof(double) * nnumers); if (newa == NULL) { return -1; } newb = malloc(sizeof(double) * nnumers); if (newb == NULL) { free(newa); return -1; } for (inumer = 0; inumer < nnumers; inumer += 1) { newa[inumer] = 0.0; newb[inumer] = 0.0; } denoma = malloc(sizeof(double) * ndenoms); if (denoma == NULL) { free(newa); free(newb); return -1; } denomb = malloc(sizeof(double) * ndenoms); if (denomb == NULL) { free(newa); free(newb); free(denoma); return -1; } for (idenom = 0; idenom < ndenoms; idenom += 1) { denoma[idenom] = 0.0; denomb[idenom] = 0.0; } /* Calculate the coeff numerators and denominators */ /* Iterate over dset timepoints (TRs) => BRIK read from disk once */ for (ival = ignore; ival < nvals; ival += 1) { scalefactor = DSET_BRICK_FACTOR(dset, ival); /* Calculate coeff numerators and denominators over all data */ switch (DSET_BRICK_TYPE(dset, ival)) { case MRI_short: RIC_CALCCOEFFAB__DO_CALCNUMERDENOM(short); break; case MRI_byte: RIC_CALCCOEFFAB__DO_CALCNUMERDENOM(byte); break; case MRI_float: RIC_CALCCOEFFAB__DO_CALCNUMERDENOM(float); break; default: /* Unsupported datatype */ free(newa); free(newb); free(denoma); free(denomb); return -1; } } /* Divide the coeff numerators by their denominators */ idenom = 0; inumer = 0; /* m loop outside voxel loop <- coeff arrays bigger than one volume */ for (m = 1; m <= M; m += 1) { slicestart = 0; /* Iterate over slices */ for (islice = 0; islice < nslices; islice += 1) { sliceend = slicestart + nvoxpers; /* Divide numerator by denominator */ for (ivox = slicestart; ivox < sliceend; ivox += 1) { newa[inumer] /= denoma[idenom]; newb[inumer] /= denomb[idenom]; inumer += 1; } slicestart = sliceend; idenom += 1; } } *a = newa; *b = newb; free(denoma); free(denomb); return 0; }
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) ; }
int main( int argc , char *argv[] ) { int vstep=0 , ii,nvox , ntin , ntout , do_one=0 , nup=-1 ; THD_3dim_dataset *inset=NULL , *outset ; char *prefix="Upsam", *dsetname=NULL ; int verb=0 , iarg=1, datum = MRI_float; float *ivec , *ovec , trin , trout, *fac=NULL, *ofac=NULL, top=0.0, maxtop=0.0; /*------- help the pitifully ignorant user? -------*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dUpsample [options] n dataset\n" "\n" "* Upsamples a 3D+time dataset, in the time direction,\n" " by a factor of 'n'.\n" "* The value of 'n' must be between 2 and 320 (inclusive).\n" "* The output dataset is in float format by default.\n" "\n" "Options:\n" "--------\n" " -1 or -one = Use linear interpolation. Otherwise,\n" " or -linear 7th order polynomial interpolation is used.\n" "\n" " -prefix pp = Define the prefix name of the output dataset.\n" " [default prefix is 'Upsam']\n" "\n" " -verb = Be eloquently and mellifluosly verbose.\n" "\n" " -n n = An alternate way to specify n\n" " -input dataset = An alternate way to specify dataset\n" "\n" " -datum ddd = Use datatype ddd at output. Choose from\n" " float (default), short, byte.\n" "Example:\n" "--------\n" " 3dUpsample -prefix LongFred 5 Fred+orig\n" "\n" "Nota Bene:\n" "----------\n" "* You should not use this for files that were 3dTcat-ed across\n" " imaging run boundaries, since that will result in interpolating\n" " between non-contiguous time samples!\n" "* If the input has M time points, the output will have n*M time\n" " points. The last n-1 of them will be past the end of the original\n" " time series.\n" "* This program gobbles up memory and diskspace as a function of n.\n" " You can reduce output file size with -datum option.\n" "\n" "--- RW Cox - April 2008\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dUpsample"); machdep(); PRINT_VERSION("3dUpsample"); AUTHOR("RWCox") ; AFNI_logger("3dUpsample",argc,argv); /*------- read command line args -------*/ datum = MRI_float; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncasecmp(argv[iarg],"-prefix",5) == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); prefix = argv[iarg] ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal string after -prefix: '%s'",prefix) ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-one",4) == 0 || strcmp (argv[iarg],"-1" ) == 0 || strncasecmp(argv[iarg],"-lin",4) == 0 ){ do_one = 1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-verb",3) == 0 ){ verb = 1 ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-n") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); nup = (int)strtod(argv[iarg],NULL) ; if( nup < 2 || nup > 320 ) ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-input") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); dsetname = argv[iarg]; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-datum") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); if( strcmp(argv[iarg],"short") == 0 ){ datum = MRI_short ; } else if( strcmp(argv[iarg],"float") == 0 ){ datum = MRI_float ; } else if( strcmp(argv[iarg],"byte") == 0 ){ datum = MRI_byte ; } else { ERROR_message("-datum of type '%s' not supported in 3dUpsample!\n", argv[iarg] ) ; exit(1) ; } iarg++ ; continue ; } ERROR_message("Unknown argument on command line: '%s'",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit (1); } /*------- check options for completeness and consistency -----*/ if (nup == -1) { if( iarg+1 >= argc ) ERROR_exit("need 'n' and 'dataset' on command line!") ; nup = (int)strtod(argv[iarg++],NULL) ; if( nup < 2 || nup > 320 ) ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ; } if (!dsetname) { if( iarg >= argc ) ERROR_exit("need 'dataset' on command line!") ; dsetname = argv[iarg]; } inset = THD_open_dataset(dsetname) ; if( !ISVALID_DSET(inset) ) ERROR_exit("3dUpsample can't open dataset '%s'", dsetname) ; ntin = DSET_NVALS(inset) ; trin = DSET_TR(inset) ; if( ntin < 2 ) ERROR_exit("dataset '%s' has only 1 value per voxel?!",dsetname) ; nvox = DSET_NVOX(inset) ; if( verb ) INFO_message("loading input dataset into memory") ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; /*------ create output dataset ------*/ ntout = ntin * nup ; trout = trin / nup ; /* scaling factor for output */ fac = NULL; maxtop = 0.0; if (MRI_IS_INT_TYPE(datum)) { fac = (float *)calloc(DSET_NVALS(inset), sizeof(float)); ofac = (float *)calloc(ntout, sizeof(float)); for (ii=0; ii<DSET_NVALS(inset); ++ii) { top = MCW_vol_amax( DSET_NVOX(inset),1,1 , DSET_BRICK_TYPE(inset,ii), DSET_BRICK_ARRAY(inset,ii) ) ; if (DSET_BRICK_FACTOR(inset, ii)) top = top * DSET_BRICK_FACTOR(inset,ii); fac[ii] = (top > MRI_TYPE_maxval[datum]) ? top/MRI_TYPE_maxval[datum] : 0.0 ; if (top > maxtop) maxtop = top; } if (storage_mode_from_filename(prefix) != STORAGE_BY_BRICK) { fac[0] = (maxtop > MRI_TYPE_maxval[datum]) ? maxtop/MRI_TYPE_maxval[datum] : 0.0 ; for (ii=0; ii<ntout; ++ii) ofac[ii] = fac[0]; if (verb) INFO_message("Forcing global scaling, Max = %f, fac = %f\n", maxtop, fac[0]); } else { if (verb) INFO_message("Reusing scaling factors of input dset\n"); upsample_1( nup, DSET_NVALS(inset), fac, ofac); } } free(fac); fac = NULL; outset = EDIT_empty_copy(inset) ; EDIT_dset_items( outset , ADN_nvals , ntout , ADN_ntt , DSET_NUM_TIMES(inset) > 1 ? ntout : 0 , ADN_datum_all , datum , ADN_brick_fac , ofac , ADN_prefix , prefix , ADN_none ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dUpsample" , argc,argv , outset ) ; free(ofac); ofac = NULL; if( outset->taxis != NULL ){ outset->taxis->ttdel /= nup ; outset->taxis->ttdur /= nup ; if( outset->taxis->toff_sl != NULL ){ for( ii=0 ; ii < outset->taxis->nsl ; ii++ ) outset->taxis->toff_sl[ii] /= nup ; } } for( ii=0 ; ii < ntout ; ii++ ){ /* create empty bricks to be filled below */ EDIT_substitute_brick( outset , ii , datum , NULL ) ; } /*------- loop over voxels and process them one at a time ---------*/ if( verb ) INFO_message("Upsampling time series from %d to %d: %s interpolation", ntin , ntout , (do_one) ? "linear" : "heptic" ) ; if( verb && nvox > 499 ) vstep = nvox / 50 ; if( vstep > 0 ) fprintf(stderr,"++ voxel loop: ") ; ivec = (float *)malloc(sizeof(float)*ntin) ; ovec = (float *)malloc(sizeof(float)*ntout) ; for( ii=0 ; ii < nvox ; ii++ ){ if( vstep > 0 && ii%vstep==vstep-1 ) vstep_print() ; THD_extract_array( ii , inset , 0 , ivec ) ; if( do_one ) upsample_1( nup , ntin , ivec , ovec ) ; else upsample_7( nup , ntin , ivec , ovec ) ; THD_insert_series( ii , outset , ntout , MRI_float , ovec , datum==MRI_float ? 1:0 ) ; } /* end of loop over voxels */ if( vstep > 0 ) fprintf(stderr," Done!\n") ; /*----- clean up and go away -----*/ DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ; if( verb ) INFO_message("Total CPU time = %.1f s",COX_cpu_time()) ; exit(0); }
char * THD_dataset_info( THD_3dim_dataset *dset , int verbose ) { THD_dataxes *daxes ; THD_fvec3 fv1 , fv2 , fv3 ; int ival , ntimes , nval_per , n1,n2,n3 , kv,npar ; float tf, angle=0.0; long long tb ; static char *RR="[R]" , *LL="[L]" , *PP="[P]" , *AA="[A]" , *SS="[S]" , *II="[I]" , *ZZ=" " ; char *xlbot , *xltop , *ylbot , *yltop , *zlbot , *zltop , *cpt ; char str[1024], soblq[1024] ; int nstr , obliquity; char *outbuf = NULL ; /* output buffer */ ENTRY("THD_dataset_info") ; if( ! ISVALID_3DIM_DATASET(dset) ) RETURN(NULL) ; daxes = dset->daxes ; if( DSET_IS_BRIK(dset) ) outbuf = THD_zzprintf(outbuf,"Dataset File: %s\n" , DSET_FILECODE(dset) ) ; else outbuf = THD_zzprintf(outbuf,"Dataset File: %s\n" , DSET_BRIKNAME(dset) ) ; outbuf = THD_zzprintf(outbuf,"Identifier Code: %s Creation Date: %s\n" , dset->idcode.str , dset->idcode.date ) ; outbuf = THD_zzprintf(outbuf, "Template Space: %s\n", dset->atlas_space); if( ISANAT(dset) ){ outbuf = THD_zzprintf(outbuf,"Dataset Type: %s (-%s)\n", ANAT_typestr[dset->func_type] , ANAT_prefixstr[dset->func_type] ) ; } else { outbuf = THD_zzprintf(outbuf,"Dataset Type: %s (-%s)\n", FUNC_typestr[dset->func_type] , FUNC_prefixstr[dset->func_type] ) ; } /* 25 April 1998: do byte order stuff */ switch( DSET_BYTEORDER(dset) ){ case LSB_FIRST: outbuf = THD_zzprintf(outbuf,"Byte Order: %s" , LSB_FIRST_STRING) ; break ; case MSB_FIRST: outbuf = THD_zzprintf(outbuf,"Byte Order: %s" , MSB_FIRST_STRING) ; break ; } if( THD_find_string_atr(dset->dblk,ATRNAME_BYTEORDER) == NULL ) /* 19 Sep 1999 */ outbuf = THD_zzprintf(outbuf," {assumed}") ; kv = mri_short_order() ; switch( kv ){ case LSB_FIRST: outbuf = THD_zzprintf(outbuf," [this CPU native = %s]\n" , LSB_FIRST_STRING) ; break ; case MSB_FIRST: outbuf = THD_zzprintf(outbuf," [this CPU native = %s]\n" , MSB_FIRST_STRING) ; break ; } /*-- 21 Jun 2002: print storage mode --*/ if( dset->dblk->diskptr != NULL ){ outbuf = THD_zzprintf(outbuf,"Storage Mode: %s\n", storage_mode_str(dset->dblk->diskptr->storage_mode)); } tb = dset->dblk->total_bytes ; if( tb > 0 ) outbuf = THD_zzprintf(outbuf,"Storage Space: %s (%s) bytes\n", commaized_integer_string(dset->dblk->total_bytes) , approximate_number_string(dset->dblk->total_bytes) ) ; /*-- keywords --*/ if( verbose >= 0 ){ cpt = DSET_KEYWORDS(dset) ; if( cpt != NULL && cpt[0] != '\0' ){ int j = strlen(cpt) ; if( j < 99 ){ outbuf = THD_zzprintf(outbuf,"Keywords: %s\n" , cpt ) ; } else { int k ; outbuf = THD_zzprintf(outbuf,"\n----- KEYWORDS -----\n") ; for( k=0 ; k < j ; k += ZMAX ) outbuf = THD_zzprintf(outbuf,SZMAX,cpt+k) ; outbuf = THD_zzprintf(outbuf,"\n") ; } } } /*-- idcodes --*/ if( verbose >= 0 ){ if( ! ISZERO_IDCODE(dset->anat_parent_idcode) ) outbuf = THD_zzprintf(outbuf,"Anatomy Parent: %s [%s]\n" , dset->anat_parent_name , dset->anat_parent_idcode.str ) ; else if( strlen(dset->anat_parent_name) > 0 ) outbuf = THD_zzprintf(outbuf,"Anatomy Parent: %s\n" , dset->anat_parent_name ) ; if( ! ISZERO_IDCODE(dset->warp_parent_idcode) ) outbuf = THD_zzprintf(outbuf,"Warp Parent: %s [%s]\n" , dset->warp_parent_name , dset->warp_parent_idcode.str) ; else if( strlen(dset->warp_parent_name) > 0 ) outbuf = THD_zzprintf(outbuf,"Warp Parent: %s\n" , dset->warp_parent_name ) ; } /*-- tagset --*/ if( verbose > 0 && dset->tagset != NULL && dset->tagset->num > 0 ){ int ii , ns=0 ; for( ii=0 ; ii < dset->tagset->num ; ii++ ) if( dset->tagset->tag[ii].set ) ns++ ; outbuf = THD_zzprintf(outbuf,"Tagset: %d set [out of %d total]\n", ns , dset->tagset->num ) ; } /* are we oblique ? */ if((obliquity = dset_obliquity(dset, &angle)) >= 0) { if(angle>0.0) { sprintf (soblq, "Data Axes Tilt: Oblique (%.3f deg. from plumb)\n" "Data Axes Approximate Orientation:", angle); } else { sprintf (soblq, "Data Axes Tilt: Plumb\n" "Data Axes Orientation:"); } { char *gstr = EDIT_get_geometry_string(dset) ; if( gstr != NULL && *gstr != '\0' ) outbuf = THD_zzprintf(outbuf,"Geometry String: \"%s\"\n",gstr) ; } } else { sprintf (soblq, "Data Axes Tilt: Unspecified, assumed plumb\n" "Data Axes Orientation:"); } outbuf = THD_zzprintf(outbuf, "%s\n" " first (x) = %s\n" " second (y) = %s\n" " third (z) = %s [-orient %c%c%c]\n" , soblq, ORIENT_typestr[daxes->xxorient] , ORIENT_typestr[daxes->yyorient] , ORIENT_typestr[daxes->zzorient] , ORIENT_typestr[daxes->xxorient][0] , ORIENT_typestr[daxes->yyorient][0] , ORIENT_typestr[daxes->zzorient][0] ) ; LOAD_FVEC3(fv1 , daxes->xxorg , daxes->yyorg , daxes->zzorg) ; fv1 = THD_3dmm_to_dicomm( dset , fv1 ) ; LOAD_FVEC3(fv2 , daxes->xxorg + (daxes->nxx-1)*daxes->xxdel , daxes->yyorg + (daxes->nyy-1)*daxes->yydel , daxes->zzorg + (daxes->nzz-1)*daxes->zzdel ) ; fv2 = THD_3dmm_to_dicomm( dset , fv2 ) ; if( fv1.xyz[0] > fv2.xyz[0] ) FSWAP( fv1.xyz[0] , fv2.xyz[0] ) ; if( fv1.xyz[1] > fv2.xyz[1] ) FSWAP( fv1.xyz[1] , fv2.xyz[1] ) ; if( fv1.xyz[2] > fv2.xyz[2] ) FSWAP( fv1.xyz[2] , fv2.xyz[2] ) ; LOAD_FVEC3(fv3 , daxes->xxdel , daxes->yydel , daxes->zzdel) ; fv3 = THD_3dmm_to_dicomm( dset , fv3 ) ; XLAB(xlbot,fv1.xyz[0]) ; YLAB(ylbot,fv1.xyz[1]) ; ZLAB(zlbot,fv1.xyz[2]) ; XLAB(xltop,fv2.xyz[0]) ; YLAB(yltop,fv2.xyz[1]) ; ZLAB(zltop,fv2.xyz[2]) ; n1 = DAXES_NUM(daxes,ORI_R2L_TYPE) ; n2 = DAXES_NUM(daxes,ORI_A2P_TYPE) ; n3 = DAXES_NUM(daxes,ORI_I2S_TYPE) ; outbuf = THD_zzprintf(outbuf, "R-to-L extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n" "A-to-P extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n" "I-to-S extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n" , fv1.xyz[0],xlbot , fv2.xyz[0],xltop , fabs(fv3.xyz[0]) , n1 , fv1.xyz[1],ylbot , fv2.xyz[1],yltop , fabs(fv3.xyz[1]) , n2 , fv1.xyz[2],zlbot , fv2.xyz[2],zltop , fabs(fv3.xyz[2]) , n3 ) ; /*-- 01 Feb 2001: print the center of the dataset as well --*/ if( verbose > 0 ){ fv1.xyz[0] = 0.5*(fv1.xyz[0]+fv2.xyz[0]) ; XLAB(xlbot,fv1.xyz[0]) ; fv1.xyz[1] = 0.5*(fv1.xyz[1]+fv2.xyz[1]) ; YLAB(ylbot,fv1.xyz[1]) ; fv1.xyz[2] = 0.5*(fv1.xyz[2]+fv2.xyz[2]) ; ZLAB(zlbot,fv1.xyz[2]) ; outbuf = THD_zzprintf(outbuf, "R-to-L center: %9.3f %s\n" "A-to-P center: %9.3f %s\n" "I-to-S center: %9.3f %s\n" , fv1.xyz[0],xlbot , fv1.xyz[1],ylbot , fv1.xyz[2],zlbot ) ; } ntimes = DSET_NUM_TIMES(dset) ; nval_per = DSET_NVALS_PER_TIME(dset) ; if( ntimes > 1 ){ outbuf = THD_zzprintf(outbuf, "Number of time steps = %d" , ntimes ) ; STATUS("timestep") ; outbuf = THD_zzprintf(outbuf, " Time step = %.5f%s Origin = %.5f%s" , dset->taxis->ttdel , UNITS_TYPE_LABEL(dset->taxis->units_type) , dset->taxis->ttorg , UNITS_TYPE_LABEL(dset->taxis->units_type) ) ; if( dset->taxis->nsl > 0 ) outbuf = THD_zzprintf(outbuf," Number time-offset slices = %d Thickness = %.3f", dset->taxis->nsl , fabs(dset->taxis->dz_sl) ) ; outbuf = THD_zzprintf(outbuf,"\n") ; STATUS("nsl done") ; if( verbose > 0 && dset->taxis->nsl > 0 && dset->taxis->toff_sl != NULL ){ outbuf = THD_zzprintf(outbuf,"Time-offsets per slice:") ; for( ival=0 ; ival < dset->taxis->nsl ; ival++ ) outbuf = THD_zzprintf(outbuf, " %.3f" , dset->taxis->toff_sl[ival] ) ; outbuf = THD_zzprintf(outbuf,"\n") ; } } else { outbuf = THD_zzprintf(outbuf, "Number of values stored at each pixel = %d\n" , nval_per ) ; } #if 0 if( verbose > 0 && ntimes > 1 ) nval_per = dset->dblk->nvals ; else nval_per = 1 ; /* 12 Feb 2002 */ #else nval_per = dset->dblk->nvals ; if( verbose < 0 && nval_per > 5 ) nval_per = 3 ; #endif /* print out stuff for each sub-brick */ for( ival=0 ; ival < nval_per ; ival++ ){ STATUS("ival a") ; sprintf( str , " -- At sub-brick #%d '%s' datum type is %s" , ival , DSET_BRICK_LAB(dset,ival) , MRI_TYPE_name[DSET_BRICK_TYPE(dset,ival)] ) ; nstr = strlen(str) ; tf = DSET_BRICK_FACTOR(dset,ival) ; if( ISVALID_STATISTIC(dset->stats) ){ if( tf != 0.0 ){ sprintf( str+nstr , ":%13.6g to %13.6g [internal]\n" "%*s[*%13.6g] %13.6g to %13.6g [scaled]\n" , dset->stats->bstat[ival].min/tf , dset->stats->bstat[ival].max/tf , nstr-16," " , tf , dset->stats->bstat[ival].min , dset->stats->bstat[ival].max ) ; } else { sprintf( str+nstr , ":%13.6g to %13.6g\n" , dset->stats->bstat[ival].min , dset->stats->bstat[ival].max ) ; } } else if( tf != 0.0 ){ sprintf( str+nstr , " [*%g]\n",tf) ; } else { sprintf( str+nstr , "\n") ; } STATUS("ival b") ; outbuf = THD_zzprintf(outbuf,"%s",str) ; /** 30 Nov 1997: print sub-brick stat params **/ kv = DSET_BRICK_STATCODE(dset,ival) ; if( FUNC_IS_STAT(kv) ){ STATUS("ival c") ; outbuf = THD_zzprintf(outbuf," statcode = %s",FUNC_prefixstr[kv] ) ; npar = FUNC_need_stat_aux[kv] ; if( npar > 0 ){ outbuf = THD_zzprintf(outbuf,"; statpar =") ; for( kv=0 ; kv < npar ; kv++ ) outbuf = THD_zzprintf(outbuf," %g",DSET_BRICK_STATPAR(dset,ival,kv)) ; } outbuf = THD_zzprintf(outbuf,"\n") ; STATUS("ival d") ; } cpt = DSET_BRICK_KEYWORDS(dset,ival) ; if( cpt != NULL && cpt[0] != '\0' ){ outbuf = THD_zzprintf(outbuf," keywords = %.66s\n",cpt) ; } STATUS("ival z") ; } if( verbose < 0 && nval_per < dset->dblk->nvals ) /* 21 Sep 2007 */ outbuf = THD_zzprintf(outbuf, "** For info on all %d sub-bricks, use '3dinfo -verb' **\n", dset->dblk->nvals) ; /** print out dataset global statistical parameters **/ if( ISFUNC(dset) && FUNC_need_stat_aux[dset->func_type] > 0 ){ outbuf = THD_zzprintf(outbuf,"Auxiliary functional statistical parameters:\n %s\n", FUNC_label_stat_aux[dset->func_type] ) ; for( ival=0 ; ival < FUNC_need_stat_aux[dset->func_type] ; ival++ ) outbuf = THD_zzprintf(outbuf," %g",dset->stat_aux[ival]) ; outbuf = THD_zzprintf(outbuf,"\n") ; } /** If present, print out History **/ { char *chn ; int j,k ; chn = tross_Get_History(dset) ; if( chn != NULL ){ j = strlen(chn) ; outbuf = THD_zzprintf(outbuf,"\n----- HISTORY -----\n") ; for( k=0 ; k < j ; k += ZMAX ) outbuf = THD_zzprintf(outbuf,SZMAX,chn+k) ; free(chn) ; outbuf = THD_zzprintf(outbuf,"\n") ; } } /** If present, print out Notes **/ if( verbose >= 0 ){ ATR_int *notecount; int num_notes, i, j, mmm ; char *chn , *chd ; notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT"); if( notecount != NULL ){ num_notes = notecount->in[0] ; if( verbose == 0 && num_notes > 5 ) num_notes = 5 ; mmm = (verbose > 0) ? ZMAX : 1200 ; /* 400 it was! Come on Bob, have a heart! -ZSS */ for (i=1; i<= num_notes; i++) { chn = tross_Get_Note( dset , i ) ; if( chn != NULL ){ j = strlen(chn) ; if( j > mmm ) chn[mmm] = '\0' ; chd = tross_Get_Notedate(dset,i) ; if( chd == NULL ){ chd = AFMALL(char,16) ; strcpy(chd,"no date") ; } outbuf = THD_zzprintf(outbuf,"\n----- NOTE %d [%s] -----\n%s\n",i,chd,chn) ; free(chn) ; free(chd) ; }
int main( int argc , char *argv[] ) { int nx,ny,nz , nxyz , ii,kk , num1,num2 , num_tt=0 , iv , piece , fim_offset; float dx,dy,dz , dxyz , num1_inv=0.0 , num2_inv , num1m1_inv=0.0 , num2m1_inv , dof , dd,tt,q1,q2 , f1,f2 , tt_max=0.0 ; THD_3dim_dataset *dset=NULL , *new_dset=NULL ; THD_3dim_dataset * base_dset; float *av1 , *av2 , *sd1 , *sd2 , *ffim , *gfim ; float *base_ary=NULL; void *vsp ; void *vdif ; /* output mean difference */ char cbuf[THD_MAX_NAME] ; float fbuf[MAX_STAT_AUX] , fimfac ; int output_datum ; float npiece , memuse ; float *dofbrik=NULL , *dofar=NULL ; THD_3dim_dataset *dof_dset=NULL ; /*-- read command line arguments --*/ if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ) TT_syntax(NULL) ; /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ mainENTRY("3dttest main"); machdep() ; PRINT_VERSION("3dttest") ; INFO_message("For most purposes, 3dttest++ should be used instead of 3dttest!") ; { int new_argc ; char ** new_argv ; addto_args( argc , argv , &new_argc , &new_argv ) ; if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; } } AFNI_logger("3dttest",argc,argv) ; TT_read_opts( argc , argv ) ; if( ! TT_be_quiet ) printf("3dttest: t-tests of 3D datasets, by RW Cox\n") ; /*-- read first dataset in set2 to get dimensions, etc. --*/ dset = THD_open_dataset( TT_set2->ar[0] ) ; /* 20 Dec 1999 BDW */ if( ! ISVALID_3DIM_DATASET(dset) ) ERROR_exit("Unable to open dataset file %s",TT_set2->ar[0]); nx = dset->daxes->nxx ; ny = dset->daxes->nyy ; nz = dset->daxes->nzz ; nxyz = nx * ny * nz ; dx = fabs(dset->daxes->xxdel) ; dy = fabs(dset->daxes->yydel) ; dz = fabs(dset->daxes->zzdel) ; dxyz = dx * dy * dz ; #ifdef TTDEBUG printf("*** nx=%d ny=%d nz=%d\n",nx,ny,nz) ; #endif /*-- make an empty copy of this dataset, for eventual output --*/ #ifdef TTDEBUG printf("*** making empty dataset\n") ; #endif new_dset = EDIT_empty_copy( dset ) ; tross_Make_History( "3dttest" , argc,argv , new_dset ) ; strcpy( cbuf , dset->self_name ) ; strcat( cbuf , "+TT" ) ; iv = DSET_PRINCIPAL_VALUE(dset) ; if( TT_datum >= 0 ){ output_datum = TT_datum ; } else { output_datum = DSET_BRICK_TYPE(dset,iv) ; if( output_datum == MRI_byte ) output_datum = MRI_short ; } #ifdef TTDEBUG printf(" ** datum = %s\n",MRI_TYPE_name[output_datum]) ; #endif iv = EDIT_dset_items( new_dset , ADN_prefix , TT_prefix , ADN_label1 , TT_prefix , ADN_directory_name , TT_session , ADN_self_name , cbuf , ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_TT_TYPE , ADN_nvals , FUNC_nvals[FUNC_TT_TYPE] , ADN_ntt , 0 , /* 07 Jun 2007 */ ADN_datum_all , output_datum , ADN_none ) ; if( iv > 0 ) ERROR_exit("%d errors in attempting to create output dataset!",iv ) ; if( THD_deathcon() && THD_is_file(new_dset->dblk->diskptr->header_name) ) ERROR_exit( "Output dataset file %s already exists--cannot continue!\a", new_dset->dblk->diskptr->header_name ) ; #ifdef TTDEBUG printf("*** deleting exemplar dataset\n") ; #endif THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; /** macro to test a malloc-ed pointer for validity **/ #define MTEST(ptr) \ if((ptr)==NULL) \ ( fprintf(stderr,"*** Cannot allocate memory for statistics!\n"), exit(0) ) /*-- make space for the t-test computations --*/ /* (allocate entire volumes) 13 Dec 2005 [rickr] */ npiece = 3.0 ; /* need at least this many */ if( TT_paired ) npiece += 1.0 ; else if( TT_set1 != NULL ) npiece += 2.0 ; npiece += mri_datum_size(output_datum) / (float) sizeof(float) ; npiece += mri_datum_size(output_datum) / (float) sizeof(float) ; #if 0 piece_size = TT_workmem * MEGA / ( npiece * sizeof(float) ) ; if( piece_size > nxyz ) piece_size = nxyz ; #ifdef TTDEBUG printf("*** malloc-ing space for statistics: %g float arrays of length %d\n", npiece,piece_size) ; #endif #endif av2 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av2) ; sd2 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd2) ; ffim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(ffim) ; num2 = TT_set2->num ; if( TT_paired ){ av1 = sd1 = NULL ; gfim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(gfim) ; num1 = num2 ; } else if( TT_set1 != NULL ){ av1 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av1) ; sd1 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd1) ; gfim = NULL ; num1 = TT_set1->num ; } else { av1 = sd1 = NULL ; gfim = NULL ; num1 = 0 ; } vdif = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vdif) ; vsp = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vsp) ; /* 27 Dec 2002: make DOF dataset (if prefix is given, and unpooled is on) */ if( TT_pooled == 0 && TT_dof_prefix[0] != '\0' ){ dofbrik = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(dofbrik) ; dof_dset = EDIT_empty_copy( new_dset ) ; tross_Make_History( "3dttest" , argc,argv , dof_dset ) ; EDIT_dset_items( dof_dset , ADN_prefix , TT_dof_prefix , ADN_directory_name , TT_session , ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE, ADN_func_type , FUNC_BUCK_TYPE , ADN_nvals , 1 , ADN_datum_all , MRI_float , ADN_none ) ; if( THD_is_file(dof_dset->dblk->diskptr->header_name) ) ERROR_exit( "-dof_prefix dataset file %s already exists--cannot continue!\a", dof_dset->dblk->diskptr->header_name ) ; EDIT_substitute_brick( dof_dset , 0 , MRI_float , dofbrik ) ; } /* print out memory usage to edify the user */ if( ! TT_be_quiet ){ memuse = sizeof(float) * nxyz * npiece + ( mri_datum_size(output_datum) + sizeof(short) ) * nxyz ; if( dofbrik != NULL ) memuse += sizeof(float) * nxyz ; /* 27 Dec 2002 */ printf("--- allocated %d Megabytes memory for internal use (%d volumes)\n", (int)(memuse/MEGA), (int)npiece) ; } mri_fix_data_pointer( vdif , DSET_BRICK(new_dset,0) ) ; /* attach bricks */ mri_fix_data_pointer( vsp , DSET_BRICK(new_dset,1) ) ; /* to new dataset */ /** only short and float are allowed for output **/ if( output_datum != MRI_short && output_datum != MRI_float ) ERROR_exit("Illegal output data type %d = %s", output_datum , MRI_TYPE_name[output_datum] ) ; num2_inv = 1.0 / num2 ; num2m1_inv = 1.0 / (num2-1) ; if( num1 > 0 ){ num1_inv = 1.0 / num1 ; num1m1_inv = 1.0 / (num1-1) ; } /*----- loop over pieces to process the input datasets with -----*/ /** macro to open a dataset and make it ready for processing **/ #define DOPEN(ds,name) \ do{ int pv ; (ds) = THD_open_dataset((name)) ; /* 16 Sep 1999 */ \ if( !ISVALID_3DIM_DATASET((ds)) ) \ ERROR_exit("Can't open dataset: %s",(name)) ; \ if( (ds)->daxes->nxx!=nx || (ds)->daxes->nyy!=ny || (ds)->daxes->nzz!=nz ) \ ERROR_exit("Axes size mismatch: %s",(name)) ; \ if( !EQUIV_GRIDS((ds),new_dset) ) \ WARNING_message("Grid mismatch: %s",(name)) ; \ if( DSET_NUM_TIMES((ds)) > 1 ) \ ERROR_exit("Can't use time-dependent data: %s",(name)) ; \ if( TT_use_editor ) EDIT_one_dataset( (ds), &TT_edopt ) ; \ else DSET_load((ds)) ; \ pv = DSET_PRINCIPAL_VALUE((ds)) ; \ if( DSET_ARRAY((ds),pv) == NULL ) \ ERROR_exit("Can't access data: %s",(name)) ; \ if( DSET_BRICK_TYPE((ds),pv) == MRI_complex ) \ ERROR_exit("Can't use complex data: %s",(name)) ; \ break ; } while (0) #if 0 /* can do it directly now (without offsets) 13 Dec 2005 [rickr] */ /** macro to return pointer to correct location in brick for current processing **/ #define SUB_POINTER(ds,vv,ind,ptr) \ do{ switch( DSET_BRICK_TYPE((ds),(vv)) ){ \ default: ERROR_exit("Illegal datum! ***"); \ case MRI_short:{ short * fim = (short *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; \ case MRI_byte:{ byte * fim = (byte *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; \ case MRI_float:{ float * fim = (float *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; } break ; } while(0) #endif /** number of pieces to process **/ /* num_piece = (nxyz + piece_size - 1) / nxyz ; */ #if 0 nice(2) ; /** lower priority a little **/ #endif /* possibly open TT_base_dset now, and convert to floats */ if( TT_base_dname ) { DOPEN(base_dset, TT_base_dname) ; base_ary = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(base_ary) ; EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(base_dset,0) , DSET_BRICK_TYPE(base_dset,0),DSET_ARRAY(base_dset,0), /* input */ MRI_float ,base_ary ) ; /* output */ THD_delete_3dim_dataset( base_dset , False ) ; base_dset = NULL ; } /* only 1 'piece' now 13 Dec 2005 [rickr] */ for( piece=0 ; piece < 1 ; piece++ ){ fim_offset = 0 ; #ifdef TTDEBUG printf("*** start of piece %d: length=%d offset=%d\n",piece,nxyz,fim_offset) ; #else if( ! TT_be_quiet ){ printf("--- starting piece %d/%d (%d voxels) ",piece+1,1,nxyz) ; fflush(stdout) ; } #endif /** process set2 (and set1, if paired) **/ for( ii=0 ; ii < nxyz ; ii++ ) av2[ii] = 0.0 ; for( ii=0 ; ii < nxyz ; ii++ ) sd2[ii] = 0.0 ; for( kk=0 ; kk < num2 ; kk++ ){ /** read in the data **/ DOPEN(dset,TT_set2->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set2->ar[kk]); #endif #if 0 /* fimfac will be compute when the results are ready */ if( piece == 0 && kk == 0 ){ fimfac = DSET_BRICK_FACTOR(dset,iv) ; if( fimfac == 0.0 ) fimfac = 1.0 ; fimfacinv = 1.0 / fimfac ; #ifdef TTDEBUG printf(" ** set fimfac = %g\n",fimfac) ; #endif } #endif /** convert it to floats (in ffim) **/ EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,ffim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; /** get the paired dataset, if present **/ if( TT_paired ){ DOPEN(dset,TT_set1->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set1->ar[kk]); #endif EDIT_coerce_scale_type( nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,gfim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; if( TT_voxel >= 0 ) fprintf(stderr,"-- paired values #%02d: %f, %f\n", kk,ffim[TT_voxel],gfim[TT_voxel]) ; for( ii=0 ; ii < nxyz ; ii++ ) ffim[ii] -= gfim[ii] ; } else if( TT_voxel >= 0 ) fprintf(stderr,"-- set2 value #%02d: %f\n",kk,ffim[TT_voxel]); #ifdef TTDEBUG printf(" * adding into av2 and sd2\n") ; #endif /* accumulate into av2 and sd2 */ for( ii=0 ; ii < nxyz ; ii++ ){ dd = ffim[ii] ; av2[ii] += dd ; sd2[ii] += dd * dd ; } } /* end of loop over set2 datasets */ /** form the mean and stdev of set2 **/ #ifdef TTDEBUG printf(" ** forming mean and sigma of set2\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] *= num2_inv ; dd = (sd2[ii] - num2*av2[ii]*av2[ii]) ; sd2[ii] = (dd > 0.0) ? sqrt( num2m1_inv * dd ) : 0.0 ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- s2 mean = %g, sd = %g\n", av2[TT_voxel],sd2[TT_voxel]) ; /** if set1 exists but is not paired with set2, process it now **/ if( ! TT_paired && TT_set1 != NULL ){ for( ii=0 ; ii < nxyz ; ii++ ) av1[ii] = 0.0 ; for( ii=0 ; ii < nxyz ; ii++ ) sd1[ii] = 0.0 ; for( kk=0 ; kk < num1 ; kk++ ){ DOPEN(dset,TT_set1->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set1->ar[kk]); #endif EDIT_coerce_scale_type( nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,ffim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; #ifdef TTDEBUG printf(" * adding into av1 and sd1\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ dd = ffim[ii] ; av1[ii] += dd ; sd1[ii] += dd * dd ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- set1 value #%02d: %g\n",kk,ffim[TT_voxel]) ; } /* end of loop over set1 datasets */ /** form the mean and stdev of set1 **/ #ifdef TTDEBUG printf(" ** forming mean and sigma of set1\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ av1[ii] *= num1_inv ; dd = (sd1[ii] - num1*av1[ii]*av1[ii]) ; sd1[ii] = (dd > 0.0) ? sqrt( num1m1_inv * dd ) : 0.0 ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- s1 mean = %g, sd = %g\n", av1[TT_voxel], sd1[TT_voxel]) ; } /* end of processing set1 by itself */ /***** now form difference and t-statistic *****/ #ifndef TTDEBUG if( ! TT_be_quiet ){ printf("+") ; fflush(stdout) ; } /* progress */ #else printf(" ** computing t-tests next\n") ; #endif #if 0 /* will do at end using EDIT_convert_dtype 13 Dec 2005 [rickr] */ /** macro to assign difference value to correct type of array **/ #define DIFASS switch( output_datum ){ \ case MRI_short: sdar[ii] = (short) (fimfacinv*dd) ; break ; \ case MRI_float: fdar[ii] = (float) dd ; break ; } #define TOP_SS 32700 #define TOP_TT (32700.0/FUNC_TT_SCALE_SHORT) #endif if( TT_paired || TT_use_bval == 1 ){ /** case 1: paired estimate or 1-sample **/ if( TT_paired || TT_n1 == 0 ){ /* the olde waye: 1 sample test */ f2 = 1.0 / sqrt( (double) num2 ) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ; /* final mean */ if( sd2[ii] > 0.0 ){ num_tt++ ; tt = av2[ii] / (f2 * sd2[ii]) ; sd2[ii] = tt; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0; } } if( TT_voxel >= 0 ) fprintf(stderr,"-- paired/bval mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; } else { /* 10 Oct 2007: -sdn1 was used with -base1: 'two' sample test */ f1 = (TT_n1-1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ; f2 = (num2 -1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ; /* final mean */ q1 = f1 * TT_sd1*TT_sd1 + f2 * sd2[ii]*sd2[ii] ; if( q1 > 0.0 ){ num_tt++ ; tt = av2[ii] / sqrt(q1) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0 ; } } } /* end of -sdn1 special case */ #ifdef TTDEBUG printf(" ** paired or bval test: num_tt = %d\n",num_tt) ; #endif } else if( TT_pooled ){ /** case 2: unpaired 2-sample, pooled variance **/ f1 = (num1-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ; f2 = (num2-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= av1[ii] ; /* final mean */ q1 = f1 * sd1[ii]*sd1[ii] + f2 * sd2[ii]*sd2[ii] ; if( q1 > 0.0 ){ num_tt++ ; tt = av2[ii] / sqrt(q1) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0 ; } } if( TT_voxel >= 0 ) fprintf(stderr,"-- unpaired, pooled mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; #ifdef TTDEBUG printf(" ** pooled test: num_tt = %d\n",num_tt) ; #endif } else { /** case 3: unpaired 2-sample, unpooled variance **/ /** 27 Dec 2002: modified to save DOF into dofar **/ if( dofbrik != NULL ) dofar = dofbrik + fim_offset ; /* 27 Dec 2002 */ for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= av1[ii] ; q1 = num1_inv * sd1[ii]*sd1[ii] ; q2 = num2_inv * sd2[ii]*sd2[ii] ; if( q1>0.0 && q2>0.0 ){ /* have positive variances? */ num_tt++ ; tt = av2[ii] / sqrt(q1+q2) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; if( dofar != NULL ) /* 27 Dec 2002 */ dofar[ii] = (q1+q2)*(q1+q2) / (num1m1_inv*q1*q1 + num2m1_inv*q2*q2) ; } else { sd2[ii] = 0.0 ; if( dofar != NULL ) dofar[ii] = 1.0 ; /* 27 Dec 2002 */ } } if( TT_voxel >= 0 ) fprintf(stderr,"-- unpaired, unpooled mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; #ifdef TTDEBUG printf(" ** unpooled test: num_tt = %d\n",num_tt) ; #endif } #ifndef TTDEBUG if( ! TT_be_quiet ){ printf("\n") ; fflush(stdout) ; } #endif } /* end of loop over pieces of the input */ if( TT_paired ){ printf("--- Number of degrees of freedom = %d (paired test)\n",num2-1) ; dof = num2 - 1 ; } else if( TT_use_bval == 1 ){ if( TT_n1 == 0 ){ printf("--- Number of degrees of freedom = %d (1-sample test)\n",num2-1) ; dof = num2 - 1 ; } else { dof = TT_n1+num2-2 ; printf("--- Number of degrees of freedom = %d (-sdn1 2-sample test)\n",(int)dof) ; } } else { printf("--- Number of degrees of freedom = %d (2-sample test)\n",num1+num2-2) ; dof = num1+num2-2 ; if( ! TT_pooled ) printf(" (For unpooled variance estimate, this is only approximate!)\n") ; } printf("--- Number of t-tests performed = %d out of %d voxels\n",num_tt,nxyz) ; printf("--- Largest |t| value found = %g\n",tt_max) ; kk = sizeof(ptable) / sizeof(float) ; for( ii=0 ; ii < kk ; ii++ ){ tt = student_p2t( ptable[ii] , dof ) ; printf("--- Double sided tail p = %8f at t = %8f\n" , ptable[ii] , tt ) ; } /**----------------------------------------------------------------------**/ /** now convert data to output format 13 Dec 2005 [rickr] **/ /* first set mean */ fimfac = EDIT_convert_dtype(nxyz , MRI_float,av2 , output_datum,vdif , 0.0) ; DSET_BRICK_FACTOR(new_dset, 0) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; dd = fimfac; /* save for debug output */ /* if output is of type short, limit t-stat magnitude to 32.7 */ if( output_datum == MRI_short ){ for( ii=0 ; ii < nxyz ; ii++ ){ if ( sd2[ii] > 32.7 ) sd2[ii] = 32.7 ; else if( sd2[ii] < -32.7 ) sd2[ii] = -32.7 ; } } fimfac = EDIT_convert_dtype(nxyz , MRI_float,sd2 , output_datum,vsp , 0.0) ; DSET_BRICK_FACTOR(new_dset, 1) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; #ifdef TTDEBUG printf(" ** fimfac for mean, t-stat = %g, %g\n",dd, fimfac) ; #endif /**----------------------------------------------------------------------**/ INFO_message("Writing combined dataset into %s\n", DSET_BRIKNAME(new_dset) ) ; fbuf[0] = dof ; for( ii=1 ; ii < MAX_STAT_AUX ; ii++ ) fbuf[ii] = 0.0 ; (void) EDIT_dset_items( new_dset , ADN_stat_aux , fbuf , ADN_none ) ; #if 0 /* factors already set */ fbuf[0] = (output_datum == MRI_short && fimfac != 1.0 ) ? fimfac : 0.0 ; fbuf[1] = (output_datum == MRI_short ) ? 1.0 / FUNC_TT_SCALE_SHORT : 0.0 ; (void) EDIT_dset_items( new_dset , ADN_brick_fac , fbuf , ADN_none ) ; #endif if( !AFNI_noenv("AFNI_AUTOMATIC_FDR") ) ii = THD_create_all_fdrcurves(new_dset) ; else ii = 0 ; THD_load_statistics( new_dset ) ; THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ; if( ii > 0 ) ININFO_message("created %d FDR curves in header",ii) ; if( dof_dset != NULL ){ /* 27 Dec 2002 */ DSET_write( dof_dset ) ; WROTE_DSET( dof_dset ) ; } 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 ; }
/*! contains code shamelessly stolen from Rick who stole it from Bob. */ SUMA_Boolean SUMA_Get_isosurface_datasets ( SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt) { static char FuncName[]={"SUMA_Get_isosurface_datasets"}; int i; SUMA_Boolean LocalHead = NOPE; SUMA_ENTRY; if (!Opt->in_vol && !Opt->in_name) { SUMA_S_Err("NULL input"); SUMA_RETURN(NOPE); } if (!Opt->in_vol) { /* open it */ Opt->in_vol = THD_open_dataset( Opt->in_name ); } if (!Opt->in_vol) { SUMA_S_Err("No volume could be had"); SUMA_RETURN(NOPE); } if (!ISVALID_DSET(Opt->in_vol)) { if (!Opt->in_name) { SUMA_SL_Err("NULL input volume."); SUMA_RETURN(NOPE); } else { SUMA_SL_Err("invalid volume."); SUMA_RETURN(NOPE); } } else if ( DSET_BRICK_TYPE(Opt->in_vol, 0) == MRI_complex) { SUMA_SL_Err("Can't do complex data."); SUMA_RETURN(NOPE); } Opt->nvox = DSET_NVOX( Opt->in_vol ); if (DSET_NVALS( Opt->in_vol) != 1) { SUMA_SL_Err("Input volume can only have one sub-brick in it.\n" "Use [.] selectors to choose sub-brick needed."); SUMA_RETURN(NOPE); } Opt->mcdatav = (double *)SUMA_malloc(sizeof(double)*Opt->nvox); if (!Opt->mcdatav) { SUMA_SL_Crit("Failed to allocate for maskv"); SUMA_RETURN(NOPE); } if (Opt->xform == SUMA_ISO_XFORM_MASK) { SUMA_LH("SUMA_ISO_XFORM_MASK"); switch (Opt->MaskMode) { case SUMA_ISO_CMASK: SUMA_LH("SUMA_ISO_CMASK"); if (Opt->cmask) { /* here's the second order grand theft */ int clen = strlen( Opt->cmask ); char * cmd; byte *bmask; cmd = (char *)malloc((clen + 1) * sizeof(char)); strcpy( cmd, Opt->cmask); bmask = EDT_calcmask( cmd, &Opt->ninmask, 0 ); SUMA_LHv("Have %d\n", Opt->ninmask); free( cmd ); /* free EDT_calcmask() string */ if ( bmask == NULL ) { SUMA_SL_Err("Failed to compute mask from -cmask option"); SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL; SUMA_RETURN(NOPE); } if ( Opt->ninmask != Opt->nvox ) { SUMA_SL_Err("Input and cmask datasets do not have " "the same dimensions\n" ); SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL; SUMA_RETURN(NOPE); } Opt->ninmask = THD_countmask( Opt->ninmask, bmask ); SUMA_LHv("Have %d\n", Opt->ninmask); for (i=0; i<Opt->nvox; ++i) if (bmask[i]) Opt->mcdatav[i] = (double)bmask[i]; else Opt->mcdatav[i] = -1; free(bmask);bmask=NULL; } else { SUMA_SL_Err("NULL cmask"); SUMA_RETURN(NOPE); } break; case SUMA_ISO_VAL: case SUMA_ISO_RANGE: SUMA_LH("SUMA_ISO_VAL, SUMA_ISO_RANGE"); /* load the dset */ DSET_load(Opt->in_vol); Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox); if (!Opt->dvec) { SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery."); SUMA_RETURN(NOPE); } EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) , DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , MRI_double , Opt->dvec ) ; /* no need for data in input volume anymore */ PURGE_DSET(Opt->in_vol); Opt->ninmask = 0; if (Opt->MaskMode == SUMA_ISO_VAL) { for (i=0; i<Opt->nvox; ++i) { if (Opt->dvec[i] == Opt->v0) { Opt->mcdatav[i] = 1; ++ Opt->ninmask; } else Opt->mcdatav[i] = -1; } } else if (Opt->MaskMode == SUMA_ISO_RANGE) { for (i=0; i<Opt->nvox; ++i) { if (Opt->dvec[i] >= Opt->v0 && Opt->dvec[i] < Opt->v1) { Opt->mcdatav[i] = 1; ++ Opt->ninmask; } else Opt->mcdatav[i] = -1; } } else { SUMA_SL_Err("Bad Miracle."); SUMA_RETURN(NOPE); } SUMA_free(Opt->dvec); Opt->dvec = NULL; /* this vector is not even created in SUMA_ISO_CMASK mode ...*/ break; default: SUMA_SL_Err("Unexpected value of MaskMode"); SUMA_RETURN(NOPE); break; } } else if (Opt->xform == SUMA_ISO_XFORM_SHIFT) { /* load the dset */ DSET_load(Opt->in_vol); Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox); if (!Opt->dvec) { SUMA_SL_Crit("Failed to allocate for dvec.\nOh misery."); SUMA_RETURN(NOPE); } EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) , DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , MRI_double , Opt->dvec ) ; /* no need for data in input volume anymore */ PURGE_DSET(Opt->in_vol); Opt->ninmask = Opt->nvox; for (i=0; i<Opt->nvox; ++i) { Opt->mcdatav[i] = Opt->dvec[i] - Opt->v0; } SUMA_free(Opt->dvec); Opt->dvec = NULL; } else if (Opt->xform == SUMA_ISO_XFORM_NONE) { /* load the dset */ DSET_load(Opt->in_vol); Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox); if (!Opt->dvec) { SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery."); SUMA_RETURN(NOPE); } EDIT_coerce_scale_type( Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) , DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , MRI_double , Opt->dvec ) ; /* no need for data in input volume anymore */ PURGE_DSET(Opt->in_vol); Opt->ninmask = Opt->nvox; for (i=0; i<Opt->nvox; ++i) { Opt->mcdatav[i] = Opt->dvec[i]; } SUMA_free(Opt->dvec); Opt->dvec = NULL; } else { SUMA_SL_Err("Bad Opt->xform."); SUMA_RETURN(NOPE); } if ( Opt->ninmask <= 0 ) { if (Opt->ninmask == 0) { SUMA_SL_Err("A negative value!\nNothing to do." ); } else { SUMA_SL_Err("An empty mask!\n Nothing to do." ); } SUMA_RETURN(NOPE); } if (Opt->debug > 0) { fprintf( SUMA_STDERR, "%s:\nInput dset %s has nvox = %d, nvals = %d", FuncName, SUMA_CHECK_NULL_STR(Opt->in_name), Opt->nvox, DSET_NVALS(Opt->in_vol) ); fprintf( SUMA_STDERR, " (%d voxels in mask)\n", Opt->ninmask ); } SUMA_RETURN(YUP); }