void output_results (THD_3dim_dataset * new_dset) { int ierror; /* flag for errors in editing dataset */ /*----- Make sure that output is a bucket dataset -----*/ ierror = EDIT_dset_items( new_dset , ADN_func_type , FUNC_BUCK_TYPE, ADN_none ) ; if (ierror > 0) FDR_error ("Errors in attempting to create output dataset."); /*----- Output the FDR dataset -----*/ if( !FDR_quiet ) fprintf(stderr,"Computing sub-brick statistics\n") ; THD_load_statistics( new_dset ) ; THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ; if( !FDR_quiet ) fprintf(stderr,"Wrote output to %s\n", DSET_BRIKNAME(new_dset) ); /*----- Deallocate memory for output dataset -----*/ THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ; }
int WB_netw_corr(int Do_r, int Do_Z, int HAVE_ROIS, char *prefix, int NIFTI_OUT, int *NROI_REF, int *Dim, double ***ROI_AVE_TS, int **ROI_LABELS_REF, THD_3dim_dataset *insetTIME, byte *mskd2, int Nmask, int argc, char *argv[]) { int i,j,k; float **AVE_TS_fl=NULL; // not great, but another format of TS char OUT_indiv0[300]; char OUT_indiv[300]; char OUT_indivZ[300]; MRI_IMAGE *mri=NULL; THD_3dim_dataset *OUT_CORR_MAP=NULL; THD_3dim_dataset *OUT_Z_MAP=NULL; float *zscores=NULL; int Nvox; Nvox = Dim[0]*Dim[1]*Dim[2]; // make average time series per voxel AVE_TS_fl = calloc( 1,sizeof(AVE_TS_fl)); for(i=0 ; i<1 ; i++) AVE_TS_fl[i] = calloc(Dim[3],sizeof(float)); if( (AVE_TS_fl == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (time series out).\n\n"); exit(123); } fprintf(stderr,"\nHAVE_ROIS=%d",HAVE_ROIS); for( k=0 ; k<HAVE_ROIS ; k++) { // each netw gets own file sprintf(OUT_indiv0,"%s_%03d_INDIV", prefix, k); mkdir(OUT_indiv0, 0777); for( i=0 ; i<NROI_REF[k] ; i++ ) { fprintf(stderr,"\nNROI_REF[%d]= %d",k,NROI_REF[k]); for( j=0 ; j<Dim[3] ; j++) AVE_TS_fl[0][j] = (float) ROI_AVE_TS[k][i][j]; if( NIFTI_OUT ) sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d.nii.gz", OUT_indiv0,ROI_LABELS_REF[k][i+1]); else sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d", OUT_indiv0,ROI_LABELS_REF[k][i+1]); mri = mri_float_arrays_to_image(AVE_TS_fl,Dim[3],1); OUT_CORR_MAP = THD_Tcorr1D(insetTIME, mskd2, Nmask, mri, "pearson", OUT_indiv); if(Do_r){ THD_load_statistics(OUT_CORR_MAP); tross_Copy_History( insetTIME , OUT_CORR_MAP ) ; tross_Make_History( "3dNetcorr", argc, argv, OUT_CORR_MAP ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(OUT_CORR_MAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(OUT_CORR_MAP)); THD_write_3dim_dataset(NULL, NULL, OUT_CORR_MAP, True); INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_CORR_MAP)); } if(Do_Z){ if( NIFTI_OUT ) sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d.nii.gz", OUT_indiv0,ROI_LABELS_REF[k][i+1]); else sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d", OUT_indiv0,ROI_LABELS_REF[k][i+1]); OUT_Z_MAP = EDIT_empty_copy(OUT_CORR_MAP); EDIT_dset_items( OUT_Z_MAP, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , OUT_indivZ, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(OUT_Z_MAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(OUT_Z_MAP)); zscores = (float *)calloc(Nvox,sizeof(float)); if( (zscores == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (zscores).\n\n"); exit(123); } for( j=0 ; j<Nvox ; j++ ) if( mskd2[j] ) // control for r ==1 BOBatanhf( THD_get_voxel(OUT_CORR_MAP, j, 0) ); /* if( THD_get_voxel(OUT_CORR_MAP, j, 0) > MAX_R ) zscores[j] = (float) atanh(MAX_R); else if ( THD_get_voxel(OUT_CORR_MAP, j, 0) < -MAX_R ) zscores[j] = (float) atanh(-MAX_R); else zscores[j] = (float) atanh(THD_get_voxel(OUT_CORR_MAP, j, 0));*/ EDIT_substitute_brick(OUT_Z_MAP, 0, MRI_float, zscores); zscores=NULL; THD_load_statistics(OUT_Z_MAP); tross_Copy_History(insetTIME, OUT_Z_MAP); tross_Make_History("3dNetcorr", argc, argv, OUT_Z_MAP); THD_write_3dim_dataset(NULL, NULL, OUT_Z_MAP, True); INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_Z_MAP)); DSET_delete(OUT_Z_MAP); free(OUT_Z_MAP); OUT_Z_MAP=NULL; } DSET_delete(OUT_CORR_MAP); free(OUT_CORR_MAP); OUT_CORR_MAP=NULL; } } free(zscores); mri_free(mri); for( i=0 ; i<1 ; i++) free(AVE_TS_fl[i]); free(AVE_TS_fl); RETURN(1); }
int main( int argc , char * argv[] ) { int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ; float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ; MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ; THD_3dim_dataset **ortset=NULL ; int nortset=0 ; THD_3dim_dataset *inset=NULL , *outset=NULL; char *prefix="RSFC" ; byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , nx,ny,nz,nvox , nfft=0 , kk ; float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime ; MRI_vectim *mrv ; float pvrad=0.0f ; int nosat=0 ; int do_despike=0 ; // @@ non-BP variables float fbotALL=0.0f, ftopALL=999999.9f; // do full range version int NumDen = 0; // switch for doing numerator or denom THD_3dim_dataset *outsetALL=NULL ; int m, mm; float delf; // harmonics int ind_low,ind_high,N_ny, ctr; float sqnt,nt_fac; gsl_fft_real_wavetable *real1, *real2; // GSL stuff gsl_fft_real_workspace *work; double *series1, *series2; double *xx1,*xx2; float numer,denom,val; float *alff=NULL,*malff=NULL,*falff=NULL, *rsfa=NULL,*mrsfa=NULL,*frsfa=NULL; // values float meanALFF=0.0f,meanRSFA=0.0f; // will be for mean in brain region THD_3dim_dataset *outsetALFF=NULL; THD_3dim_dataset *outsetmALFF=NULL; THD_3dim_dataset *outsetfALFF=NULL; THD_3dim_dataset *outsetRSFA=NULL; THD_3dim_dataset *outsetmRSFA=NULL; THD_3dim_dataset *outsetfRSFA=NULL; char out_lff[300]; char out_alff[300]; char out_malff[300]; char out_falff[300]; char out_rsfa[300]; char out_mrsfa[300]; char out_frsfa[300]; char out_unBP[300]; int SERIES_OUT = 1; int UNBP_OUT = 0; int DO_RSFA = 1; int BP_LAST = 0; // option for only doing filter to LFFs at very end of proc float de_rsfa=0.0f,nu_rsfa=0.0f; double pow1=0.0,pow2=0.0; /*-- help? --*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "\n Program to calculate common resting state functional connectivity (RSFC)\n" " parameters (ALFF, mALFF, fALFF, RSFA, etc.) for resting state time\n" " series. This program is **heavily** based on the existing\n" " 3dBandPass by RW Cox, with the amendments to calculate RSFC\n" " parameters written by PA Taylor (July, 2012).\n" " This program is part of FATCAT (Taylor & Saad, 2013) in AFNI. Importantly,\n" " its functionality can be included in the `afni_proc.py' processing-script \n" " generator; see that program's help file for an example including RSFC\n" " and spectral parameter calculation via the `-regress_RSFC' option.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " All options of 3dBandPass may be used here (with a couple other\n" " parameter options, as well): essentially, the motivation of this\n" " program is to produce ALFF, etc. values of the actual RSFC time\n" " series that you calculate. Therefore, all the 3dBandPass processing\n" " you normally do en route to making your final `resting state time\n" " series' is done here to generate your LFFs, from which the\n" " amplitudes in the LFF band are calculated at the end. In order to\n" " calculate fALFF, the same initial time series are put through the\n" " same processing steps which you have chosen but *without* the\n" " bandpass part; the spectrum of this second time series is used to\n" " calculate the fALFF denominator.\n" " \n" " For more information about each RSFC parameter, see, e.g.: \n" " ALFF/mALFF -- Zang et al. (2007),\n" " fALFF -- Zou et al. (2008),\n" " RSFA -- Kannurpatti & Biswal (2008).\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " + USAGE: 3dRSFC [options] fbot ftop dataset\n" "\n" "* One function of this program is to prepare datasets for input\n" " to 3dSetupGroupInCorr. Other uses are left to your imagination.\n" "\n" "* 'dataset' is a 3D+time sequence of volumes\n" " ++ This must be a single imaging run -- that is, no discontinuities\n" " in time from 3dTcat-ing multiple datasets together.\n" "\n" "* fbot = lowest frequency in the passband, in Hz\n" " ++ fbot can be 0 if you want to do a lowpass filter only;\n" " HOWEVER, the mean and Nyquist freq are always removed.\n" "\n" "* ftop = highest frequency in the passband (must be > fbot)\n" " ++ if ftop > Nyquist freq, then it's a highpass filter only.\n" "\n" "* Set fbot=0 and ftop=99999 to do an 'allpass' filter.\n" " ++ Except for removal of the 0 and Nyquist frequencies, that is.\n" "\n" "* You cannot construct a 'notch' filter with this program!\n" " ++ You could use 3dRSFC followed by 3dcalc to get the same effect.\n" " ++ If you are understand what you are doing, that is.\n" " ++ Of course, that is the AFNI way -- if you don't want to\n" " understand what you are doing, use Some other PrograM, and\n" " you can still get Fine StatisticaL maps.\n" "\n" "* 3dRSFC will fail if fbot and ftop are too close for comfort.\n" " ++ Which means closer than one frequency grid step df,\n" " where df = 1 / (nfft * dt) [of course]\n" "\n" "* The actual FFT length used will be printed, and may be larger\n" " than the input time series length for the sake of efficiency.\n" " ++ The program will use a power-of-2, possibly multiplied by\n" " a power of 3 and/or 5 (up to and including the 3rd power of\n" " each of these: 3, 9, 27, and 5, 25, 125).\n" "\n" "* Note that the results of combining 3dDetrend and 3dRSFC will\n" " depend on the order in which you run these programs. That's why\n" " 3dRSFC has the '-ort' and '-dsort' options, so that the\n" " time series filtering can be done properly, in one place.\n" "\n" "* The output dataset is stored in float format.\n" "\n" "* The order of processing steps is the following (most are optional), and\n" " for the LFFs, the bandpass is done between the specified fbot and ftop,\n" " while for the `whole spectrum' (i.e., fALFF denominator) the bandpass is:\n" " done only to exclude the time series mean and the Nyquist frequency:\n" " (0) Check time series for initial transients [does not alter data]\n" " (1) Despiking of each time series\n" " (2) Removal of a constant+linear+quadratic trend in each time series\n" " (3) Bandpass of data time series\n" " (4) Bandpass of -ort time series, then detrending of data\n" " with respect to the -ort time series\n" " (5) Bandpass and de-orting of the -dsort dataset,\n" " then detrending of the data with respect to -dsort\n" " (6) Blurring inside the mask [might be slow]\n" " (7) Local PV calculation [WILL be slow!]\n" " (8) L2 normalization [will be fast.]\n" " (9) Calculate spectrum and amplitudes, for RSFC parameters.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "--------\n" "OPTIONS:\n" "--------\n" " -despike = Despike each time series before other processing.\n" " ++ Hopefully, you don't actually need to do this,\n" " which is why it is optional.\n" " -ort f.1D = Also orthogonalize input to columns in f.1D\n" " ++ Multiple '-ort' options are allowed.\n" " -dsort fset = Orthogonalize each voxel to the corresponding\n" " voxel time series in dataset 'fset', which must\n" " have the same spatial and temporal grid structure\n" " as the main input dataset.\n" " ++ At present, only one '-dsort' option is allowed.\n" " -nodetrend = Skip the quadratic detrending of the input that\n" " occurs before the FFT-based bandpassing.\n" " ++ You would only want to do this if the dataset\n" " had been detrended already in some other program.\n" " -dt dd = set time step to 'dd' sec [default=from dataset header]\n" " -nfft N = set the FFT length to 'N' [must be a legal value]\n" " -norm = Make all output time series have L2 norm = 1\n" " ++ i.e., sum of squares = 1\n" " -mask mset = Mask dataset\n" " -automask = Create a mask from the input dataset\n" " -blur fff = Blur (inside the mask only) with a filter\n" " width (FWHM) of 'fff' millimeters.\n" " -localPV rrr = Replace each vector by the local Principal Vector\n" " (AKA first singular vector) from a neighborhood\n" " of radius 'rrr' millimiters.\n" " ++ Note that the PV time series is L2 normalized.\n" " ++ This option is mostly for Bob Cox to have fun with.\n" "\n" " -input dataset = Alternative way to specify input dataset.\n" " -band fbot ftop = Alternative way to specify passband frequencies.\n" "\n" " -prefix ppp = Set prefix name of output dataset. Name of filtered time\n" " series would be, e.g., ppp_LFF+orig.*, and the parameter\n" " outputs are named with obvious suffices.\n" " -quiet = Turn off the fun and informative messages. (Why?)\n" " -no_rs_out = Don't output processed time series-- just output\n" " parameters (not recommended, since the point of\n" " calculating RSFC params here is to have them be quite\n" " related to the time series themselves which are used for\n" " further analysis)." " -un_bp_out = Output the un-bandpassed series as well (default is not \n" " to). Name would be, e.g., ppp_unBP+orig.* .\n" " with suffix `_unBP'.\n" " -no_rsfa = If you don't want RSFA output (default is to do so).\n" " -bp_at_end = A (probably unnecessary) switch to have bandpassing be \n" " the very last processing step that is done in the\n" " sequence of steps listed above; at Step 3 above, only \n" " the time series mean and nyquist are BP'ed out, and then\n" " the LFF series is created only after Step 9. NB: this \n" " probably makes only very small changes for most\n" " processing sequences (but maybe not, depending usage).\n" "\n" " -notrans = Don't check for initial positive transients in the data:\n" " *OR* ++ The test is a little slow, so skipping it is OK,\n" " -nosat if you KNOW the data time series are transient-free.\n" " ++ Or set AFNI_SKIP_SATCHECK to YES.\n" " ++ Initial transients won't be handled well by the\n" " bandpassing algorithm, and in addition may seriously\n" " contaminate any further processing, such as inter-\n" " voxel correlations via InstaCorr.\n" " ++ No other tests are made [yet] for non-stationary \n" " behavior in the time series data.\n" "\n" "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" "\n" " If you use this program, please reference the introductory/description\n" " paper for the FATCAT toolbox:\n" " Taylor PA, Saad ZS (2013). FATCAT: (An Efficient) Functional\n" " And Tractographic Connectivity Analysis Toolbox. Brain \n" " Connectivity 3(5):523-535.\n" "____________________________________________________________________________\n" ); PRINT_AFNI_OMP_USAGE( " 3dRSFC" , " * At present, the only part of 3dRSFC that is parallelized is the\n" " '-blur' option, which processes each sub-brick independently.\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } /*-- startup --*/ mainENTRY("3dRSFC"); machdep(); AFNI_logger("3dRSFC",argc,argv); PRINT_VERSION("3dRSFC (from 3dBandpass by RW Cox): version THETA"); AUTHOR("PA Taylor"); nosat = AFNI_yesenv("AFNI_SKIP_SATCHECK") ; nopt = 1 ; while( nopt < argc && argv[nopt][0] == '-' ){ if( strcmp(argv[nopt],"-despike") == 0 ){ /* 08 Oct 2010 */ do_despike++ ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-nfft") == 0 ){ int nnup ; if( ++nopt >= argc ) ERROR_exit("need an argument after -nfft!") ; nfft = (int)strtod(argv[nopt],NULL) ; nnup = csfft_nextup_even(nfft) ; if( nfft < 16 || nfft != nnup ) ERROR_exit("value %d after -nfft is illegal! Next legal value = %d",nfft,nnup) ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-blur") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -blur!") ; blur = strtod(argv[nopt],NULL) ; if( blur <= 0.0f ) WARNING_message("non-positive blur?!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-localPV") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -localpv!") ; pvrad = strtod(argv[nopt],NULL) ; if( pvrad <= 0.0f ) WARNING_message("non-positive -localpv?!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-prefix") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -prefix!") ; prefix = strdup(argv[nopt]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("bad -prefix option!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-automask") == 0 ){ if( mask != NULL ) ERROR_exit("Can't use -mask AND -automask!") ; do_automask = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-mask") == 0 ){ THD_3dim_dataset *mset ; if( ++nopt >= argc ) ERROR_exit("Need argument after '-mask'") ; if( mask != NULL || do_automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset( argv[nopt] ) ; CHECK_OPEN_ERROR(mset,argv[nopt]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset); mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ; if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[nopt]) ; nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ; if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ; if( nmask < 1 ) ERROR_exit("Mask is too small to process") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-norm") == 0 ){ do_norm = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-quiet") == 0 ){ verb = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-no_rs_out") == 0 ){ // @@ SERIES_OUT = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-un_bp_out") == 0 ){ // @@ UNBP_OUT = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-no_rsfa") == 0 ){ // @@ DO_RSFA = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-bp_at_end") == 0 ){ // @@ BP_LAST = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-notrans") == 0 || strcmp(argv[nopt],"-nosat") == 0 ){ nosat = 1 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-ort") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -ort!") ; if( ortar == NULL ) INIT_IMARR(ortar) ; ortim = mri_read_1D( argv[nopt] ) ; if( ortim == NULL ) ERROR_exit("can't read from -ort '%s'",argv[nopt]) ; mri_add_name(argv[nopt],ortim) ; ADDTO_IMARR(ortar,ortim) ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-dsort") == 0 ){ THD_3dim_dataset *qset ; if( ++nopt >= argc ) ERROR_exit("need an argument after -dsort!") ; if( nortset > 0 ) ERROR_exit("only 1 -dsort option is allowed!") ; qset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(qset,argv[nopt]) ; ortset = (THD_3dim_dataset **)realloc(ortset, sizeof(THD_3dim_dataset *)*(nortset+1)) ; ortset[nortset++] = qset ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-nodetrend",6) == 0 ){ qdet = 0 ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-dt") == 0 ){ if( ++nopt >= argc ) ERROR_exit("need an argument after -dt!") ; dt = (float)strtod(argv[nopt],NULL) ; if( dt <= 0.0f ) WARNING_message("value after -dt illegal!") ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-input") == 0 ){ if( inset != NULL ) ERROR_exit("Can't have 2 -input options!") ; if( ++nopt >= argc ) ERROR_exit("need an argument after -input!") ; inset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(inset,argv[nopt]) ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-band",5) == 0 ){ if( ++nopt >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ; if( have_freq ) WARNING_message("second -band option replaces first one!") ; fbot = strtod(argv[nopt++],NULL) ; ftop = strtod(argv[nopt++],NULL) ; have_freq = 1 ; continue ; } ERROR_exit("Unknown option: '%s'",argv[nopt]) ; } /** check inputs for reasonablositiness **/ if( !have_freq ){ if( nopt+1 >= argc ) ERROR_exit("Need frequencies on command line after options!") ; fbot = (float)strtod(argv[nopt++],NULL) ; ftop = (float)strtod(argv[nopt++],NULL) ; } if( inset == NULL ){ if( nopt >= argc ) ERROR_exit("Need input dataset name on command line after options!") ; inset = THD_open_dataset(argv[nopt]) ; CHECK_OPEN_ERROR(inset,argv[nopt]) ; nopt++ ; } DSET_UNMSEC(inset) ; if( fbot < 0.0f ) ERROR_exit("fbot value can't be negative!") ; if( ftop <= fbot ) ERROR_exit("ftop value %g must be greater than fbot value %g!",ftop,fbot) ; ntime = DSET_NVALS(inset) ; if( ntime < 9 ) ERROR_exit("Input dataset is too short!") ; if( nfft <= 0 ){ nfft = csfft_nextup_even(ntime) ; if( verb ) INFO_message("Data length = %d FFT length = %d",ntime,nfft) ; (void)THD_bandpass_set_nfft(nfft) ; } else if( nfft < ntime ){ ERROR_exit("-nfft %d is less than data length = %d",nfft,ntime) ; } else { kk = THD_bandpass_set_nfft(nfft) ; if( kk != nfft && verb ) INFO_message("Data length = %d FFT length = %d",ntime,kk) ; } if( dt <= 0.0f ){ dt = DSET_TR(inset) ; if( dt <= 0.0f ){ WARNING_message("Setting dt=1.0 since input dataset lacks a time axis!") ; dt = 1.0f ; } } ftopALL = 1./dt ;// Aug,2016: should solve problem of a too-large // value for THD_bandpass_vectors(), while still // being >f_{Nyquist} if( !THD_bandpass_OK(ntime,dt,fbot,ftop,1) ) ERROR_exit("Can't continue!") ; nx = DSET_NX(inset); ny = DSET_NY(inset); nz = DSET_NZ(inset); nvox = nx*ny*nz; /* check mask, or create it */ if( verb ) INFO_message("Loading input dataset time series" ) ; DSET_load(inset) ; if( mask != NULL ){ if( mask_nx != nx || mask_ny != ny || mask_nz != nz ) ERROR_exit("-mask dataset grid doesn't match input dataset") ; } else if( do_automask ){ mask = THD_automask( inset ) ; if( mask == NULL ) ERROR_message("Can't create -automask from input dataset?") ; nmask = THD_countmask( DSET_NVOX(inset) , mask ) ; if( verb ) INFO_message("Number of voxels in automask = %d",nmask); if( nmask < 1 ) ERROR_exit("Automask is too small to process") ; } else { mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ; memset(mask,1,sizeof(byte)*nvox) ; // if( verb ) // @@ alert if aaaalllllll vox are going to be analyzed! INFO_message("No mask ==> processing all %d voxels",nvox); } /* A simple check of dataset quality [08 Feb 2010] */ if( !nosat ){ float val ; INFO_message( "Checking dataset for initial transients [use '-notrans' to skip this test]") ; val = THD_saturation_check(inset,mask,0,0) ; kk = (int)(val+0.54321f) ; if( kk > 0 ) ININFO_message( "Looks like there %s %d non-steady-state initial time point%s :-(" , ((kk==1) ? "is" : "are") , kk , ((kk==1) ? " " : "s") ) ; else if( val > 0.3210f ) /* don't ask where this threshold comes from! */ ININFO_message( "MAYBE there's an initial positive transient of 1 point, but it's hard to tell\n") ; else ININFO_message("No widespread initial positive transient detected :-)") ; } /* check -dsort inputs for match to inset */ for( kk=0 ; kk < nortset ; kk++ ){ if( DSET_NX(ortset[kk]) != nx || DSET_NY(ortset[kk]) != ny || DSET_NZ(ortset[kk]) != nz || DSET_NVALS(ortset[kk]) != ntime ) ERROR_exit("-dsort %s doesn't match input dataset grid" , DSET_BRIKNAME(ortset[kk]) ) ; } /* convert input dataset to a vectim, which is more fun */ // @@ convert BP'ing ftop/bot into indices for the DFT (below) delf = 1.0/(ntime*dt); ind_low = (int) rint(fbot/delf); ind_high = (int) rint(ftop/delf); if( ntime % 2 ) // nyquist number N_ny = (ntime-1)/2; else N_ny = ntime/2; sqnt = sqrt(ntime); nt_fac = sqrt(ntime*(ntime-1)); // @@ if BP_LAST==0: // now we go through twice, doing LFF bandpass for NumDen==0 and // `full spectrum' processing for NumDen==1. // if BP_LAST==1: // now we go through once, doing only `full spectrum' processing for( NumDen=0 ; NumDen<2 ; NumDen++) { //if( NumDen==1 ){ // full spectrum // fbot = fbotALL; // ftop = ftopALL; //} // essentially, just doesn't BP here, and the perfect filtering at end // is used for both still; this makes the final output spectrum // contain only frequencies in range of 0.01-0.08 if( BP_LAST==1 ) INFO_message("Only doing filtering to LFFs at end!"); mrv = THD_dset_to_vectim( inset , mask , 0 ) ; if( mrv == NULL ) ERROR_exit("Can't load time series data!?") ; if( NumDen==1 ) DSET_unload(inset) ; // @@ only unload on 2nd pass /* similarly for the ort vectors */ if( ortar != NULL ){ for( kk=0 ; kk < IMARR_COUNT(ortar) ; kk++ ){ ortim = IMARR_SUBIM(ortar,kk) ; if( ortim->nx < ntime ) ERROR_exit("-ort file %s is shorter than input dataset time series", ortim->name ) ; ort = (float **)realloc( ort , sizeof(float *)*(nort+ortim->ny) ) ; for( vv=0 ; vv < ortim->ny ; vv++ ) ort[nort++] = MRI_FLOAT_PTR(ortim) + ortim->nx * vv ; } } /* all the real work now */ if( do_despike ){ int_pair nsp ; if( verb ) INFO_message("Testing data time series for spikes") ; nsp = THD_vectim_despike9( mrv ) ; if( verb ) ININFO_message(" -- Squashed %d spikes from %d voxels",nsp.j,nsp.i) ; } if( verb ) INFO_message("Bandpassing data time series") ; if( (BP_LAST==0) && (NumDen==0) ) (void)THD_bandpass_vectim( mrv , dt,fbot,ftop , qdet , nort,ort ) ; else (void)THD_bandpass_vectim( mrv , dt,fbotALL,ftopALL, qdet,nort,ort ) ; /* OK, maybe a little more work */ if( nortset == 1 ){ MRI_vectim *orv ; orv = THD_dset_to_vectim( ortset[0] , mask , 0 ) ; if( orv == NULL ){ ERROR_message("Can't load -dsort %s",DSET_BRIKNAME(ortset[0])) ; } else { float *dp , *mvv , *ovv , ff ; if( verb ) INFO_message("Orthogonalizing to bandpassed -dsort") ; //(void)THD_bandpass_vectim( orv , dt,fbot,ftop , qdet , nort,ort ) ; //@@ if( (BP_LAST==0) && (NumDen==0) ) (void)THD_bandpass_vectim(orv,dt,fbot,ftop,qdet,nort,ort); else (void)THD_bandpass_vectim(orv,dt,fbotALL,ftopALL,qdet,nort,ort); THD_vectim_normalize( orv ) ; dp = malloc(sizeof(float)*mrv->nvec) ; THD_vectim_vectim_dot( mrv , orv , dp ) ; for( vv=0 ; vv < mrv->nvec ; vv++ ){ ff = dp[vv] ; if( ff != 0.0f ){ mvv = VECTIM_PTR(mrv,vv) ; ovv = VECTIM_PTR(orv,vv) ; for( kk=0 ; kk < ntime ; kk++ ) mvv[kk] -= ff*ovv[kk] ; } } VECTIM_destroy(orv) ; free(dp) ; } } if( blur > 0.0f ){ if( verb ) INFO_message("Blurring time series data spatially; FWHM=%.2f",blur) ; mri_blur3D_vectim( mrv , blur ) ; } if( pvrad > 0.0f ){ if( verb ) INFO_message("Local PV-ing time series data spatially; radius=%.2f",pvrad) ; THD_vectim_normalize( mrv ) ; THD_vectim_localpv( mrv , pvrad ) ; } if( do_norm && pvrad <= 0.0f ){ if( verb ) INFO_message("L2 normalizing time series data") ; THD_vectim_normalize( mrv ) ; } /* create output dataset, populate it, write it, then quit */ if( (NumDen==0) ) { // @@ BP'ed version; will do filt if BP_LAST if(BP_LAST) // do bandpass here for BP_LAST (void)THD_bandpass_vectim(mrv,dt,fbot,ftop,qdet,0,NULL); if( verb ) INFO_message("Creating output dataset in memory, then writing it") ; outset = EDIT_empty_copy(inset) ; if(SERIES_OUT){ sprintf(out_lff,"%s_LFF",prefix); EDIT_dset_items( outset , ADN_prefix,out_lff , ADN_none ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dBandpass" , argc,argv , outset ) ; } for( vv=0 ; vv < ntime ; vv++ ) EDIT_substitute_brick( outset , vv , MRI_float , NULL ) ; #if 1 THD_vectim_to_dset( mrv , outset ) ; #else AFNI_OMP_START ; #pragma omp parallel { float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ; #pragma omp for for( vv=0 ; vv < ntime ; vv++ ){ far = DSET_BRICK_ARRAY(outset,vv) ; var = mrv->fvec + vv ; for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ; } } AFNI_OMP_END ; #endif VECTIM_destroy(mrv) ; if(SERIES_OUT){ // @@ DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ; } } else{ // @@ non-BP'ed version if( verb ) INFO_message("Creating output dataset 2 in memory") ; // do this here because LFF version was also BP'ed at end. if(BP_LAST) // do bandpass here for BP_LAST (void)THD_bandpass_vectim(mrv,dt,fbotALL,ftopALL,qdet,0,NULL); outsetALL = EDIT_empty_copy(inset) ; if(UNBP_OUT){ sprintf(out_unBP,"%s_unBP",prefix); EDIT_dset_items( outsetALL, ADN_prefix, out_unBP, ADN_none ); tross_Copy_History( inset , outsetALL ) ; tross_Make_History( "3dRSFC" , argc,argv , outsetALL ) ; } for( vv=0 ; vv < ntime ; vv++ ) EDIT_substitute_brick( outsetALL , vv , MRI_float , NULL ) ; #if 1 THD_vectim_to_dset( mrv , outsetALL ) ; #else AFNI_OMP_START ; #pragma omp parallel { float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ; #pragma omp for for( vv=0 ; vv < ntime ; vv++ ){ far = DSET_BRICK_ARRAY(outsetALL,vv) ; var = mrv->fvec + vv ; for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ; } } AFNI_OMP_END ; #endif VECTIM_destroy(mrv) ; if(UNBP_OUT){ DSET_write(outsetALL) ; if( verb ) WROTE_DSET(outsetALL) ; } } }// end of NumDen loop // @@ INFO_message("Starting the (f)ALaFFel calcs") ; // allocations series1 = (double *)calloc(ntime,sizeof(double)); series2 = (double *)calloc(ntime,sizeof(double)); xx1 = (double *)calloc(2*ntime,sizeof(double)); xx2 = (double *)calloc(2*ntime,sizeof(double)); alff = (float *)calloc(nvox,sizeof(float)); malff = (float *)calloc(nvox,sizeof(float)); falff = (float *)calloc(nvox,sizeof(float)); if( (series1 == NULL) || (series2 == NULL) || (xx1 == NULL) || (xx2 == NULL) || (alff == NULL) || (malff == NULL) || (falff == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(122); } if(DO_RSFA) { rsfa = (float *)calloc(nvox,sizeof(float)); mrsfa = (float *)calloc(nvox,sizeof(float)); frsfa = (float *)calloc(nvox,sizeof(float)); if( (rsfa == NULL) || (mrsfa == NULL) || (frsfa == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } } work = gsl_fft_real_workspace_alloc (ntime); real1 = gsl_fft_real_wavetable_alloc (ntime); real2 = gsl_fft_real_wavetable_alloc (ntime); gsl_complex_packed_array compl_freqs1 = xx1; gsl_complex_packed_array compl_freqs2 = xx2; // ********************************************************************* // ********************************************************************* // ************** Falafelling = ALFF/fALFF calcs ***************** // ********************************************************************* // ********************************************************************* // Be now have the BP'ed data set (outset) and the non-BP'ed one // (outsetALL). now we'll FFT both, get amplitudes in appropriate // ranges, and calculate: ALFF, mALFF, fALFF, ctr = 0; for( kk=0; kk<nvox ; kk++) { if(mask[kk]) { // BP one, and unBP one, either for BP_LAST or !BP_LAST for( m=0 ; m<ntime ; m++ ) { series1[m] = THD_get_voxel(outset,kk,m); series2[m] = THD_get_voxel(outsetALL,kk,m); } mm = gsl_fft_real_transform(series1, 1, ntime, real1, work); mm = gsl_fft_halfcomplex_unpack(series1, compl_freqs1, 1, ntime); mm = gsl_fft_real_transform(series2, 1, ntime, real2, work); mm = gsl_fft_halfcomplex_unpack(series2, compl_freqs2, 1, ntime); numer = 0.0f; denom = 0.0f; de_rsfa = 0.0f; nu_rsfa = 0.0f; for( m=1 ; m<N_ny ; m++ ) { mm = 2*m; pow2 = compl_freqs2[mm]*compl_freqs2[mm] + compl_freqs2[mm+1]*compl_freqs2[mm+1]; // power //pow2*=2;// factor of 2 since ampls are even funcs denom+= (float) sqrt(pow2); // amplitude de_rsfa+= (float) pow2; if( ( m>=ind_low ) && ( m<=ind_high ) ){ pow1 = compl_freqs1[mm]*compl_freqs1[mm]+ compl_freqs1[mm+1]*compl_freqs1[mm+1]; //pow1*=2; numer+= (float) sqrt(pow1); nu_rsfa+= (float) pow1; } } if( denom>0.000001 ) falff[kk] = numer/denom; else falff[kk] = 0.; alff[kk] = 2*numer/sqnt;// factor of 2 since ampl is even funct meanALFF+= alff[kk]; if(DO_RSFA){ nu_rsfa = sqrt(2*nu_rsfa); // factor of 2 since ampls de_rsfa = sqrt(2*de_rsfa); // are even funcs if( de_rsfa>0.000001 ) frsfa[kk] = nu_rsfa/de_rsfa; else frsfa[kk]=0.; rsfa[kk] = nu_rsfa/nt_fac; meanRSFA+= rsfa[kk]; } ctr+=1; } } meanALFF/= ctr; meanRSFA/= ctr; gsl_fft_real_wavetable_free(real1); gsl_fft_real_wavetable_free(real2); gsl_fft_real_workspace_free(work); // ALFFs divided by mean of brain value for( kk=0 ; kk<nvox ; kk++ ) if(mask[kk]){ malff[kk] = alff[kk]/meanALFF; if(DO_RSFA) mrsfa[kk] = rsfa[kk]/meanRSFA; } // ************************************************************** // ************************************************************** // Store and output // ************************************************************** // ************************************************************** outsetALFF = EDIT_empty_copy( inset ) ; sprintf(out_alff,"%s_ALFF",prefix); EDIT_dset_items( outsetALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_alff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetALFF)); EDIT_substitute_brick(outsetALFF, 0, MRI_float, alff); alff=NULL; THD_load_statistics(outsetALFF); tross_Make_History("3dRSFC", argc, argv, outsetALFF); THD_write_3dim_dataset(NULL, NULL, outsetALFF, True); outsetfALFF = EDIT_empty_copy( inset ) ; sprintf(out_falff,"%s_fALFF",prefix); EDIT_dset_items( outsetfALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_falff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetfALFF)); EDIT_substitute_brick(outsetfALFF, 0, MRI_float, falff); falff=NULL; THD_load_statistics(outsetfALFF); tross_Make_History("3dRSFC", argc, argv, outsetfALFF); THD_write_3dim_dataset(NULL, NULL, outsetfALFF, True); outsetmALFF = EDIT_empty_copy( inset ) ; sprintf(out_malff,"%s_mALFF",prefix); EDIT_dset_items( outsetmALFF, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_malff, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmALFF)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetmALFF)); EDIT_substitute_brick(outsetmALFF, 0, MRI_float, malff); malff=NULL; THD_load_statistics(outsetmALFF); tross_Make_History("3dRSFC", argc, argv, outsetmALFF); THD_write_3dim_dataset(NULL, NULL, outsetmALFF, True); if(DO_RSFA){ outsetRSFA = EDIT_empty_copy( inset ) ; sprintf(out_rsfa,"%s_RSFA",prefix); EDIT_dset_items( outsetRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_rsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetRSFA)); EDIT_substitute_brick(outsetRSFA, 0, MRI_float, rsfa); rsfa=NULL; THD_load_statistics(outsetRSFA); tross_Make_History("3dRSFC", argc, argv, outsetRSFA); THD_write_3dim_dataset(NULL, NULL, outsetRSFA, True); outsetfRSFA = EDIT_empty_copy( inset ) ; sprintf(out_frsfa,"%s_fRSFA",prefix); EDIT_dset_items( outsetfRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_frsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetfRSFA)); EDIT_substitute_brick(outsetfRSFA, 0, MRI_float, frsfa); frsfa=NULL; THD_load_statistics(outsetfRSFA); tross_Make_History("3dRSFC", argc, argv, outsetfRSFA); THD_write_3dim_dataset(NULL, NULL, outsetfRSFA, True); outsetmRSFA = EDIT_empty_copy( inset ) ; sprintf(out_mrsfa,"%s_mRSFA",prefix); EDIT_dset_items( outsetmRSFA, ADN_nvals, 1, ADN_datum_all , MRI_float , ADN_prefix , out_mrsfa, ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmRSFA)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetmRSFA)); EDIT_substitute_brick(outsetmRSFA, 0, MRI_float, mrsfa); mrsfa=NULL; THD_load_statistics(outsetmRSFA); tross_Make_History("3dRSFC", argc, argv, outsetmRSFA); THD_write_3dim_dataset(NULL, NULL, outsetmRSFA, True); } // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ DSET_delete(inset); DSET_delete(outsetALL); DSET_delete(outset); DSET_delete(outsetALFF); DSET_delete(outsetmALFF); DSET_delete(outsetfALFF); DSET_delete(outsetRSFA); DSET_delete(outsetmRSFA); DSET_delete(outsetfRSFA); free(inset); free(outsetALL); free(outset); free(outsetALFF); free(outsetmALFF); free(outsetfALFF); free(outsetRSFA); free(outsetmRSFA); free(outsetfRSFA); free(rsfa); free(mrsfa); free(frsfa); free(alff); free(malff); free(falff); free(mask); free(series1); free(series2); free(xx1); free(xx2); exit(0) ; }
/*! Replace a voxel's value by the value's rank in the entire set of input datasets */ int main( int argc , char * argv[] ) { THD_3dim_dataset ** dsets_in = NULL, *dset=NULL; /*input and output datasets*/ int nopt=0, nbriks=0, nsubbriks=0, ib=0, isb=0; byte *cmask=NULL; int *all_uniques=NULL, **uniques=NULL, *final_unq=NULL, *N_uniques=NULL; int N_final_unq=0, iun=0, total_unq=0; INT_HASH_DATUM *rmap=NULL, *hd=NULL; int imax=0, iunq=0, ii=0, id = 0; long int off=0; char *prefix=NULL; char stmp[THD_MAX_PREFIX+1]={""}; FILE *fout=NULL; /*----- Read command line -----*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ Rank_help (); exit(0) ; } mainENTRY("3dRank main"); machdep(); AFNI_logger("3dRank",argc,argv); nopt = 1 ; while( nopt < argc && argv[nopt][0] == '-' ){ if( strcmp(argv[nopt],"-ver") == 0 ){ PRINT_VERSION("3dRank"); AUTHOR("Ziad Saad"); nopt++; continue; } if( strcmp(argv[nopt],"-help") == 0 ){ Rank_help(); exit(0) ; } if( strcmp(argv[nopt],"-prefix") == 0 ){ ++nopt; if (nopt>=argc) { fprintf(stderr,"**ERROR: Need string after -prefix\n"); exit(1); } prefix = argv[nopt] ; ++nopt; continue; } if( strcmp(argv[nopt],"-input") == 0 ){ dsets_in = (THD_3dim_dataset**) calloc(argc-nopt+1, sizeof(THD_3dim_dataset*)); ++nopt; nbriks=0; while (nopt < argc ) { dsets_in[nbriks] = THD_open_dataset( argv[nopt] ); if( !ISVALID_DSET(dsets_in[nbriks]) ){ fprintf(stderr,"**ERROR: can't open dataset %s\n",argv[nopt]) ; exit(1); } ++nopt; ++nbriks; } continue; } ERROR_exit( " Error - unknown option %s", argv[nopt]); } if (nopt < argc) { ERROR_exit( " Error unexplained trailing option: %s\n", argv[nopt]); } if (!nbriks) { ERROR_exit( " Error no volumes entered on command line?"); } /* some checks and inits*/ nsubbriks = 0; for (ib = 0; ib<nbriks; ++ib) { if (!is_integral_dset(dsets_in[ib], 0)) { ERROR_exit("Dset %s is not of an integral data type.", DSET_PREFIX(dsets_in[ib])); } nsubbriks += DSET_NVALS(dsets_in[ib]); } /* Now get unique arrays */ uniques = (int **)calloc(nsubbriks, sizeof(int*)); N_uniques = (int *)calloc(nsubbriks, sizeof(int)); total_unq = 0; iun = 0; for (ib = 0; ib<nbriks; ++ib) { DSET_mallocize(dsets_in[ib]); DSET_load(dsets_in[ib]); for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) { uniques[iun] = THD_unique_vals(dsets_in[ib], isb, &(N_uniques[iun]), cmask); total_unq += N_uniques[iun]; ++iun; } } /* put all the arrays together and get the unique of the uniques */ all_uniques = (int *)calloc(total_unq, sizeof(int)); off=0; for (iun=0; iun<nsubbriks; ++iun) { memcpy(all_uniques+off, uniques[iun], N_uniques[iun]*sizeof(int)); off += N_uniques[iun]; } /* free intermediate unique arrays */ for (iun=0; iun<nsubbriks; ++iun) { free(uniques[iun]); } free(uniques); uniques=NULL; free(N_uniques); N_uniques=NULL; /* get unique of catenated array */ if (!(final_unq = UniqueInt (all_uniques, total_unq, &N_final_unq, 0 ))) { ERROR_exit( " Failed to get unique list (%d, %d, %d) ", total_unq, N_final_unq, nsubbriks); } free(all_uniques); all_uniques=NULL; if (prefix) { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "%s.rankmap.1D", prefix); } else { if (nbriks == 1) { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "%s.rankmap.1D", DSET_PREFIX(dsets_in[0])); } else { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "%s+.rankmap.1D", DSET_PREFIX(dsets_in[0])); } } if (stmp[0]) { if ((fout = fopen(stmp,"w"))) { fprintf(fout, "#Rank Map (%d unique values)\n", N_final_unq); fprintf(fout, "#Col. 0: Rank\n"); fprintf(fout, "#Col. 1: Input Dset Value\n"); } } /* get the maximum integer in the unique array */ imax = 0; for (iunq=0; iunq<N_final_unq; ++iunq) { if (final_unq[iunq] > imax) imax = final_unq[iunq]; if (fout) fprintf(fout, "%d %d\n", iunq, final_unq[iunq]); hd = (INT_HASH_DATUM*)calloc(1,sizeof(INT_HASH_DATUM)); hd->id = final_unq[iunq]; hd->index = iunq; HASH_ADD_INT(rmap, id, hd); } fclose(fout); fout=NULL; /* now cycle over all dsets and replace their voxel values with rank */ for (ib = 0; ib<nbriks; ++ib) { for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) { EDIT_BRICK_LABEL( dsets_in[ib],isb, "rank" ) ; EDIT_BRICK_TO_NOSTAT( dsets_in[ib],isb ) ; EDIT_BRICK_FACTOR( dsets_in[ib],isb, 0.0);/* no factors for rank*/ switch (DSET_BRICK_TYPE(dsets_in[ib],isb) ){ default: fprintf(stderr, "** Bad dset type for unique operation.\n" "Only Byte, Short, and float dsets are allowed.\n"); break ; /* this should not happen here, so don't bother returning*/ case MRI_short:{ short *mar = (short *) DSET_ARRAY(dsets_in[ib],isb) ; if (imax > MRI_TYPE_maxval[MRI_short]) { WARNING_message("Maximum rank value of %d is\n" "than maximum value for dset datatype of %d\n", imax, MRI_TYPE_maxval[MRI_short]); } for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ ) if (!cmask || cmask[ii]) { id = (int)mar[ii]; HASH_FIND_INT(rmap,&id ,hd); if (hd) mar[ii] = (short)(hd->index); else ERROR_exit("** Failed to find key %d in hash table\n",id); } else mar[ii] = 0; } break ; case MRI_byte:{ byte *mar ; if (imax > MRI_TYPE_maxval[MRI_short]) { WARNING_message("Maximum rank value of %d is\n" "than maximum value for dset datatype of %d\n", imax, MRI_TYPE_maxval[MRI_byte]); } mar = (byte *) DSET_ARRAY(dsets_in[ib],isb) ; for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ ) if (!cmask || cmask[ii]) { id = (int)mar[ii]; HASH_FIND_INT(rmap,&id ,hd); if (hd) mar[ii] = (byte)(hd->index); else ERROR_exit("** Failed to find key %d in hash table\n",id); } else mar[ii] = 0; } break ; case MRI_float:{ float *mar = (float *) DSET_ARRAY(dsets_in[ib],isb) ; for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ ) if (!cmask || cmask[ii]) { id = (int)mar[ii]; /* Assuming float is integral valued */ HASH_FIND_INT(rmap,&id ,hd); if (hd) mar[ii] = (float)(hd->index); else ERROR_exit("** Failed to find key %d in hash table\n",id); } else mar[ii] = 0; } break ; } } /* update range, etc. */ THD_load_statistics(dsets_in[ib]); /* Now write the bricks */ if (prefix) { if (nbriks == 1) { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "%s", prefix); } else { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "r%02d.%s", ib, prefix); } } else { snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, "rank.%s", DSET_PREFIX(dsets_in[ib])); } EDIT_dset_items( dsets_in[ib] , ADN_prefix , stmp , ADN_none ) ; /* change storage mode, this way prefix will determine format of output dset */ dsets_in[ib]->dblk->diskptr->storage_mode = STORAGE_BY_BRICK; tross_Make_History( "3dRank" , argc, argv , dsets_in[ib] ) ; if (DSET_IS_MASTERED(dsets_in[ib])) { /* THD_write_3dim_dataset won't write a mastered dude */ dset = EDIT_full_copy(dsets_in[ib],stmp); } else { dset = dsets_in[ib]; } /* New ID */ ZERO_IDCODE(dset->idcode); dset->idcode = MCW_new_idcode() ; if (!THD_write_3dim_dataset( NULL, stmp, dset,True )) { ERROR_message("Failed to write %s", stmp); exit(1); } else { WROTE_DSET(dsets_in[ib]); if (dset != dsets_in[ib]) DSET_deletepp(dset); DSET_deletepp(dsets_in[ib]); } } /* destroy hash */ while (rmap) { hd = rmap; HASH_DEL(rmap,hd); free(hd); } free(final_unq); final_unq=NULL; 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 */ }
int main(int argc, char *argv[]) { int i,j,k,m,n,aa,ii,jj,kk,mm,rr; int iarg; int nmask1=0; int nmask2=0; THD_3dim_dataset *insetFA = NULL, *insetV1 = NULL, *insetMD = NULL, *insetL1 = NULL; THD_3dim_dataset *insetEXTRA=NULL; THD_3dim_dataset *mset2=NULL; THD_3dim_dataset *mset1=NULL; THD_3dim_dataset *outsetMAP=NULL, *outsetMASK=NULL; char *prefix="tracky"; int LOG_TYPE=0; char in_FA[300]; char in_V1[300]; char in_MD[300]; char in_L1[300]; int EXTRAFILE=0; // switch for whether other file is input as WM map char OUT_bin[300]; char OUT_tracstat[300]; char prefix_mask[300]; char prefix_map[300]; // FACT algopts FILE *fout0; float MinFA=0.2,MaxAngDeg=45,MinL=20.0; float MaxAng; int SeedPerV[3]={2,2,2}; int ArrMax=0; float tempvmagn; int Nvox=-1; // tot number vox int Dim[3]={0,0,0}; // dim in each dir int Nseed=0,M=30,bval=1000; int DimSeed[3]; // number of seeds there will be float Ledge[3]; // voxel edge lengths int *ROI1, *ROI2; short int *temp_arr; char *temp_byte; int **Tforw, **Tback; int **Ttot; float **flTforw, **flTback; float ****coorded; int ****INDEX; int len_forw, len_back; // int count of num of squares through float phys_forw[1], phys_back[1]; int idx; float ave_tract_len, ave_tract_len_phys; int inroi1, inroi2, KEEPIT; // switches for detecting int in[3]; // to pass to trackit float physin[3]; // also for trackit, physical loc, int totlen; float totlen_phys; int Numtract; int READS_in; float READS_fl; int end[2][3]; int test_ind[2][3]; int roi3_ct=0, id=0; float roi3_mu_MD = 0.,roi3_mu_RD = 0.,roi3_mu_L1 = 0.,roi3_mu_FA = 0.; float roi3_sd_MD = 0.,roi3_sd_RD = 0.,roi3_sd_L1 = 0.,roi3_sd_FA = 0.; float tempMD,tempFA,tempRD,tempL1; char dset_or[4] = "RAI"; THD_3dim_dataset *dsetn; int TV_switch[3] = {0,0,0}; TAYLOR_BUNDLE *tb=NULL; TAYLOR_TRACT *tt=NULL; char *mode = "NI_fast_binary"; NI_element *nel=NULL; int dump_opts=0; tv_io_header header1 = {.id_string = "TRACK\0", .origin = {0,0,0}, .n_scalars = 3, .scal_n[0] = "FA", .scal_n[1] = "MD", .scal_n[2] = "L1", .n_properties = 0, .vox_to_ras = {{0.,0.,0.,0.},{0.,0.,0.,0.}, {0.,0.,0.,0.},{0.,0.,0.,0.}}, // reset this later based on actual data set .voxel_order = "RAI\0", .invert_x = 0, .invert_y = 0, .invert_z = 0, .swap_xy = 0, .swap_yz = 0, .swap_zx = 0, .n_count = 0, .version = 2, .hdr_size = 1000}; // for testing names... char *postfix[4]={"+orig.HEAD\0",".nii.gz\0",".nii\0","+tlrc.HEAD\0"}; int FOUND =-1; int RECORD_ORIG = 0; float Orig[3] = {0.0,0.0,0.0}; mainENTRY("3dTrackID"); machdep(); // **************************************************************** // **************************************************************** // load AFNI stuff // **************************************************************** // **************************************************************** INFO_message("version: MU"); /** scan args **/ if (argc == 1) { usage_TrackID(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_TrackID(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-verb") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-verb'") ; set_tract_verb(atoi(argv[iarg])); iarg++ ; continue ; } if( strcmp(argv[iarg],"-write_opts") == 0) { dump_opts=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-rec_orig") == 0) { RECORD_ORIG=1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-tract_out_mode") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-tract_out_mode'") ; if (strcmp(argv[iarg], "NI_fast_binary") && strcmp(argv[iarg], "NI_fast_text") && strcmp(argv[iarg], "NI_slow_binary") && strcmp(argv[iarg], "NI_slow_text") ) { ERROR_message("Bad value (%s) for -tract_out_mode",argv[iarg]); exit(1); } mode = argv[iarg]; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask1") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask1'") ; mset1 = THD_open_dataset( argv[iarg] ) ; if( mset1 == NULL ) ERROR_exit("Can't open mask1 dataset '%s'", argv[iarg]) ; DSET_load(mset1) ; CHECK_LOAD_ERROR(mset1) ; nmask1 = DSET_NVOX(mset1) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask2") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask2'") ; mset2 = THD_open_dataset( argv[iarg] ) ; if( mset2 == NULL ) ERROR_exit("Can't open mask2 dataset '%s'", argv[iarg]) ; DSET_load(mset2) ; CHECK_LOAD_ERROR(mset2) ; nmask2 = DSET_NVOX(mset2) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-prefix'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-prefix'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-input'"); for( i=0 ; i<4 ; i++) { sprintf(in_FA,"%s_FA%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_FA)) { FOUND = i; break; } } insetFA = THD_open_dataset(in_FA) ; if( (insetFA == NULL ) || (FOUND==-1)) ERROR_exit("Can't open dataset '%s': for FA.",in_FA); DSET_load(insetFA) ; CHECK_LOAD_ERROR(insetFA) ; Nvox = DSET_NVOX(insetFA) ; Dim[0] = DSET_NX(insetFA); Dim[1] = DSET_NY(insetFA); Dim[2] = DSET_NZ(insetFA); Ledge[0] = fabs(DSET_DX(insetFA)); Ledge[1] = fabs(DSET_DY(insetFA)); Ledge[2] = fabs(DSET_DZ(insetFA)); Orig[0] = DSET_XORG(insetFA); Orig[1] = DSET_YORG(insetFA); Orig[2] = DSET_ZORG(insetFA); // check tot num vox match (as proxy for dims...) if( (Nvox != nmask1) || (Nvox != nmask2) ) ERROR_exit("Input dataset does not match both mask volumes!"); // this stores the original data file orientation for later use, // as well since we convert everything to RAI temporarily, as // described below header1.voxel_order[0]=ORIENT_typestr[insetFA->daxes->xxorient][0]; header1.voxel_order[1]=ORIENT_typestr[insetFA->daxes->yyorient][0]; header1.voxel_order[2]=ORIENT_typestr[insetFA->daxes->zzorient][0]; for( i=0 ; i<3 ; i++) { header1.dim[i] = Dim[i]; header1.voxel_size[i] = Ledge[i]; // will want this when outputting file later for TrackVis. TV_switch[i] = !(dset_or[i]==header1.voxel_order[i]); } dset_or[3]='\0'; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_V1,"%s_V1%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_V1)) { FOUND = i; break; } } insetV1 = THD_open_dataset(in_V1); if( insetV1 == NULL ) ERROR_exit("Can't open dataset '%s':V1",in_V1); DSET_load(insetV1) ; CHECK_LOAD_ERROR(insetV1) ; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_L1,"%s_L1%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_L1)) { FOUND = i; break; } } insetL1 = THD_open_dataset(in_L1); if( insetL1 == NULL ) ERROR_exit("Can't open dataset '%s':L1",in_L1); DSET_load(insetL1) ; CHECK_LOAD_ERROR(insetL1) ; FOUND = -1; for( i=0 ; i<4 ; i++) { sprintf(in_MD,"%s_MD%s", argv[iarg],postfix[i]); if(THD_is_ondisk(in_MD)) { FOUND = i; break; } } insetMD = THD_open_dataset(in_MD); if( insetMD == NULL ) ERROR_exit("Can't open dataset '%s':MD",in_MD); DSET_load(insetMD) ; CHECK_LOAD_ERROR(insetMD) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-algopt") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-algopt'"); if (!(nel = ReadTractAlgOpts(argv[iarg]))) { ERROR_message("Failed to read options in %s\n", argv[iarg]); exit(19); } if (NI_getTractAlgOpts(nel, &MinFA, &MaxAngDeg, &MinL, SeedPerV, &M, &bval)) { ERROR_message("Failed to get options"); exit(1); } NI_free_element(nel); nel=NULL; iarg++ ; continue ; } if( strcmp(argv[iarg],"-logic") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-logic'"); INFO_message("ROI logic type is: %s",argv[iarg]); if( strcmp(argv[iarg],"AND") == 0 ) LOG_TYPE = 1; else if( strcmp(argv[iarg],"OR") == 0 ) LOG_TYPE = 0; else if( strcmp(argv[iarg],"ALL") == 0 ) LOG_TYPE = -1; else ERROR_exit("Illegal after '-logic': need 'OR' or 'AND'"); iarg++ ; continue ; } //@@ if( strcmp(argv[iarg],"-extra_set") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-extra_set'"); EXTRAFILE = 1; // switch on insetEXTRA = THD_open_dataset(argv[iarg]); if( (insetEXTRA == NULL ) ) ERROR_exit("Can't open dataset '%s': for extra set.",argv[iarg]); DSET_load(insetEXTRA) ; CHECK_LOAD_ERROR(insetEXTRA) ; if( !((Dim[0] == DSET_NX(insetEXTRA)) && (Dim[1] == DSET_NY(insetEXTRA)) && (Dim[2] == DSET_NZ(insetEXTRA)))) ERROR_exit("Dimensions of extra set '%s' don't match those of the DTI prop ones ('%s', etc.).",argv[iarg], in_FA); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } if (iarg < 4) { ERROR_message("Too few options. Try -help for details.\n"); exit(1); } if (dump_opts) { nel = NI_setTractAlgOpts(NULL, &MinFA, &MaxAngDeg, &MinL, SeedPerV, &M, &bval); WriteTractAlgOpts(prefix, nel); NI_free_element(nel); nel=NULL; } // Process the options a little for( i=0 ; i<3 ; i++) DimSeed[i] = Dim[i]*SeedPerV[i]; Nseed = Nvox*SeedPerV[0]*SeedPerV[1]*SeedPerV[2]; // convert to cos of rad value for comparisons, instead of using acos() MaxAng = cos(CONV*MaxAngDeg); // switch to add header-- option for now, added Sept. 2012 // for use with map_TrackID to map tracks to different space if(RECORD_ORIG) { for( i=0 ; i<3 ; i++) header1.origin[i] = Orig[i]; } // at some point, we will have to convert indices into // pseudo-locations; being forced into this choice means that // different data set orientations would be represented differently // and incorrectly in some instances... so, for now, we'll resample // everything to RAI, and then resample back later. guess this will // just slow things down slightly. // have all be RAI for processing here if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(insetFA, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetFA); insetFA=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetMD, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetMD); insetMD=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetV1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetV1); insetV1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(insetL1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetL1); insetL1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(mset1, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(mset1); mset1=dsetn; dsetn=NULL; dsetn = r_new_resam_dset(mset2, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(mset2); mset2=dsetn; dsetn=NULL; if(EXTRAFILE) { dsetn = r_new_resam_dset(insetEXTRA, NULL, 0.0, 0.0, 0.0, dset_or, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(insetEXTRA); insetEXTRA=dsetn; dsetn=NULL; } } // **************************************************************** // **************************************************************** // make arrays for tracking // **************************************************************** // **************************************************************** // for temp storage array, just a multiple of longest dimension! if(Dim[0] > Dim[1]) ArrMax = Dim[0] * 4; else ArrMax = Dim[1] * 4; if(4*Dim[2] > ArrMax) ArrMax = Dim[2] * 4; ROI1 = (int *)calloc(Nvox, sizeof(int)); ROI2 = (int *)calloc(Nvox, sizeof(int)); temp_arr = (short int *)calloc(Nvox, sizeof(short int)); temp_byte = (char *)calloc(Nvox, sizeof(char)); // temp storage whilst tracking Tforw = calloc(ArrMax, sizeof(Tforw)); for(i=0 ; i<ArrMax ; i++) Tforw[i] = calloc(3, sizeof(int)); Ttot = calloc(2*ArrMax , sizeof(Ttot)); for(i=0 ; i<2*ArrMax ; i++) Ttot[i] = calloc(3, sizeof(int)); Tback = calloc(ArrMax, sizeof(Tback)); for(i=0 ; i<ArrMax ; i++) Tback[i] = calloc(3, sizeof(int)); // temp storage whilst tracking, physical loc flTforw = calloc(ArrMax, sizeof(flTforw)); for(i=0 ; i<ArrMax ; i++) flTforw[i] = calloc(3, sizeof(int)); flTback = calloc(ArrMax,sizeof(flTback)); for(i=0 ; i<ArrMax ; i++) flTback[i] = calloc(3, sizeof(int)); if( (ROI1 == NULL) || (ROI2 == NULL) || (temp_arr == NULL) || (Tforw == NULL) || (Tback == NULL) || (flTforw == NULL) || (flTback == NULL) || (Ttot == NULL)) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(12); } coorded = (float ****) calloc( Dim[0], sizeof(float ***) ); for ( i = 0 ; i < Dim[0] ; i++ ) coorded[i] = (float ***) calloc( Dim[1], sizeof(float **) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) coorded[i][j] = (float **) calloc( Dim[2], sizeof(float *) ); for ( i=0 ; i<Dim[0] ; i++ ) for ( j=0 ; j<Dim[1] ; j++ ) for ( k= 0 ; k<Dim[2] ; k++ ) //3 comp of V1 and FA coorded[i][j][k] = (float *) calloc( 4, sizeof(float) ); INDEX = (int ****) calloc( Dim[0], sizeof(int ***) ); for ( i = 0 ; i < Dim[0] ; i++ ) INDEX[i] = (int ***) calloc( Dim[1], sizeof(int **) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) INDEX[i][j] = (int **) calloc( Dim[2], sizeof(int *) ); for ( i=0 ; i<Dim[0] ; i++ ) for ( j=0 ; j<Dim[1] ; j++ ) for ( k= 0 ; k<Dim[2] ; k++ ) INDEX[i][j][k] = (int *) calloc( 4, sizeof(int) ); // this statement will never be executed if allocation fails above if( (INDEX == NULL) || (coorded == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(122); } for(i=0 ; i<Nvox ; i++) { if(THD_get_voxel( mset1, i, 0) >0.5){ ROI1[i] = 1; } if(THD_get_voxel( mset2, i, 0) >0.5) ROI2[i] = 1; } // set up eigvecs in 3D coord sys, // mark off where ROIs are and keep index handy idx=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { for( m=0 ; m<3 ; m++ ) coorded[i][j][k][m] = THD_get_voxel(insetV1, idx, m); if(EXTRAFILE) coorded[i][j][k][3] = THD_get_voxel(insetEXTRA, idx, 0); else coorded[i][j][k][3] = THD_get_voxel(insetFA, idx, 0); // make sure that |V1| == 1 for all eigenvects, otherwise it's /// a problem in the tractography; currently, some from // 3dDWItoDT do not have this property... tempvmagn = sqrt(coorded[i][j][k][0]*coorded[i][j][k][0]+ coorded[i][j][k][1]*coorded[i][j][k][1]+ coorded[i][j][k][2]*coorded[i][j][k][2]); if( tempvmagn<0.99 ) for( m=0 ; m<3 ; m++ ) coorded[i][j][k][m]/= tempvmagn; INDEX[i][j][k][0] =idx; // first value is the index itself if( ROI1[idx]==1 ) INDEX[i][j][k][1]=1; // second value identifies ROI1 mask else INDEX[i][j][k][1]=0; if( ROI2[idx]==1 ) INDEX[i][j][k][2]=1; // third value identifies ROI2 mask else INDEX[i][j][k][2]=0; // fourth value will be counter for number of kept tracks // passing through INDEX[i][j][k][3] = 0; idx+= 1; } // ************************************************************* // ************************************************************* // Beginning of main loop // ************************************************************* // ************************************************************* Numtract = 0; ave_tract_len = 0.; ave_tract_len_phys = 0.; sprintf(OUT_bin,"%s.trk",prefix); if( (fout0 = fopen(OUT_bin, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_bin); exit(16); } fwrite(&header1,sizeof(tv_io_header),1,fout0); if (get_tract_verb()) { INFO_message("Begin tracking..."); } tb = AppCreateBundle(NULL, 0, NULL, insetFA); // start bundle id = 0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) if(coorded[i][j][k][3] >= MinFA) { for( ii=0 ; ii<SeedPerV[0] ; ii++ ) for( jj=0 ; jj<SeedPerV[1] ; jj++ ) for( kk=0 ; kk<SeedPerV[2] ; kk++ ) { in[0] = i; in[1] = j; in[2] = k; physin[0] = ((float) in[0] + (0.5 + (float) ii)/SeedPerV[0])*Ledge[0]; physin[1] = ((float) in[1] + (0.5 + (float) jj)/SeedPerV[1])*Ledge[1]; physin[2] = ((float) in[2] + (0.5 + (float) kk)/SeedPerV[2])*Ledge[2]; len_forw = TrackIt(coorded, in, physin, Ledge, Dim, MinFA, MaxAng, ArrMax, Tforw, flTforw, 1, phys_forw); // reset, because it's changed in TrackIt func in[0] = i; in[1] = j; in[2] = k; physin[0] = ((float) in[0] + (0.5 + (float) ii)/SeedPerV[0])*Ledge[0]; physin[1] = ((float) in[1] + (0.5 + (float) jj)/SeedPerV[1])*Ledge[1]; physin[2] = ((float) in[2] + (0.5 + (float) kk)/SeedPerV[2])*Ledge[2]; len_back = TrackIt(coorded, in, physin, Ledge, Dim, MinFA, MaxAng, ArrMax, Tback, flTback, -1, phys_back); KEEPIT = 0; // a simple switch totlen = len_forw+len_back-1; // NB: overlap of starts totlen_phys = phys_forw[0] + phys_back[0]; if( totlen_phys >= MinL ) { // glue together for simpler notation later for( n=0 ; n<len_back ; n++) { // all of this rr = len_back-n-1; // read in backward for(m=0;m<3;m++) Ttot[rr][m] = Tback[n][m]; } for( n=1 ; n<len_forw ; n++){// skip first->overlap rr = n+len_back-1; // put after for(m=0;m<3;m++) Ttot[rr][m] = Tforw[n][m]; } // <<So close and orthogonal condition>>: // test projecting ends, to see if they abut ROI. for(m=0;m<3;m++) { //actual projected ends end[1][m] = 2*Ttot[totlen-1][m]-Ttot[totlen-2][m]; end[0][m] = 2*Ttot[0][m]-Ttot[1][m]; // default choice, just retest known ends // as default test_ind[1][m] = test_ind[0][m] = Ttot[0][m]; } tt = Create_Tract(len_back, flTback, len_forw, flTforw, id, insetFA); ++id; if (LOG_TYPE == -1) { KEEPIT = 1; } else { inroi1 = 0; // check forw for( n=0 ; n<len_forw ; n++) { if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][1]==1){ inroi1 = 1; break; } else continue; } if( inroi1==0 ){// after 1st half, check 2nd half for( m=0 ; m<len_back ; m++) { if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][1]==1){ inroi1 = 1; break; } else continue; } } // after 1st&2nd halves, check bound/neigh if( inroi1==0 ) { if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][1]==1) inroi1 = 1; if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][1]==1) inroi1 = 1; } if( ((LOG_TYPE ==0) && (inroi1 ==0)) || ((LOG_TYPE ==1) && (inroi1 ==1))) { // have to check in ROI2 inroi2 = 0; // check forw for( n=0 ; n<len_forw ; n++) { if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][2]==1){ inroi2 = 1; break; } else continue; } //after 1st half, check 2nd half if( inroi2==0 ) { for( m=0 ; m<len_back ; m++) { if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][2]==1){ inroi2 = 1; break; } else continue; } } // after 1st&2nd halves, check bound/neigh if( inroi2==0 ) { if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][2]==1) inroi2 = 1; if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][2]==1) inroi2 = 1; } // for both cases, need to see it here to keep if( inroi2 ==1 ) KEEPIT = 1; // otherwise, it's gone } else if((LOG_TYPE ==0) && (inroi1 ==1)) KEEPIT = 1; } } // by now, we *know* if we're keeping this or not. if( KEEPIT == 1 ) { tb = AppCreateBundle(tb, 1, tt, NULL); tt = Free_Tracts(tt, 1); READS_in = totlen; fwrite(&READS_in,sizeof(READS_in),1,fout0); for( n=0 ; n<len_back ; n++) { //put this one in backwords, to make it connect m = len_back - 1 - n; for(aa=0 ; aa<3 ; aa++) { // recenter phys loc for trackvis, if nec... // just works this way (where they define // origin) READS_fl = flTback[m][aa]; if(!TV_switch[aa]) READS_fl = Ledge[aa]*Dim[aa]-READS_fl; fwrite(&READS_fl,sizeof(READS_fl),1,fout0); } mm = INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][0]; READS_fl =THD_get_voxel(insetFA, mm, 0); // FA fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetMD, mm, 0); // MD fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetL1, mm, 0); // L1 fwrite(&READS_fl,sizeof(READS_fl),1,fout0); // count this voxel for having a tract INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][3]+= 1; } for( m=1 ; m<len_forw ; m++) { for(aa=0 ; aa<3 ; aa++) { // recenter phys loc for trackvis, if nec... READS_fl = flTforw[m][aa]; if(!TV_switch[aa]) READS_fl = Ledge[aa]*Dim[aa]-READS_fl; fwrite(&READS_fl,sizeof(READS_fl),1,fout0); } mm = INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][0]; READS_fl =THD_get_voxel(insetFA, mm, 0); // FA fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetMD, mm, 0); // MD fwrite(&READS_fl,sizeof(READS_fl),1,fout0); READS_fl =THD_get_voxel(insetL1, mm, 0); // L1 fwrite(&READS_fl,sizeof(READS_fl),1,fout0); // count this voxel for having a tract INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][3]+= 1; } ave_tract_len+= totlen; ave_tract_len_phys+= totlen_phys; Numtract+=1; } } } fclose(fout0); if (get_tract_verb()) { INFO_message("Done tracking, have %d tracks.", tb->N_tracts); Show_Taylor_Bundle(tb, NULL, 3); } if (!Write_Bundle(tb,prefix,mode)) { ERROR_message("Failed to write the bundle"); } // ************************************************************** // ************************************************************** // Some simple stats on ROIs and outputs // ************************************************************** // ************************************************************** for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( INDEX[i][j][k][3]>=1 ) { tempMD = THD_get_voxel(insetMD,INDEX[i][j][k][0],0); tempFA = THD_get_voxel(insetFA,INDEX[i][j][k][0],0); tempL1 = THD_get_voxel(insetL1,INDEX[i][j][k][0],0); tempRD = 0.5*(3*tempMD-tempL1); roi3_mu_MD+= tempMD; roi3_mu_FA+= tempFA; roi3_mu_L1+= tempL1; roi3_mu_RD+= tempRD; roi3_sd_MD+= tempMD*tempMD; roi3_sd_FA+= tempFA*tempFA; roi3_sd_L1+= tempL1*tempL1; roi3_sd_RD+= tempRD*tempRD; roi3_ct+= 1; } } if(roi3_ct > 0 ) { // !!!! make into afni file roi3_mu_MD/= (float) roi3_ct; roi3_mu_FA/= (float) roi3_ct; roi3_mu_L1/= (float) roi3_ct; roi3_mu_RD/= (float) roi3_ct; roi3_sd_MD-= roi3_ct*roi3_mu_MD*roi3_mu_MD; roi3_sd_FA-= roi3_ct*roi3_mu_FA*roi3_mu_FA; roi3_sd_L1-= roi3_ct*roi3_mu_L1*roi3_mu_L1; roi3_sd_RD-= roi3_ct*roi3_mu_RD*roi3_mu_RD; roi3_sd_MD/= (float) roi3_ct-1; roi3_sd_FA/= (float) roi3_ct-1; roi3_sd_L1/= (float) roi3_ct-1; roi3_sd_RD/= (float) roi3_ct-1; roi3_sd_MD = sqrt(roi3_sd_MD); roi3_sd_FA = sqrt(roi3_sd_FA); roi3_sd_L1 = sqrt(roi3_sd_L1); roi3_sd_RD = sqrt(roi3_sd_RD); sprintf(OUT_tracstat,"%s.stats",prefix); if( (fout0 = fopen(OUT_tracstat, "w")) == NULL) { fprintf(stderr, "Error opening file %s.",OUT_tracstat); exit(19); } fprintf(fout0,"%d\t%d\n",Numtract,roi3_ct); fprintf(fout0,"%.3f\t%.3f\n",ave_tract_len/Numtract, ave_tract_len_phys/Numtract); // as usual, these next values would have to be divided by the // bval to get their actual value in standard phys units fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_FA,roi3_sd_FA); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_MD,roi3_sd_MD); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_RD,roi3_sd_RD); fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_L1,roi3_sd_L1); fclose(fout0); sprintf(prefix_map,"%s_MAP",prefix); sprintf(prefix_mask,"%s_MASK",prefix); outsetMAP = EDIT_empty_copy( mset1 ) ; EDIT_dset_items( outsetMAP , ADN_datum_all , MRI_short , ADN_prefix , prefix_map , ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMAP)); outsetMASK = EDIT_empty_copy( mset1 ) ; EDIT_dset_items( outsetMASK , ADN_datum_all , MRI_byte , ADN_prefix , prefix_mask , ADN_none ) ; if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMASK)); m=0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { temp_arr[m]=INDEX[i][j][k][3]; if(temp_arr[m]>0.5) temp_byte[m]=1; else temp_byte[m]=0; m++; } // re-orient the data as original inputs // (this function copies the pointer) EDIT_substitute_brick(outsetMAP, 0, MRI_short, temp_arr); temp_arr=NULL; if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(outsetMAP, NULL, 0.0, 0.0, 0.0, header1.voxel_order, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(outsetMAP); outsetMAP=dsetn; dsetn=NULL; } EDIT_dset_items( outsetMAP , ADN_prefix , prefix_map , ADN_none ) ; THD_load_statistics(outsetMAP ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMAP)); tross_Make_History( "3dTrackID" , argc , argv , outsetMAP) ; THD_write_3dim_dataset(NULL, NULL, outsetMAP, True); // re-orient the data as original inputs EDIT_substitute_brick(outsetMASK, 0, MRI_byte, temp_byte); temp_byte=NULL; if(TV_switch[0] || TV_switch[1] || TV_switch[2]) { dsetn = r_new_resam_dset(outsetMASK, NULL, 0.0, 0.0, 0.0, header1.voxel_order, RESAM_NN_TYPE, NULL, 1, 0); DSET_delete(outsetMASK); outsetMASK=dsetn; dsetn=NULL; } EDIT_dset_items( outsetMASK , ADN_prefix , prefix_mask , ADN_none ) ; THD_load_statistics(outsetMASK); if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outsetMASK)); tross_Make_History( "3dTrackID" , argc , argv , outsetMASK) ; THD_write_3dim_dataset(NULL, NULL, outsetMASK, True); INFO_message("Number of tracts found = %d",Numtract) ; } else INFO_message("\n No Tracts Found!!!\n"); // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ // !!! need to free afni-sets? DSET_delete(insetFA); DSET_delete(insetMD); DSET_delete(insetL1); DSET_delete(insetV1); DSET_delete(insetEXTRA); //DSET_delete(outsetMAP); //DSET_delete(outsetMASK); DSET_delete(mset2); DSET_delete(mset1); free(prefix); free(insetV1); free(insetFA); free(mset1); free(mset2); free(insetEXTRA); free(ROI1); free(ROI2); free(temp_byte); for( i=0 ; i<ArrMax ; i++) { free(Tforw[i]); free(Tback[i]); free(flTforw[i]); free(flTback[i]); } free(Tforw); free(Tback); free(flTforw); free(flTback); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) for( k=0 ; k<Dim[2] ; k++) free(coorded[i][j][k]); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) free(coorded[i][j]); for( i=0 ; i<Dim[0] ; i++) free(coorded[i]); free(coorded); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) for( k=0 ; k<Dim[2] ; k++) free(INDEX[i][j][k]); for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) free(INDEX[i][j]); for( i=0 ; i<Dim[0] ; i++) free(INDEX[i]); free(INDEX); free(temp_arr); // need to free for( i=0 ; i<2*ArrMax ; i++) free(Ttot[i]); free(Ttot); //free(mode); return 0; }
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) ; }
int main( int argc , char * argv[] ) { int ninp , ids , nv , iv,jv,kv , ivout , new_nvals , have_fdr = 0, nfdr = 0 ; THD_3dim_dataset * new_dset=NULL , * dset ; char buf[256] ; double angle; /*----- identify program -----*/ #if 0 printf ("\n\nProgram %s \n", PROGRAM_NAME); printf ("Last revision: %s \n\n", LAST_MOD_DATE); #endif /*** read input options ***/ mainENTRY("3dbucket main"); machdep(); PRINT_VERSION("3dbucket") ; set_obliquity_report(0); /* silence obliquity */ /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ { 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("3dbucket",argc,argv) ; BUCK_read_opts( argc , argv ) ; /*** create new dataset (empty) ***/ ninp = BUCK_dsar->num ; if( ninp < 1 ){ fprintf(stderr,"*** No input datasets?\n") ; exit(1) ; } new_nvals = 0 ; for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ; if( BUCK_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ; new_dset = EDIT_empty_copy( DSUB(0) ) ; /* 23 May 2005: check for axis consistency */ /* 06 Feb 2008: and see if there are fdrcurves to perpetuate */ if( DSUB(0)->dblk->brick_fdrcurve ) have_fdr = 1 ; for( iv=1 ; iv < ninp ; iv++ ){ if( !EQUIV_DATAXES(new_dset->daxes,DSUB(iv)->daxes) ) fprintf(stderr,"++ WARNING: %s grid mismatch with %s\n", DSET_BRIKNAME(DSUB(0)) , DSET_BRIKNAME(DSUB(iv)) ) ; if( DSUB(iv)->dblk->brick_fdrcurve ) have_fdr = 1 ; angle = dset_obliquity_angle_diff(new_dset, DSUB(iv), -1.0); if (angle > 0.0) { WARNING_message( "dataset %s has an obliquity difference of %f degress with %s\n", new_dset , angle, DSUB(iv) ); } } /* if( ninp == 1 ) */ tross_Copy_History( DSUB(0) , new_dset ) ; tross_Make_History( "3dbucket" , argc,argv , new_dset ) ; EDIT_dset_items( new_dset , ADN_prefix , BUCK_output_prefix , ADN_directory_name, BUCK_session , ADN_type , BUCK_type , ADN_func_type , ISANATTYPE(BUCK_type) ? ANAT_BUCK_TYPE : FUNC_BUCK_TYPE, ADN_ntt , 0 , ADN_nvals , new_nvals , ADN_none ) ; /* can't re-write existing dataset, unless glueing is used */ if (! BUCK_glue){ if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){ fprintf(stderr,"*** Fatal error: file %s already exists!\n", DSET_HEADNAME(new_dset) ) ; exit(1) ; } } else { /* if glueing is used, make the 'new' dataset have the same idcode as the old one */ new_dset->idcode = DSUB(0) -> idcode ; /* copy the struct */ } THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ; /* if there are fdr curves, allocate space 06 Feb 2008 [rickr] */ if( have_fdr ){ new_dset->dblk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *), new_nvals) ; if( !new_dset->dblk->brick_fdrcurve ){ fprintf(stderr,"** failed to alloc %d fdrcurves\n",new_nvals); exit(1); } if( BUCK_verb ) printf("-verb: adding fdrcurve list\n"); new_dset->dblk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *), /* 22 Oct 2008 */ new_nvals) ; } /*** loop over input datasets ***/ if( ninp > 1 ) myXtFree( new_dset->keywords ) ; ivout = 0 ; for( ids=0 ; ids < ninp ; ids++ ){ dset = DSUB(ids) ; nv = NSUBV(ids) ; if( ! BUCK_dry ){ DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; } /** loop over sub-bricks to output **/ for( iv=0 ; iv < nv ; iv++ ){ jv = SUBV(ids,iv) ; /* which sub-brick to use */ if( ! BUCK_dry ){ EDIT_substitute_brick( new_dset , ivout , DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ; /*----- preserve label when one exists --- Modified March 2010 ZSS*/ if (DSET_HAS_LABEL(dset, jv) ) sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv)); else sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ; EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ; #if 0 sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ; EDIT_dset_items( new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ; #endif EDIT_dset_items( new_dset , ADN_brick_fac_one +ivout, DSET_BRICK_FACTOR(dset,jv), #if 0 ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) , #endif ADN_none ) ; /** possibly write statistical parameters for this sub-brick **/ kv = DSET_BRICK_STATCODE(dset,jv) ; if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */ int npar = FUNC_need_stat_aux[kv] , lv ; float * par = (float *) malloc( sizeof(float) * (npar+2) ) ; float * sax = DSET_BRICK_STATAUX(dset,jv) ; par[0] = kv ; par[1] = npar ; for( lv=0 ; lv < npar ; lv++ ) par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ; EDIT_dset_items(new_dset , ADN_brick_stataux_one+ivout , par , ADN_none ) ; free(par) ; /* 2: if the input dataset has statistical parameters */ } else if( ISFUNC(dset) && /* dset has stat */ FUNC_IS_STAT(dset->func_type) && /* params */ jv == FUNC_ival_thr[dset->func_type] ){ /* thr sub-brick */ int npar , lv ; float * par , * sax ; kv = dset->func_type ; npar = FUNC_need_stat_aux[kv] ; par = (float *) malloc( sizeof(float) * (npar+2) ) ; sax = dset->stat_aux ; par[0] = kv ; par[1] = npar ; for( lv=0 ; lv < npar ; lv++ ) par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ; EDIT_dset_items(new_dset , ADN_brick_stataux_one+ivout , par , ADN_none ) ; free(par) ; } /** append any fdrcurve **/ if( have_fdr ){ /* fixed iv->jv (ick!), noticed by dglen 16 Mar 2010 [rickr] */ if(dset->dblk->brick_fdrcurve && dset->dblk->brick_fdrcurve[jv]){ COPY_floatvec(new_dset->dblk->brick_fdrcurve[ivout], dset->dblk->brick_fdrcurve[jv]) ; nfdr++; } else new_dset->dblk->brick_fdrcurve[ivout] = NULL ; if(dset->dblk->brick_mdfcurve && dset->dblk->brick_mdfcurve[jv]){ COPY_floatvec(new_dset->dblk->brick_mdfcurve[ivout], dset->dblk->brick_mdfcurve[jv]) ; } else new_dset->dblk->brick_mdfcurve[ivout] = NULL ; } /** print a message? **/ if( BUCK_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" , DSET_FILECODE(dset) , jv , DSET_FILECODE(new_dset) , ivout ) ; } else { printf("-dry: would copy %s[%d] into %s[%d]\n" , DSET_FILECODE(dset) , jv , DSET_FILECODE(new_dset) , ivout ) ; } ivout++ ; } /** loop over all bricks in input dataset and unload them if they aren't going into the output (not required, but is done to economize on memory) **/ if( ! BUCK_dry && nv < DSET_NVALS(dset) ){ for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){ /* all input sub-bricks */ for( iv=0 ; iv < nv ; iv++ ){ /* all output sub-bricks */ jv = SUBV(ids,iv) ; if( jv == kv ) break ; /* input matches output */ } if( iv == nv ){ mri_free( DSET_BRICK(dset,kv) ) ; #if 0 if( BUCK_verb ) printf("-verb: unloaded unused %s[%d]\n" , DSET_FILECODE(dset) , kv ) ; #endif } } } } /* end of loop over input datasets */ if( ! BUCK_dry ){ if( BUCK_verb ){ if( have_fdr ) fprintf(stderr,"-verb: added %d of %d fdr curves\n", nfdr, new_nvals); fprintf(stderr,"-verb: loading statistics\n") ; } THD_load_statistics( new_dset ) ; if( BUCK_glue ) putenv("AFNI_DECONFLICT=OVERWRITE") ; if( BUCK_glue && BUCK_ccode >= 0 ) THD_set_write_compression(BUCK_ccode) ; /* 16 Mar 2010 */ THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ; if( BUCK_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ; } exit(0) ; }
int main(int argc, char *argv[]) { int i, k, ii; int iarg; char *prefix=NULL; char *maskname=NULL; char *gradsname=NULL; char *dtsname=NULL; THD_3dim_dataset *MASK=NULL; THD_3dim_dataset *DTS=NULL; MRI_IMAGE *GRADS=NULL, *GRADS_IN=NULL; int Ngrads=0, Nfull=0; int Nvox=-1; // tot number vox int Dim[3]={0,0,0}; // dim in each dir float NOISESCALE_DWI = -1.; float NOISESCALE_B0 = -1; float S0 = 1000.; float bval = 1.; int NOISE_IN_S0 = 0; byte *mskd2=NULL; // not great, but another format of mask float **dwi=NULL; THD_3dim_dataset *DWI_OUT=NULL; const gsl_rng_type * T; gsl_rng *r; long seed; srand(time(0)); seed = time(NULL) ; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); gsl_rng_set (r, seed); // ################################################################### // ######################### load ################################## // ################################################################### mainENTRY("3dDTtoNoisyDWI"); machdep(); if (argc == 1) { usage_DTtoNoisyDWI(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_DTtoNoisyDWI(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-dt_in") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-eig_vecs'"); dtsname = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-prefix'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-prefix'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); maskname = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-grads") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); gradsname = strdup(argv[iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-noise_DWI") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-noise_DWI'"); NOISESCALE_DWI = atof(argv[iarg]); iarg++ ; continue ; } if( strcmp(argv[iarg],"-noise_B0") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-noise_B0'"); NOISESCALE_B0 = atof(argv[iarg]); iarg++ ; continue ; } if( strcmp(argv[iarg],"-S0") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-S0'"); S0 = atof(argv[iarg]); if(S0 <= 0 ) ERROR_exit("The '-S0' value must be >0."); iarg++ ; continue ; } if( strcmp(argv[iarg],"-bval") == 0) { if( ++iarg >= argc ) ERROR_exit("Need numerical argument after '-bval'"); bval = atof(argv[iarg]); if(bval <= 0 ) ERROR_exit("The '-bval' value must be >0."); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // ################################################################### // #################### some checks ############################### // ################################################################### if(!prefix) ERROR_exit("Need to give a '-prefix'."); if(!dtsname) ERROR_exit("Need to input diffusion tensor file after '-dt_in'."); if(!gradsname) ERROR_exit("Need to input gradient file after '-grads'."); if( NOISESCALE_DWI<0 ) ERROR_exit("Fractional noise value after '-snr0' needs to be >0. " "It sets the noise scale of ref signal S0."); if(NOISESCALE_DWI > 0) INFO_message("You have chosen an SNR0 of approximately %.2f for DWIs", 1./NOISESCALE_DWI); else INFO_message("You have noiseless (i.e., infinite SNR) set of DWIs"); if( NOISESCALE_B0 < 0 ) NOISESCALE_B0 = NOISESCALE_DWI; if(NOISESCALE_B0 > 0) INFO_message("You have chosen an SNR0 of approximately %.2f for the B0", 1./NOISESCALE_B0); else INFO_message("You have noiseless (i.e., infinite SNR) reference B0."); // ################################################################### if(dtsname) { DTS = THD_open_dataset(dtsname); DSET_load(DTS); CHECK_LOAD_ERROR(DTS); if( 6 != DSET_NVALS(DTS) ) ERROR_exit("DT file '%s' must have 6 bricks-- " "it has %d bricks!", dtsname, DSET_NVALS(DTS)); } Nvox = DSET_NVOX(DTS); Dim[0] = DSET_NX(DTS); Dim[1] = DSET_NY(DTS); Dim[2] = DSET_NZ(DTS); if(Nvox<0) ERROR_exit("Error reading Nvox from eigenvalue file."); mskd2 = (byte *)calloc(Nvox,sizeof(byte)); if( (mskd2 == NULL)) { fprintf(stderr, "\n\n MemAlloc failure (masks).\n\n"); exit(122); } if(maskname) { MASK = THD_open_dataset(maskname); DSET_load(MASK); CHECK_LOAD_ERROR(MASK); if( 1 != DSET_NVALS(MASK) ) ERROR_exit("Mask file '%s' is not scalar-- " "it has %d bricks!", maskname, DSET_NVALS(MASK)); for( k=0 ; k<Nvox ; k++ ) if (THD_get_voxel(MASK, k, 0) > 0 ) mskd2[k] = 1; DSET_delete(MASK); free(MASK); free(maskname); } else { for( k=0 ; k<Nvox ; k++ ) if( fabs(THD_get_voxel(DTS,k,0) > EPS_V) ) mskd2[k] = 1; } GRADS_IN = mri_read_1D (gradsname); GRADS = mri_transpose(GRADS_IN); // get rid of autotranspose... if (GRADS == NULL) ERROR_exit("Error reading gradient vector file"); mri_free(GRADS_IN); Ngrads = GRADS->ny; if(Ngrads < 6) ERROR_exit("Too few grads (there appear to be only %d).",Ngrads); if(GRADS->nx !=3 ) ERROR_exit("Wrong number of columns in the grad file: " " am reading %d instead of 3.",GRADS->nx); Nfull = Ngrads+1; INFO_message("Have surmised there are %d total grads; " "output file will have %d bricks", Ngrads,Nfull); dwi = calloc(Nfull,sizeof(dwi)); for(i=0 ; i<Nfull ; i++) dwi[i] = calloc( Nvox,sizeof(float)); INFO_message("Calculating the DWIs."); i = RicianNoiseDWIs( dwi, Nvox, Ngrads, DTS, NOISESCALE_DWI, NOISESCALE_B0, GRADS, mskd2, S0, bval, r); INFO_message("Writing the DWIs."); DWI_OUT = EDIT_empty_copy( DTS ); EDIT_dset_items(DWI_OUT, ADN_nvals, Nfull, ADN_datum_all, MRI_float , ADN_prefix, prefix, ADN_none ); for( i=0; i<Nfull ; i++) { EDIT_substitute_brick(DWI_OUT, i, MRI_float, dwi[i]); dwi[i]=NULL; } THD_load_statistics( DWI_OUT ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(DWI_OUT)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(DWI_OUT)); tross_Make_History("3dDTtoNoisyDWI", argc, argv, DWI_OUT); THD_write_3dim_dataset(NULL, NULL, DWI_OUT, True); DSET_delete(DWI_OUT); free(DWI_OUT); // ################################################################# // ########################## free ############################### // ################################################################# DSET_delete(DTS); free(DTS); for( i=0 ; i<Nfull ; i++) free(dwi[i]); free(dwi); free(prefix); free(gradsname); free(dtsname); mri_free(GRADS); return 0; }
THD_3dim_dataset * fim3d_fimmer_compute ( THD_3dim_dataset * dset_time , time_series_array * ref_ts , time_series_array * ort_ts , int itbot, char * new_prefix, float max_percent /* 19 May 1997 */ ) { THD_3dim_dataset * new_dset ; int ifim , it,iv , nvox=0 , ngood_ref , ntime , it1 , dtyp , nxyz; float * vval , * tsar , * aval , * rbest , * abest ; int * indx=NULL ; short * bar ; void * ptr ; float stataux[MAX_STAT_AUX]; float fthr , topval ; int nx_ref , ny_ref , ivec , nnow ; PCOR_references ** pc_ref ; PCOR_voxel_corr ** pc_vc ; int save_resam ; int fim_nref , nx_ort , ny_ort=0 , internal_ort ; /* 10 Dec 1996 */ static float * ref_vec = NULL ; static int nref_vec = -666 ; float * ref_ts_min = NULL, * ref_ts_max = NULL, * baseline = NULL; /* 19 May 1997 */ int i; int nupdt = 0 , /* number of updates done yet */ min_updt = 5 ; /* min number needed for display */ /*--- check for legal inputs ---*/ /* 14 Jan 1998 */ if (!DSET_GRAPHABLE(dset_time)) { fprintf (stderr, "Error: Invalid 3d+time input data file \n"); RETURN (NULL); } if (ref_ts == NULL) { fprintf (stderr, "Error: No ideal time series \n"); RETURN (NULL); } for (i = 0; i < ref_ts->num; i++) if (ref_ts->tsarr[i]->len < DSET_NUM_TIMES(dset_time)) { fprintf (stderr, "Error: ideal time series is too short: ntime=%d num_ts=%d \n", DSET_NUM_TIMES(dset_time), ref_ts->tsarr[i]->len); RETURN (NULL) ; } /** 10 Dec 1996: allow for orts **/ if( ort_ts->num > 0 ) /** 05 Sept 1997 **/ { internal_ort = 0; ny_ort = ort_ts->num; for (i = 0; i < ny_ort; i++) { nx_ort = ort_ts->tsarr[i]->len ; if (nx_ort < DSET_NUM_TIMES(dset_time)) /* 14 Jan 1998 */ { fprintf (stderr, "Error: ort time series is too short: ntime=%d ort_ts=%d \n", DSET_NUM_TIMES(dset_time), ort_ts->tsarr[i]->len); RETURN (NULL) ; } } } else { internal_ort = 1 ; } fim_nref = (internal_ort) ? 3 : (ny_ort+3) ; if( nref_vec < fim_nref ) { ref_vec = (float *) malloc (sizeof(float)*fim_nref) ; nref_vec = fim_nref; } /* arrays to store maximum change in the ideal time series */ if (max_percent > 0.0) /* 19 May 1997 */ { ref_ts_max = (float *) malloc (sizeof(float) * (ref_ts->num)); ref_ts_min = (float *) malloc (sizeof(float) * (ref_ts->num)); } nx_ref = ref_ts->tsarr[0]->len; ny_ref = ref_ts->num; ntime = DSET_NUM_TIMES(dset_time) ; ngood_ref = 0 ; it1 = -1 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ tsar = ref_ts->tsarr[ivec]->ts; ifim = 0 ; if (max_percent > 0.0) /* 19 May 1997 */ { ref_ts_min[ivec] = (float) SO_BIG; ref_ts_max[ivec] = - (float) SO_BIG; } for( it=itbot ; it < ntime ; it++ ) { if( tsar[it] < SO_BIG ) { ifim++ ; if( it1 < 0 ) it1 = it ; if (max_percent > 0.0) /* 19 May 1997 */ { if (tsar[it] > ref_ts_max[ivec]) ref_ts_max[ivec] = tsar[it]; if (tsar[it] < ref_ts_min[ivec]) ref_ts_min[ivec] = tsar[it]; } } } if( ifim < min_updt ){ STATUS("ref_ts has too few good entries!") ; RETURN(NULL) ; } ngood_ref = MAX( ifim , ngood_ref ) ; } /** at this point, ngood_ref = max number of good reference points, and it1 = index of first point used in first reference **/ dtyp = DSET_BRICK_TYPE(dset_time,it1) ; if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){ STATUS("illegal input data type!") ; RETURN(NULL) ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"new prefix = %s",new_prefix) ; STATUS(str) ; } #endif /*--- FIM: find values above threshold to fim ---*/ DSET_load(dset_time); CHECK_LOAD_ERROR(dset_time); nxyz = dset_time->dblk->diskptr->dimsizes[0] * dset_time->dblk->diskptr->dimsizes[1] * dset_time->dblk->diskptr->dimsizes[2] ; /** find the mean of the first array, compute the threshold (fthr) from it, make indx[i] be the 3D index of the i-th voxel above threshold **/ switch( dtyp ){ case MRI_short:{ short * dar = (short *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( abs(dar[iv]) > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ; } break ; case MRI_float:{ float * dar = (float *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( fabs(dar[iv]) > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ; } break ; case MRI_byte:{ byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( dar[iv] > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( dar[iv] > fthr ) indx[nvox++] = iv ; } break ; } /** allocate space for voxel values **/ vval = (float *) malloc( sizeof(float) * nvox) ; if( vval == NULL ){ fprintf(stderr,"\n*** vval malloc failure in fim3d_fimmer_compute\n") ; free(indx) ; RETURN(NULL) ; } /*----- allocate space for baseline values -----*/ if (max_percent > 0.0) /* 19 May 1997 */ { baseline = (float *) malloc (sizeof(float) * nvox); if (baseline == NULL) { fprintf(stderr, "\n*** baseline malloc failure in fim3d_fimmer_compute\n") ; free(indx) ; free(vval); RETURN(NULL) ; } else /* initialize baseline values to zero */ for (iv = 0; iv < nvox; iv++) baseline[iv] = 0.0; } /** allocate extra space for comparing results from multiple ref vectors **/ if( ny_ref > 1 ){ aval = (float *) malloc( sizeof(float) * nvox) ; rbest = (float *) malloc( sizeof(float) * nvox) ; abest = (float *) malloc( sizeof(float) * nvox) ; if( aval==NULL || rbest==NULL || abest==NULL ){ fprintf(stderr,"\n*** abest malloc failure in fim3d_fimmer_compute\n") ; free(vval) ; free(indx) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } } else { aval = rbest = abest = NULL ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"nxyz = %d nvox = %d",nxyz,nvox) ; STATUS(str) ; } #endif /*--- FIM: initialize recursive updates ---*/ pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ; pc_vc = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ; if( pc_ref == NULL || pc_vc == NULL ){ free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } ifim = 0 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ pc_ref[ivec] = new_PCOR_references( fim_nref ) ; pc_vc[ivec] = new_PCOR_voxel_corr( nvox , fim_nref ) ; if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ) ifim++ ; } if( ifim > 0 ){ for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } /*--- Make a new dataset to hold the output ---*/ new_dset = EDIT_empty_copy( dset_time ) ; it = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , ADN_malloc_type , DATABLOCK_MEM_MALLOC , ADN_type , ISHEAD(dset_time) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_COR_TYPE , ADN_nvals , FUNC_nvals[FUNC_COR_TYPE] , ADN_datum_all , MRI_short , ADN_ntt , 0 , ADN_none ) ; if( it > 0 ){ fprintf(stderr, "\n*** EDIT_dset_items error %d in fim3d_fimmer_compute\n",it) ; THD_delete_3dim_dataset( new_dset , False ) ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){ ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ; mri_fix_data_pointer( ptr , DSET_BRICK(new_dset,iv) ) ; } if( THD_count_databricks(new_dset->dblk) < new_dset->dblk->nvals ){ fprintf(stderr, "\n*** failure to malloc new bricks in fim3d_fimmer_compute\n") ; THD_delete_3dim_dataset( new_dset , False ) ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } /*--- FIM: do recursive updates ---*/ for( it=itbot ; it < ntime ; it++ ){ nnow = 0 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ tsar = ref_ts->tsarr[ivec]->ts ; if( tsar[it] >= SO_BIG ) continue ; /* skip this */ ref_vec[0] = 1.0 ; /* we always supply orts */ ref_vec[1] = (float) it ; /* for mean and linear trend */ if (internal_ort) /* 10 Dec 1996 */ { ref_vec[2] = tsar[it] ; } else { for( iv=0 ; iv < ny_ort ; iv++ ) ref_vec[iv+2] = ort_ts->tsarr[iv]->ts[it]; ref_vec[ny_ort+2] = tsar[it] ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"time index=%d ideal[%d]=%f" , it,ivec,tsar[it] ) ; if (ivec == 0) STATUS(str) ; } #endif update_PCOR_references( ref_vec , pc_ref[ivec] ) ; switch( dtyp ){ case MRI_short:{ short * dar = (short *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; case MRI_float:{ float * dar = (float *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; case MRI_byte:{ byte * dar = (byte *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; } PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ; nnow++ ; /*----- update baseline value calculation -----*/ if (max_percent > 0.0) /* 19 May 1997 */ if (ivec == 0) for (iv = 0; iv < nvox; iv++) baseline[iv] += vval[iv] / ngood_ref; } if( nnow > 0 ) nupdt++ ; /*--- Load results into the dataset and redisplay it ---*/ if( nupdt == ngood_ref ) { /*--- set the statistical parameters ---*/ stataux[0] = nupdt ; /* number of points used */ stataux[1] = (ny_ref==1) ? 1 : 2 ; /* number of references */ stataux[2] = fim_nref - 1 ; /* number of orts */ /* 12 Dec 96 */ for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ; STATUS("setting statistical parameters") ; (void) EDIT_dset_items( new_dset , ADN_stat_aux , stataux , ADN_none ) ; /*** Compute brick arrays for new dataset ***/ if( ny_ref == 1 ){ /*** Just 1 ref vector --> load values directly into dataset ***/ /*--- get alpha (coef) into vval, find max value, scale into brick array ---*/ STATUS("getting 1 ref alpha") ; PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ; /*--- replace alpha with percentage change, if so requested ---*/ if (max_percent > 0.0) /* 19 May 1997 */ { for (iv = 0; iv < nvox; iv++) { vval[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]); if (fabs(vval[iv]) < max_percent * fabs(baseline[iv])) vval[iv] = fabs( vval[iv] / baseline[iv] ); else vval[iv] = max_percent; } topval = max_percent; } else { topval = 0.0 ; for( iv=0 ; iv < nvox ; iv++ ) if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ; } bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; if( topval > 0.0 ){ topval = MRI_TYPE_maxval[MRI_short] / topval ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ; stataux[0] = 1.0/topval ; } else { stataux[0] = 0.0 ; } /*--- get correlation coefficient (pcor) into vval, scale into brick array (with fixed scaling factor) ---*/ STATUS("getting 1 ref pcor") ; PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ; bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ; stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ; } else { /*** Multiple references --> find best correlation at each voxel ***/ /*--- get first ref results into abest and rbest (best so far) ---*/ PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ; /*--- modify alpha for percentage change calculation ---*/ if (max_percent > 0.0) /* 19 May 1997 */ for (iv = 0; iv < nvox; iv++) abest[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]); PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ; /*--- for each succeeding ref vector, get results into aval and vval, if |vval| > |rbest|, then use that result instead ---*/ for( ivec=1 ; ivec < ny_ref ; ivec++ ){ PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ; PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ; for( iv=0 ; iv < nvox ; iv++ ){ if( fabs(vval[iv]) > fabs(rbest[iv]) ){ rbest[iv] = vval[iv] ; abest[iv] = aval[iv] ; /*--- modify alpha for percentage change calculation ---*/ if (max_percent > 0.0) /* 19 May 1997 */ abest[iv] *= 100.0 * (ref_ts_max[ivec] - ref_ts_min[ivec]); } } } /*--- at this point, abest and rbest are the best results, so scale them into the dataset bricks ---*/ /*--- finish percentage change calculation, if so requested ---*/ if (max_percent > 0.0) /* 19 May 1997 */ { for (iv = 0; iv < nvox; iv++) { if (fabs(abest[iv]) < max_percent * fabs(baseline[iv])) abest[iv] = fabs( abest[iv] / baseline[iv] ); else abest[iv] = max_percent; } topval = max_percent; } else { topval = 0.0 ; for( iv=0 ; iv < nvox ; iv++ ) if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ; } bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; if( topval > 0.0 ){ topval = MRI_TYPE_maxval[MRI_short] / topval ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ; stataux[0] = 1.0/topval ; } else { stataux[0] = 0.0 ; } bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ; stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ; } STATUS("setting brick_fac") ; (void) EDIT_dset_items( new_dset , ADN_brick_fac , stataux , ADN_none ) ; } } /*--- End of recursive updates; now free temporary workspaces ---*/ for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; if (ref_ts_min != NULL) free (ref_ts_min); /* 19 May 1997 */ if (ref_ts_max != NULL) free (ref_ts_max); if (baseline != NULL) free (baseline); /* --- load the statistics --- */ THD_load_statistics (new_dset); /*--- Return new dataset ---*/ RETURN(new_dset) ; }
int main(int argc, char *argv[]) { int CHECK = 0; int iarg; char *Fname_input = NULL; char *Fname_output = NULL; char *Fname_outputBV = NULL; char *Fname_bval = NULL; int opt; FILE *fin=NULL, *fout=NULL, *finbv=NULL, *foutBV=NULL; int i,j,k; int BZER=0,idx=0,idx2=0; MRI_IMAGE *flim=NULL; MRI_IMAGE *preREADIN=NULL; MRI_IMAGE *preREADBVAL=NULL; float *READIN=NULL; float *READBVAL=NULL; float OUT_MATR[MAXGRADS][7]; // b- or g-matrix float OUT_GRAD[MAXGRADS][4]; // b- or g-matrix int INV[3] = {1,1,1}; // if needing to switch int FLAG[MAXGRADS]; float temp; int YES_B = 0; int EXTRA_ZEROS=0; int HAVE_BVAL = 0; int BVAL_OUT = 0; int BVAL_OUT_SEP = 0; float BMAX_REF = 1; // i.e., essentially zero int IN_FORM = 0; // 0 for row, 1 for col int OUT_FORM = 1; // 1 for col, 2 for bmatr int HAVE_BMAX_REF=0 ; // referring to user input value int count_in=0, count_out=0; THD_3dim_dataset *dwset=NULL, *dwout=NULL; int Nbrik = 0; char *prefix=NULL ; float **temp_arr=NULL, **temp_grad=NULL; int Ndwi = 0, dwi=0, Ndwout = 0, Ndwi_final = 0, Ndwout_final = 0; int Nvox = 0; int DWI_COMP_FAC = 0; int ct_dwi = 0; float MaxDP = 0; mainENTRY("1dDW_Grad_o_Mat"); machdep(); if (argc == 1) { usage_1dDW_Grad_o_Mat(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_1dDW_Grad_o_Mat(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strcmp(argv[iarg],"-flip_x") == 0) { INV[0] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-flip_y") == 0) { INV[1] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-flip_z") == 0) { INV[2] = -1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-keep_b0s") == 0) { YES_B = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-put_zeros_top") == 0) { EXTRA_ZEROS = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_grad_rows") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_grad_rows'\n") ; Fname_input = argv[iarg]; count_in++; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_grad_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_grad_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_gmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matT_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 2; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_gmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matA_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 3; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matT_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 4; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_matA_cols'\n") ; Fname_input = argv[iarg]; count_in++; IN_FORM = 5; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_grad_rows") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_grad_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 0; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_grad_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_grad_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_gmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_gmatT_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 2; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_gmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_gmatA_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 3; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bmatT_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bmatT_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 4; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bmatA_cols") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bmatA_cols'\n") ; Fname_output = argv[iarg]; count_out++; OUT_FORM = 5; iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_bvals") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-in_bvals'\n") ; Fname_bval = argv[iarg]; HAVE_BVAL = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-bmax_ref") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-bmax_ref'\n"); BMAX_REF = atof(argv[iarg]); HAVE_BMAX_REF = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-out_bval_col") == 0) { BVAL_OUT = 1; iarg++ ; continue ; } // May,2015 if( strcmp(argv[iarg],"-out_bval_row_sep") == 0) { if( ++iarg >= argc ) ERROR_exit("Need argument after '-out_bval_row_sep'\n") ; Fname_outputBV = argv[iarg]; BVAL_OUT_SEP = 1; iarg++ ; continue ; } if( strcmp(argv[iarg],"-proc_dset") == 0 ){ // in DWIs if( ++iarg >= argc ) ERROR_exit("Need argument after '-proc_dset'") ; dwset = THD_open_dataset( argv[iarg] ) ; if( dwset == NULL ) ERROR_exit("Can't open DWI dataset '%s'", argv[iarg]) ; DSET_load(dwset) ; CHECK_LOAD_ERROR(dwset) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-pref_dset") == 0 ){ // will be output iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-pref_dset'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-pref_dset'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-dwi_comp_fac") == 0) { iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-dwi_comp_fac'\n"); DWI_COMP_FAC = atoi(argv[iarg]); if (DWI_COMP_FAC <=1) ERROR_exit("The compression factor after '-dwi_comp_fac'" "must be >1!"); iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * if( (Fname_input == NULL) ) { fprintf(stderr, "\n\tBad Command-lining! Option '-in_*' requires argument.\n"); exit(1); } if( (Fname_output == NULL) ) { fprintf(stderr, "\n\tBad Command-lining! Option '-out_*' requires arg.\n"); exit(2); } if( count_in > 1 ) { fprintf(stderr, "\n\tBad Command-lining! Can't have >1 vec file input.\n"); exit(3); } if( count_out > 1 ) { fprintf(stderr, "\n\tBad Command-lining! Can't have >1 output file opt.\n"); exit(4); } if(YES_B && dwset) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have '-keep_b0s' and '-proc_dset' together.\n"); exit(5); } if( !prefix && dwset) { fprintf(stderr, "\n** Bad Command-lining! " "Need an output '-pref_dset' when using '-proc_dset'.\n"); exit(6); } if(YES_B && DWI_COMP_FAC) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have '-keep_b0s' and '-dwi_comp_fac' together.\n"); exit(7); } if(!HAVE_BVAL && (BVAL_OUT || BVAL_OUT_SEP)) { fprintf(stderr, "\n** Bad Command-lining! " "Can't have ask for outputting bvals with no '-in_bvals FILE'.\n"); exit(8); } // ******************************************************************** // ************************* start reading **************************** // ******************************************************************** flim = mri_read_1D (Fname_input); if (flim == NULL) { ERROR_exit("Error reading gradient vector file"); } if( IN_FORM ) preREADIN = mri_transpose(flim); // effectively *undoes* autotranspose else preREADIN = mri_copy(flim); mri_free(flim); idx = preREADIN->ny; if( HAVE_BVAL ) { flim = mri_read_1D (Fname_bval); if (flim == NULL) { ERROR_exit("Error reading b-value file"); } if( flim->ny == 1) preREADBVAL = mri_transpose(flim); // effectively *undoes* autotransp else preREADBVAL = mri_copy(flim); mri_free(flim); idx2 = preREADBVAL->ny; } if(idx>= MAXGRADS ) { printf("Error, too many input grads.\n"); mri_free (preREADIN); if( HAVE_BVAL ) mri_free (preREADBVAL); exit(4); } if( ( (preREADIN->nx != 3 ) && (preREADIN->ny != 3 )) && (preREADIN->nx != 6 ) ) printf("Probably an error, " "because there aren't 3 or 6 numbers in columns!\n"); if( HAVE_BVAL && ( idx != idx2 ) ) { printf("Error, because the number of bvecs (%d)\n" "and bvals (%d) don't appear to match!\n", idx, idx2); mri_free (preREADIN); mri_free (preREADBVAL); exit(3); } if(dwset) { Nbrik = DSET_NVALS(dwset); if( idx != Nbrik ) { fprintf(stderr, "\n** ERROR: the number of bvecs (%d) does not match the " "number of briks in '-proc_dset' (%d).\n", idx, Nbrik); exit(4); } } READIN = MRI_FLOAT_PTR( preREADIN ); if( HAVE_BVAL ) READBVAL = MRI_FLOAT_PTR( preREADBVAL ); // 0 is grad row; // 1 is grad col; // 2 is gmatrRow col T; // 3 is gmatrDiag col A; // 4 is bmatrRow col T; // 5 is bmatrDiag col A; //if( IN_FORM == 0 ) // grad rows, no binfo // for( i=0; i<idx ; i++ ) // for ( j=0; j<3 ; j++ ) // OUT_GRAD[i][j+1] = *(READIN +j*idx +i) ; //else if ( IN_FORM <= 1 ) // grad cols, no binfo for( i=0; i<idx ; i++ ) for ( j=0; j<3 ; j++ ) OUT_GRAD[i][j+1] = *(READIN + 3*i+j); // A/row/3dDWItoDT: Bxx, Byy, Bzz, Bxy, Bxz, Byz // T/diag/TORTOISE: b_xx 2b_xy 2b_xz b_yy 2b_yz b_zz else if ( (IN_FORM == 3) || (IN_FORM ==5 ) ) { // diag matr for( i=0; i<idx ; i++ ) { for( j=0; j<3 ; j++ ) { OUT_MATR[i][j+1] = *(READIN+6*i+j); OUT_MATR[i][3+j+1] = *(READIN+6*i+3+j); } for( j=0; j<3 ; j++ ) if(OUT_MATR[i][j] < 0 ) CHECK++; } if(CHECK > 0) INFO_message("Warning: you *said* you input a mat'T'," " but the matr diagonals don't appear to be uniformly" " positive. If input cols 0, 3 and 5 are positive," " then you might have meant mat'A'?"); } else if ( (IN_FORM ==2 ) || (IN_FORM ==4 ) ) { // row matr CHECK = 0; for( i=0; i<idx ; i++ ) { OUT_MATR[i][1] = *(READIN +6*i); OUT_MATR[i][2] = *(READIN +6*i+3); OUT_MATR[i][3] = *(READIN +6*i+5); OUT_MATR[i][4] = *(READIN +6*i+1)/2.; OUT_MATR[i][5] = *(READIN +6*i+2)/2.; OUT_MATR[i][6] = *(READIN +6*i+4)/2.; } for( i=0; i<idx ; i++ ) for( j=0; j<3 ; j++ ) if(OUT_MATR[i][j] < 0 ) CHECK++; if(CHECK > 0) INFO_message("Warning: you *said* you input a mat'A'," " but the matr diagonals don't appear to be uniformly" " positive. If input cols 0, 1 and 2 are positive," " then you might have meant mat'T'?"); } else{ fprintf(stderr, "Coding error with format number (%d), not allowed.\n", IN_FORM); exit(2); } // get bval info if( ( (IN_FORM ==4 ) || (IN_FORM ==5 ) ) ) { //bval for( i=0; i<idx ; i++ ) { OUT_MATR[i][0] = OUT_GRAD[i][0] = OUT_MATR[i][1] + OUT_MATR[i][2] + OUT_MATR[i][3]; if( OUT_MATR[i][0] > 0.000001) for( j=1 ; j<7 ; j++ ) OUT_MATR[i][j]/= OUT_MATR[i][0]; } } else if ( HAVE_BVAL ) for( i=0; i<idx ; i++ ) { OUT_MATR[i][0] = OUT_GRAD[i][0] = *(READBVAL + i); } else if ( OUT_FORM > 3 || BVAL_OUT || BVAL_OUT_SEP || HAVE_BMAX_REF ) { fprintf(stderr, "ERROR: you asked for b-value dependent output, " "but gave me no bvals to work with.\n"); exit(2); } // * * * ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * * // at this point, all IN_FORM >1 cases which need bval have led to: // + grad[0] has bval // + matr[0] has bval // + matr file normalized and in diagonal form // * * * ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * * for( i=0; i<idx ; i++ ) if( IN_FORM > 1) j = GradConv_Gsign_from_BmatA( OUT_GRAD[i]+1, OUT_MATR[i]+1); else j = GradConv_BmatA_from_Gsign( OUT_MATR[i]+1, OUT_GRAD[i]+1); // flip if necessary for( i=0 ; i<idx ; i++) { for( j=0 ; j<3 ; j++) OUT_GRAD[i][j+1]*= INV[j]; OUT_MATR[i][4]*= INV[0]*INV[1]; OUT_MATR[i][5]*= INV[0]*INV[2]; OUT_MATR[i][6]*= INV[1]*INV[2]; } BZER=0; for( i=0 ; i<idx ; i++) { if( HAVE_BVAL || (IN_FORM ==4) || (IN_FORM ==5) ) if( OUT_GRAD[i][0] >= BMAX_REF ) FLAG[i] = 1; else{ if( YES_B ) FLAG[i] = 1; BZER++; } else { temp = 0.; for( j=1 ; j<4 ; j++) temp+= pow(OUT_GRAD[i][j],2); if( temp > 0.1 ) FLAG[i] = 1; else{ if( YES_B ) FLAG[i] = 1; BZER++; } } } if(YES_B) { printf("\tChose to *keep* %d b0s,\tas well as \t%d grads\n", BZER,idx-BZER); BZER=0; } else { printf("\tGetting rid of %d b0s,\tleaving the %d grads\n", BZER,idx-BZER); Ndwi = idx-BZER; } Ndwi_final = idx-BZER; // default: all DWIs if( DWI_COMP_FAC ) { if( Ndwi % DWI_COMP_FAC != 0 ) { fprintf(stderr, "\n** ERROR can't compress: " "Ndwi=%d, and %d/%d has a nonzero remainder (=%d).\n", Ndwi,Ndwi,DWI_COMP_FAC, Ndwi % DWI_COMP_FAC ); exit(1); } else { Ndwi_final = Ndwi/DWI_COMP_FAC; INFO_message("You have chosen a compression factor of %d, " "with %d DWIs,\n" "\tso that afterward there will be %d DWIs.", DWI_COMP_FAC, Ndwi, Ndwi_final); } } if(BVAL_OUT_SEP) if( (foutBV = fopen(Fname_outputBV, "w")) == NULL) { fprintf(stderr, "\n\nError opening file %s.\n",Fname_outputBV); exit(1); } if( (fout = fopen(Fname_output, "w")) == NULL) { fprintf(stderr, "\n\nError opening file %s.\n",Fname_output); exit(1); } // 0 is grad row; // 1 is grad col; // 2 is gmatrRow col T; // 3 is gmatrDiag col A; // 4 is bmatrRow col T; // 5 is bmatrDiag col A; if( OUT_FORM>0) { if( EXTRA_ZEROS ) { if( BVAL_OUT ) fprintf(fout,"%8d ", 0); if( BVAL_OUT_SEP ) fprintf(foutBV,"%8d ", 0); if( OUT_FORM == 1 ) for( k=1 ; k<4 ; k++ ) fprintf(fout,"%11.5f ", 0.0); else if ( OUT_FORM > 1 ) // bit superfluous at this point for( k=1 ; k<7 ; k++ ) fprintf(fout,"%11.5f ", 0.0); fprintf(fout,"\n"); } ct_dwi = 0; for(i=0 ; i<idx ; i++){ if(FLAG[i]) { if( BVAL_OUT ) fprintf(fout,"%8d ", (int) OUT_GRAD[i][0]); if( BVAL_OUT_SEP ) fprintf(foutBV,"%8d ", (int) OUT_GRAD[i][0]); if( (OUT_FORM == 4) || (OUT_FORM ==5) ) for( k=1 ; k<7 ; k++ ) OUT_MATR[i][k]*= OUT_MATR[i][0]; if( OUT_FORM == 1 ) // grad col for( k=1 ; k<4 ; k++ ) fprintf(fout,"%11.5f ", OUT_GRAD[i][k]); else if( (OUT_FORM == 3) || (OUT_FORM == 5) ) { // gmat for( k=1 ; k<6 ; k++ ) fprintf(fout,"%11.5f ", OUT_MATR[i][k]); fprintf(fout,"%11.5f", OUT_MATR[i][k]); } else if ( (OUT_FORM == 2 ) || (OUT_FORM ==4)) { // bmat fprintf(fout,"%11.5f ", OUT_MATR[i][1]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][4]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][5]); fprintf(fout,"%11.5f ", OUT_MATR[i][2]); fprintf(fout,"%11.5f ", 2*OUT_MATR[i][6]); fprintf(fout,"%11.5f", OUT_MATR[i][3]); } fprintf(fout,"\n"); ct_dwi++; } if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) { INFO_message("Reached compression level: DWI number %d", Ndwi_final); break; } } } else if(OUT_FORM ==0) { if(BVAL_OUT) WARNING_message("Ignoring '-out_bval_col' option, since " " you are outputting in rows."); for( k=1 ; k<4 ; k++ ) { if(EXTRA_ZEROS){ fprintf(fout,"% -11.5f ", 0.0); if( (k==1) && BVAL_OUT_SEP ) // only output 1 zeroin bval file fprintf(foutBV,"%8d ", 0); } ct_dwi = 0; for(i=0 ; i<idx ; i++) { if(FLAG[i]) { fprintf(fout,"% -11.5f ", OUT_GRAD[i][k]); if( (k==1) && BVAL_OUT_SEP )// only output 1 zeroin bval file fprintf(foutBV,"%8d ", (int) OUT_GRAD[i][0]); ct_dwi++; } if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) { INFO_message("Reached compression level: DWI number %d", Ndwi_final); break; } } fprintf(fout,"\n"); } } fclose(fout); if( BVAL_OUT_SEP ) { fprintf(foutBV,"\n"); fclose(foutBV); } if(dwset) { INFO_message("Processing the B0+DWI file now."); if(!BZER) { fprintf(stderr, "\n** Error in processing data set: " "no b=0 values from bvecs/bval info!\n"); exit(5); } // FLAG marks where DWIs are if not using '-keep_b0s'! Nvox = DSET_NVOX(dwset); Ndwout = Ndwi+1; temp_arr = calloc( Ndwout,sizeof(temp_arr)); for( i=0 ; i<Ndwout ; i++) temp_arr[i] = calloc( Nvox,sizeof(float)); temp_grad = calloc( Ndwi,sizeof(temp_grad)); for( i=0 ; i<Ndwi ; i++) temp_grad[i] = calloc( 3,sizeof(float)); if( (temp_arr == NULL) || (temp_grad == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure.\n\n"); exit(123); } dwi = 0; // keep track of DWI contraction for( i=0 ; i<Nbrik ; i++) if( !FLAG[i] ) // b=0 for( j=0 ; j<Nvox ; j++) temp_arr[0][j]+= THD_get_voxel(dwset,j,i); else { for( j=0 ; j<3 ; j++) temp_grad[dwi][j]= OUT_GRAD[i][j+1]; dwi++; for( j=0 ; j<Nvox ; j++) temp_arr[dwi][j]+= THD_get_voxel(dwset,j,i); } if( dwi != Ndwi ) { fprintf(stderr, "\n** Mismatch in internal DWI counting!\n"); exit(6); } // average the values for( j=0 ; j<Nvox ; j++) temp_arr[0][j]/= BZER; // can't be zero here. if( DWI_COMP_FAC ) { INFO_message("Compressing DWI file"); for( k=1 ; k<DWI_COMP_FAC ; k++) for( i=0 ; i<Ndwi_final ; i++) for( j=0 ; j<Nvox ; j++) temp_arr[1+i][j]+= temp_arr[1+k*Ndwi_final+i][j]; for( i=0 ; i<Ndwi_final ; i++) for( j=0 ; j<Nvox ; j++) temp_arr[1+i][j]/= DWI_COMP_FAC; INFO_message("Checking closeness of compressed gradient values"); MaxDP = GradCloseness(temp_grad, Ndwi, DWI_COMP_FAC); INFO_message("The max angular difference between matched/compressed\n" "\tgradients is: %f", MaxDP); if( MaxDP > 2) WARNING_message("The max angular difference seem kinda big-- you\n" " sure about the compression factor?"); } Ndwout_final = Ndwi_final + 1; INFO_message("Writing the processed data set."); dwout = EDIT_empty_copy( dwset ); EDIT_dset_items(dwout, ADN_nvals, Ndwout_final, ADN_ntt, 0, ADN_datum_all, MRI_float , ADN_prefix, prefix, ADN_none ); for( i=0; i<Ndwout_final ; i++) { EDIT_substitute_brick(dwout, i, MRI_float, temp_arr[i]); temp_arr[i]=NULL; } // if necessary for( i=Ndwout_final ; i<Ndwout ; i++) temp_arr[i]=NULL; THD_load_statistics( dwout ); if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(dwout)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(dwout)); tross_Make_History("1dDW_Grad_o_Mat", argc, argv, dwout); THD_write_3dim_dataset(NULL, NULL, dwout, True); DSET_delete(dwout); free(dwout); DSET_delete(dwset); free(dwset); for( i=0 ; i<Ndwout_final ; i++) free(temp_arr[i]); free(temp_arr); } mri_free(preREADIN); if( HAVE_BVAL ) mri_free(preREADBVAL); if(prefix) free(prefix); printf("\n\tDone. Check output file '%s' for results",Fname_output); if(dwset) { printf("\n\t-> as well as the data_set '%s'",DSET_FILECODE(dwout)); } if(BVAL_OUT_SEP) printf("\n\t-> and even the b-value rows '%s'",Fname_outputBV); printf("\n\n"); exit(0); }
int main( int argc , char * argv[] ) { int ninp , ids , nv , iv,jv,kv , ivout , new_nvals ; THD_3dim_dataset * new_dset=NULL , * dset ; char buf[256] ; /*----- Identify software -----*/ #if 0 printf ("\n\n"); printf ("Program: %s \n", PROGRAM_NAME); printf ("Author: %s \n", PROGRAM_AUTHOR); printf ("Initial Release: %s \n", PROGRAM_INITIAL); printf ("Latest Revision: %s \n", PROGRAM_LATEST); printf ("\n"); #endif /*** read input options ***/ if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) B2F_Syntax() ; mainENTRY("3dbuc2fim main"); machdep(); AFNI_logger(PROGRAM_NAME,argc,argv); PRINT_VERSION("3dbuc2fim") ; AUTHOR(PROGRAM_AUTHOR); B2F_read_opts( argc , argv ) ; /*** create new dataset (empty) ***/ ninp = B2F_dsar->num ; if( ninp < 1 ){ fprintf(stderr,"*** No input datasets?\n") ; exit(1) ; } new_nvals = 0 ; for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ; /*----- Check for acceptable number of sub-bricks -----*/ if (new_nvals < 1) { fprintf(stderr,"*** Less than 1 sub-brick specified\n") ; exit(1) ; } if (new_nvals > 2) { fprintf(stderr,"*** More than 2 sub-bricks specified\n") ; exit(1) ; } if( B2F_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ; new_dset = EDIT_empty_copy( DSUB(0) ) ; if( ninp == 1 ) tross_Copy_History( DSUB(0) , new_dset ) ; tross_Make_History( "3dbuc2fim" , argc,argv , new_dset ) ; /*----- Set default value for function type. This will be changed later, if the second sub-brick has a statistic type. -----*/ if (new_nvals == 1) B2F_func_type = FUNC_FIM_TYPE; else B2F_func_type = FUNC_THR_TYPE; EDIT_dset_items (new_dset , ADN_prefix , B2F_output_prefix , ADN_directory_name, B2F_session , ADN_type , HEAD_FUNC_TYPE, ADN_func_type , B2F_func_type, ADN_ntt , 0 , ADN_nvals , new_nvals , ADN_none ) ; if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){ fprintf(stderr,"*** Fatal error: file %s already exists!\n", DSET_HEADNAME(new_dset) ) ; exit(1) ; } THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ; /*** loop over input datasets ***/ if( ninp > 1 ) myXtFree( new_dset->keywords ) ; ivout = 0 ; for( ids=0 ; ids < ninp ; ids++ ){ dset = DSUB(ids) ; nv = NSUBV(ids) ; DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; /** loop over sub-bricks to output **/ for( iv=0 ; iv < nv ; iv++ ){ jv = SUBV(ids,iv) ; /* which sub-brick to use */ EDIT_substitute_brick( new_dset , ivout , DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ; /*----- If this sub-brick is from a bucket dataset, preserve the label for this sub-brick -----*/ if (dset->func_type == FUNC_BUCK_TYPE) sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv)); else sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ; EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ; #if 0 sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ; EDIT_dset_items( new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ; #endif EDIT_dset_items( new_dset , ADN_brick_fac_one +ivout, DSET_BRICK_FACTOR(dset,jv), #if 0 ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) , #endif ADN_none ) ; /** possibly write statistical parameters for this sub-brick **/ kv = DSET_BRICK_STATCODE(dset,jv) ; if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */ int npar = MAX_STAT_AUX , lv ; float * par = (float *) malloc( sizeof(float) * (npar) ) ; float * sax = DSET_BRICK_STATAUX(dset,jv) ; for( lv=0 ; lv < npar ; lv++ ) par[lv] = (sax != NULL && lv < FUNC_need_stat_aux[kv]) ? sax[lv] : 0.0; if (ivout == 1) { EDIT_dset_items(new_dset , ADN_func_type , kv, ADN_stat_aux, par , ADN_none ) ; } free(par) ; /* 2: if the input dataset has statistical parameters */ } else if( ISFUNC(dset) && /* dset has stat */ FUNC_IS_STAT(dset->func_type) && /* params */ jv == FUNC_ival_thr[dset->func_type] ){ /* thr sub-brick */ int npar , lv ; float * par , * sax ; kv = dset->func_type ; npar = MAX_STAT_AUX ; par = (float *) malloc( sizeof(float) * (npar+2) ) ; sax = dset->stat_aux ; for( lv=0 ; lv < npar ; lv++ ) par[lv] = (sax != NULL) ? sax[lv] : 0.0 ; if (ivout == 1) { for( lv=0 ; lv < npar+2 ; lv++ ) printf ("par[%d] = %f \n", lv, par[lv]); EDIT_dset_items(new_dset , ADN_func_type , kv, ADN_stat_aux, par , ADN_none ) ; } free(par) ; } /** print a message? **/ if( B2F_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" , DSET_FILECODE(dset) , jv , DSET_FILECODE(new_dset) , ivout ) ; ivout++ ; } /** loop over all bricks in input dataset and unload them if they aren't going into the output (not required, but is done to economize on memory) **/ if( nv < DSET_NVALS(dset) ){ for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){ /* all input sub-bricks */ for( iv=0 ; iv < nv ; iv++ ){ /* all output sub-bricks */ jv = SUBV(ids,iv) ; if( jv == kv ) break ; /* input matches output */ } if( iv == nv ){ mri_free( DSET_BRICK(dset,kv) ) ; #if 0 if( B2F_verb ) printf("-verb: unloaded unused %s[%d]\n" , DSET_FILECODE(dset) , kv ) ; #endif } } } } /* end of loop over input datasets */ if( B2F_verb ) fprintf(stderr,"-verb: loading statistics\n") ; THD_load_statistics( new_dset ) ; THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ; if( B2F_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ; exit(0) ; }
int main(int argc, char *argv[]) { int i,j,k,l,m,n,mm,ii; int idx; int iarg; THD_3dim_dataset *insetTIME = NULL; // THD_3dim_dataset *inset0 = NULL; THD_3dim_dataset *MASK=NULL; char *prefix="REHO" ; char in_name[300]; char in_mask[300]; THD_3dim_dataset *outset=NULL; char outname[300]; int NIFTI_OUT=0; int DTYPE=0; int HAVE_MASK = 0; int ***mskd; // define mask of where time series are nonzero double temp_sum; // FILE *fout0, *fout1; int Nvox=-1; // tot number vox int Dim[4]={0,0,0,0}; float fbot = -1., ftop = -1; float delF = -1; float *allF=NULL; float **allPar=NULL; int Npar=NRSFC; // currently... see list below char *namePar[NRSFC]={"ALFF", "MALFF", "FALFF", "RSFA", "MRSFA", "FRSFA"}; int MIN_full=0, MAX_full=-1; // indices of full spect int MIN_bp=0, MAX_bp = -1; // indices of lff/bp region mainENTRY("3dAmpToRSFC"); machdep(); // **************************************************************** // **************************************************************** // load AFNI stuff // **************************************************************** // **************************************************************** // INFO_message("version: NU"); /** scan args **/ if (argc == 1) { usage_AmpToRSFC(1); exit(0); } iarg = 1; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0 ) { usage_AmpToRSFC(strlen(argv[iarg])>3 ? 2:1); exit(0); } if( strncmp(argv[iarg],"-band",5) == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ; fbot = strtod(argv[iarg++],NULL) ; ftop = strtod(argv[iarg++],NULL) ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); HAVE_MASK=1; sprintf(in_mask,"%s", argv[iarg]); MASK = THD_open_dataset(in_mask) ; if( (MASK == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_mask); DSET_load(MASK); CHECK_LOAD_ERROR(MASK); iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-prefix'"); prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '-prefix'"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_amp") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_amp'"); sprintf(in_name,"%s", argv[iarg]); DTYPE = 1; // for amps iarg++ ; continue ; } if( strcmp(argv[iarg],"-in_pow") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-in_pow'"); sprintf(in_name,"%s", argv[iarg]); DTYPE = 2; // for pow iarg++ ; continue ; } if( strcmp(argv[iarg],"-mask") == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-mask'"); HAVE_MASK=1; sprintf(in_mask,"%s", argv[iarg]); MASK = THD_open_dataset(in_mask) ; if( (MASK == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_mask); DSET_load(MASK); CHECK_LOAD_ERROR(MASK); iarg++ ; continue ; } if( strcmp(argv[iarg],"-nifti") == 0) { NIFTI_OUT=1; iarg++ ; continue ; } ERROR_message("Bad option '%s'\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } // --------------------------------------------------------------- // TEST BASIC INPUT PROPERTIES if (iarg < 3) { ERROR_message("Too few options. Try -help for details.\n"); exit(1); } if( !DTYPE ) { ERROR_message("Think somebody forgot to specify an input file" " using '-in_amp ...' or '-in_pow ...'."); exit(12); } else{ insetTIME = THD_open_dataset(in_name) ; if( (insetTIME == NULL )) ERROR_exit("Can't open time series dataset '%s'.",in_name); DSET_load(insetTIME); CHECK_LOAD_ERROR(insetTIME); Nvox = DSET_NVOX(insetTIME) ; Dim[0] = DSET_NX(insetTIME); Dim[1] = DSET_NY(insetTIME); Dim[2] = DSET_NZ(insetTIME); Dim[3]= DSET_NVALS(insetTIME); delF = DSET_TR(insetTIME); } if( (fbot<0) || (ftop<0) ) { ERROR_message("Think somebody forgot to specify upper and lower" " frequency bounds using '-band ... ...'."); exit(11); } if( fbot > ftop ) ERROR_exit("Can't have ftop < fbot! Try entering frequency" "band limits again"); if( MASK ) if ( Dim[0] != DSET_NX(MASK) || Dim[1] != DSET_NY(MASK) || Dim[2] != DSET_NZ(MASK) ) { ERROR_message("Mask and inset don't appear to have the same " "dimensions.\n"); exit(1); } // **************************************************************** // **************************************************************** // pre-stuff, make storage // **************************************************************** // **************************************************************** // array of freqs-- starts at delta F, not zero, as the current // input data sets must! allF = (float *)calloc(Dim[3], sizeof(float)); // will be the output allPar = calloc(Npar,sizeof(allPar)); for(i=0 ; i<Npar ; i++) allPar[i] = calloc(Nvox,sizeof(float)); // MASK mskd = (int ***) calloc( Dim[0], sizeof(int **) ); for ( i = 0 ; i < Dim[0] ; i++ ) mskd[i] = (int **) calloc( Dim[1], sizeof(int *) ); for ( i = 0 ; i < Dim[0] ; i++ ) for ( j = 0 ; j < Dim[1] ; j++ ) mskd[i][j] = (int *) calloc( Dim[2], sizeof(int) ); if( (mskd == NULL) || (allF == NULL) || (allPar == NULL) ) { fprintf(stderr, "\n\n MemAlloc failure (mask).\n\n"); exit(33); } // ************************************************************* // ************************************************************* // Beginning of main loops // ************************************************************* // ************************************************************* // Populate freq bands. For now, delF is constant. Later.... who // knows, so make flexible allF[0] = DSET_TIMEORIGIN(insetTIME); if( allF[0] < EPS_V ) ERROR_exit("The t-axis (here, frequency) origin is 0!" "\n\t-> but you shouldn't have a baseline 0-frequency!"); for( i=1 ; i<Dim[3] ; i++ ) allF[i] = allF[i-1] + delF; // fill in rest of freq ranges; MIN_full=0 already MAX_full = Dim[3]-1; // these should be in order, so we can pass through like this. for( i=0 ; i<Dim[3] ; i++ ) { ii = Dim[3] - 1 - i; if( allF[ii] >= fbot ) MIN_bp = ii; if( allF[i] <= ftop ) MAX_bp = i; } if(MAX_bp < MIN_bp) // shouldn't happen... ERROR_exit("Something went horribly wrong with reading in the " "bandpass limits! bot:%f, top:%f",MIN_bp, MAX_bp); INFO_message("Actual BP range: indices [%d, %d] -> " "freqs [%.4f, %.4f]", MIN_bp, MAX_bp, allF[MIN_bp], allF[MAX_bp]); INFO_message("Full freq range: indices [%d, %d] -> " "freqs [%.4f, %.4f]", MIN_full, MAX_full, allF[MIN_full], allF[MAX_full]); // go through once: define data vox idx = 0; for( k=0 ; k<Dim[2] ; k++ ) for( j=0 ; j<Dim[1] ; j++ ) for( i=0 ; i<Dim[0] ; i++ ) { if( HAVE_MASK ) { if( THD_get_voxel(MASK,idx,0)>0 ) mskd[i][j][k] = 1; } else { temp_sum = 0.; for ( l=0 ; l<Dim[3] ; l++ ) temp_sum+= abs(THD_get_voxel(insetTIME,idx,l)); if ( temp_sum > EPS_V ) mskd[i][j][k] = 1; } idx++; } INFO_message("Done masking."); Spect_to_RSFC( insetTIME, DTYPE, Dim, mskd, MIN_bp, MAX_bp, MIN_full, MAX_full, allPar, Npar ); INFO_message("Done calculating parameters."); // ************************************************************** // ************************************************************** // Store and output // ************************************************************** // ************************************************************** for( m=0; m<Npar ; m++) { outset = EDIT_empty_copy(insetTIME) ; if(NIFTI_OUT) sprintf(outname,"%s_%s.nii.gz",prefix, namePar[m]); else sprintf(outname,"%s_%s",prefix, namePar[m]); INFO_message(" writing: %s %s", prefix, outname); EDIT_dset_items( outset, ADN_nvals , 1 , ADN_datum_all , MRI_float , ADN_prefix , outname , ADN_none ) ; if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outset)) ) ERROR_exit("Can't overwrite existing dataset '%s'", DSET_HEADNAME(outset)); EDIT_substitute_brick(outset, 0, MRI_float, allPar[m]); allPar[m]=NULL; THD_load_statistics(outset); tross_Make_History("3dAmpToRSFC", argc, argv, outset); THD_write_3dim_dataset(NULL, NULL, outset, True); if(outset) { DSET_delete(outset); free(outset); } } // ************************************************************ // ************************************************************ // Freeing // ************************************************************ // ************************************************************ if(allF) free(allF); if(MASK) { DSET_delete(MASK); free(MASK); } if(insetTIME) { DSET_delete(insetTIME); free(insetTIME); } if(mskd) { for( i=0 ; i<Dim[0] ; i++) for( j=0 ; j<Dim[1] ; j++) free(mskd[i][j]); for( i=0 ; i<Dim[0] ; i++) free(mskd[i]); free(mskd); } if(allPar) { // have freed other parts of this above free(allPar); } return 0; }