int GenFeatureDist(SEG_OPTS *Opt) { ENTRY("GenFeatureDist"); /* get the probability maps */ if (!Opt->pset && Opt->DO_p) { if (!(Opt->pset = p_C_GIV_A(Opt))) { ERROR_message("Failed miserably"); RETURN(0); } } /* Get the classes */ if (!Opt->cset && Opt->crefix && Opt->DO_c) { if (!(SUMA_assign_classes_eng(Opt->pset, Opt->clss->str, Opt->clss->num, Opt->keys, Opt->cmask, &Opt->cset))) { ERROR_message("Failed aimlessly"); RETURN(0); } EDIT_dset_items(Opt->cset, ADN_prefix, Opt->crefix, ADN_none); if( !THD_ok_overwrite() && THD_is_file( DSET_HEADNAME(Opt->cset) ) ){ ERROR_exit("Output file %s already exists -- cannot continue!\n", DSET_HEADNAME(Opt->cset) ) ; } } /* group classes ? */ if (Opt->group_classes) { THD_3dim_dataset *gcset=NULL; THD_3dim_dataset *gpset=NULL; if (!SUMA_Regroup_classes (Opt, Opt->clss->str, Opt->clss->num, Opt->keys, Opt->group_classes->str, Opt->group_classes->num, Opt->group_keys, Opt->cmask, Opt->pset, Opt->cset, &gpset, &gcset) ) { ERROR_message("Failed to regroup"); RETURN(0); } DSET_write(gpset); DSET_write(gcset); } RETURN(1); }
int main( int argc , char * argv[] ) { THD_3dim_dataset * dset ; int iarg , all = 0, verbose = 0, cnt = 0; if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) Syntax() ; iarg = 1 ; cnt = 1; while (cnt < argc) { if( strncmp(argv[iarg],"-all",4) == 0 ){ all = 1 ; iarg++ ; } else if( strncmp(argv[iarg],"-verbose",5) == 0 ){ verbose = 1 ; iarg++ ; } ++cnt; } for( ; iarg < argc ; iarg++ ){ dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ){ printf("-1\n") ; continue ; } if (!all) { if (verbose) { printf("%s: %d\n", DSET_HEADNAME(dset), DSET_NVALS(dset)) ; } else { printf("%d\n",DSET_NVALS(dset)) ; } } else { if (verbose) { printf("%s: %d %d %d %d\n", DSET_HEADNAME(dset), DSET_NX(dset), DSET_NY(dset), DSET_NZ(dset), DSET_NVALS(dset)) ; } else { printf("%d %d %d %d\n", DSET_NX(dset), DSET_NY(dset), DSET_NZ(dset), DSET_NVALS(dset)) ; } } THD_delete_3dim_dataset( dset , False ) ; } exit(0) ; }
void RT_test_callback(void *junk) { RT_status *rts = GLOBAL_library.realtime_status ; int cc , nval,nbr ; if( rts == NULL ){ ERROR_message("bad call to RT_test_callback"); return; } INFO_message("RT_test_callback: numchan=%d status=%d numdset=%d", rts->numchan , rts->status , rts->numdset ) ; for( cc=0 ; cc < rts->numdset ; cc++ ){ /* print out some dataset info */ if( !ISVALID_DSET(rts->dset[cc]) ){ ININFO_message(" dset[%d] invalid!",cc) ; /* should never happen */ } else { nval = DSET_NVALS(rts->dset[cc]) ; /* number of bricks */ nbr = THD_count_databricks(rts->dset[cc]->dblk) ; /* number with data */ ININFO_message(" dset[%d] '%s': nvals=%d nbr=%d", cc , DSET_HEADNAME(rts->dset[cc]) , nval,nbr ) ; } } return ; }
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; }
int main( int argc , char * argv[] ) { THD_3dim_dataset *mask_dset=NULL, *iset=NULL, *sset=NULL, *xset=NULL, *vset=NULL; char *prefix="toy"; int iarg=1 , mcount, udatum = MRI_float; byte *maskvox=NULL; mainENTRY("3dToyProg main"); machdep(); AFNI_logger("3dToyProg",argc,argv); #ifdef USING_MCW_MALLOC enable_mcw_malloc() ; #endif /*-- options --*/ set_obliquity_report(0); /* silence obliquity */ while( iarg < argc && argv[iarg][0] == '-' ){ CHECK_HELP(argv[iarg], help_3dToyProg); if( strncmp(argv[iarg],"-mask",5) == 0 ){ if (iarg >= argc) ERROR_exit("Need dset after -mask"); mask_dset = THD_open_dataset( argv[++iarg] ) ; if( mask_dset == NULL ) ERROR_exit("Cannot open mask dataset!\n") ; if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex ) ERROR_exit("Cannot deal with complex-valued mask dataset!\n"); iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0) { if (iarg >= argc) ERROR_exit("Need dset after -mask"); if (!(iset = THD_open_dataset( argv[++iarg]))) { ERROR_exit("Cannot open input dataset %s!\n", argv[iarg]) ; } DSET_mallocize(iset); DSET_load(iset); /* load data part of dataset */ iarg++ ; continue ; } if( strncmp(argv[iarg],"-prefix",6) == 0) { if (iarg >= argc) ERROR_exit("Need name after -prefix"); prefix = argv[++iarg]; iarg++ ; continue ; continue ; } if( strcmp(argv[iarg],"-datum") == 0) { if (iarg >= argc) ERROR_exit("Need datum type after -datum"); ++iarg; if (!strcmp(argv[iarg],"float")) udatum = MRI_float; else if (!strcmp(argv[iarg],"short")) udatum = MRI_short; else { ERROR_exit( "For the purpose of this demo, only float and short are allowed"); } iarg++ ; continue ; continue ; } ERROR_message("ILLEGAL option: %s\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } if( argc < 2 ){ help_3dToyProg(TXT, 0); PRINT_COMPILE_DATE ; exit(0) ; } if( !iset ) ERROR_exit("No dataset on command line!?") ; if (mask_dset) { if (THD_dataset_mismatch(mask_dset, iset)) ERROR_exit("grid mismatch between input dset and mask dset"); maskvox = THD_makemask( mask_dset , 0 , 1.0, -1.0 ) ; mcount = THD_countmask( DSET_NVOX(mask_dset) , maskvox ) ; if( mcount <= 0 ) ERROR_exit("No voxels in the mask!\n") ; INFO_message("%d voxels in the mask dset %s\n", mcount, DSET_PREFIX(mask_dset)) ; DSET_delete(mask_dset) ; mask_dset=NULL; /* Done with the mask dset */ } /* An illustration of how volume navigation works */ Dataset_Navigation(iset); /* Let us create a dataset from scratch */ sset = New_Dataset_From_Scratch(prefix); /* Now for the output, add history, check for overwrite and write away */ tross_Copy_History( iset , sset );/* Copy the old history (not mandatory). */ tross_Make_History("3dToyProg", argc, argv ,sset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(sset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(sset)); } else DSET_write(sset); /* Now we'll do some voxelwise computations */ xset = Voxelwise_Operations(sset, maskvox, prefix); tross_Copy_History( iset , xset ) ; /* Copy the old */ tross_Make_History("3dToyProg", argc, argv ,xset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(xset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(xset)); } else DSET_write(xset); /* Or some volumewise operations */ vset = Volumewise_Operations(sset, prefix, udatum); tross_Copy_History( iset , vset ) ; /* Copy the old */ tross_Make_History("3dToyProg", argc, argv ,vset) ; /* add the new */ if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(vset)) ) { ERROR_message( "Output %s already exists, use -overwrite to do you know what", DSET_HEADNAME(vset)); } else DSET_write(vset); /* cleanup */ DSET_delete(xset); xset = NULL; DSET_delete(vset); vset = NULL; DSET_delete(sset); sset = NULL; exit(0) ; }
int main( int argc , char * argv[] ) { int narg=1, do_automask=0 , iv , nxyz , do_set=0 , *rois=NULL, N_rois=0, all_rois = 0; THD_3dim_dataset *xset ; byte *mmm=NULL ; int nmask=0 , nvox_mask=0 ; THD_fvec3 cmv , setv ; /*-- read command line arguments --*/ if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ){ printf("Usage: 3dCM [options] dset\n" "Output = center of mass of dataset, to stdout.\n" " -mask mset Means to use the dataset 'mset' as a mask:\n" " Only voxels with nonzero values in 'mset'\n" " will be averaged from 'dataset'. Note\n" " that the mask dataset and the input dataset\n" " must have the same number of voxels.\n" " -automask Generate the mask automatically.\n" " -set x y z After computing the CM of the dataset, set the\n" " origin fields in the header so that the CM\n" " will be at (x,y,z) in DICOM coords.\n" " -roi_vals v0 v1 v2 ... : Compute center of mass for each blob\n" " with voxel value of v0, v1, v2, etc.\n" " This option is handy for getting ROI \n" " centers of mass.\n" " -all_rois Don't bother listing the values of ROIs you want\n" " the program will find all of them and produce a \n" " full list.\n" " NOTE: Masking options are ignored with -roi_vals and -all_rois\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } LOAD_FVEC3(setv,0,0,0) ; /* ZSS: To quiet init. warnings */ narg = 1 ; while( narg < argc && argv[narg][0] == '-' ){ if( strcmp(argv[narg],"-set") == 0 ){ float xset,yset,zset ; if( narg+3 >= argc ){ fprintf(stderr,"*** -set need 3 args following!\n") ; exit(1) ; } xset = strtod( argv[++narg] , NULL ) ; yset = strtod( argv[++narg] , NULL ) ; zset = strtod( argv[++narg] , NULL ) ; LOAD_FVEC3(setv,xset,yset,zset) ; do_set = 1 ; THD_set_write_compression(COMPRESS_NONE); /* do not alter compression*/ narg++ ; continue ; } if( strncmp(argv[narg],"-mask",5) == 0 ){ THD_3dim_dataset *mask_dset ; if( mmm != NULL ){ fprintf(stderr,"*** Cannot have two -mask options!\n") ; exit(1) ; } if( do_automask ){ fprintf(stderr,"*** Can't have -mask and -automask!\n") ; exit(1) ; } if( narg+1 >= argc ){ fprintf(stderr,"*** -mask option requires a following argument!\n"); exit(1) ; } mask_dset = THD_open_dataset( argv[++narg] ) ; CHECK_OPEN_ERROR(mask_dset,argv[narg]) ; if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex ){ fprintf(stderr,"*** Cannot deal with complex-valued mask dataset!\n"); exit(1) ; } mmm = THD_makemask( mask_dset , 0 , 1.0,0.0 ) ; nvox_mask = DSET_NVOX(mask_dset) ; nmask = THD_countmask( nvox_mask , mmm ) ; if( mmm == NULL || nmask <= 0 ){ fprintf(stderr,"*** Can't make mask from dataset %s\n",argv[narg-1]); exit(1) ; } DSET_delete( mask_dset ) ; narg++ ; continue ; } if( strncmp(argv[narg],"-roi_vals",5) == 0 ){ if( narg+1 >= argc ){ fprintf(stderr,"*** -mask option requires a following argument(s)!\n"); exit(1) ; } rois = (int *)calloc(argc, sizeof(int)); N_rois = 0; ++narg; while (narg < argc-1 && argv[narg][0] != '-') { rois[N_rois++] = atoi(argv[narg]); ++narg; } continue ; } if( strncmp(argv[narg],"-all_rois",5) == 0 ){ all_rois = 1; narg++ ; continue ; } if( strcmp(argv[narg],"-automask") == 0 ){ if( mmm != NULL ){ fprintf(stderr,"*** Can't have -mask and -automask!\n") ; exit(1) ; } do_automask = 1 ; narg++ ; continue ; } fprintf(stderr,"*** Unknown option: %s\n",argv[narg]) ; exit(1) ; } /* should have at least 1 more argument */ if( argc <= narg ){ fprintf(stderr,"*** No input dataset!?\n") ; exit(1) ; } for( ; narg < argc ; narg++ ){ xset = THD_open_dataset( argv[narg] ) ; if( xset == NULL ){ fprintf(stderr,"+++ Can't open dataset %s -- skipping\n",argv[narg]); continue ; } DSET_load(xset) ; if( !DSET_LOADED(xset) ){ fprintf(stderr,"+++ Can't load dataset %s -- skipping\n",argv[narg]); DSET_delete(xset) ; continue ; } if( do_automask ){ if( mmm != NULL ){ free(mmm); mmm = NULL; } mmm = THD_automask(xset) ; nvox_mask = DSET_NVOX(xset) ; nmask = THD_countmask( nvox_mask , mmm ) ; if( mmm == NULL || nmask <= 0 ){ fprintf( stderr, "+++ Can't make automask from dataset %s " "-- skipping\n",argv[narg]) ; DSET_delete(xset) ; continue ; } } nxyz = DSET_NVOX(xset) ; if( mmm != NULL && nxyz != nvox_mask ){ fprintf(stderr,"+++ Mask/Dataset grid size mismatch at %s\n -- skipping\n",argv[narg]) ; DSET_delete(xset) ; continue ; } if (all_rois) { if (!(rois = THD_unique_vals(xset, 0, &N_rois, NULL)) || N_rois == 0) { ERROR_message("No rois or error in THD_unique_vals"); continue; } fprintf(stderr,"#%d distinct ROIs", N_rois); } if (!N_rois) { cmv = THD_cmass( xset , 0 , mmm ) ; printf("%g %g %g\n",cmv.xyz[0],cmv.xyz[1],cmv.xyz[2]) ; DSET_unload(xset) ; if( do_set ){ THD_fvec3 dv , ov ; if( DSET_IS_MASTERED(xset) ){ fprintf(stderr,"+++ Can't modify CM of dataset %s\n",argv[narg]) ; } else { /* lose obliquity */ /* recompute Tc(Cardinal transformation matrix for new grid output */ THD_make_cardinal(xset); LOAD_FVEC3(ov,DSET_XORG(xset),DSET_YORG(xset),DSET_ZORG(xset)) ; ov = THD_3dmm_to_dicomm( xset , ov ) ; dv = SUB_FVEC3(setv,cmv) ; ov = ADD_FVEC3(dv,ov) ; ov = THD_dicomm_to_3dmm( xset , ov ) ; xset->daxes->xxorg = ov.xyz[0] ; xset->daxes->yyorg = ov.xyz[1] ; xset->daxes->zzorg = ov.xyz[2] ; /* allow overwriting header for all types of output data */ putenv("AFNI_DECONFLICT=OVERWRITE") ; tross_Make_History( "3dCM" , argc,argv , xset );/* ZSS Dec. 09 08 */ if(DSET_IS_BRIK(xset)) { INFO_message("Rewriting header %s",DSET_HEADNAME(xset)) ; DSET_overwrite_header( xset ) ; } else { /* for other dataset types like NIFTI, rewrite whole dset */ DSET_load( xset ) ; DSET_overwrite(xset) ; INFO_message("Wrote new dataset: %s",DSET_BRIKNAME(xset)) ; } } } } else { float *xyz; if ((xyz = THD_roi_cmass(xset , 0 , rois, N_rois))) { printf("#Dset %s\n",DSET_BRIKNAME(xset)); for (iv=0; iv<N_rois; ++iv) { printf("#ROI %d\n", rois[iv]); printf("%g %g %g\n",xyz[3*iv],xyz[3*iv+1],xyz[3*iv+2]) ; } free(xyz); free(rois); } else { ERROR_message("Failed in THD_roi_cmass"); continue; } } DSET_delete(xset) ; } exit(0); }
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 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 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 iv,nvals , nvec , ii,jj,kk , nvox ; THD_3dim_dataset * new_dset=NULL ; double * choleski ; float ** refvec , * fv , * fc , * fit ; MRI_IMAGE * flim ; /*** read input options ***/ if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) DT_Syntax() ; /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ mainENTRY("3dDetrend main"); machdep() ; PRINT_VERSION("3dDetrend"); AFNI_logger("3dDetrend",argc,argv) ; { int new_argc ; char ** new_argv ; addto_args( argc , argv , &new_argc , &new_argv ) ; if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; } } DT_read_opts( argc , argv ) ; /*** create new dataset (empty) ***/ new_dset = EDIT_empty_copy( DT_dset ) ; /* make a copy of its header */ /* modify its header */ tross_Copy_History( DT_dset , new_dset ) ; tross_Make_History( "3dDetrend" , argc,argv , new_dset ) ; EDIT_dset_items( new_dset , ADN_prefix , DT_output_prefix , ADN_directory_name, DT_session , ADN_none ) ; /* can't re-write existing dataset */ if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ) ERROR_exit("File %s already exists!\n",DSET_HEADNAME(new_dset) ) ; /* read input in, and attach its bricks to the output dataset */ /* (not good in a plugin, but OK in a standalone program!) */ if( DT_verb ) INFO_message("Loading input dataset bricks\n") ; DSET_mallocize( new_dset ) ; DSET_mallocize( DT_dset ) ; DSET_load( DT_dset ) ; CHECK_LOAD_ERROR(DT_dset) ; nvals = DSET_NVALS(new_dset) ; for( iv=0 ; iv < nvals ; iv++ ) EDIT_substitute_brick( new_dset , iv , DSET_BRICK_TYPE(DT_dset,iv) , DSET_ARRAY(DT_dset,iv) ) ; if( DT_norm && DSET_BRICK_TYPE(new_dset,0) != MRI_float ){ INFO_message("Turning -normalize option off (input not in float format)"); DT_norm = 0 ; } /* load reference (detrending) vectors; setup to do least squares fitting of each voxel */ nvec = 0 ; for( ii=0 ; ii < IMARR_COUNT(DT_imar) ; ii++ ) /* number of detrending vectors */ nvec += IMARR_SUBIMAGE(DT_imar,ii)->ny ; refvec = (float **) malloc( sizeof(float *)*nvec ) ; for( kk=ii=0 ; ii < IMARR_COUNT(DT_imar) ; ii++ ){ fv = MRI_FLOAT_PTR( IMARR_SUBIMAGE(DT_imar,ii) ) ; for( jj=0 ; jj < IMARR_SUBIMAGE(DT_imar,ii)->ny ; jj++ ) /* compute ptr */ refvec[kk++] = fv + ( jj * IMARR_SUBIMAGE(DT_imar,ii)->nx ) ; /* to vectors */ } fit = (float *) malloc( sizeof(float) * nvals ) ; /* will get fit to voxel data */ /*--- do the all-voxels-together case ---*/ if( !DT_byslice ){ choleski = startup_lsqfit( nvals , NULL , nvec , refvec ) ; if( choleski == NULL ) ERROR_exit("Choleski factorization fails: linearly dependent vectors!\n") ; /* loop over voxels, fitting and detrending (or replacing) */ nvox = DSET_NVOX(new_dset) ; if( DT_verb ) INFO_message("Computing voxel fits\n") ; for( kk=0 ; kk < nvox ; kk++ ){ flim = THD_extract_series( kk , new_dset , 0 ) ; /* data */ fv = MRI_FLOAT_PTR(flim) ; fc = delayed_lsqfit( nvals, fv, nvec, refvec, choleski ) ; /* coef */ for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = 0.0 ; for( jj=0 ; jj < nvec ; jj++ ) for( ii=0 ; ii < nvals ; ii++ ) fit[ii] += fc[jj] * refvec[jj][ii] ; /* fit */ if( !DT_replace ) /* remove */ for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = fv[ii] - fit[ii] ; if( DT_norm ) THD_normalize( nvals , fit ) ; /* 23 Nov 1999 */ THD_insert_series( kk, new_dset, nvals, MRI_float, fit, 0 ) ; free(fc) ; mri_free(flim) ; } free(choleski) ; /*- end of all-voxels-together case -*/ } #ifdef ALLOW_BYSLICE else { /*- start of slice case [08 Dec 1999] -*/ int ksl , nslice , tt , nx,ny , nxy , kxy ; MRI_IMAGE * vim ; /* make separate space for the slice-wise detrending vectors */ for( kk=ii=0 ; ii < DT_nvector ; ii++ ){ for( jj=0 ; jj < IMARR_SUBIMAGE(DT_imar,ii)->ny ; jj++ ) /* replace ptrs */ refvec[kk++] = (float *) malloc( sizeof(float) * nvals ) ; /* to vectors */ } nslice = DSET_NZ(new_dset) ; nxy = DSET_NX(new_dset) * DSET_NY(new_dset) ; /* loop over slices */ for( ksl=0 ; ksl < nslice ; ksl++ ){ if( DT_verb ) INFO_message("Computing voxel fits for slice %d\n",ksl) ; /* extract slice vectors from input interlaced vectors */ for( kk=ii=0 ; ii < DT_nvector ; ii++ ){ /* loop over vectors */ vim = IMARR_SUBIMAGE(DT_imar,ii) ; /* ii-th vector image */ nx = vim->nx ; ny = vim->ny ; /* dimensions */ for( jj=0 ; jj < ny ; jj++ ){ /* loop over columns */ fv = MRI_FLOAT_PTR(vim) + (jj*nx) ; /* ptr to column */ for( tt=0 ; tt < nvals ; tt++ ) /* loop over time */ refvec[kk][tt] = fv[ksl+tt*nslice] ; /* data point */ } } /* initialize fitting for this slice */ choleski = startup_lsqfit( nvals , NULL , nvec , refvec ) ; if( choleski == NULL ) ERROR_exit("Choleski fails: linearly dependent vectors at slice %d\n",ksl) ; /* loop over voxels in this slice */ for( kxy=0 ; kxy < nxy ; kxy++ ){ kk = kxy + ksl*nxy ; /* 3D index */ flim = THD_extract_series( kk , new_dset , 0 ) ; /* data */ fv = MRI_FLOAT_PTR(flim) ; fc = delayed_lsqfit( nvals, fv, nvec, refvec, choleski ) ; /* coef */ for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = 0.0 ; for( jj=0 ; jj < nvec ; jj++ ) for( ii=0 ; ii < nvals ; ii++ ) fit[ii] += fc[jj] * refvec[jj][ii] ; /* fit */ if( !DT_replace ) /* remove */ for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = fv[ii] - fit[ii] ; if( DT_norm ) THD_normalize( nvals , fit ) ; /* 23 Nov 1999 */ THD_insert_series( kk, new_dset, nvals, MRI_float, fit, 0 ) ; free(fc) ; mri_free(flim) ; } free(choleski) ; } /* end of loop over slices */ } /*- end of -byslice case -*/ #endif /*-- done done done done --*/ DSET_write(new_dset) ; if( DT_verb ) WROTE_DSET(new_dset) ; exit(0) ; }
int main( int argc , char * argv[] ) { int iarg ; THD_3dim_dataset *inset , *outset ; int add_I=0 , add_S=0 , add_A=0 , add_P=0 , add_L=0 , add_R=0 ; int RLsiz=0, APsiz=0, ISsiz=0 ; /* 23 Mar 2004 */ char * prefix="zeropad" ; int add_z=0 ; /* 07 Feb 2001 */ int mm_flag=0 ; /* 13 Feb 2001 */ int flag ; THD_3dim_dataset *mset=NULL ; /* 14 May 2002 */ /*-- help? --*/ mainENTRY("3dZeropad main"); machdep(); AFNI_logger("3dZeropad",argc,argv); PRINT_VERSION("3dZeropad") ; /*-- read command line options --*/ if( argc == 1){ usage_3dZeropad(1); exit(0); } /* Bob's help shortcut */ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){ usage_3dZeropad(strlen(argv[iarg])>3 ? 2:1); exit(0); } /*- -I, -S, etc. -*/ if( strlen(argv[iarg]) == 2 ){ switch( argv[iarg][1] ){ case 'I': add_I = (int) strtod(argv[++iarg],NULL) ; break ; case 'S': add_S = (int) strtod(argv[++iarg],NULL) ; break ; case 'A': add_A = (int) strtod(argv[++iarg],NULL) ; break ; case 'P': add_P = (int) strtod(argv[++iarg],NULL) ; break ; case 'L': add_L = (int) strtod(argv[++iarg],NULL) ; break ; case 'R': add_R = (int) strtod(argv[++iarg],NULL) ; break ; /* 07 Feb 2001: slice-direction is special */ case 'z': case 'Z': add_z = (int) strtod(argv[++iarg],NULL) ; break ; default: fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; exit(1) ; } if( mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg-1]) ; exit(1) ; } iarg++ ; continue ; /* skip to next argument */ } /*- -RL, -AP, -IS [23 Mar 2004] -*/ if( strcmp(argv[iarg],"-RL") == 0 || strcmp(argv[iarg],"-LR") == 0 ){ if( add_R || add_L || mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use -RL with -R, -L, or -master!\n"); exit(1) ; } RLsiz = (int) strtod(argv[++iarg],NULL) ; if( RLsiz < 1 ){ fprintf(stderr,"** 3dZeropad: value after -RL is illegal!\n") ; exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-AP") == 0 || strcmp(argv[iarg],"-PA") == 0 ){ if( add_A || add_P || mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use -AP with -A, -P, or -master!\n"); exit(1) ; } APsiz = (int) strtod(argv[++iarg],NULL) ; if( APsiz < 1 ){ fprintf(stderr,"** 3dZeropad: value after -AP is illegal!\n") ; exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-IS") == 0 || strcmp(argv[iarg],"-SI") == 0 ){ if( add_S || add_I || mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use -IS with -I, -S, or -master!\n"); exit(1) ; } ISsiz = (int) strtod(argv[++iarg],NULL) ; if( ISsiz < 1 ){ fprintf(stderr,"** 3dZeropad: value after -IS is illegal!\n") ; exit(1) ; } iarg++ ; continue ; } /*- -mm -*/ if( strcmp(argv[iarg],"-mm") == 0 ){ if( mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg]) ; exit(1) ; } mm_flag = 1 ; iarg++ ; continue ; } /*- -prefix -*/ if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"** 3dZeropad: Illegal string after -prefix!\n"); exit(1) ; } iarg++ ; continue ; } /*-- -master [14 May 2002] --*/ if( strcmp(argv[iarg],"-master") == 0 ){ if( add_I || add_S || add_A || mm_flag || add_P || add_R || add_L || add_z || RLsiz || APsiz || ISsiz ){ fprintf(stderr,"** 3dZeropad: Can't use -master with -I,-S,-A,-P,-R,-L, or -mm!\n"); exit(1) ; } if( mset != NULL ){ fprintf(stderr,"** 3dZeropad: Can't use -master twice!\n"); exit(1); } mset = THD_open_dataset( argv[++iarg] ) ; if( !ISVALID_DSET(mset) ){ fprintf(stderr,"** 3dZeropad: Can't open -master %s\n",argv[iarg]); exit(1); } THD_make_cardinal(mset); /* deoblique 21 Oct, 2011 [rickr] */ iarg++ ; continue ; } /*- what the hell? -*/ fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1) ; } if (iarg < 2) { ERROR_message("Too few options, try %s -help for details\n",argv[0]); exit(1); } /*- check to see if the user asked for something, anything -*/ if( mset == NULL ){ if( add_I==0 && add_S==0 && add_P==0 && add_A==0 && add_L==0 && add_R==0 && add_z==0 && RLsiz==0 && APsiz==0 && ISsiz==0 ){ fprintf(stderr,"++ 3dZeropad: All inputs are zero? Making a copy!\n") ; } } /* check for conflicts [23 Mar 2004] */ if( RLsiz > 0 && (add_R || add_L || add_z) ){ fprintf(stderr,"** 3dZeropad: Can't use -R or -L or -z with -RL!\n"); exit(1); } if( APsiz > 0 && (add_A || add_P || add_z) ){ fprintf(stderr,"** 3dZeropad: Can't use -A or -P or -z with -AP!\n"); exit(1); } if( ISsiz > 0 && (add_I || add_S || add_z) ){ fprintf(stderr,"** 3dZeropad: Can't use -I or -S or -z with -IS!\n"); exit(1); } /*-- read the input dataset --*/ if( iarg >= argc ){ fprintf(stderr,"** 3dZeropad: No input dataset on command line!\n"); exit(1); } #if 0 if( strncmp(argv[iarg],"3dcalc(",7) == 0 ){ fprintf(stderr,"** 3dZeropad: Can't use '3dcalc()' input datasets here!\n"); exit(1); } #endif inset = THD_open_dataset( argv[iarg] ) ; if( inset == NULL ){ fprintf(stderr,"** 3dZeropad: Can't open dataset %s\n",argv[iarg]); exit(1); } THD_make_cardinal(inset); /* deoblique 21 Oct, 2011 [rickr] */ #if 0 if( DSET_IS_MASTERED(inset) ){ fprintf(stderr,"** 3dZeropad: Can't use partial datasets!\n"); exit(1); } #endif /*-- 14 May 2002: use master dataset now? --*/ if( mset != NULL ){ THD_dataxes *max=mset->daxes, *iax=inset->daxes ; int nerr=0 ; float mxbot,mybot,mzbot , mxtop,mytop,mztop , mdx,mdy,mdz ; float ixbot,iybot,izbot , ixtop,iytop,iztop , idx,idy,idz ; int mnx,mny,mnz , inx,iny,inz ; int add_xb,add_xt , add_yb,add_yt , add_zb,add_zt ; /* check if datasets are oriented the same */ if( max->xxorient != iax->xxorient || max->yyorient != iax->yyorient || max->zzorient != iax->zzorient ){ fprintf(stderr, "** 3dZeropad: Master (%s) and Input (%s) dataset not oriented the same!\n", DSET_PREFIX(mset), DSET_PREFIX(inset)); nerr++ ; } /* check if datasets have same voxel dimensions */ mdx = max->xxdel ; mdy = max->yydel ; mdz = max->zzdel ; idx = iax->xxdel ; idy = iax->yydel ; idz = iax->zzdel ; mnx = max->nxx ; mny = max->nyy ; mnz = max->nzz ; inx = iax->nxx ; iny = iax->nyy ; inz = iax->nzz ; if( fabs(mdx-idx) > 0.01*fabs(mdx) || fabs(mdy-idy) > 0.01*fabs(mdy) || fabs(mdz-idz) > 0.01*fabs(mdz) ){ fprintf(stderr,"** 3dZeropad: Master and Input datasets don't have same voxel size!\n"); nerr++ ; } if( nerr ) exit(1) ; /* calculate coords at top and bottom of each dataset */ mxbot = max->xxorg ; mxtop = mxbot + mnx*mdx ; mybot = max->yyorg ; mytop = mybot + mny*mdy ; mzbot = max->zzorg ; mztop = mzbot + mnz*mdz ; ixbot = iax->xxorg ; ixtop = ixbot + inx*idx ; iybot = iax->yyorg ; iytop = iybot + iny*idy ; izbot = iax->zzorg ; iztop = izbot + inz*idz ; /* calculate amount to add/trim at each face */ add_xb = (int) rint((ixbot-mxbot)/idx) ; add_xt = (int) rint((mxtop-ixtop)/idx) ; add_yb = (int) rint((iybot-mybot)/idy) ; add_yt = (int) rint((mytop-iytop)/idy) ; add_zb = (int) rint((izbot-mzbot)/idz) ; add_zt = (int) rint((mztop-iztop)/idz) ; /* map trims from x,y,z to RL,AP,IS coords */ switch( iax->xxorient ){ case ORI_R2L_TYPE: add_R = add_xb ; add_L = add_xt ; break ; case ORI_L2R_TYPE: add_L = add_xb ; add_R = add_xt ; break ; case ORI_I2S_TYPE: add_I = add_xb ; add_S = add_xt ; break ; case ORI_S2I_TYPE: add_S = add_xb ; add_I = add_xt ; break ; case ORI_A2P_TYPE: add_A = add_xb ; add_P = add_xt ; break ; case ORI_P2A_TYPE: add_P = add_xb ; add_A = add_xt ; break ; } switch( iax->yyorient ){ case ORI_R2L_TYPE: add_R = add_yb ; add_L = add_yt ; break ; case ORI_L2R_TYPE: add_L = add_yb ; add_R = add_yt ; break ; case ORI_I2S_TYPE: add_I = add_yb ; add_S = add_yt ; break ; case ORI_S2I_TYPE: add_S = add_yb ; add_I = add_yt ; break ; case ORI_A2P_TYPE: add_A = add_yb ; add_P = add_yt ; break ; case ORI_P2A_TYPE: add_P = add_yb ; add_A = add_yt ; break ; } switch( iax->zzorient ){ case ORI_R2L_TYPE: add_R = add_zb ; add_L = add_zt ; break ; case ORI_L2R_TYPE: add_L = add_zb ; add_R = add_zt ; break ; case ORI_I2S_TYPE: add_I = add_zb ; add_S = add_zt ; break ; case ORI_S2I_TYPE: add_S = add_zb ; add_I = add_zt ; break ; case ORI_A2P_TYPE: add_A = add_zb ; add_P = add_zt ; break ; case ORI_P2A_TYPE: add_P = add_zb ; add_A = add_zt ; break ; } fprintf(stderr,"++ 3dZeropad -master => -I %d -S %d -A %d -P %d -R %d -L %d\n", add_I,add_S,add_A,add_P,add_R,add_L ) ; DSET_delete(mset) ; } /*-- 07 Feb 2001: if -z was used, fix that now --*/ if( add_z != 0 ){ switch( inset->daxes->zzorient ){ case ORI_R2L_TYPE: case ORI_L2R_TYPE: if( add_R != 0 && add_R != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -R\n"); if( add_L != 0 && add_L != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -L\n"); add_R = add_L = add_z ; break ; case ORI_P2A_TYPE: case ORI_A2P_TYPE: if( add_P != 0 && add_P != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -P\n"); if( add_A != 0 && add_A != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -A\n"); add_P = add_A = add_z ; break ; case ORI_I2S_TYPE: case ORI_S2I_TYPE: if( add_I != 0 && add_I != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -I\n"); if( add_I != 0 && add_S != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -S\n"); add_I = add_S = add_z ; break ; } } /*-- 23 Mar 2004: expand/contract if ordered --*/ if( RLsiz > 0 ){ int nold=0 ; if( inset->daxes->xxorient == ORI_R2L_TYPE || inset->daxes->xxorient == ORI_L2R_TYPE ) nold = inset->daxes->nxx ; else if( inset->daxes->yyorient == ORI_R2L_TYPE || inset->daxes->yyorient == ORI_L2R_TYPE ) nold = inset->daxes->nyy ; else if( inset->daxes->zzorient == ORI_R2L_TYPE || inset->daxes->zzorient == ORI_L2R_TYPE ) nold = inset->daxes->nzz ; if( nold > 0 ){ add_R = (RLsiz-nold) / 2 ; add_L = RLsiz-(nold+add_R) ; } } if( APsiz > 0 ){ int nold=0 ; if( inset->daxes->xxorient == ORI_A2P_TYPE || inset->daxes->xxorient == ORI_P2A_TYPE ) nold = inset->daxes->nxx ; else if( inset->daxes->yyorient == ORI_A2P_TYPE || inset->daxes->yyorient == ORI_P2A_TYPE ) nold = inset->daxes->nyy ; else if( inset->daxes->zzorient == ORI_A2P_TYPE || inset->daxes->zzorient == ORI_P2A_TYPE ) nold = inset->daxes->nzz ; if( nold > 0 ){ add_A = (APsiz-nold) / 2 ; add_P = APsiz-(nold+add_A) ; } } if( ISsiz > 0 ){ int nold=0 ; if( inset->daxes->xxorient == ORI_I2S_TYPE || inset->daxes->xxorient == ORI_S2I_TYPE ) nold = inset->daxes->nxx ; else if( inset->daxes->yyorient == ORI_I2S_TYPE || inset->daxes->yyorient == ORI_S2I_TYPE ) nold = inset->daxes->nyy ; else if( inset->daxes->zzorient == ORI_I2S_TYPE || inset->daxes->zzorient == ORI_S2I_TYPE ) nold = inset->daxes->nzz ; if( nold > 0 ){ add_I = (ISsiz-nold) / 2 ; add_S = ISsiz-(nold+add_I) ; } } /*-- 04 Oct 2000: all the real work is now in thd_zeropad.c --*/ flag = ZPAD_PURGE ; if( mm_flag ) flag |= ZPAD_MM ; outset = THD_zeropad( inset , add_I, add_S, add_A, add_P, add_L, add_R, prefix , flag ) ; if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) ){ fprintf(stderr, "** 3dZeropad: output file %s already exists - FATAL ERROR!\n", DSET_HEADNAME(outset) ) ; exit(1) ; } if( outset == NULL ){ fprintf(stderr,"** 3dZeropad: Some error occurred in processing!\n") ; exit(1) ; } tross_Copy_History( inset , outset ) ; /* 31 Jan 2001 - RWCox */ tross_Make_History( "3dZeropad" , argc,argv , outset ) ; if (DSET_write(outset) != False) { fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ; exit(0) ; } else { fprintf(stderr, "** 3dZeropad: Failed to write output!\n" ) ; exit(1) ; } }
MRI_IMARR * THD_extract_many_series( int ns, int *ind, THD_3dim_dataset *dset ) { MRI_IMARR *imar ; /* output */ MRI_IMAGE *im ; int nv , ival , kk ; char *iar ; /* brick in the input */ float **far ; /* 27 Feb 2003: ptrs to output */ ENTRY("THD_extract_many_series") ; if( ns <= 0 || ind == NULL | dset == NULL ) RETURN( NULL ); /* try to load dataset */ nv = dset->dblk->nvals ; iar = DSET_ARRAY(dset,0) ; if( iar == NULL ){ /* if data needs to be loaded from disk */ (void) THD_load_datablock( dset->dblk ) ; iar = DSET_ARRAY(dset,0) ; if( iar == NULL ){ static int nerr=0 ; if( nerr < 2 ){ ERROR_message("Can't load dataset %s",DSET_HEADNAME(dset)); nerr++; } RETURN( NULL ); } } /* create output */ far = (float **) malloc(sizeof(float *)*ns) ; /* 27 Feb 2003 */ NULL_CHECK(far) ; INIT_IMARR(imar) ; for( kk=0 ; kk < ns ; kk++ ){ im = mri_new( nv , 1 , MRI_float ) ; /* N.B.: now does 0 fill */ far[kk] = MRI_FLOAT_PTR(im) ; /* ptr to kk-th output series */ ADDTO_IMARR(imar,im) ; } /* fill the output */ switch( DSET_BRICK_TYPE(dset,0) ){ default: /* don't know what to do --> return nada */ DESTROY_IMARR(imar) ; free(far) ; RETURN( NULL ); case MRI_byte:{ byte * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (byte *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; case MRI_short:{ short * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (short *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; case MRI_float:{ float * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (float *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]] ; } } } } break ; #if 0 case MRI_int:{ int * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (int *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]] ; } } } } break ; case MRI_double:{ double * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (double *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = (float)bar[ind[kk]] ; } } } } break ; #endif case MRI_complex:{ complex * bar ; for( ival=0 ; ival < nv ; ival++ ){ bar = (complex *) DSET_ARRAY(dset,ival) ; if( bar != NULL ){ for( kk=0 ; kk < ns ; kk++ ){ far[kk][ival] = bar[ind[kk]].r ; } } } } break ; } /* scale outputs, if needed */ if( THD_need_brick_factor(dset) ){ MRI_IMAGE *qim ; for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; qim = mri_mult_to_float( dset->dblk->brick_fac , im ) ; mri_free(im) ; IMARR_SUBIMAGE(imar,kk) = qim ; } } #if 0 /* 27 Feb 2003 */ /* convert to floats, if needed */ if( IMARR_SUBIMAGE(imar,0)->kind != MRI_float ){ MRI_IMAGE * qim ; for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; qim = mri_to_float( im ) ; mri_free(im) ; IMARR_SUBIMAGE(imar,kk) = qim ; } } #endif /* add time axis stuff to output images, if present */ if( dset->taxis != NULL ){ float zz , tt ; int kz ; for( kk=0 ; kk < ns ; kk++ ){ kz = ind[kk] / ( dset->daxes->nxx * dset->daxes->nyy ) ; zz = dset->daxes->zzorg + kz * dset->daxes->zzdel ; tt = THD_timeof( 0 , zz , dset->taxis ) ; im = IMARR_SUBIMAGE(imar,kk) ; im->xo = tt ; im->dx = dset->taxis->ttdel ; /* origin and delta */ if( dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */ im->xo *= 0.001 ; im->dx *= 0.001 ; } } } else { for( kk=0 ; kk < ns ; kk++ ){ im = IMARR_SUBIMAGE(imar,kk) ; im->xo = 0.0 ; im->dx = 1.0 ; } } free(far) ; RETURN(imar); }
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 force=0 ; /* KRH loudly deprecating usage 04/13/05/ */ int iarg=1 ; THD_3dim_dataset *dset ; /* output dataset */ int nvals , ii , jj , kk ; MRI_IMARR *anar ; /* stuff from ANALYZE headers */ MRI_IMAGE *anim ; int nxan=0,nyan=0,nzan=0 , an_datum=0 , an_swapped=0 ; float dxan=-1.0,dyan=0.0,dzan=0.0 ; char anor[8] = "\0" ; THD_ivec3 nxyz , orixyz ; THD_fvec3 dxyz , orgxyz ; float TR=1.0 ; int tunits=UNITS_SEC_TYPE ; int is_fbuc=0 , is_abuc=0 , is_3dtime=0 ; int view_type=VIEW_ORIGINAL_TYPE ; char *prefix="a2a" ; int xorient=-1, yorient=-1, zorient=-1 ; int use_zoff=0,use_xoff=0,use_yoff=0 ; float zoff=0.0,xoff=0.0,yoff=0.0 ; THD_3dim_dataset *gset=NULL ; /* geometry parent */ float *fac ; char **flab , *fatr ; /*-- help the poor user? --*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ A2A_help(); exit(0); } mainENTRY("3dANALYZEtoAFNI main"); machdep(); PRINT_VERSION("3dANALYZEtoAFNI"); /*-- parse options --*/ while( iarg < argc && argv[iarg][0] == '-' ){ /* -prefix */ if( strcmp(argv[iarg],"-prefix") == 0 ){ if( ++iarg >= argc ){ fprintf(stderr,"** -prefix needs an argument!\n"); exit(1); } prefix = argv[iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"** Illegal prefix!\n"); exit(1); } if( strstr(prefix,"/") != NULL ){ fprintf(stderr,"** Can't use directory names in the prefix!\n"); exit(1); } iarg++ ; continue ; } /* -view */ if( strcmp(argv[iarg],"-view") == 0 ){ char *str ; if( ++iarg >= argc ){ fprintf(stderr,"** -view needs an argument!\n"); exit(1); } str = argv[iarg] ; if( str[0] == '+' ) str++ ; for( ii=FIRST_VIEW_TYPE ; ii <= LAST_VIEW_TYPE ; ii++ ) if( strcmp(str,VIEW_codestr[ii]) == 0 ) break ; if( ii <= LAST_VIEW_TYPE ){ view_type = ii ; } else { fprintf(stderr,"** Illegal -view code!\n"); exit(1); } iarg++ ; continue ; } /* -zorigin */ if( strcmp(argv[iarg],"-zorigin") == 0 ){ if( ++iarg >= argc ){ fprintf(stderr,"** -zorigin needs an argument!\n"); exit(1); } zoff = strtod( argv[iarg] , NULL ) ; use_zoff = 1 ; iarg++ ; continue ; } /* -orient */ #define ORCODE(aa) \ ( (aa)=='R' ? ORI_R2L_TYPE : (aa)=='L' ? ORI_L2R_TYPE : \ (aa)=='P' ? ORI_P2A_TYPE : (aa)=='A' ? ORI_A2P_TYPE : \ (aa)=='I' ? ORI_I2S_TYPE : (aa)=='S' ? ORI_S2I_TYPE : ILLEGAL_TYPE ) #define OR3OK(x,y,z) ( ((x)&6) + ((y)&6) + ((z)&6) == 6 ) if( strcmp(argv[iarg],"-orient") == 0 ){ char acod ; if( ++iarg >= argc ){ fprintf(stderr,"** -orient needs an argument!\n"); exit(1); } if( strlen(argv[iarg]) != 3 ){ fprintf(stderr,"** Illegal -orient code!\n"); exit(1); } acod = toupper(argv[iarg][0]) ; xorient = ORCODE(acod) ; acod = toupper(argv[iarg][1]) ; yorient = ORCODE(acod) ; acod = toupper(argv[iarg][2]) ; zorient = ORCODE(acod) ; if( xorient<0 || yorient<0 || zorient<0 || ! OR3OK(xorient,yorient,zorient) ){ fprintf(stderr,"** Unusable -orient code!\n"); exit(1); } iarg++ ; continue ; } /* -geomparent */ if( strcmp(argv[iarg],"-geomparent") == 0 ){ if( ++iarg >= argc ){ fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1); } gset = THD_open_dataset( argv[iarg] ); CHECK_OPEN_ERROR(gset,argv[iarg]); iarg++ ; continue ; } /* -TR */ if( strcmp(argv[iarg],"-TR") == 0 ){ char *eptr ; if( ++iarg >= argc ){ fprintf(stderr,"** -geomparent needs an argument!\n"); exit(1); } TR = strtod( argv[iarg] , &eptr ) ; if( TR <= 0.0 ){ fprintf(stderr,"** -TR needs a positive value after it!\n"); exit(1); } if( strcmp(eptr,"ms")==0 || strcmp(eptr,"msec")==0 ){ tunits = UNITS_MSEC_TYPE ; WARNING_message("TR in millisecond units is deprecated.") ; } else if( strcmp(eptr,"s")==0 || strcmp(eptr,"sec")==0 ){ tunits = UNITS_SEC_TYPE ; } else if( strcmp(eptr,"Hz")==0 || strcmp(eptr,"Hertz")==0 ){ tunits = UNITS_HZ_TYPE ; } is_3dtime = 1 ; is_abuc = is_fbuc = 0 ; iarg++ ; continue ; } /* -fbuc */ if( strcmp(argv[iarg],"-fbuc") == 0 ){ is_fbuc = 1 ; is_abuc = is_3dtime = 0 ; iarg++ ; continue ; } /* -abuc */ if( strcmp(argv[iarg],"-abuc") == 0 ){ is_abuc = 1 ; is_fbuc = is_3dtime = 0 ; iarg++ ; continue ; } /* -OK */ if( strcmp(argv[iarg],"-OK") == 0 ){ force = 1 ; iarg++ ; continue ; } /** don't know this one **/ fprintf(stderr,"** Illegal option %s\n",argv[iarg]); exit(1); } if (!force) { A2A_help(); exit(0); } /*-- check number of remaining args --*/ nvals = argc - iarg ; if( nvals <= 0 ){ fprintf(stderr,"** No ANALYZE files on command line!?\n"); exit(1); } /*-- try to read each ANALYZE file and glean info from it --*/ CLEAR_MRILIB_globals ; /* setup */ fac = (float *) malloc(sizeof(float)*nvals) ; for( ii=iarg ; ii < argc ; ii++ ){ if( strstr(argv[ii],"/") != NULL ){ fprintf(stderr,"** ANALYZE files must all be in current directory!\n") ; exit(1) ; } anar = mri_read_analyze75( argv[ii] ) ; /* read it */ if( anar == NULL || IMARR_COUNT(anar) == 0 ){ fprintf(stderr,"** Can't read %s as ANALYZE-75 format .hdr file!\n",argv[ii]); exit(1) ; } anim = IMARR_SUBIM(anar,0) ; /* first 2D image */ fac[ii-iarg] = anim->dv ; /* save scale factor, if any */ if( ii == iarg ){ /* first time in: store header values */ nxan = anim->nx ; nyan = anim->ny ; nzan = IMARR_COUNT(anar) ; if( MRILIB_orients[0] != '\0' ) strcpy(anor,MRILIB_orients) ; an_datum = anim->kind ; if( anim->dw > 0.0 ){ dxan = anim->dx; dyan = anim->dy; dzan = anim->dz; } an_swapped = anim->was_swapped ; } else { /* check later sub-bricks */ if( nxan != anim->nx || nyan != anim->ny || nzan != IMARR_COUNT(anar) ){ fprintf(stderr,"** File %s has different dimensions than %s\n", argv[ii] , argv[iarg] ) ; exit(1) ; } if( an_datum != anim->kind ){ fprintf(stderr,"** File %s has different kind of data than %s\n", argv[ii] , argv[iarg] ) ; exit(1) ; } if( an_swapped != anim->was_swapped ){ fprintf(stderr,"** File %s %s byte-swapped, but %s %s\n", argv[ii] , (anim->was_swapped) ? "is" : "isn't" , argv[iarg] , (an_swapped) ? "is" : "isn't" ) ; exit(1) ; } if( anim->dw > 0.0 ){ if( dxan < 0.0 ){ dxan = anim->dx; dyan = anim->dy; dzan = anim->dz; } else { if( dxan != anim->dx || dyan != anim->dy || dzan != anim->dz ){ fprintf(stderr,"++ WARNING: File %s has variant voxel sizes!\n", argv[ii]) ; } } } if( anor[0] == '\0' && MRILIB_orients[0] != '\0' ) strcpy(anor,MRILIB_orients) ; } /* end of checking later volumes for compatibility */ /* destroy this data (we've sucked it dry) */ DESTROY_IMARR(anar) ; } /* end of loop over ANALYZE files */ /*-- check geomparent, if present --*/ if( gset != NULL ){ if( DSET_NX(gset)!=nxan || DSET_NY(gset)!=nyan || DSET_NZ(gset)!=nzan ){ fprintf(stderr,"** geomparent and ANALYZE files have different dimensions!\n"); exit(1) ; } if( xorient >= 0 ){ fprintf(stderr,"++ WARNING: geomparent overrides -orient!\n") ; } xorient = gset->daxes->xxorient ; yorient = gset->daxes->yyorient ; zorient = gset->daxes->zzorient ; if( use_zoff ){ fprintf(stderr,"++ WARNING: geomparent overrides -zorigin!\n") ; } use_xoff = use_yoff = use_zoff = 1 ; xoff = gset->daxes->xxorg ; yoff = gset->daxes->yyorg ; zoff = gset->daxes->zzorg ; dxan = gset->daxes->xxdel ; dyan = gset->daxes->yydel ; dzan = gset->daxes->zzdel ; if( gset->taxis != NULL ){ TR = gset->taxis->ttdel ; tunits = gset->taxis->units_type ; } DSET_delete(gset) ; /* delete to save memory */ } else { /* don't have geomparent, so check if other data is OK */ if( xorient < 0 ){ xorient = ORI_R2L_TYPE ; yorient = ORI_A2P_TYPE ; zorient = ORI_I2S_TYPE ; fprintf(stderr,"++ WARNING: orientation defaults to RAI\n") ; } if( dxan <= 0.0 ){ dxan = dyan = dzan = 1.0 ; fprintf(stderr,"++ WARNING: voxel size defaults to 1 mm\n") ; } if( ORIENT_sign[xorient] == '-' ) dxan = -dxan ; if( ORIENT_sign[yorient] == '-' ) dyan = -dyan ; if( ORIENT_sign[zorient] == '-' ) dzan = -dzan ; } /* end of setup for new dataset parameters */ /*-- At last: create empty output dataset --*/ dset = EDIT_empty_copy(NULL) ; nxyz.ijk[0] = nxan ; dxyz.xyz[0] = dxan ; nxyz.ijk[1] = nyan ; dxyz.xyz[1] = dyan ; nxyz.ijk[2] = nzan ; dxyz.xyz[2] = dzan ; orixyz.ijk[0] = xorient ; orixyz.ijk[1] = yorient ; orixyz.ijk[2] = zorient ; orgxyz.xyz[0] = (use_xoff) ? xoff : -0.5*(nxan-1)*dxan ; orgxyz.xyz[1] = (use_yoff) ? yoff : -0.5*(nyan-1)*dyan ; orgxyz.xyz[2] = (use_zoff) ? zoff : -0.5*(nzan-1)*dzan ; EDIT_dset_items( dset , ADN_prefix , prefix , ADN_datum_all , an_datum , ADN_nxyz , nxyz , ADN_xyzdel , dxyz , ADN_xyzorg , orgxyz , ADN_xyzorient , orixyz , ADN_nvals , nvals , ADN_view_type , view_type , ADN_brick_fac , fac , ADN_none ) ; /*-- select dataset type (3D+time or bucket) --*/ if( nvals == 1 && is_3dtime ){ is_3dtime = 0; is_abuc = 1; fprintf(stderr,"++ WARNING: can't make a 3D+time dataset from 1 volume!\n") ; } if( !is_3dtime && !is_abuc && !is_fbuc ){ if( nvals > 1 ) is_3dtime = 1 ; else is_abuc = 1 ; } if( is_3dtime ){ EDIT_dset_items( dset , ADN_ntt , nvals , ADN_ttorg , 0.0 , ADN_ttdel , TR , ADN_ttdur , 0.0 , ADN_tunits , tunits , ADN_type , HEAD_ANAT_TYPE , ADN_func_type, ANAT_EPI_TYPE , ADN_none ) ; } else if( is_abuc ){ EDIT_dset_items( dset , ADN_type , HEAD_ANAT_TYPE , ADN_func_type, ANAT_BUCK_TYPE , ADN_none ) ; } else if( is_fbuc ){ EDIT_dset_items( dset , ADN_type , HEAD_FUNC_TYPE , ADN_func_type, FUNC_BUCK_TYPE , ADN_none ) ; } /*-- make filename array and store it in dataset header --*/ flab = (char **) malloc(sizeof(char *)*nvals) ; kk = 0 ; for( ii=0 ; ii < nvals ; ii++ ){ jj = strlen( argv[iarg+ii] ) ; /* convert .hdr */ flab[ii] = strdup( argv[iarg+ii] ) ; /* filename to */ strcpy( flab[ii]+jj-3 , "img" ) ; /* .img name */ kk += (jj+2) ; THD_store_datablock_label( dset->dblk , ii , flab[ii] ) ; } fatr = malloc(kk) ; fatr[0] = '\0' ; /* all filenames */ for( ii=0 ; ii < nvals ; ii++ ){ /* into one big */ strcat(fatr,flab[ii] ); strcat(fatr," "); /* string */ free(flab[ii]) ; } /*-- setting this attribute marks the dataset as being stored by volumes, rather than all data in one .BRIK file --*/ THD_set_string_atr( dset->dblk , "VOLUME_FILENAMES" , fatr ) ; free(fatr) ; free(flab) ; /*-- set byte ordering flag --*/ jj = mri_short_order() ; /* order of this CPU */ if( an_swapped ) dset->dblk->diskptr->byte_order = REVERSE_ORDER(jj) ; else dset->dblk->diskptr->byte_order = jj ; /*-- set history attribute --*/ tross_Make_History( "3dANALYZEtoAFNI" , argc,argv , dset ) ; /*-- write dataset header --*/ THD_write_3dim_dataset( NULL,NULL , dset , False ) ; fprintf(stderr,"++ Wrote dataset header %s\n",DSET_HEADNAME(dset)) ; exit(0) ; }
int main(int argc, char **argv) { static char FuncName[]={"3dSeg"}; SEG_OPTS *Opt=NULL; char *atr=NULL; float *mixfrac= NULL; int i=0; double ff; SUMA_SEND_2AFNI SS2A; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = Seg_Default(argv, argc); Opt = Seg_ParseInput (Opt,argv, argc); Opt->hist = tross_commandline( FuncName , argc , argv ) ; /* load the input data */ if (!(Opt->aset = Seg_load_dset( Opt->aset_name ))) { SUMA_RETURN(1); } if (!Seg_CheckOpts(Opt)) { SUMA_S_Err("Failed on option check"); SUMA_RETURN(1); } /* Load mask dataset */ if (Opt->mset_name) { if (!strncasecmp(Opt->mset_name,"auto", 4)) { byte *mm=NULL; int j; short *sb=NULL; if (!(mm = THD_automask(Opt->aset))) { SUMA_RETURN(1); } NEW_SHORTY(Opt->aset, DSET_NVALS(Opt->aset), "automask.cp", Opt->mset); sb = (short *)DSET_ARRAY(Opt->mset,0); for (j=0; j<DSET_NVOX(Opt->mset); ++j) { sb[j] = (short)mm[j]; } free(mm); mm=NULL; } else if (!(Opt->mset = Seg_load_dset( Opt->mset_name ))) { SUMA_RETURN(1); } } /* reference classes */ if (Opt->gold_name) { if (!(Opt->gold = Seg_load_dset( Opt->gold_name ))) { SUMA_RETURN(1); } } if (Opt->gold_bias_name) { if (!(Opt->gold_bias = Seg_load_dset( Opt->gold_bias_name ))) { SUMA_RETURN(1); } } if (!Opt->clss) { SUMA_S_Err("Need -classes option"); SUMA_RETURN(1); } /* Talk ? */ if (Opt->ps->cs->talk_suma) { Opt->ps->cs->istream = SUMA_BRAINWRAP_LINE; Opt->ps->cs->afni_istream = SUMA_AFNI_STREAM_INDEX2; if (!SUMA_SendToAfni (Opt->ps->cs, NULL, 0)) { SUMA_SL_Err("Failed to initialize SUMA_SendToAfni"); Opt->ps->cs->afni_Send = NOPE; Opt->ps->cs->Send = NOPE; } else { /* send in_vol to afni */ SUMA_SL_Note("Sending anat volume to AFNI"); SS2A.dset = Opt->aset; SS2A.at_sb=-1; if (!SUMA_SendToAfni(Opt->ps->cs, &SS2A, 1)) { SUMA_SL_Err("Failed to send volume to AFNI"); Opt->ps->cs->afni_Send = NOPE; } } } /* classified set ? */ if (Opt->this_cset_name) { /* user supplied initializer */ if (!(Opt->cset = Seg_load_dset( Opt->this_cset_name ))) { SUMA_RETURN(1); } } /* labeltable? */ if (Opt->labeltable_name) { Dtable *vl_dtable=NULL; char *labeltable_str=NULL; int kk=0; /* read the table */ if (!(labeltable_str = AFNI_suck_file( Opt->labeltable_name))) { ERROR_exit("Failed to read %s", Opt->labeltable_name); } if (!(vl_dtable = Dtable_from_nimlstring(labeltable_str))) { ERROR_exit("Could not parse labeltable"); } CLASS_KEYS_FROM_LT(vl_dtable); destroy_Dtable(vl_dtable); vl_dtable=NULL; } if (!Opt->keys) { Dtable *vl_dtable=NULL; if (Opt->cset && (vl_dtable = DSET_Label_Dtable(Opt->cset))) { if (Opt->debug) SUMA_S_Note("Getting keys from -cset dataset"); /* try getting keys from cset */ CLASS_KEYS_FROM_LT(vl_dtable); /* Do not delete vl_dtable, it is the same pointer in Opt->cset */ } else { /* add default keys */ if (Opt->debug) SUMA_S_Note("Keys not available, assuming defaults"); Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int)); for (i=0; i<Opt->clss->num; ++i) { Opt->keys[i] = i+1; } } } /* Make sure you have no negative values and requesting bias field correction. The implementation uses log() for this so the negative values would be ill advised */ { float amin, amax; THD_subbrick_minmax(Opt->aset, 0, 1,&amin, &amax); if (amin < 0 && Opt->bias_param > 0) { SUMA_S_Err("Cannot use field bias correction on volumes with negative\n" "values. Either turn off bias field estimation with -bias_fwhm 0.0\n" "or shift the values of the input by something like:\n" " 3dcalc -a %s -expr 'a+bool(a)*%d' -prefix SHIFTED\n" "and rerun the segmentation on SHIFTED. Note the suggested shift\n" "leaves zero values unchanged.", DSET_HEADNAME(Opt->aset), (int)ceil(-amin+1.0)); exit(1); } } /* Show the match between keys and classes */ if (Opt->debug > 1) { SUMA_S_Note("Class-->key map"); SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys); } if (Opt->clss->num < 2) { if (Opt->debug <= 1) { SUMA_S_Note("Class-->key map"); SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys); } SUMA_S_Err("Less than 2 classes? I am out of here"); SUMA_RETURN(0); } /* Mask setup */ if (Opt->debug > 1) { SUMA_S_Note("MaskSetup"); } Opt->cmask = MaskSetup(Opt, Opt->aset, 1, &(Opt->mset), &(Opt->cmask), Opt->dimcmask, Opt->mask_bot, Opt->mask_top, &(Opt->cmask_count)); if (Opt->VoxDbg >= 0) { SUMA_S_Note("DBG setup"); fprintf(Opt->VoxDbgOut, "Command:"); for (i=0; i<argc; ++i) { fprintf(Opt->VoxDbgOut, "%s ", argv[i]); } fprintf(Opt->VoxDbgOut, "\nDebug info for voxel %d\n", Opt->VoxDbg); } Opt->cs = SUMA_New_Class_Stat(Opt->clss->str, Opt->clss->num, Opt->keys, 3, NULL); /* Load prob. of class given features */ if (Opt->priCgAname && strcmp(Opt->priCgAname, "INIT_MIXFRAC")) { if (!(Opt->priCgA = Seg_load_dset(Opt->priCgAname))) { SUMA_S_Errv("Failed to read priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } if (GRID_MISMATCH(Opt->priCgA, Opt->aset)) { SUMA_S_Err("All input data must have same grid (-priCgA != -aset)"); SUMA_RETURN(1); } /* Make sure dset is properly formatted */ if (!SUMA_ShortizeProbDset(&Opt->priCgA, Opt->cs, Opt->cmask, Opt->cmask_count, Opt, &Opt->priCgA)) { SUMA_S_Errv("Failed to shortize priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } /* set the floor of the input dset */ if (0) { SUMA_S_Note("Setting probability floor, USEFULNESS NOT TESTED..."); if (!set_p_floor(Opt->priCgA, 0.1, Opt->cmask)) { SUMA_S_Errv("Failed to set p floor for priCgA %s\n", Opt->priCgAname); SUMA_RETURN(1); } } } else { /* uniform probability */ } /* Load prob. of class given location */ if (Opt->priCgLname && strcmp(Opt->priCgLname, "INIT_MIXFRAC")) { if (!(Opt->priCgL = Seg_load_dset(Opt->priCgLname))) { SUMA_S_Errv("Failed to read priCgL %s\n", Opt->priCgLname); SUMA_RETURN(1); } if (GRID_MISMATCH(Opt->priCgL, Opt->aset)) { SUMA_S_Err("All input data must have same grid (-priCgL != -aset)"); SUMA_RETURN(1); } /* Make sure dset is properly formatted */ if (!SUMA_ShortizeProbDset(&Opt->priCgL, Opt->cs, Opt->cmask, Opt->cmask_count, Opt, &Opt->priCgL)) { SUMA_S_Errv("Failed to shortize priCgL %s\n", Opt->priCgLname); SUMA_RETURN(1); } } else { /* uniform probability */ } /* check on weights of priors */ if (Opt->wA >= 0.0 && Opt->wL < 0.0) { Opt->wL = 1.0 - Opt->wA; } else if (Opt->wL >= 0.0 && Opt->wA < 0.0) { Opt->wA = 1.0 - Opt->wL; } else if (Opt->wA < 0.0 && Opt->wL < 0.0) { /* defaults */ Opt->wA = 0.5; Opt->wL = 0.5; } ff = Opt->wA+Opt->wL; Opt->wA = Opt->wA/ff; Opt->wL = Opt->wL/ff; if (!Opt->cset) { if (!SUMA_SegInitCset(Opt->aset, &Opt->cset, Opt->cmask, Opt->cmask_count, Opt->mixopt, Opt->cs, Opt)) { SUMA_S_Err("Failed to get initializer"); SUMA_RETURN(1); } } if (Opt->debug > 1) { SUMA_Seg_Write_Dset(Opt->proot, "classes_init", Opt->cset, -1, Opt->hist); } /* Now add the 'OTHER' class if needed */ if (Opt->Other) { if (!SUMA_AddOther( Opt->clss, &Opt->keys, Opt->cmask, Opt->cmask_count, Opt->cset, Opt->pstCgALL, Opt->priCgA, Opt->priCgL, Opt->cs)) { SUMA_S_Err("Failed to add other"); SUMA_RETURN(0); } } /* store mixfrac in class stats */ for (i=0;i<Opt->cs->N_label; ++i) { if ((ff = SUMA_mixopt_2_mixfrac(Opt->mixopt, Opt->cs->label[i], Opt->cs->keys[i], Opt->cs->N_label, Opt->cmask, Opt->cset))<0.0) { SUMA_S_Errv("Can't get mixfrac for %s\n", Opt->mixopt); SUMA_RETURN(1); } SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "init.mix", ff); SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "mix", ff); } /* Now call the workhorse */ if (!SUMA_SegEngine(Opt)) { SUMA_S_Err("Failed in SUMA_SegEngine"); exit(1); } /* write output */ if (Opt->Bset && !Opt->this_fset_name) { tross_Append_History(Opt->Bset, Opt->hist); SUMA_Seg_Write_Dset(Opt->proot, "BiasField", /* DSET_PREFIX(Opt->Bset) */ Opt->Bset, -1, Opt->hist); } if (Opt->xset && !Opt->this_xset_name) { AFNI_FEED(Opt->ps->cs, "BiasCorrect", -1, Opt->xset); SUMA_Seg_Write_Dset(Opt->proot, "AnatUB", /* DSET_PREFIX(Opt->xset)*/ Opt->xset, -1, Opt->hist); } if (Opt->cset) { SUMA_Seg_Write_Dset(Opt->proot, "Classes", /* Opt->crefix */ Opt->cset, -1, Opt->hist); AFNI_FEED(Opt->ps->cs, "FinalClasses", -1, Opt->cset); } if (Opt->pstCgALL) { SUMA_Seg_Write_Dset(Opt->proot, "Posterior", /* Opt->prefix */ Opt->pstCgALL, -1, Opt->hist); AFNI_FEED(Opt->ps->cs, "pstCgALL-final", -1, Opt->pstCgALL); } if (Opt->aset) { SUMA_Seg_Write_Dset(Opt->proot, "Anat", Opt->aset, -1, Opt->hist); } if (Opt->debug) SUMA_S_Note("Writing Unmodulated output"); if (!(SUMA_pst_C_giv_ALL(Opt->xset, Opt->cmask, Opt->cmask_count, Opt->cs, NULL, NULL, Opt->B, Opt->T, 0, &Opt->pstCgALL))) { SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL unmodulated"); SUMA_RETURN(1); } SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.p", Opt->pstCgALL, -1, Opt->hist); if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, Opt->cmask, &Opt->cset))) { SUMA_S_Err("Failed in assign_classes"); SUMA_RETURN(1); } SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.c", Opt->cset, -1, Opt->hist); /* all done, free */ Opt = free_SegOpts(Opt); PRINT_COMPILE_DATE ; SUMA_RETURN(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[] ) { THD_3dim_dataset *dset , *oset=NULL , *tset=NULL ; int nvals , iv , nxyz , ii,jj,kk , iarg , kz,kzold ; float cut1=2.5,cut2=4.0 , sq2p,sfac , fq ; MRI_IMAGE *flim ; char *prefix="despike" , *tprefix=NULL ; int corder=-1 , nref , ignore=0 , polort=2 , nuse , nomask=0 ; int nspike, nbig, nproc ; float **ref ; float c21,ic21 , pspike,pbig ; short *sar , *qar ; byte *tar , *mask=NULL ; float *zar , *yar ; int datum ; int localedit=0 ; /* 04 Apr 2007 */ int verb=1 ; int do_NEW = 0 ; /* 29 Nov 2013 */ MRI_IMAGE *NEW_psinv=NULL ; int dilate = 4 ; /* 04 Dec 2013 */ int ctim = 0 ; /*----- Read command line -----*/ AFNI_SETUP_OMP(0) ; /* 24 Jun 2013 */ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dDespike [options] dataset\n" "Removes 'spikes' from the 3D+time input dataset and writes\n" "a new dataset with the spike values replaced by something\n" "more pleasing to the eye.\n" "\n" "Method:\n" " * L1 fit a smooth-ish curve to each voxel time series\n" " [see -corder option for description of the curve]\n" " [see -NEW option for a different & faster fitting method]\n" " * Compute the MAD of the difference between the curve and\n" " the data time series (the residuals).\n" " * Estimate the standard deviation 'sigma' of the residuals\n" " as sqrt(PI/2)*MAD.\n" " * For each voxel value, define s = (value-curve)/sigma.\n" " * Values with s > c1 are replaced with a value that yields\n" " a modified s' = c1+(c2-c1)*tanh((s-c1)/(c2-c1)).\n" " * c1 is the threshold value of s for a 'spike' [default c1=2.5].\n" " * c2 is the upper range of the allowed deviation from the curve:\n" " s=[c1..infinity) is mapped to s'=[c1..c2) [default c2=4].\n" "\n" "Options:\n" " -ignore I = Ignore the first I points in the time series:\n" " these values will just be copied to the\n" " output dataset [default I=0].\n" " -corder L = Set the curve fit order to L:\n" " the curve that is fit to voxel data v(t) is\n" "\n" " k=L [ (2*PI*k*t) (2*PI*k*t) ]\n" " f(t) = a+b*t+c*t*t + SUM [ d * sin(--------) + e * cos(--------) ]\n" " k=1 [ k ( T ) k ( T ) ]\n" "\n" " where T = duration of time series;\n" " the a,b,c,d,e parameters are chosen to minimize\n" " the sum over t of |v(t)-f(t)| (L1 regression);\n" " this type of fitting is is insensitive to large\n" " spikes in the data. The default value of L is\n" " NT/30, where NT = number of time points.\n" "\n" " -cut c1 c2 = Alter default values for the spike cut values\n" " [default c1=2.5, c2=4.0].\n" " -prefix pp = Save de-spiked dataset with prefix 'pp'\n" " [default pp='despike']\n" " -ssave ttt = Save 'spikiness' measure s for each voxel into a\n" " 3D+time dataset with prefix 'ttt' [default=no save]\n" " -nomask = Process all voxels\n" " [default=use a mask of high-intensity voxels, ]\n" " [as created via '3dAutomask -dilate 4 dataset'].\n" " -dilate nd = Dilate 'nd' times (as in 3dAutomask). The default\n" " value of 'nd' is 4.\n" " -q[uiet] = Don't print '++' informational messages.\n" "\n" " -localedit = Change the editing process to the following:\n" " If a voxel |s| value is >= c2, then replace\n" " the voxel value with the average of the two\n" " nearest non-spike (|s| < c2) values; the first\n" " one previous and the first one after.\n" " Note that the c1 cut value is not used here.\n" "\n" " -NEW = Use the 'new' method for computing the fit, which\n" " should be faster than the L1 method for long time\n" " series (200+ time points); however, the results\n" " are similar but NOT identical. [29 Nov 2013]\n" " * You can also make the program use the 'new'\n" " method by setting the environment variable\n" " AFNI_3dDespike_NEW\n" " to the value YES; as in\n" " setenv AFNI_3dDespike_NEW YES (csh)\n" " export AFNI_3dDespike_NEW=YES (bash)\n" " * If this variable is set to YES, you can turn off\n" " the '-NEW' processing by using the '-OLD' option.\n" " -->>* For time series more than 500 points long, the\n" " '-OLD' algorithm is tremendously slow. You should\n" " use the '-NEW' algorith in such cases.\n" " ** At some indeterminate point in the future, the '-NEW'\n" " method will become the default!\n" " -->>* As of 29 Sep 2016, '-NEW' is the default if there\n" " is more than 500 points in the time series dataset.\n" "\n" " -NEW25 = A slightly more aggressive despiking approach than\n" " the '-NEW' method.\n" "\n" "Caveats:\n" "* Despiking may interfere with image registration, since head\n" " movement may produce 'spikes' at the edge of the brain, and\n" " this information would be used in the registration process.\n" " This possibility has not been explored or calibrated.\n" "* [LATER] Actually, it seems like the registration problem\n" " does NOT happen, and in fact, despiking seems to help!\n" "* Check your data visually before and after despiking and\n" " registration!\n" " [Hint: open 2 AFNI controllers, and turn Time Lock on.]\n" ) ; PRINT_AFNI_OMP_USAGE("3dDespike",NULL) ; PRINT_COMPILE_DATE ; exit(0) ; } /** AFNI package setup and logging **/ mainENTRY("3dDespike main"); machdep(); AFNI_logger("3dDespike",argc,argv); PRINT_VERSION("3dDespike") ; AUTHOR("RW Cox") ; /** parse options **/ if( AFNI_yesenv("AFNI_3dDespike_NEW") ) do_NEW = 1 ; /* 29 Nov 2013 */ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-q",2) == 0 ){ /* 04 Apr 2007 */ verb = 0 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-v",2) == 0 ){ verb++ ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-NEW") == 0 ){ /* 29 Nov 2013 */ do_NEW = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-NEW25") == 0 ){ /* 29 Sep 2016 */ do_NEW = 1 ; use_des25 = 1 ; cut1 = 2.5f ; cut2 = 3.2f ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-OLD") == 0 ){ do_NEW = 0 ; iarg++ ; continue ; } /** -localedit **/ if( strcmp(argv[iarg],"-localedit") == 0 ){ /* 04 Apr 2007 */ localedit = 1 ; iarg++ ; continue ; } /** don't use masking **/ if( strcmp(argv[iarg],"-nomask") == 0 ){ nomask = 1 ; iarg++ ; continue ; } /** dilation count [04 Dec 2013] **/ if( strcmp(argv[iarg],"-dilate") == 0 ){ dilate = (int)strtod(argv[++iarg],NULL) ; if( dilate <= 0 ) dilate = 1 ; else if( dilate > 99 ) dilate = 99 ; iarg++ ; continue ; } /** output dataset prefix **/ if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ) ERROR_exit("-prefix is not good"); iarg++ ; continue ; } /** ratio dataset prefix **/ if( strcmp(argv[iarg],"-ssave") == 0 ){ tprefix = argv[++iarg] ; if( !THD_filename_ok(tprefix) ) ERROR_exit("-ssave prefix is not good"); iarg++ ; continue ; } /** trigonometric polynomial order **/ if( strcmp(argv[iarg],"-corder") == 0 ){ corder = strtol( argv[++iarg] , NULL , 10 ) ; if( corder < 0 ) ERROR_exit("Illegal value of -corder"); iarg++ ; continue ; } /** how much to ignore at start **/ if( strcmp(argv[iarg],"-ignore") == 0 ){ ignore = strtol( argv[++iarg] , NULL , 10 ) ; if( ignore < 0 ) ERROR_exit("Illegal value of -ignore"); iarg++ ; continue ; } /** thresholds for s ratio **/ if( strcmp(argv[iarg],"-cut") == 0 ){ cut1 = strtod( argv[++iarg] , NULL ) ; cut2 = strtod( argv[++iarg] , NULL ) ; if( cut1 < 1.0 || cut2 < cut1+0.5 ) ERROR_exit("Illegal values after -cut"); iarg++ ; continue ; } ERROR_exit("Unknown option: %s",argv[iarg]) ; } c21 = cut2-cut1 ; ic21 = 1.0/c21 ; /*----- read input dataset -----*/ if( iarg >= argc ) ERROR_exit("No input dataset!!??"); dset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(dset,argv[iarg]) ; datum = DSET_BRICK_TYPE(dset,0) ; if( (datum != MRI_short && datum != MRI_float) || !DSET_datum_constant(dset) ) ERROR_exit("Can't process non-short, non-float dataset!") ; if( verb ) INFO_message("Input data type = %s\n",MRI_TYPE_name[datum]) ; nvals = DSET_NUM_TIMES(dset) ; nuse = nvals - ignore ; if( nuse < 15 ) ERROR_exit("Can't use dataset with < 15 time points per voxel!") ; if( nuse > 500 && !do_NEW ){ INFO_message("Switching to '-NEW' method since number of time points = %d > 500",nuse) ; do_NEW = 1 ; } if( use_des25 && nuse < 99 ) use_des25 = 0 ; if( verb ) INFO_message("ignoring first %d time points, using last %d",ignore,nuse); if( corder > 0 && 4*corder+2 > nuse ){ ERROR_exit("-corder %d is too big for NT=%d",corder,nvals) ; } else if( corder < 0 ){ corder = rint(nuse/30.0) ; if( corder > 50 && !do_NEW ) corder = 50 ; if( verb ) INFO_message("using %d time points => -corder %d",nuse,corder) ; } else { if( verb ) INFO_message("-corder %d set from command line",corder) ; } nxyz = DSET_NVOX(dset) ; if( verb ) INFO_message("Loading dataset %s",argv[iarg]) ; DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; /*-- create automask --*/ if( !nomask ){ mask = THD_automask( dset ) ; if( verb ){ ii = THD_countmask( DSET_NVOX(dset) , mask ) ; INFO_message("%d voxels in the automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ; } for( ii=0 ; ii < dilate ; ii++ ) THD_mask_dilate( DSET_NX(dset), DSET_NY(dset), DSET_NZ(dset), mask, 3 ) ; if( verb ){ ii = THD_countmask( DSET_NVOX(dset) , mask ) ; INFO_message("%d voxels in the dilated automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ; } } else { if( verb ) INFO_message("processing all %d voxels in dataset",DSET_NVOX(dset)) ; } /*-- create empty despiked dataset --*/ oset = EDIT_empty_copy( dset ) ; EDIT_dset_items( oset , ADN_prefix , prefix , ADN_brick_fac , NULL , ADN_datum_all , datum , ADN_none ) ; if( THD_deathcon() && THD_is_file(DSET_HEADNAME(oset)) ) ERROR_exit("output dataset already exists: %s",DSET_HEADNAME(oset)); tross_Copy_History( oset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , oset ) ; /* create bricks (will be filled with zeros) */ for( iv=0 ; iv < nvals ; iv++ ) EDIT_substitute_brick( oset , iv , datum , NULL ) ; /* copy the ignored bricks */ switch( datum ){ case MRI_short: for( iv=0 ; iv < ignore ; iv++ ){ sar = DSET_ARRAY(oset,iv) ; qar = DSET_ARRAY(dset,iv) ; memcpy( sar , qar , DSET_BRICK_BYTES(dset,iv) ) ; DSET_unload_one(dset,iv) ; } break ; case MRI_float: for( iv=0 ; iv < ignore ; iv++ ){ zar = DSET_ARRAY(oset,iv) ; yar = DSET_ARRAY(dset,iv) ; memcpy( zar , yar , DSET_BRICK_BYTES(dset,iv) ) ; DSET_unload_one(dset,iv) ; } break ; } /*-- setup to save a threshold statistic dataset, if desired --*/ if( tprefix != NULL ){ float *fac ; tset = EDIT_empty_copy( dset ) ; fac = (float *) malloc( sizeof(float) * nvals ) ; for( ii=0 ; ii < nvals ; ii++ ) fac[ii] = TFAC ; EDIT_dset_items( tset , ADN_prefix , tprefix , ADN_brick_fac , fac , ADN_datum_all , MRI_byte , ADN_func_type , FUNC_FIM_TYPE , ADN_none ) ; free(fac) ; tross_Copy_History( tset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , tset ) ; #if 0 if( THD_is_file(DSET_HEADNAME(tset)) ) ERROR_exit("-ssave dataset already exists"); #endif tross_Copy_History( tset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , tset ) ; for( iv=0 ; iv < nvals ; iv++ ) EDIT_substitute_brick( tset , iv , MRI_byte , NULL ) ; } /*-- setup to find spikes --*/ sq2p = sqrt(0.5*PI) ; sfac = sq2p / 1.4826f ; /* make ref functions */ nref = 2*corder+3 ; ref = (float **) malloc( sizeof(float *) * nref ) ; for( jj=0 ; jj < nref ; jj++ ) ref[jj] = (float *) malloc( sizeof(float) * nuse ) ; /* r(t) = 1 */ for( iv=0 ; iv < nuse ; iv++ ) ref[0][iv] = 1.0 ; jj = 1 ; /* r(t) = t - tmid */ { float tm = 0.5 * (nuse-1.0) ; float fac = 2.0 / nuse ; for( iv=0 ; iv < nuse ; iv++ ) ref[1][iv] = (iv-tm)*fac ; jj = 2 ; /* r(t) = (t-tmid)**jj */ for( ; jj <= polort ; jj++ ) for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = pow( (iv-tm)*fac , (double)jj ) ; } for( kk=1 ; kk <= corder ; kk++ ){ fq = (2.0*PI*kk)/nuse ; /* r(t) = sin(2*PI*k*t/N) */ for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = sin(fq*iv) ; jj++ ; /* r(t) = cos(2*PI*k*t/N) */ for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = cos(fq*iv) ; jj++ ; } /****** setup for the NEW solution method [29 Nov 2013] ******/ if( do_NEW ){ NEW_psinv = DES_get_psinv(nuse,nref,ref) ; INFO_message("Procesing time series with NEW model fit algorithm") ; } else { INFO_message("Procesing time series with OLD model fit algorithm") ; } /*--- loop over voxels and do work ---*/ #define Laplace_t2p(val) ( 1.0 - nifti_stat2cdf( (val), 15, 0.0, 1.4427 , 0.0 ) ) if( verb ){ if( !localedit ){ INFO_message("smash edit thresholds: %.1f .. %.1f MADs",cut1*sq2p,cut2*sq2p) ; ININFO_message(" [ %.3f%% .. %.3f%% of normal distribution]", 200.0*qg(cut1*sfac) , 200.0*qg(cut2*sfac) ) ; ININFO_message(" [ %.3f%% .. %.3f%% of Laplace distribution]" , 100.0*Laplace_t2p(cut1) , 100.0*Laplace_t2p(cut2) ) ; } else { INFO_message("local edit threshold: %.1f MADS",cut2*sq2p) ; ININFO_message(" [ %.3f%% of normal distribution]", 200.0*qg(cut2*sfac) ) ; ININFO_message(" [ %.3f%% of Laplace distribution]", 100.0*Laplace_t2p(cut1) ) ; } INFO_message("%d slices to process",DSET_NZ(dset)) ; } kzold = -1 ; nspike = 0 ; nbig = 0 ; nproc = 0 ; ctim = NI_clock_time() ; AFNI_OMP_START ; #pragma omp parallel if( nxyz > 6666 ) { int ii , iv , iu , id , jj ; float *far , *dar , *var , *fitar , *ssp , *fit , *zar ; short *sar , *qar ; byte *tar ; float fsig , fq , cls , snew , val ; float *NEW_wks=NULL ; #pragma omp critical (DESPIKE_malloc) { far = (float *) malloc( sizeof(float) * nvals ) ; dar = (float *) malloc( sizeof(float) * nvals ) ; var = (float *) malloc( sizeof(float) * nvals ) ; fitar = (float *) malloc( sizeof(float) * nvals ) ; ssp = (float *) malloc( sizeof(float) * nvals ) ; fit = (float *) malloc( sizeof(float) * nref ) ; if( do_NEW ) NEW_wks = (float *)malloc(sizeof(float)*DES_workspace_size(nuse,nref)) ; } #ifdef USE_OMP INFO_message("start OpenMP thread #%d",omp_get_thread_num()) ; #endif #pragma omp for for( ii=0 ; ii < nxyz ; ii++ ){ /* ii = voxel index */ if( mask != NULL && mask[ii] == 0 ) continue ; /* skip this voxel */ #ifndef USE_OMP kz = DSET_index_to_kz(dset,ii) ; /* starting a new slice */ if( kz != kzold ){ if( verb ){ fprintf(stderr, "++ start slice %2d",kz ) ; if( nproc > 0 ){ pspike = (100.0*nspike)/nproc ; pbig = (100.0*nbig )/nproc ; fprintf(stderr, "; so far %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]", nproc,nspike,pspike,nbig,pbig ) ; } fprintf(stderr,"\n") ; } kzold = kz ; } #else if( verb && ii % 2345 == 1234 ) fprintf(stderr,".") ; #endif /*** extract ii-th time series into far[] ***/ switch( datum ){ case MRI_short: for( iv=0 ; iv < nuse ; iv++ ){ qar = DSET_ARRAY(dset,iv+ignore) ; /* skip ignored data */ far[iv] = (float)qar[ii] ; } break ; case MRI_float: for( iv=0 ; iv < nuse ; iv++ ){ zar = DSET_ARRAY(dset,iv+ignore) ; far[iv] = zar[ii] ; } break ; } AAmemcpy(dar,far,sizeof(float)*nuse) ; /* copy time series into dar[] */ /*** solve for L1 fit ***/ if( do_NEW ) cls = DES_solve( NEW_psinv , far , fit , NEW_wks ) ; /* 29 Nov 2013 */ else cls = cl1_solve( nuse , nref , far , ref , fit,0 ) ; /* the slow part */ if( cls < 0.0f ){ /* fit failed! */ #if 0 fprintf(stderr,"curve fit fails at voxel %d %d %d\n", DSET_index_to_ix(dset,ii) , DSET_index_to_jy(dset,ii) , DSET_index_to_kz(dset,ii) ) ; #endif continue ; /* skip this voxel */ } for( iv=0 ; iv < nuse ; iv++ ){ /* detrend */ val = fit[0] + fit[1]*ref[1][iv] /* quadratic part of curve fit */ + fit[2]*ref[2][iv] ; for( jj=3 ; jj < nref ; jj++ ) /* rest of curve fit */ val += fit[jj] * ref[jj][iv] ; fitar[iv] = val ; /* save curve fit value */ var[iv] = dar[iv]-val ; /* remove fitted value = resid */ far[iv] = fabsf(var[iv]) ; /* abs value of resid */ } /*** compute estimate standard deviation of detrended data ***/ fsig = sq2p * qmed_float(nuse,far) ; /* also mangles far array */ /*** process time series for spikes, editing data in dar[] ***/ if( fsig > 0.0f ){ /* data wasn't fit perfectly */ /* find spikiness for each point in time */ fq = 1.0f / fsig ; for( iv=0 ; iv < nuse ; iv++ ){ ssp[iv] = fq * var[iv] ; /* spikiness s = how many sigma out */ } /* save spikiness in -ssave datset */ if( tset != NULL ){ for( iv=0 ; iv < nuse ; iv++ ){ tar = DSET_ARRAY(tset,iv+ignore) ; snew = ITFAC*fabsf(ssp[iv]) ; /* scale for byte storage */ tar[ii] = BYTEIZE(snew) ; /* cf. mrilib.h */ } } /* process values of |s| > cut1, editing dar[] */ for( iv=0 ; iv < nuse ; iv++ ){ /* loop over time points */ if( !localedit ){ /** classic 'smash' edit **/ if( ssp[iv] > cut1 ){ snew = cut1 + c21*mytanh((ssp[iv]-cut1)*ic21) ; /* edit s down */ dar[iv] = fitar[iv] + snew*fsig ; #pragma omp critical (DESPIKE_counter) { nspike++ ; if( ssp[iv] > cut2 ) nbig++ ; } } else if( ssp[iv] < -cut1 ){ snew = -cut1 + c21*mytanh((ssp[iv]+cut1)*ic21) ; /* edit s up */ dar[iv] = fitar[iv] + snew*fsig ; #pragma omp critical (DESPIKE_counter) { nspike++ ; if( ssp[iv] < -cut2 ) nbig++ ; } } } else { /** local edit: 04 Apr 2007 **/ if( ssp[iv] >= cut2 || ssp[iv] <= -cut2 ){ for( iu=iv+1 ; iu < nuse ; iu++ ) /* find non-spike above */ if( ssp[iu] < cut2 && ssp[iu] > -cut2 ) break ; for( id=iv-1 ; id >= 0 ; id-- ) /* find non-spike below */ if( ssp[id] < cut2 && ssp[id] > -cut2 ) break ; switch( (id>=0) + 2*(iu<nuse) ){ /* compute replacement val */ case 3: val = 0.5*(dar[iu]+dar[id]); break; /* iu and id OK */ case 2: val = dar[iu] ; break; /* only iu OK */ case 1: val = dar[id] ; break; /* only id OK */ default: val = fitar[iv] ; break; /* shouldn't be */ } dar[iv] = val ; #pragma omp critical (DESPIKE_counter) { nspike++ ; nbig++ ; } } } } /* end of loop over time points */ #pragma omp atomic nproc += nuse ; /* number data points processed */ } /* end of processing time series when fsig is positive */ /* put dar[] time series (possibly edited above) into output bricks */ switch( datum ){ case MRI_short: for( iv=0 ; iv < nuse ; iv++ ){ sar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */ sar[ii] = (short)dar[iv] ; /* original or mutated data */ } break ; case MRI_float: for( iv=0 ; iv < nuse ; iv++ ){ zar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */ zar[ii] = dar[iv] ; /* original or mutated data */ } break ; } } /* end of loop over voxels #ii */ #pragma omp critical (DESPIKE_malloc) { free(fit); free(ssp); free(fitar); free(var); free(dar); free(far); if( do_NEW ) free(NEW_wks) ; } } /* end OpenMP */ AFNI_OMP_END ; #ifdef USE_OMP if( verb ) fprintf(stderr,"\n") ; #endif ctim = NI_clock_time() - ctim ; INFO_message( "Elapsed despike time = %s" , nice_time_string(ctim) ) ; if( ctim > 345678 && !do_NEW ) ININFO_message("That was SLOW -- try the '-NEW' option for a speedup") ; #ifdef USE_OMP if( verb ) fprintf(stderr,"\n") ; #endif /*--- finish up ---*/ if( do_NEW ) mri_free(NEW_psinv) ; DSET_delete(dset) ; /* delete input dataset */ if( verb ){ if( nproc > 0 ){ pspike = (100.0*nspike)/nproc ; pbig = (100.0*nbig )/nproc ; INFO_message("FINAL: %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]", nproc,nspike,pspike,nbig,pbig ) ; } else { INFO_message("FINAL: no good voxels found to process!!??") ; } } /* write results */ DSET_write(oset) ; if( verb ) WROTE_DSET(oset) ; DSET_delete(oset) ; if( tset != NULL ){ DSET_write(tset) ; if( verb ) WROTE_DSET(tset) ; DSET_delete(tset) ; } exit( THD_get_write_error_count() ) ; }
void THD_check_idcodes( THD_sessionlist *ssl ) { int iss , idd,jdd , ivv , dsnum , nd ; THD_session *sess ; THD_3dim_dataset * dset , **dsl ; ENTRY("THD_check_idcodes") ; /*-- sanity check --*/ if( ! ISVALID_SESSIONLIST(ssl) || ssl->num_sess <= 0 ) EXRETURN ; /*-- count number of datasets --*/ for( dsnum=iss=0 ; iss < ssl->num_sess ; iss++ ){ sess = ssl->ssar[iss] ; if( !ISVALID_SESSION(sess) ) continue ; for( idd=0 ; idd < sess->num_dsset ; idd++ ){ for( ivv=FIRST_VIEW_TYPE ; ivv <= LAST_VIEW_TYPE ; ivv++ ){ dset = GET_SESSION_DSET(sess, idd, ivv); /* dset = sess->dsset_xform_table[idd][ivv] ;*/ if( ISVALID_DSET(dset) ) dsnum++ ; } } } STATUS("counted datasets") ; if( dsnum < 2 ) EXRETURN ; /* 21 Feb 2007 */ /*-- make list of datasets --*/ dsl = (THD_3dim_dataset **) malloc( sizeof(THD_3dim_dataset *) * dsnum ) ; for( nd=iss=0 ; iss < ssl->num_sess ; iss++ ){ sess = ssl->ssar[iss] ; if( !ISVALID_SESSION(sess) ) continue ; for( idd=0 ; idd < sess->num_dsset ; idd++ ){ for( ivv=FIRST_VIEW_TYPE ; ivv <= LAST_VIEW_TYPE ; ivv++ ){ dset = GET_SESSION_DSET(sess, idd, ivv); /* dset = sess->dsset_xform_table[idd][ivv] ;*/ if( ISVALID_DSET(dset) ) dsl[nd++] = dset ; } } } STATUS("collected datasets") ; /*-- check list for duplicates --*/ for( iss=idd=0 ; idd < dsnum-1 ; idd++ ){ nd = 0 ; for( jdd=idd+1 ; jdd < dsnum ; jdd++ ){ if( DUPLICATE_DSETS(dsl[idd],dsl[jdd]) ){ /* 20 Dec 2001: change EQUIV_IDCODES() to DUPLICATE_DSETS() */ fprintf(stderr, "\n*** WARNING: Identical ID codes in %s and %s", DSET_HEADNAME(dsl[idd]) , DSET_HEADNAME(dsl[jdd]) ) ; iss++ ; } } } if( iss > 0 ) fprintf(stderr,"\n") ; free(dsl) ; EXRETURN ; }
int main( int argc , char * argv[] ) { THD_3dim_dataset *dset, *outset=NULL; int iarg=1, npad = 0, extent=0; char *prefix=NULL, *iname=NULL; char *oijkext = NULL; FILE *fout_ijkext=NULL; int extent_ijk=0; int extent_ijk_midslice=0; int imid=0, jmid=0, kmid=0; int extent_xyz_midslice=0; float xmid=0, ymid=0, zmid=0; /*-- startup bureaucracy --*/ mainENTRY("3dAutobox main"); machdep(); AFNI_logger("3dAutobox",argc,argv); PRINT_VERSION("3dAutobox") ; /*-- read command line options --*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){ help_autobox(); exit(0) ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"** 3dAutobox: Illegal string after -prefix!\n"); exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-input") == 0 ){ iname = argv[++iarg] ; // This is a bad check, because it doesn't permit subbrick // selection! Will do check later. /*if( !THD_filename_ok(iname) ){ fprintf(stderr,"** 3dAutobox: Illegal string after -input!\n"); exit(1) ; }*/ iarg++ ; continue ; } if( strcmp(argv[iarg],"-noclust") == 0 ){ MRI_autobbox_clust(0) ; /* turn of clustering and clipping */ THD_autobbox_clip(0) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-npad") == 0 ){ npad = (int)strtod(argv[++iarg],NULL) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-extent_ijk") == 0 ){ extent_ijk = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-extent_ijk_to_file") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-extent_ijk_to_file'\n") ; oijkext = argv[iarg]; iarg++ ; continue ; } if( strcmp(argv[iarg],"-extent_ijk_midslice") == 0 ){ extent_ijk_midslice = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-extent_xyz_midslice") == 0 ){ extent_xyz_midslice = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-extent") == 0 ){ extent = 1 ; iarg++ ; continue ; } /*- washappenin, dood? -*/ ERROR_message("** 3dAutobox: %s makes no sense here.\n", argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit(1); } if( argc < 2){ help_autobox(); exit(0); } /* got input ? */ if( iarg == argc-1 ) iname = argv[iarg] ; else if (iarg != argc) ERROR_exit("** 3dAutobox: %s is nonsense on the line \n" " I know you're John; stop pretending you have an accent!", argv[iarg]) ; if( !iname ) ERROR_exit("** 3dAutobox: Where is my input?") ; /*-- read data --*/ dset = THD_open_dataset(iname); // Check here instead of after -input. if( dset == NULL ) ERROR_exit("Can't open time series dataset '%s'.",iname); CHECK_OPEN_ERROR(dset,iname); if( DSET_BRICK_TYPE(dset,0) != MRI_short && DSET_BRICK_TYPE(dset,0) != MRI_byte && DSET_BRICK_TYPE(dset,0) != MRI_float ) ERROR_exit("** ILLEGAL dataset type: %s :-(", MRI_type_name[DSET_BRICK_TYPE(dset,0)]) ; DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; { int nx=DSET_NX(dset), ny=DSET_NY(dset), nz=DSET_NZ(dset), nxy=nx*ny ; int xm=-1,xp=-1,ym=-1,yp=-1,zm=-1,zp=-1; THD_autobbox( dset , &xm,&xp , &ym,&yp , &zm,&zp, NULL ) ; xm -= npad; ym -= npad; zm -= npad; /* for LRF */ xp += npad; yp += npad; zp += npad; INFO_message("Auto bbox: x=%d..%d y=%d..%d z=%d..%d\n", xm,xp,ym,yp,zm,zp ) ; // [PT: Oct 18, 2018] New output text file, if desired if( oijkext ) { if( (fout_ijkext = fopen(oijkext, "w")) == NULL ) { fprintf(stderr, "\n\nError opening file %s.\n", oijkext); exit(1); } fprintf( fout_ijkext, "%8d %8d %8d %8d %8d %8d\n", xm, xp, ym, yp, zm, zp ); fclose(fout_ijkext); INFO_message("Wrote ijk extents file: %s", oijkext); } if( extent_ijk ) printf( "%8d %8d %8d %8d %8d %8d\n", xm, xp, ym, yp, zm, zp ); if( extent_ijk_midslice ) { imid = (xm + xp) / 2; // integer division fine, b/c we need ints jmid = (ym + yp) / 2; kmid = (zm + zp) / 2; printf( "%8d %8d %8d\n", imid, jmid, kmid ); } if ( (extent && !prefix) || (extent_xyz_midslice && !prefix) ) prefix = "EXTENT_ONLY"; if( prefix ){ outset = THD_zeropad( dset , -xm, xp-nx+1, -ym, yp-ny+1, -zm, zp-nz+1, prefix , ZPAD_IJK ) ; if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) ) ERROR_exit("3dAutobox: output file %s already exists :-(", DSET_HEADNAME(outset) ) ; if( outset == NULL ) ERROR_exit("3dAutobox: Some error occurred in processing :-(") ; tross_Copy_History( dset , outset ) ; /* 31 Jan 2001 - RWCox */ tross_Make_History( "3dAutobox" , argc,argv , outset ) ; if (!strstr(prefix,"EXTENT_ONLY")) { DSET_write(outset) ; INFO_message("3dAutobox: output dataset = %s", DSET_BRIKNAME(outset)) ; } if (extent) { float RL_AP_IS[6]; THD_dset_extent(outset, '-', RL_AP_IS); printf("Extent auto bbox: R=%f L=%f A=%f P=%f I=%f S=%f\n", RL_AP_IS[0],RL_AP_IS[1], RL_AP_IS[2],RL_AP_IS[3], RL_AP_IS[4],RL_AP_IS[5] ) ; } if( extent_xyz_midslice ) { INFO_message("aaa" ); float RL_AP_IS2[6]; THD_dset_extent(outset, '-', RL_AP_IS2); xmid = (RL_AP_IS2[0] + RL_AP_IS2[1]) / 2.; ymid = (RL_AP_IS2[2] + RL_AP_IS2[3]) / 2.; zmid = (RL_AP_IS2[4] + RL_AP_IS2[5]) / 2.; printf( "%10.5f %10.5f %10.5f\n", xmid, ymid, zmid ); } } } exit(0) ; }
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) ; }
int THD_conformist( int ndset, THD_3dim_dataset **dset, int flags , int *ijkpad ) { int iset , xpad_m,xpad_p , ypad_m,ypad_p , zpad_m,zpad_p , nwrit ; THD_dataxes *cx , *dx ; THD_3dim_dataset *qset ; int_pair pm ; int do_norefit = (flags & CONFORM_NOREFIT) ; int do_rewrite = (flags & CONFORM_REWRITE) && !do_norefit ; int do_ijkpad = (ijkpad != NULL) ; ENTRY("THD_conformist") ; /* check for good inputs */ if( ndset <= 0 || dset == NULL ) RETURN(-1) ; for( iset=0 ; iset < ndset ; iset++ ) if( !ISVALID_DSET(dset[iset]) ) RETURN(-2) ; /* check if all inputs are on the same grid (i.e., no work to do) */ for( iset=1 ; iset < ndset ; iset++ ){ if( ! EQUIV_DATAXES(dset[0]->daxes,dset[iset]->daxes) ) break ; } if( iset == ndset ){ if( do_ijkpad ){ for( iset=0 ; iset < 6*ndset ; iset++ ) ijkpad[iset] = 0 ; } RETURN(0) ; } /* construct the dataxes that encloses all the input datasets */ cx = THD_superset_dataxes( dset[0]->daxes , dset[1]->daxes ) ; if( cx == NULL ){ ERROR_message("3dConformist: '%s' and '%s' aren't compatible", DSET_HEADNAME(dset[0]) , DSET_HEADNAME(dset[1]) ) ; RETURN(-3) ; } for( iset=2 ; iset < ndset ; iset++ ){ dx = THD_superset_dataxes( cx , dset[iset]->daxes ) ; if( dx == NULL ){ ERROR_message("3dConformist: '%s' is not compatible with others", DSET_HEADNAME(dset[iset]) ) ; myXtFree(cx) ; RETURN(-3) ; } myXtFree(cx) ; cx = dx ; dx = NULL ; } /* now, re-create and re-write all datasets */ if( do_rewrite ) fprintf(stderr," + thd_conformist re-write loop: ") ; for( nwrit=iset=0 ; iset < ndset ; iset++ ){ if( EQUIV_DATAXES(cx,dset[iset]->daxes) ){ /* already OK */ if( do_rewrite ) fprintf(stderr,"-") ; if( do_ijkpad ) ijkpad[6*iset+0] = ijkpad[6*iset+1] = ijkpad[6*iset+2] = ijkpad[6*iset+3] = ijkpad[6*iset+4] = ijkpad[6*iset+5] = 0 ; continue ; } pm = zpadax_pm( cx->nxx , cx->xxorg , dset[iset]->daxes->nxx , dset[iset]->daxes->xxorg , cx->xxdel ) ; xpad_m = pm.i ; xpad_p = pm.j ; pm = zpadax_pm( cx->nyy , cx->yyorg , dset[iset]->daxes->nyy , dset[iset]->daxes->yyorg , cx->yydel ) ; ypad_m = pm.i ; ypad_p = pm.j ; pm = zpadax_pm( cx->nzz , cx->zzorg , dset[iset]->daxes->nzz , dset[iset]->daxes->zzorg , cx->zzdel ) ; zpad_m = pm.i ; zpad_p = pm.j ; if( do_ijkpad ){ ijkpad[6*iset+0] = xpad_m; ijkpad[6*iset+1] = xpad_p; ijkpad[6*iset+2] = ypad_m; ijkpad[6*iset+3] = ypad_p; ijkpad[6*iset+4] = zpad_m; ijkpad[6*iset+5] = zpad_p; } if( do_norefit ) continue ; /* just wanted ijkpad, I guess */ qset = THD_zeropad( dset[iset] , xpad_m,xpad_p , ypad_m,ypad_p , zpad_m,zpad_p , "BertieWooster" , ZPAD_PURGE | ZPAD_IJK ) ; if( qset == NULL ){ /* this should never happen */ if( do_rewrite ) fprintf(stderr,"\n") ; ERROR_message("thd_conformist: skipping dataset %s", DSET_HEADNAME(dset[iset])) ; continue ; } qset->idcode = dset[iset]->idcode ; EDIT_dset_items( qset , ADN_prefix , DSET_PREFIX(dset[iset]) , ADN_none ) ; if( do_rewrite ){ THD_delete_3dim_dataset( dset[iset] , True ) ; DSET_overwrite(qset) ; DSET_unload(qset) ; fprintf(stderr,"+") ; } else { THD_delete_3dim_dataset( dset[iset] , False ) ; } dset[iset] = qset ; nwrit++ ; } if( do_rewrite ) fprintf(stderr,"\n") ; RETURN(nwrit) ; }
int main( int argc , char * argv[] ) { int iarg=1 , dcode=0 , maxgap=2 , nftot=0 ; char * prefix="zfillin" , * dstr=NULL; THD_3dim_dataset * inset , * outset ; MRI_IMAGE * brim ; int verb=0 ; if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dZFillin [options] dataset\n" "Extracts 1D rows in the given direction from a 3D dataset,\n" "searches for zeros that are 'close' to nonzero values in the row,\n" "and replaces the zeros with the closest nonzero neighbor.\n" "\n" "OPTIONS:\n" " -maxstep N = set the maximum distance to a neighbor\n" " [default=2].\n" " -dir D = set the direction of fill to 'D', which can\n" " be one of the following:\n" " A-P, P-A, I-S, S-I, L-R, R-L, x, y, z\n" " The first 6 are anatomical directions;\n" " the last 3 are reference to the dataset\n" " internal axes [no default value].\n" " -prefix P = set the prefix to 'P' for the output dataset.\n" "\n" "N.B.: * If the input dataset has more than one sub-brick,\n" " only the first one will be processed.\n" " * At this time, 3dZFillin only works on byte-valued datasets\n" "\n" "This program's only purpose is to fill up the Talairach Daemon\n" "bricks obtained from the UT San Antonio database.\n" "\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dZFillin main") ; machdep() ; AFNI_logger("3dZfillin",argc,argv) ; PRINT_VERSION(3dZFillin") ; /*-- scan args --*/ while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-verb",5) == 0 ){ verb++ ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ){ fprintf(stderr,"*** Illegal string after -prefix!\n"); exit(1) ; } iarg++ ; continue ; } if( strcmp(argv[iarg],"-maxstep") == 0 ){ maxgap = strtol( argv[++iarg] , NULL , 10 ) ; if( maxgap < 1 ){ fprintf(stderr,"*** Illegal value after -maxgap!\n"); exit(1); } iarg++ ; continue ; } if( strcmp(argv[iarg],"-dir") == 0 ){ dstr = argv[++iarg] ; iarg++ ; continue ; } fprintf(stderr,"*** Illegal option: %s\n",argv[iarg]) ; exit(1) ; } if( dstr == NULL ){ fprintf(stderr,"*** No -dir option on command line!\n"); exit(1); } if( iarg >= argc ){ fprintf(stderr,"*** No input dataset on command line!\n"); exit(1); } inset = THD_open_dataset( argv[iarg] ) ; if( inset == NULL ){ fprintf(stderr,"*** Can't open dataset %s\n",argv[iarg]); exit(1); } outset = EDIT_empty_copy( inset ) ; EDIT_dset_items( outset , ADN_prefix , prefix , ADN_none ) ; if( THD_deathcon() && THD_is_file( DSET_HEADNAME(outset) ) ){ fprintf(stderr,"** Output file %s exists -- cannot overwrite!\n", DSET_HEADNAME(outset) ) ; exit(1) ; } tross_Copy_History( inset , outset ) ; tross_Make_History( "3dZFillin" , argc,argv , outset ) ; if( DSET_NVALS(inset) > 1 ){ fprintf(stderr,"++ WARNING: input dataset has more than one sub-brick!\n"); EDIT_dset_items( outset , ADN_ntt , 0 , ADN_nvals , 1 , ADN_none ) ; } if( DSET_BRICK_TYPE(outset,0) != MRI_byte ){ fprintf(stderr,"*** This program only works on byte datasets!\n"); exit(1) ; } switch( *dstr ){ case 'x': dcode = 1 ; break ; case 'y': dcode = 2 ; break ; case 'z': dcode = 3 ; break ; default: if( *dstr == ORIENT_tinystr[outset->daxes->xxorient][0] || *dstr == ORIENT_tinystr[outset->daxes->xxorient][1] ) dcode = 1 ; if( *dstr == ORIENT_tinystr[outset->daxes->yyorient][0] || *dstr == ORIENT_tinystr[outset->daxes->yyorient][1] ) dcode = 2 ; if( *dstr == ORIENT_tinystr[outset->daxes->zzorient][0] || *dstr == ORIENT_tinystr[outset->daxes->zzorient][1] ) dcode = 3 ; break ; } if( dcode == 0 ){ fprintf(stderr,"*** Illegal -dir direction!\n") ; exit(1) ; } if( verb ) fprintf(stderr,"++ Direction = axis %d in dataset\n",dcode) ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; brim = mri_copy( DSET_BRICK(inset,0) ) ; DSET_unload(inset) ; EDIT_substitute_brick( outset , 0 , brim->kind , mri_data_pointer(brim) ) ; nftot = THD_dataset_zfillin( outset , 0 , dcode , maxgap ) ; fprintf(stderr,"++ Number of voxels filled = %d\n",nftot) ; if (DSET_write(outset) != False) { fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ; exit(0) ; } else { fprintf(stderr, "** 3dZFillin: Failed to write output!\n" ) ; exit(1) ; } }
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; }