int main( int argc , char * argv[] ) { void (*smth)(int,float *) = linear3_func ; /* default filter */ char prefix[256] = "smooth" ; int new_datum = ILLEGAL_TYPE , old_datum ; int nopt ; THD_3dim_dataset * old_dset , * new_dset ; int ii,kk , nxyz , ntime , use_fac , ityp , nbytes ; void * new_brick ; byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ byte ** new_bptr = NULL ; /* one of these will be the array of */ short ** new_sptr = NULL ; /* pointers to output dataset sub-bricks */ float ** new_fptr = NULL ; /* (depending on output datum type) */ float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * faci = NULL ; #define BLACKMAN 1 #define HAMMING 2 #define CUSTOM 3 #define EXTEND 77 #define ZERO 78 #define TREND 79 int ntap=0 ; /* 01 Mar 2001 */ float *ftap=NULL ; int nwin=0,nfil=EXTEND ; /* 03 Mar 2001 */ void (*lfil)(int,float *,int,float *) = linear_filter_extend ; float * (*lwin)(int) = NULL ; /* start of code */ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dTsmooth [options] dataset\n" "Smooths each voxel time series in a 3D+time dataset and produces\n" "as output a new 3D+time dataset (e.g., lowpass filter in time).\n" "\n" "*** Also see program 3dBandpass ***\n" "\n" "General Options:\n" " -prefix ppp = Sets the prefix of the output dataset to be 'ppp'.\n" " [default = 'smooth']\n" " -datum type = Coerce output dataset to be stored as the given type.\n" " [default = input data type]\n" "\n" "Three Point Filtering Options [07 July 1999]\n" "--------------------------------------------\n" "The following options define the smoothing filter to be used.\n" "All these filters use 3 input points to compute one output point:\n" " Let a = input value before the current point\n" " b = input value at the current point\n" " c = input value after the current point\n" " [at the left end, a=b; at the right end, c=b]\n" "\n" " -lin = 3 point linear filter: 0.15*a + 0.70*b + 0.15*c\n" " [This is the default smoother]\n" " -med = 3 point median filter: median(a,b,c)\n" " -osf = 3 point order statistics filter:\n" " 0.15*min(a,b,c) + 0.70*median(a,b,c) + 0.15*max(a,b,c)\n" "\n" " -3lin m = 3 point linear filter: 0.5*(1-m)*a + m*b + 0.5*(1-m)*c\n" " Here, 'm' is a number strictly between 0 and 1.\n" "\n" "General Linear Filtering Options [03 Mar 2001]\n" "----------------------------------------------\n" " -hamming N = Use N point Hamming or Blackman windows.\n" " -blackman N (N must be odd and bigger than 1.)\n" " -custom coeff_filename.1D (odd # of coefficients must be in a \n" " single column in ASCII file)\n" " (-custom added Jan 2003)\n" " WARNING: If you use long filters, you do NOT want to include the\n" " large early images in the program. Do something like\n" " 3dTsmooth -hamming 13 'fred+orig[4..$]'\n" " to eliminate the first 4 images (say).\n" " The following options determing how the general filters treat\n" " time points before the beginning and after the end:\n" " -EXTEND = BEFORE: use the first value; AFTER: use the last value\n" " -ZERO = BEFORE and AFTER: use zero\n" " -TREND = compute a linear trend, and extrapolate BEFORE and AFTER\n" " The default is -EXTEND. These options do NOT affect the operation\n" " of the 3 point filters described above, which always use -EXTEND.\n" ) ; printf("\n" MASTER_SHORTHELP_STRING ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dTsmooth main"); machdep(); AFNI_logger("3dTsmooth",argc,argv); PRINT_VERSION("3dTsmooth") ; /* parse options */ nopt = 1 ; while( nopt < argc && argv[nopt][0] == '-' ){ if( strcmp(argv[nopt],"-EXTEND") == 0 ){ /* 03 Mar 2001 */ nfil = EXTEND ; lfil = linear_filter_extend ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-ZERO") == 0 ){ /* 03 Mar 2001 */ nfil = ZERO ; lfil = linear_filter_zero ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-TREND") == 0 ){ /* 03 Mar 2001 */ nfil = TREND ; lfil = linear_filter_trend ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-hamming") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -hamming!\n");exit(1);} ntap = (int) strtod(argv[nopt],NULL) ; if( ntap < 3 || ntap%2 != 1 ){fprintf(stderr,"*** Illegal -hamming!\n");exit(1);} nwin = HAMMING ; lwin = hamming_window ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-blackman") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -blackman!\n");exit(1);} ntap = (int) strtod(argv[nopt],NULL) ; if( ntap < 3 || ntap%2 != 1 ){fprintf(stderr,"*** Illegal -blackman!\n");exit(1);} nwin = BLACKMAN ; lwin = blackman_window ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-custom") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -custom!\n");exit(1);} strcpy(custom_file, argv[nopt]) ; nwin = CUSTOM ; lwin = custom_filter ; ntap = 1; nopt++ ; continue ; } if( strcmp(argv[nopt],"-prefix") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -prefix!\n");exit(1);} strcpy(prefix,argv[nopt]) ; if( !THD_filename_ok(prefix) ){fprintf(stderr,"*** Illegal -prefix!\n");exit(1);} nopt++ ; continue ; } if( strcmp(argv[nopt],"-datum") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -datum!\n");exit(1);} if( strcmp(argv[nopt],"short") == 0 ){ new_datum = MRI_short ; } else if( strcmp(argv[nopt],"float") == 0 ){ new_datum = MRI_float ; } else if( strcmp(argv[nopt],"byte") == 0 ){ new_datum = MRI_byte ; } else { fprintf(stderr,"*** Illegal -datum!\n");exit(1); } nopt++ ; continue ; } if( strcmp(argv[nopt],"-lin") == 0 ){ bf = 0.70 ; af = cf = 0.15 ; smth = linear3_func ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-med") == 0 ){ smth = median3_func ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-osf") == 0 ){ smth = osfilt3_func ; nopt++ ; continue ; } if( strcmp(argv[nopt],"-3lin") == 0 ){ if( ++nopt >= argc ){fprintf(stderr,"*** Illegal -3lin!\n");exit(1);} bf = strtod( argv[nopt] , NULL ) ; if( bf <= 0.0 || bf >= 1.0 ){fprintf(stderr,"*** Illegal -3lin!\n");exit(1);} af = cf = 0.5*(1.0-bf) ; smth = linear3_func ; nopt++ ; continue ; } fprintf(stderr,"*** Unknown option: %s\n",argv[nopt]) ; exit(1) ; } /* end of loop over options */ if( nopt >= argc ){ fprintf(stderr,"*** No input dataset?!\n") ; exit(1) ; } /* open dataset */ old_dset = THD_open_dataset( argv[nopt] ) ; if( old_dset == NULL ){ fprintf(stderr,"*** Can't open dataset %s\n",argv[nopt]) ; exit(1) ; } ntime = DSET_NVALS(old_dset) ; nxyz = DSET_NVOX(old_dset) ; if( ntime < 4 ){ fprintf(stderr,"*** Can't smooth dataset with less than 4 time points!\n") ; exit(1) ; } DSET_load(old_dset) ; CHECK_LOAD_ERROR(old_dset) ; old_datum = DSET_BRICK_TYPE(old_dset,0) ; if( new_datum < 0 ) new_datum = old_datum ; switch( old_datum ){ /* pointer type depends on input datum type */ /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nxyz-1 and k=0..ntime-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * ntime ) ; for( kk=0 ; kk < ntime ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nxyz-1 and k=0..ntime-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * ntime ) ; for( kk=0 ; kk < ntime ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nxyz-1 and k=0..ntime-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * ntime ) ; for( kk=0 ; kk < ntime ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk) ; break ; } /* end of switch on input type */ /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * ntime ) ; /* voxel timeseries */ /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * ntime ) ; /* factors */ use_fac = 0 ; for( kk=0 ; kk < ntime ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ){ free(fac) ; fac == NULL ; } else { faci = (float *) malloc( sizeof(float) * ntime ) ; for( kk=0 ; kk < ntime ; kk++ ) faci[kk] = 1.0 / fac[kk] ; } /*---------------------- make a new dataset ----------------------*/ new_dset = EDIT_empty_copy( old_dset ) ; tross_Copy_History( old_dset , new_dset ) ; tross_Make_History( "3dTsmooth" , argc,argv , new_dset ) ; /*-- edit some of its internal parameters --*/ EDIT_dset_items( new_dset , ADN_prefix , prefix , ADN_malloc_type , DATABLOCK_MEM_MALLOC , ADN_datum_all , new_datum , ADN_none ) ; /*-- make brick(s) for this dataset --*/ switch( new_datum ){ case MRI_byte: new_bptr = (byte **) malloc( sizeof(byte *) * ntime ) ; break ; case MRI_short: new_sptr = (short **) malloc( sizeof(short *) * ntime ) ; break ; case MRI_float: new_fptr = (float **) malloc( sizeof(float *) * ntime ) ; break ; } for( kk=0 ; kk < ntime ; kk++ ){ ityp = DSET_BRICK_TYPE(new_dset,kk) ; /* type of data */ nbytes = DSET_BRICK_BYTES(new_dset,kk) ; /* how much data */ new_brick = malloc( nbytes ) ; /* make room */ if( new_brick == NULL ){ fprintf(stderr,"*** Can't get memory for output dataset!\n") ; exit(1) ; } EDIT_substitute_brick( new_dset , kk , ityp , new_brick ) ; switch( new_datum ){ case MRI_byte: new_bptr[kk] = (byte * ) new_brick ; break ; case MRI_short: new_sptr[kk] = (short *) new_brick ; break ; case MRI_float: new_fptr[kk] = (float *) new_brick ; break ; } } if( lwin != NULL && ntap > 0 ){ /* 03 Mar 2001 */ ftap = lwin(ntap) ; if( lfil == NULL ) lfil = linear_filter_extend ; if( nwin == CUSTOM ) ntap = custom_ntaps ; } /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /***** loop over voxels *****/ for( ii=0 ; ii < nxyz ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ case MRI_byte: for( kk=0 ; kk < ntime ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; case MRI_short: for( kk=0 ; kk < ntime ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; case MRI_float: for( kk=0 ; kk < ntime ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; } /* end of switch over input type */ if( use_fac ) for( kk=0 ; kk < ntime ; kk++ ) fxar[kk] *= fac[kk] ; /* do smoothing */ if( ftap != NULL ) lfil( ntap,ftap , ntime,fxar ) ; /* 01 Mar 2001 */ else smth( ntime , fxar ) ; /* 3 point smoother */ /*** put data into output dataset ***/ switch( new_datum ){ case MRI_byte: if( use_fac ) for( kk=0 ; kk < ntime ; kk++ ) new_bptr[kk][ii] = (byte)(fxar[kk] * faci[kk]) ; else for( kk=0 ; kk < ntime ; kk++ ) new_bptr[kk][ii] = (byte) fxar[kk] ; break ; case MRI_short: if( use_fac ) for( kk=0 ; kk < ntime ; kk++ ) new_sptr[kk][ii] = (short)(fxar[kk] * faci[kk]) ; else for( kk=0 ; kk < ntime ; kk++ ) new_sptr[kk][ii] = (short) fxar[kk] ; break ; case MRI_float: if( use_fac ) for( kk=0 ; kk < ntime ; kk++ ) new_fptr[kk][ii] = (float)(fxar[kk] * faci[kk]) ; else for( kk=0 ; kk < ntime ; kk++ ) new_fptr[kk][ii] = (float) fxar[kk] ; break ; } } /* end of loop over voxels */ DSET_unload(old_dset) ; free(ftap) ; if (DSET_write(new_dset) != False) { fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(new_dset)) ; exit(0) ; } else { fprintf(stderr, "** 3dTsmooth: Failed to write output!\n" ) ; exit(1) ; } }
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 iarg , nvox=0 , iv,ii,cnum , verb=1 ; int automask=1 ; /* allow masks as input 14 Jul 2010 [rickr] */ THD_3dim_dataset *aset , *bset ; byte *amm , *bmm ; int naa , nbb , nabu,nabi , naout , nbout ; float paout , pbout , xrat,yrat,zrat ; float_triple axyz , bxyz ; /*-- read command line arguments --*/ if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ){ printf( "Usage: 3dABoverlap [options] A B\n" "Output (to screen) is a count of various things about how\n" "the automasks of datasets A and B overlap or don't overlap.\n" "\n" "* Dataset B will be resampled to match dataset A, if necessary,\n" " which will be slow if A is high resolution. In such a case,\n" " you should only use one sub-brick from dataset B.\n" " ++ The resampling of B is done before the automask is generated.\n" "* The values output are labeled thusly:\n" " #A = number of voxels in the A mask\n" " #B = number of voxels in the B mask\n" " #(A uni B) = number of voxels in the either or both masks (set union)\n" " #(A int B) = number of voxels present in BOTH masks (set intesection)\n" " #(A \\ B) = number of voxels in A mask that aren't in B mask\n" " #(B \\ A) = number of voxels in B mask that arent' in A mask\n" " %%(A \\ B) = percentage of voxels from A mask that aren't in B mask\n" " %%(B \\ A) = percentage of voxels from B mask that aren't in A mask\n" " Rx(B/A) = radius of gyration of B mask / A mask, in x direction\n" " Ry(B/A) = radius of gyration of B mask / A mask, in y direction\n" " Rz(B/A) = radius of gyration of B mask / A mask, in z direction\n" "* If B is an EPI dataset sub-brick, and A is a skull stripped anatomical\n" " dataset, then %%(B \\ A) might be useful for assessing if the EPI\n" " brick B is grossly misaligned with respect to the anatomical brick A.\n" "* The radius of gyration ratios might be useful for determining if one\n" " dataset is grossly larger or smaller than the other.\n" "\n" "OPTIONS\n" "-------\n" " -no_automask = consider input datasets as masks\n" " (automask does not work on mask datasets)\n" " -quiet = be as quiet as possible (without being entirely mute)\n" " -verb = print out some progress reports (to stderr)\n" "\n" "NOTES\n" "-----\n" " * If an input dataset is comprised of bytes and contains only one\n" " sub-brick, then this program assumes it is already an automask-\n" " generated dataset and the automask operation will be skipped.\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } iarg = 1 ; /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ /* check options */ while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-verb") == 0 ){ verb++ ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-quiet") == 0 ){ verb = 0 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-no_automask") == 0 ){ automask = 0 ; iarg++ ; continue ; } ERROR_exit("Illegal option: %s",argv[iarg]) ; } mainENTRY("3dOverlap main") ; machdep() ; if( verb ) PRINT_VERSION("3dOverlap") ; AFNI_logger("3dOverlap",argc,argv) ; /* input datasets */ if( iarg+1 >= argc ) ERROR_exit("Need 2 input datasets on command line") ; aset = THD_open_dataset(argv[iarg]) ; CHECK_OPEN_ERROR(aset,argv[iarg]) ; iarg++ ; bset = THD_open_dataset(argv[iarg]) ; CHECK_OPEN_ERROR(bset,argv[iarg]) ; iarg++ ; nvox = DSET_NVOX(aset) ; if( !EQUIV_GRIDS(aset,bset) ){ /** must resample **/ THD_3dim_dataset *cset ; if( verb ) INFO_message("resampling dataset B to match dataset A") ; cset = r_new_resam_dset( bset, aset, 0.0,0.0,0.0,NULL, MRI_BILINEAR, NULL, 1, 0 ) ; DSET_delete(bset) ; bset = cset ; } if( iarg < argc ) WARNING_message("Extra arguments?") ; DSET_load(aset); CHECK_LOAD_ERROR(aset); DSET_load(bset); CHECK_LOAD_ERROR(bset); /* 10 Aug 2009: keep input datasets without automask, if appropriate */ if( DSET_NVALS(aset) > 1 || DSET_BRICK_TYPE(aset,0) != MRI_byte ){ /* allow masks as input (via -no_automask) 14 Jul 2010 [rickr] */ if( automask ) amm = THD_automask(aset); else amm = THD_makemask(aset, 0, 1, 0); /* use any non-zero */ DSET_unload(aset); } else { amm = DSET_BRICK_ARRAY(aset,0) ; } if( DSET_NVALS(bset) > 1 || DSET_BRICK_TYPE(bset,0) != MRI_byte ){ /* allow masks as input (via -no_automask) 14 Jul 2010 [rickr] */ if( automask ) bmm = THD_automask(bset); else bmm = THD_makemask(bset, 0, 1, 0); /* use any non-zero */ DSET_unload(bset); } else { bmm = DSET_BRICK_ARRAY(bset,0) ; } naa = mask_count ( nvox , amm ) ; nbb = mask_count ( nvox , bmm ) ; nabi = mask_intersect_count( nvox , amm , bmm ) ; nabu = mask_union_count ( nvox , amm , bmm ) ; naout = naa - nabi ; nbout = nbb - nabi ; paout = (naa > 0) ? naout/(float)naa : 0.0f ; pbout = (nbb > 0) ? nbout/(float)nbb : 0.0f ; axyz = mask_rgyrate( DSET_NX(aset),DSET_NY(aset),DSET_NZ(aset) , amm ) ; bxyz = mask_rgyrate( DSET_NX(bset),DSET_NY(bset),DSET_NZ(bset) , bmm ) ; xrat = (axyz.a > 0.0f && bxyz.a > 0.0f) ? bxyz.a / axyz.a : 0.0f ; yrat = (axyz.b > 0.0f && bxyz.b > 0.0f) ? bxyz.b / axyz.b : 0.0f ; zrat = (axyz.c > 0.0f && bxyz.c > 0.0f) ? bxyz.c / axyz.c : 0.0f ; if( verb ) printf("#A=%s B=%s\n",DSET_BRIKNAME(aset),DSET_BRIKNAME(bset)) ; if( verb ) printf("#A #B #(A uni B) #(A int B) " "#(A \\ B) #(B \\ A) %%(A \\ B) %%(B \\ A) " "Rx(B/A) Ry(B/A) Rz(B/A)\n") ; printf("%-12d %-12d %-12d %-12d %-12d %-12d %7.4f %7.4f %7.4f %7.4f %7.4f\n", naa , nbb , nabu, nabi, naout,nbout,100.0f*paout,100.0f*pbout, xrat,yrat,zrat ) ; exit(0) ; }
int main (int argc, char *argv[]) { THD_3dim_dataset *old_dset, *new_dset, *I0_dset; /* input and output datasets */ int nopt, nbriks, nvox; int i; MRI_IMAGE *grad1Dptr = NULL; MRI_IMAGE *anat_im = NULL; MRI_IMAGE *data_im = NULL; double fac; short *sar = NULL, *tempsptr = NULL, tempval; byte *maskptr = NULL, *tempbptr = NULL; char tempstr[25]; /*----- Read command line -----*/ if (argc < 2 || strcmp (argv[1], "-help") == 0) { printf ("Usage: 3dDTtoDWI [options] gradient-file I0-dataset DT-dataset\n" "Computes multiple gradient images from 6 principle direction tensors and\n" " corresponding gradient vector coordinates applied to the I0-dataset.\n" " The program takes three parameters as input : \n" " a 1D file of the gradient vectors with lines of ASCII floats Gxi,Gyi,Gzi.\n" " Only the non-zero gradient vectors are included in this file (no G0 line).\n" " The I0 dataset is a volume without any gradient applied.\n" " The DT dataset is the 6-sub-brick dataset containing the diffusion tensor data,\n" " Dxx, Dxy, Dyy, Dxz, Dyz, Dzz (lower triangular row-wise order)\n" " Options:\n" " -prefix pname = Use 'pname' for the output dataset prefix name.\n" " [default='DWI']\n" " -automask = mask dataset so that the gradient images are computed only for\n" " high-intensity (presumably brain) voxels. The intensity level is\n" " determined the same way that 3dClipLevel works.\n\n" " -datum type = output dataset type [float/short/byte] (default is float).\n" " -help = show this help screen.\n" " Example:\n" " 3dDTtoDWI -prefix DWI -automask tensor25.1D 'DT+orig[26]' DT+orig.\n\n" " The output is a n sub-brick bucket dataset containing computed DWI images.\n" " where n is the number of vectors in the gradient file + 1\n" "\n"); printf ("\n" MASTER_SHORTHELP_STRING); exit (0); } mainENTRY ("3dDTtoDWI main"); machdep (); AFNI_logger ("3dDTtoDWI", argc, argv); PRINT_VERSION("3dDTtoDWI") ; nopt = 1; datum = MRI_float; while (nopt < argc && argv[nopt][0] == '-') { /*-- prefix --*/ if (strcmp (argv[nopt], "-prefix") == 0) { if (++nopt >= argc) { fprintf (stderr, "*** Error - prefix needs an argument!\n"); exit (1); } MCW_strncpy (prefix, argv[nopt], THD_MAX_PREFIX); /* change name from default prefix */ /* check file name to be sure not to overwrite - mod drg 12/9/2004 */ if (!THD_filename_ok (prefix)) { fprintf (stderr, "*** Error - %s is not a valid prefix!\n", prefix); exit (1); } nopt++; continue; } /*-- datum --*/ if (strcmp (argv[nopt], "-datum") == 0) { if (++nopt >= argc) { fprintf (stderr, "*** Error - datum needs an argument!\n"); exit (1); } if (strcmp (argv[nopt], "short") == 0) { datum = MRI_short; } else if (strcmp (argv[nopt], "float") == 0) { datum = MRI_float; } else if (strcmp (argv[nopt], "byte") == 0) { datum = MRI_byte; } else { fprintf (stderr, "-datum of type '%s' is not supported!\n", argv[nopt]); exit (1); } nopt++; continue; } if (strcmp (argv[nopt], "-automask") == 0) { automask = 1; nopt++; continue; } fprintf(stderr, "*** Error - unknown option %s\n", argv[nopt]); exit(1); } /*----- read input datasets -----*/ if (nopt >= argc) { fprintf (stderr, "*** Error - No input dataset!?\n"); exit (1); } /* first input dataset - should be gradient vector file of ascii floats Gx,Gy,Gz */ /* read gradient vector 1D file */ grad1Dptr = mri_read_1D (argv[nopt]); if (grad1Dptr == NULL) { fprintf (stderr, "*** Error reading gradient vector file\n"); exit (1); } if (grad1Dptr->ny != 3) { fprintf (stderr, "*** Error - Only 3 columns of gradient vectors allowed\n"); fprintf (stderr, "%d columns found\n", grad1Dptr->nx); mri_free (grad1Dptr); exit (1); } if (grad1Dptr->nx < 6) { fprintf (stderr, "*** Error - Must have at least 6 gradient vectors\n"); fprintf (stderr, "%d columns found\n", grad1Dptr->nx); mri_free (grad1Dptr); exit (1); } nbriks = grad1Dptr->nx + 1; /* number of gradients specified here from file */ nopt++; /* open I0 dataset - idealized no gradient image */ I0_dset = THD_open_dataset (argv[nopt]); CHECK_OPEN_ERROR(I0_dset,argv[nopt]) ; DSET_mallocize (I0_dset); DSET_load (I0_dset); /* load dataset */ data_im = DSET_BRICK (I0_dset, 0); /* set pointer to the 0th sub-brik of the dataset */ fac = DSET_BRICK_FACTOR(I0_dset, 0); /* get scale factor for each sub-brik*/ if(fac==0.0) fac=1.0; if((data_im->kind != MRI_float)) { fprintf (stderr, "*** Error - Can only open float datasets. Use 3dcalc to convert.\n"); mri_free (grad1Dptr); mri_free (data_im); exit (1); } I0_ptr = mri_data_pointer(data_im) ; /* pointer to I0 data */ nopt++; /* Now read in all the MRI volumes for each gradient vector */ /* assumes first one is no gradient */ old_dset = THD_open_dataset (argv[nopt]); CHECK_OPEN_ERROR(old_dset,argv[nopt]) ; /* expect at least 6 values per voxel - 6 sub-briks as input dataset */ if (DSET_NVALS (old_dset) <6) { fprintf (stderr, "*** Error - Dataset must have at least 6 sub-briks to describe the diffusion tensor\n"); mri_free (grad1Dptr); mri_free (data_im); exit (1); } InitGlobals (grad1Dptr->nx + 1); /* initialize all the matrices and vectors */ Computebmatrix (grad1Dptr, BMAT_NZ); /* compute bij=GiGj */ INFO_message("The maximum magnitude of the bmatrix appears to be: %.2f", MAX_BVAL); if (automask) { DSET_mallocize (old_dset); DSET_load (old_dset); /* get B0 (anatomical image) from dataset */ /*anat_im = THD_extract_float_brick( 0, old_dset ); */ anat_im = DSET_BRICK (old_dset, 0); /* set pointer to the 0th sub-brik of the dataset */ maskptr = mri_automask_image (anat_im); /* maskptr is a byte pointer for volume */ /* convert byte mask to same format type as dataset */ nvox = DSET_NVOX (old_dset); sar = (short *) calloc (nvox, sizeof (short)); /* copy maskptr values to far ptr */ tempsptr = sar; tempbptr = maskptr; for (i = 0; i < nvox; i++) { *tempsptr++ = (short) *tempbptr++; tempval = *(tempsptr - 1); } free (maskptr); /*old_dset->dblk->malloc_type = DATABLOCK_MEM_MALLOC; *//* had to set this? */ EDIT_add_brick (old_dset, MRI_short, 0.0, sar); /* add sub-brik to end */ } /* temporarily set artificial timing to 1 second interval */ EDIT_dset_items (old_dset, ADN_ntt, DSET_NVALS (old_dset), ADN_ttorg, 0.0, ADN_ttdel, 1.0, ADN_tunits, UNITS_SEC_TYPE, NULL); /*------------- ready to compute new dataset -----------*/ new_dset = MAKER_4D_to_typed_fbuc (old_dset, /* input dataset */ prefix, /* output prefix */ datum, /* output datum */ 0, /* ignore count */ 0, /* can't detrend in maker function KRH 12/02 */ nbriks, /* number of briks */ DTtoDWI_tsfunc, /* timeseries processor */ NULL, /* data for tsfunc */ NULL, /* mask */ 0 /* Allow auto scaling of output */ ); FreeGlobals (); mri_free (grad1Dptr); if (automask) { mri_free (anat_im); DSET_unload_one (old_dset, 0); sar = NULL; } if (new_dset != NULL) { tross_Copy_History (old_dset, new_dset); for(i=0;i<nbriks;i++) { sprintf(tempstr,"grad%3.3d", i); EDIT_dset_items (new_dset, ADN_brick_label_one + i, tempstr, ADN_none); } tross_Make_History ("3dDTtoDWI", argc, argv, new_dset); DSET_write (new_dset); fprintf(stderr,"--- Output dataset %s\n", DSET_BRIKNAME(new_dset)); } else { fprintf (stderr, "*** Error - Unable to compute output dataset!\n"); exit (1); } exit (0); }
void UC_read_opts( int argc , char * argv[] ) { int nopt = 1 ; float val ; int kk, nxyz, mm,nn ; float * vv , * bb ; while( nopt < argc && argv[nopt][0] == '-' ){ /**** -verbose ****/ if( strncmp(argv[nopt],"-verbose",5) == 0 ){ UC_be_quiet = 0 ; nopt++ ; continue ; } /**** -prefix prefix ****/ if( strncmp(argv[nopt],"-prefix",6) == 0 ){ nopt++ ; if( nopt >= argc ) UC_syntax("-prefix needs an argument!") ; MCW_strncpy( UC_prefix , argv[nopt++] , THD_MAX_PREFIX ) ; continue ; } /**** -mask mset ****/ if( strncmp(argv[nopt],"-mask",5) == 0 ){ THD_3dim_dataset * mset ; int ii,nn ; nopt++ ; if( nopt >= argc ) UC_syntax("need arguments after -mask!") ; mset = THD_open_dataset( argv[nopt] ) ; if( mset == NULL ) UC_syntax("can't open -mask dataset!") ; UC_mask = THD_makemask( mset , 0 , 1.0,0.0 ) ; UC_mask_nvox = DSET_NVOX(mset) ; DSET_delete(mset) ; if( UC_mask == NULL ) UC_syntax("can't use -mask dataset!") ; UC_mask_hits = THD_countmask( UC_mask_nvox , UC_mask ) ; if( UC_mask_hits == 0 ) UC_syntax("mask is all zeros!") ; if( !UC_be_quiet ) printf("--- %d voxels in mask\n",UC_mask_hits) ; UC_iv = (int *) malloc( sizeof(int) * UC_mask_hits ) ; for( nn=ii=0 ; ii < UC_mask_nvox ; ii++ ) if( UC_mask[ii] ) UC_iv[nn++] = ii ; nopt++ ; continue ; } /**** -ptail p ****/ if( strcmp(argv[nopt],"-ptail") == 0 ){ if( ++nopt >= argc ) UC_syntax("-ptail needs an argument!") ; UC_ptail = strtod( argv[nopt] , NULL ) ; if( UC_ptail <= 0.0 || UC_ptail >= 0.499 ) UC_syntax("value after -ptail is illegal!") ; nopt++ ; continue ; } /**** unknown switch ****/ fprintf(stderr,"\n*** unrecognized option %s\n",argv[nopt]) ; exit(1) ; } /* end of loop over options */ /*--- a simple consistency check ---*/ /*--- last input is dataset name ---*/ if( nopt >= argc ) UC_syntax("no input dataset name?") ; UC_dset = THD_open_dataset( argv[nopt] ) ; if( !ISVALID_3DIM_DATASET(UC_dset) ){ fprintf(stderr,"\n*** can't open dataset file %s\n",argv[nopt]) ; exit(1) ; } nxyz = DSET_NVOX(UC_dset) ; if( UC_mask != NULL && nxyz != UC_mask_nvox ) UC_syntax("mask and input dataset size mismatch!") ; /*--- load vectors ---*/ UC_nvec = (UC_mask_hits > 0) ? UC_mask_hits : nxyz ; UC_vdim = DSET_NVALS(UC_dset) ; if( UC_vdim < 4 ) UC_syntax("input dataset needs at least 4 sub-bricks!") ; vv = (float *) malloc( sizeof(float) * UC_nvec * UC_vdim ) ; UC_vec = (float **) malloc( sizeof(float *) * UC_nvec ) ; for( kk=0 ; kk < UC_nvec ; kk++ ) UC_vec[kk] = vv + (kk*UC_vdim) ; if( !UC_be_quiet ) printf("--- reading input dataset\n") ; DSET_load(UC_dset) ; CHECK_LOAD_ERROR(UC_dset) ; /* copy brick data into float storage */ if( !UC_be_quiet ) printf("--- loading vectors\n") ; bb = (float *) malloc( sizeof(float) * nxyz ) ; for( mm=0 ; mm < UC_vdim ; mm++ ){ EDIT_coerce_type( nxyz , DSET_BRICK_TYPE(UC_dset,mm) , DSET_ARRAY(UC_dset,mm) , MRI_float , bb ) ; DSET_unload_one( UC_dset , mm ) ; if( UC_mask == NULL ){ for( kk=0 ; kk < nxyz ; kk++ ) UC_vec[kk][mm] = bb[kk] ; } else { for( nn=kk=0 ; kk < nxyz ; kk++ ) if( UC_mask[kk] ) UC_vec[nn++][mm] = bb[kk] ; } } free(bb) ; DSET_unload( UC_dset ) ; /* detrend and normalize vectors */ if( !UC_be_quiet ) printf("--- normalizing vectors\n") ; for( kk=0 ; kk < UC_nvec ; kk++ ) normalize( UC_vdim , UC_vec[kk] ) ; return ; }
void DT_read_opts( int argc , char * argv[] ) { int nopt = 1 , nvals , ii , nvcheck , nerr=0 ; MRI_IMARR *slice_imar ; INIT_IMARR(DT_imar) ; INIT_IMARR(slice_imar) ; while( nopt < argc && argv[nopt][0] == '-' ){ /**** -polort p ****/ if( strncmp(argv[nopt],"-polort",6) == 0 ){ char *cpt ; nopt++ ; if( nopt >= argc ) ERROR_exit("Need argument after -polort") ; DT_polort = (int)strtod(argv[nopt],&cpt) ; if( *cpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ; if( DT_polort < 0 ) WARNING_message("Ignoring negative value after -polort") ; nopt++ ; continue ; } /**** -prefix prefix ****/ if( strncmp(argv[nopt],"-prefix",6) == 0 ){ nopt++ ; if( nopt >= argc ) ERROR_exit("Need argument after -prefix") ; MCW_strncpy( DT_output_prefix , argv[nopt] , THD_MAX_PREFIX ) ; if( !THD_filename_ok(DT_output_prefix) ) ERROR_exit("bad name '%s' after -prefix",argv[nopt]) ; nopt++ ; continue ; } /**** -session directory ****/ if( strncmp(argv[nopt],"-session",6) == 0 ){ nopt++ ; if( nopt >= argc ) ERROR_exit("Need argument after -session") ; MCW_strncpy( DT_session , argv[nopt] , THD_MAX_NAME ) ; if( !THD_filename_ok(DT_session) ) ERROR_exit("bad name '%s' after -session",argv[nopt]) ; nopt++ ; continue ; } /**** -verb ****/ if( strncmp(argv[nopt],"-verb",5) == 0 ){ DT_verb++ ; nopt++ ; continue ; } /**** -replace ****/ if( strncmp(argv[nopt],"-replace",5) == 0 ){ DT_replace++ ; nopt++ ; continue ; } /**** -byslice [08 Dec 1999] ****/ if( strncmp(argv[nopt],"-byslice",5) == 0 ){ #ifdef ALLOW_BYSLICE if( IMARR_COUNT(slice_imar) > 0 ) ERROR_exit("can't mix -byslice and -slicevector") ; DT_byslice++ ; nopt++ ; continue ; #else ERROR_exit("-byslice is no longer suppported") ; #endif } /**** -normalize [23 Nov 1999] ****/ if( strncmp(argv[nopt],"-normalize",5) == 0 ){ DT_norm++ ; nopt++ ; continue ; } /**** -vector ****/ if( strncmp(argv[nopt],"-vector",4) == 0 ){ MRI_IMAGE * flim ; nopt++ ; if( nopt >= argc ) ERROR_exit("need argument after -vector") ; flim = mri_read_1D( argv[nopt++] ) ; if( flim == NULL ) ERROR_exit("can't read -vector '%s'",argv[nopt-1]) ; ADDTO_IMARR(DT_imar,flim) ; if( DT_verb ) INFO_message("Read file %s: rows=%d cols=%d", argv[nopt-1],flim->ny,flim->nx ) ; continue ; } /**** -slicevector ****/ if( strncmp(argv[nopt],"-slicevector",6) == 0 ){ MRI_IMAGE *flim ; nopt++ ; if( nopt >= argc ) ERROR_exit("need argument after -slicevector") ; #ifdef ALLOW_BYSLICE if( DT_byslice ) ERROR_exit("can't mix -slicevector and -byslice") ; #endif flim = mri_read_1D( argv[nopt++] ) ; if( flim == NULL ) ERROR_exit("can't read -slicevector '%s'",argv[nopt-1]) ; ADDTO_IMARR(slice_imar,flim) ; if( DT_verb ) INFO_message("Read file %s: rows=%d cols=%d", argv[nopt-1],flim->ny,flim->nx ) ; continue ; } /**** -del ****/ if( strncmp(argv[nopt],"-del",4) == 0 ){ nopt++ ; if( nopt >= argc ) ERROR_exit("need argument after -del") ; DT_current_del = strtod( argv[nopt++] , NULL ) ; if( DT_verb ) INFO_message("Set expression stepsize = %g\n",DT_current_del) ; continue ; } /**** -expr ****/ if( strncmp(argv[nopt],"-expr",4) == 0 ){ int nexp , qvar , kvar ; char sym[4] ; nopt++ ; if( nopt >= argc ) ERROR_exit("need argument after -expr") ; nexp = DT_exnum + 1 ; if( DT_exnum == 0 ){ /* initialize storage */ DT_expr = (char **) malloc( sizeof(char *) ) ; DT_excode = (PARSER_code **) malloc( sizeof(PARSER_code *) ) ; DT_exdel = (float *) malloc( sizeof(float) ) ; DT_exvar = (int *) malloc( sizeof(int) ) ; } else { DT_expr = (char **) realloc( DT_expr , sizeof(char *)*nexp ) ; DT_excode = (PARSER_code **) realloc( DT_excode , sizeof(PARSER_code *)*nexp ) ; DT_exdel = (float *) realloc( DT_exdel , sizeof(float)*nexp) ; DT_exvar = (int *) realloc( DT_exvar , sizeof(int)*nexp) ; } DT_expr[DT_exnum] = argv[nopt] ; /* string */ DT_exdel[DT_exnum] = DT_current_del ; /* delta */ DT_excode[DT_exnum] = PARSER_generate_code( argv[nopt] ) ; /* compile */ if( DT_excode[DT_exnum] == NULL ) ERROR_exit("Illegal expression: '%s'",argv[nopt]) ; qvar = 0 ; kvar = -1 ; /* find symbol */ for( ii=0 ; ii < 26 ; ii++ ){ sym[0] = 'A' + ii ; sym[1] = '\0' ; if( PARSER_has_symbol(sym,DT_excode[DT_exnum]) ){ qvar++ ; if( kvar < 0 ) kvar = ii ; if( DT_verb ) INFO_message("Found expression symbol %s\n",sym) ; } } if( qvar > 1 ) ERROR_exit("-expr '%s' has too many symbols",DT_expr[DT_exnum]) ; else if( qvar == 0 ) WARNING_message("-expr '%s' is constant",DT_expr[DT_exnum]) ; DT_exvar[DT_exnum] = kvar ; DT_exnum = nexp ; nopt++ ; continue ; } /**** ERROR ****/ ERROR_exit("Unknown option: %s\n",argv[nopt]) ; } /* end of scan over options */ /*-- check for errors --*/ if( nopt >= argc ) ERROR_exit("No input dataset?!") ; #ifdef ALLOW_BYSLICE if( IMARR_COUNT(slice_imar) > 0 && DT_byslice ) ERROR_exit("Illegal mixing of -slicevector and -byslice") ; #endif DT_nvector = IMARR_COUNT(DT_imar) ; if( DT_nvector + DT_exnum == 0 && DT_polort < 0 ) ERROR_exit("No detrending options ordered!") ; #ifdef ALLOW_BYSLICE if( DT_nvector == 0 && DT_byslice ) ERROR_exit("No -vector option supplied with -byslice!") ; #endif /*--- read input dataset ---*/ DT_dset = THD_open_dataset( argv[nopt] ) ; CHECK_OPEN_ERROR(DT_dset,argv[nopt]) ; if( DT_dset == NULL ) ERROR_exit("Can't open dataset %s\n",argv[nopt]) ; DT_current_del = DSET_TR(DT_dset) ; if( DT_current_del <= 0.0 ){ DT_current_del = 1.0 ; if( DT_verb ) WARNING_message("Input has no TR value; setting TR=1.0\n") ; } else if( DT_verb ){ INFO_message("Input has TR=%g\n",DT_current_del) ; } /*-- check vectors for good size --*/ nvcheck = nvals = DSET_NVALS(DT_dset) ; #ifdef ALLOW_BYSLICE if( DT_byslice ) nvcheck *= DSET_NZ(DT_dset) ; #endif for( ii=0 ; ii < DT_nvector ; ii++ ){ if( IMARR_SUBIMAGE(DT_imar,ii)->nx < nvcheck ){ ERROR_message("%d-th -vector is shorter (%d) than dataset (%d)", ii+1,IMARR_SUBIMAGE(DT_imar,ii)->nx,nvcheck) ; nerr++ ; } } if( nerr > 0 ) ERROR_exit("Cannot continue") ; /*--- create time series from expressions */ if( DT_exnum > 0 ){ double atoz[26] , del ; int kvar , jj ; MRI_IMAGE *flim ; float *flar ; for( jj=0 ; jj < DT_exnum ; jj++ ){ if( DT_verb ) INFO_message("Evaluating %d-th -expr\n",jj+1) ; kvar = DT_exvar[jj] ; del = DT_exdel[jj] ; if( del <= 0.0 ) del = DT_current_del ; flim = mri_new( nvals , 1 , MRI_float ) ; flar = MRI_FLOAT_PTR(flim) ; for( ii=0 ; ii < 26 ; ii++ ) atoz[ii] = 0.0 ; for( ii=0 ; ii < nvals ; ii++ ){ if( kvar >= 0 ) atoz[kvar] = ii * del ; flar[ii] = PARSER_evaluate_one( DT_excode[jj] , atoz ) ; } ADDTO_IMARR( DT_imar , flim ) ; } } /*--- from polort [10 Apr 2006] ---*/ if( DT_polort >= 0 ){ int kk ; MRI_IMAGE *flim ; float *flar ; double fac=2.0/(nvals-1.0) ; for( kk=0 ; kk <= DT_polort ; kk++ ){ flim = mri_new( nvals , 1 , MRI_float ) ; flar = MRI_FLOAT_PTR(flim) ; for( ii=0 ; ii < nvals ; ii++ ) flar[ii] = Plegendre(fac*ii-1.0,kk) ; ADDTO_IMARR( DT_imar , flim ) ; } } return ; }
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) ; } }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"ConvertSurface"}; int kar, volexists, i, j, Doinv, randseed, Domergesurfs=0, pciref; float DoR2S, fv[3], *pcxyzref; double xcen[3], sc[3]; double xform[4][4]; char *if_name = NULL, *of_name = NULL, *if_name2 = NULL, *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL, *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL, *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, *ifpar_name2 = NULL; SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, iparType = SUMA_FT_NOT_SPECIFIED, oType = SUMA_FT_NOT_SPECIFIED; SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, iparForm = SUMA_FF_NOT_SPECIFIED, oFormat = SUMA_FF_NOT_SPECIFIED; SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL; SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL; SUMA_SFname *SF_name = NULL; void *SO_name = NULL; char orsurf[6], orcode[6], *PCprojpref=NULL, *NodeDepthpref=NULL; THD_warp *warp=NULL ; THD_3dim_dataset *aset=NULL; SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Do_flip; SUMA_Boolean Doxmat, Do_wind, Do_p2s, onemore, Do_native, Do_PolDec; int Do_PCproj, Do_PCrot, Do_NodeDepth; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean exists; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;-ipar;"); kar = 1; xmat_name = NULL; xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0; brk = NOPE; orcode[0] = '\0'; randseed = 1234; sprintf(orsurf,"RAI"); Docen = NOPE; Doxmat = NOPE; Do_tlrc = NOPE; Do_mni_RAI = NOPE; Do_mni_LPI = NOPE; Do_acpc = NOPE; Do_wind = NOPE; Do_flip = NOPE; Do_p2s = NOPE; Do_native = NOPE; DoR2S = 0.0; Do_PolDec = NOPE; Do_PCproj = NO_PRJ; Do_PCrot = NO_ROT; pciref = -1; pcxyzref = NULL; PCprojpref = NULL; NodeDepthpref = NULL; Do_NodeDepth = 0; Doinv = 0; Domergesurfs = 0; onemore = NOPE; while (kar < argc) { /* loop accross command ine options */ /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/ if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) { usage_SUMA_ConvertSurface(ps, strlen(argv[kar]) > 3 ? 2:1); exit (0); } SUMA_SKIP_COMMON_OPTIONS(brk, kar); SUMA_TO_LOWER(argv[kar]); if (!brk && (strcmp(argv[kar], "-seed") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 integer after -seed\n"); exit (1); } randseed = atoi(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-xyzscale") == 0)) { kar ++; if (kar+2 >= argc) { fprintf (SUMA_STDERR, "need 3 values after -XYZscale\n"); exit (1); } sc[0] = strtod(argv[kar], NULL); kar ++; sc[1] = strtod(argv[kar], NULL); kar ++; sc[2] = strtod(argv[kar], NULL); xmat_name = "Scale"; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-xmat_1d") == 0) || (strcmp(argv[kar], "-xmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -xmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 0; brk = YUP; } if (!brk && ( (strcmp(argv[kar], "-ixmat_1d") == 0) || (strcmp(argv[kar], "-ixmat_1D") == 0) ) ) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -ixmat_1D\n"); exit (1); } xmat_name = argv[kar]; Doxmat = YUP; Doinv = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-polar_decomp") == 0)) { Do_PolDec = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-merge_surfs") == 0)) { Domergesurfs = 1; brk = YUP; } if (!brk && (strcmp(argv[kar], "-pc_proj") == 0)) { kar ++; if (kar+1 >= argc) { fprintf (SUMA_STDERR, "need 2 argument after -pc_proj\n"); exit (1); } if (!strcmp(argv[kar],"PC0_plane")) Do_PCproj = E1_PLN_PRJ; else if (!strcmp(argv[kar],"PC1_plane")) Do_PCproj = E2_PLN_PRJ; else if (!strcmp(argv[kar],"PC2_plane")) Do_PCproj = E3_PLN_PRJ; else if (!strcmp(argv[kar],"PCZ_plane")) Do_PCproj = EZ_PLN_PRJ; else if (!strcmp(argv[kar],"PCY_plane")) Do_PCproj = EY_PLN_PRJ; else if (!strcmp(argv[kar],"PCX_plane")) Do_PCproj = EX_PLN_PRJ; else if (!strcmp(argv[kar],"PC0_dir")) Do_PCproj = E1_DIR_PRJ; else if (!strcmp(argv[kar],"PC1_dir")) Do_PCproj = E2_DIR_PRJ; else if (!strcmp(argv[kar],"PC2_dir")) Do_PCproj = E3_DIR_PRJ; else if (!strcmp(argv[kar],"PCZ_dir")) Do_PCproj = EZ_DIR_PRJ; else if (!strcmp(argv[kar],"PCY_dir")) Do_PCproj = EY_DIR_PRJ; else if (!strcmp(argv[kar],"PCX_dir")) Do_PCproj = EX_DIR_PRJ; else { SUMA_S_Err("Bad value of %s for -pca_proj", argv[kar]); exit(1); } ++kar; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -pc_proj should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } PCprojpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-node_depth") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need a prefix argument after -node_depth\n"); exit (1); } Do_NodeDepth = 1; if (argv[kar][0] == '-') { SUMA_S_Err("Prefix for -node_depth should not start with '-'.\n" "Could it be that %s is another option and \n" "the prefix was forgtotten?", argv[kar]); exit(1); } NodeDepthpref = argv[kar]; brk = YUP; } if (!brk && (strcmp(argv[kar], "-make_consistent") == 0)) { Do_wind = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-flip_orient") == 0)) { Do_flip = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xcenter") == 0)) { kar ++; if (kar+2>= argc) { fprintf (SUMA_STDERR, "need 3 arguments after -xcenter\n"); exit (1); } xcen[0] = atof(argv[kar]); ++kar; xcen[1] = atof(argv[kar]); ++kar; xcen[2] = atof(argv[kar]); Docen = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-native") == 0)) { Do_native = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-orient_out") == 0)) { kar ++; if (kar>= argc) { fprintf (SUMA_STDERR, "need 1 argument after -orient_out\n"); exit (1); } snprintf(orcode, 4*sizeof(char), "%s", argv[kar]); if (!SUMA_ok_orstring(orcode)) { fprintf (SUMA_STDERR, "%s is a bad orientation string\n", orcode); exit (1); } brk = YUP; } if (!brk && (strcmp(argv[kar], "-radial_to_sphere") == 0)) { kar ++; if (kar >= argc) { fprintf (SUMA_STDERR, "need 1 argument after -radial_to_sphere\n"); exit (1); } DoR2S = atof(argv[kar]); brk = YUP; } if (!brk && (strcmp(argv[kar], "-patch2surf") == 0)) { Do_p2s = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_ascii") == 0)) { oFormat = SUMA_XML_ASCII_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64") == 0)) { oFormat = SUMA_XML_B64_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-xml_b64gz") == 0)) { oFormat = SUMA_XML_B64GZ_SURF; brk = YUP; } if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) { Do_tlrc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-acpc") == 0)) { Do_acpc = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_rai") == 0)) { Do_mni_RAI = YUP; brk = YUP; } if (!brk && (strcmp(argv[kar], "-mni_lpi") == 0)) { Do_mni_LPI = YUP; brk = YUP; } if (!brk && !ps->arg_checked[kar]) { fprintf (SUMA_STDERR, "Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]); suggest_best_prog_option(argv[0], argv[kar]); exit (1); } else { brk = NOPE; kar ++; } } if (argc < 3) { SUMA_S_Err("Too few options"); usage_SUMA_ConvertSurface (ps, 0); exit (1); } /* transfer info from ps structure (backward compat) */ if (ps->o_N_surfnames) { of_name = ps->o_surfnames[0]; of_name2 = ps->o_surftopo[0]; oType = ps->o_FT[0]; if (oFormat == SUMA_FF_NOT_SPECIFIED) { oFormat = ps->o_FF[0]; } } if (ps->i_N_surfnames) { if_name = ps->i_surfnames[0]; if_name2 = ps->i_surftopo[0]; iType = ps->i_FT[0]; iForm = ps->i_FF[0]; } if (ps->ipar_N_surfnames) { ifpar_name = ps->ipar_surfnames[0]; ifpar_name2 = ps->ipar_surftopo[0]; iparType = ps->ipar_FT[0]; iparForm = ps->ipar_FF[0]; } if (ps->N_sv) sv_name = ps->sv[0]; if (ps->N_vp) vp_name = ps->vp[0]; /* sanity checks */ if (Do_native && orcode[0] != '\0') { SUMA_S_Err("Options -native and -orient_out are mutually exclusive"); exit(1); } if (Do_mni_LPI && Do_mni_RAI) { SUMA_S_Err("\nCombining -MNI_lpi and -MNI_rai options.\nNot good."); exit(1); } if (!if_name) { SUMA_S_Err("input surface not specified.\n"); exit(1); } if (!of_name && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output surface or projection PREFIX not specified.\n"); exit(1); } if (iType == SUMA_FT_NOT_SPECIFIED) { SUMA_S_Err("input type not recognized.\n"); exit(1); } if (oType == SUMA_FT_NOT_SPECIFIED && (Do_PCproj < 0 && !Do_NodeDepth) ) { SUMA_S_Err("output type not recognized.\n"); exit(1); } if ( oType != SUMA_GIFTI && oFormat >= SUMA_XML_SURF && oFormat <= SUMA_XML_B64GZ_SURF && (Do_PCproj < 0 && !Do_NodeDepth) ){ SUMA_S_Err("XML output options only valid with -o_gii\n"); exit(1); } if (iType == SUMA_SUREFIT) { if (!if_name2) { SUMA_S_Err("input SureFit surface incorrectly specified.\n"); exit(1); } if (sv_name && !vp_name) { SUMA_S_Err("VolParent needs the -sv option for SureFit surfaces."); exit(1); } } if (iType == SUMA_VEC) { if (!if_name2) { SUMA_S_Err("Input vec surface incorrectly specified.\n"); exit(1); } } if (( Do_mni_RAI || Do_mni_LPI) && !Do_tlrc) { SUMA_SL_Warn ( "I hope you know what you're doing.\n" "The MNI transform should only be applied to a\n" "Surface in the AFNI tlrc coordinate space.\n"); } if (Do_acpc && Do_tlrc) { SUMA_S_Err("You can't do -tlrc and -acpc simultaneously."); exit(1); } if ((Doxmat || Docen) && (Do_acpc || Do_tlrc)) { SUMA_S_Err("You can't do -tlrc or -acpc with -xmat_1D and -xcenter.\n"); exit(1); } if ((!Doxmat && Docen)) { SUMA_S_Err("You can't use -xcenter without -xmat_1D.\n"); exit(1); } if (oType == SUMA_SUREFIT) { if (!of_name2) { SUMA_S_Err("output SureFit surface incorrectly specified. \n"); exit(1); } } if (oType == SUMA_VEC) { if (!of_name2) { SUMA_S_Err("output vec surface incorrectly specified. \n"); exit(1); } } if ( ps->i_N_surfnames > 1 && !Domergesurfs) { SUMA_S_Err("Multiple surfaces specified without -merge_surfs option\n" "Nothing to do for such an input\n"); exit(1); } /* test for existence of input files */ if (!SUMA_is_predefined_SO_name(if_name, NULL, NULL, NULL, NULL) && !SUMA_filexists(if_name)) { SUMA_S_Errv("if_name %s not found.\n", if_name); exit(1); } if (if_name2) { if (!SUMA_filexists(if_name2)) { SUMA_S_Errv("if_name2 %s not found.\n", if_name2); exit(1); } } if (ifpar_name2) { if (!SUMA_filexists(ifpar_name2)) { SUMA_S_Errv("ifpar_name2 %s not found.\n", ifpar_name2); exit(1); } } if (ifpar_name) { if (!SUMA_filexists(ifpar_name)) { SUMA_S_Errv("ifpar_name %s not found.\n", ifpar_name); exit(1); } } if (xmat_name) { if (!strstr(special_xmats,xmat_name) && !SUMA_filexists(xmat_name)) { SUMA_S_Errv("xmat file %s not found.\n", xmat_name); exit(1); } } else { if (Do_PolDec) { SUMA_S_Err("-polar_decomp is useless without -xmat_1D"); exit(1); } } if (sv_name) { char *head = NULL, view[10]; head = SUMA_AfniPrefix(sv_name, view, NULL, &volexists); if (!SUMA_AfniExistsView(volexists, view) && !SUMA_filexists(sv_name)) { fprintf (SUMA_STDERR, "Error %s: volume %s not found.\n", FuncName, head); exit(1); } if (head) SUMA_free(head); head = NULL; } if ((Do_tlrc || Do_acpc) && (!sv_name)) { fprintf (SUMA_STDERR, "Error %s: -tlrc must be used with -sv option.\n", FuncName); exit(1); } if (vp_name) { if (!SUMA_filexists(vp_name)) { fprintf (SUMA_STDERR, "Error %s: %s not found.\n", FuncName, vp_name); exit(1); } } /* check for existence of output files */ if ((Do_PCproj < 0 && !Do_NodeDepth) ) { if (of_name2) { SUMA_SFname *SFname; SO_name = SUMA_2Prefix2SurfaceName (of_name, of_name2, NULL, vp_name, oType, &exists); SFname = (SUMA_SFname *)SO_name; OF_name2 = SUMA_copy_string(SFname->name_topo); OF_name = SUMA_copy_string(SFname->name_coord); } else { SO_name = SUMA_Prefix2SurfaceName (of_name, NULL, vp_name, oType, &exists); OF_name = SUMA_copy_string((char *) SO_name); } if (exists && !THD_ok_overwrite()) { if (OF_name2) fprintf (SUMA_STDERR, "Error %s: output file(s) %s and/or %s exist already.\n", FuncName, OF_name, OF_name2); else fprintf ( SUMA_STDERR, "Error %s: output file %s exists already.\n", FuncName, OF_name); exit(1); } } /* now for the real work */ if (Doxmat) { MRI_IMAGE *im = NULL; double *far=NULL; int nrow, ncol; if (!strcmp(xmat_name,"RandRigid")) { SUMA_FillRandXform(xform, randseed, 2); } else if (!strcmp(xmat_name,"RandAffine")) { SUMA_FillRandXform(xform, randseed, 3); } else if (!strcmp(xmat_name,"RandShift")) { SUMA_FillRandXform(xform, randseed, 1); } else if (!strcmp(xmat_name,"Scale")) { SUMA_FillScaleXform(xform, sc); } else if (!strcmp(xmat_name,"NegXY")) { SUMA_FillXYnegXform(xform); } else { im = mri_read_double_1D (xmat_name); if (!im) { SUMA_SLP_Err("Failed to read 1D file"); exit(1); } far = MRI_DOUBLE_PTR(im); nrow = im->nx; ncol = im->ny; if (nrow == 1) { if (ncol != 12) { SUMA_SL_Err("Mat file must have\n" "one row of 12 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } i = 0; while (i < 12) { xform[i/4][0] = far[i]; ++i; xform[i/4][1] = far[i]; ++i; xform[i/4][2] = far[i]; ++i; xform[i/4][3] = far[i]; ++i; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } else { if (ncol < 4 ) { SUMA_SL_Err("Mat file must have\n" "at least 4 columns."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (nrow < 3 ) { SUMA_SL_Err("Mat file must have\n" "at least 3 rows."); mri_free(im); im = NULL; /* done with that baby */ exit(1); } if (ncol > 4) { SUMA_SL_Warn( "Ignoring entries beyond 4th \n" "column in transform file."); } if (nrow > 3) { SUMA_SL_Warn( "Ignoring entries beyond 3rd\n" "row in transform file.\n"); } for (i=0; i < 3; ++i) { xform[i][0] = far[i]; xform[i][1] = far[i+nrow]; xform[i][2] = far[i+2*nrow]; xform[i][3] = far[i+3*nrow]; } xform[3][0] = 0.0; xform[3][1] = 0.0; xform[3][2] = 0.0; xform[3][3] = 1.0; } } if (LocalHead) { fprintf(SUMA_STDERR,"\n++ ConvertSurface xform:\n"); for (i=0; i < 4; ++i) { fprintf(SUMA_STDERR," %+.5f\t%+.5f\t%+.5f\t%+.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf(SUMA_STDERR,"\n"); } mri_free(im); im = NULL; if (Doinv) { mat44 A, A0; LOAD_MAT44( A0, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); A = nifti_mat44_inverse(A0); UNLOAD_MAT44(A, \ xform[0][0], xform[0][1], xform[0][2], xform[0][3], \ xform[1][0], xform[1][1], xform[1][2], xform[1][3], \ xform[2][0], xform[2][1], xform[2][2], xform[2][3] ); } if (Do_PolDec) { #ifdef USE_DECOMPOSE_SHOEMAKE /* a little something to do a polar decomposition on M into M = Q*S*/ { float det, m[4][4], q[4][4], s[4][4]; char *stmp = SUMA_append_string("QS_",xmat_name); FILE *fout = fopen(stmp,"w"); SUMA_free(stmp); stmp = NULL; SUMA_S_Note("FixMe! #include above and if(1) here ..."); det = polar_decomp(M, q,s); fprintf(fout,"#[M][D]: (D is the shift)\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(fout,"#Q:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], q[i][3]); fprintf(fout,"#S:\n"); for (i=0;i<3; ++i) fprintf(fout, "#%.5f %.5f %.5f %.5f\n", s[i][0], s[i][1], s[i][2], s[i][3]); fprintf(fout,"#det: %f\n", det); fprintf(fout, "#[Q][D]: A close xform to [M][D], " "without scaling.\n#M = Q*S\n"); for (i=0;i<3; ++i) fprintf(fout, "%.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); fclose(fout); SUMA_free(stmp); stmp = NULL; } /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", M[i][0], M[i][1], M[i][2], M[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf(SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", q[i][0], q[i][1], q[i][2], M[i][3]); for (i=0;i<3; ++i) { M[i][0] = q[i][0]; M[i][1] = q[i][1]; M[i][2] = q[i][2]; } #else {/* use the NIFTI polar decomposition function (same results as above)*/ mat33 Q, A; for (i=0;i<3;++i) { A.m[i][0] = xform[i][0]; A.m[i][1] = xform[i][1]; A.m[i][2] = xform[i][2]; } Q = nifti_mat33_polar( A ); /* replace user's xform with orthogonal one: */ fprintf(SUMA_STDOUT,"Replacing matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", xform[i][0], xform[i][1], xform[i][2], xform[i][3]); fprintf(SUMA_STDOUT," with matrix:\n"); for (i=0;i<3; ++i) fprintf( SUMA_STDOUT, " %.5f %.5f %.5f %.5f\n", Q.m[i][0], Q.m[i][1], Q.m[i][2], xform[i][3]); for (i=0;i<3; ++i) { xform[i][0] = Q.m[i][0]; xform[i][1] = Q.m[i][1]; xform[i][2] = Q.m[i][2]; } } #endif } } if ( ps->i_N_surfnames == 1) { /* load that one surface */ SO = SUMA_Load_Surface_Object_Wrapper ( if_name, if_name2, vp_name, iType, iForm, sv_name, 1); if (!SO) { SUMA_S_Err("Failed to read input surface.\n"); exit (1); } } else if ( ps->i_N_surfnames > 1 && Domergesurfs) { SUMA_SurfaceObject **SOar=NULL; int ii; SUMA_S_Notev("Merging %d surfaces into 1\n", ps->i_N_surfnames); SOar = (SUMA_SurfaceObject **) SUMA_calloc(ps->i_N_surfnames, sizeof(SUMA_SurfaceObject *)); if (ps->N_sv > 1 || ps->N_vp > 1) { SUMA_S_Errv("Cannot handle multiple (%d) -sv or multiple (%d) -vp\n", ps->N_sv, ps->N_vp); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SOar[ii] = SUMA_Load_Surface_Object_Wrapper(ps->i_surfnames[ii], ps->i_surftopo[ii], vp_name, ps->i_FT[0], ps->i_FF[0], sv_name, 1); } if (!(SO = SUMA_MergeSurfs(SOar, ps->i_N_surfnames))) { SUMA_S_Err("Failed to merge"); exit(1); } for (ii = 0; ii<ps->i_N_surfnames; ++ii) { SUMA_Free_Surface_Object(SOar[ii]); SOar[ii]=NULL; } SUMA_free(SOar); SOar=NULL; } if (DoR2S > 0.0000001) { if (!SUMA_ProjectSurfaceToSphere(SO, NULL , DoR2S , NULL)) { SUMA_S_Err("Failed to project to surface"); exit(1); } } if (ifpar_name) { SOpar = SUMA_Load_Surface_Object_Wrapper ( ifpar_name, ifpar_name2, vp_name, iparType, iparForm, sv_name, 1); if (!SOpar) { SUMA_S_Err("Failed to read input parent surface.\n"); exit (1); } /* need edge list */ if (!SUMA_SurfaceMetrics_eng (SOpar,"EdgeList", NULL, 0, SUMAg_CF->DsetList)) { SUMA_SL_Err("Failed to create edgelist for parent"); exit(1); } } /* if Do_wind */ if (Do_wind) { fprintf (SUMA_STDOUT, "Checking and repairing mesh's winding consistency...\n"); /* check the winding, but that won't fix the normals, you'll have to recalculate those things, if need be ... */ if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, 0, SUMAg_CF->DsetList)) { SUMA_S_Err("Failed in SUMA_SurfaceMetrics.\n"); exit(1); } } if (Do_flip) { fprintf (SUMA_STDOUT, "Flipping triangle winding...\n"); SUMA_FlipSOTriangles(SO); } if (Do_tlrc) { fprintf (SUMA_STDOUT,"Performing talairach transform...\n"); /* form the tlrc version of the surface volume */ tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (tlrc_name, "%s%s+tlrc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(tlrc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name); exit(1); } /* read the tlrc header */ aset = THD_open_dataset(tlrc_name) ; if( !ISVALID_DSET(aset) ){ SUMA_S_Err("%s is not a valid data set.\n", tlrc_name) ; exit(1); } if( aset->warp == NULL ){ SUMA_S_Err("tlrc_name does not contain a talairach transform.\n"); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed in SUMA_AFNI_forward_warp_xyz.\n"); exit(1); } } if (Do_acpc) { fprintf (SUMA_STDOUT,"Performing acpc transform...\n"); /* form the acpc version of the surface volume */ acpc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+ strlen(SO->VolPar->prefix)+60, sizeof(char)); sprintf (acpc_name, "%s%s+acpc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix); if (!SUMA_filexists(acpc_name)) { fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, acpc_name); exit(1); } /* read the acpc header */ aset = THD_open_dataset(acpc_name) ; if( !ISVALID_DSET(aset) ){ fprintf (SUMA_STDERR, "Error %s: %s is not a valid data set.\n", FuncName, acpc_name) ; exit(1); } if( aset->warp == NULL ){ fprintf (SUMA_STDERR, "Error %s: acpc_name does not contain an acpc transform.\n", FuncName); exit(1); } warp = aset->warp ; /* now warp the coordinates, one node at a time */ if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName); exit(1); } } if (Do_mni_RAI) { fprintf (SUMA_STDOUT,"Performing MNI_RAI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "RAI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"RAI"); } if (Do_mni_LPI) { fprintf (SUMA_STDOUT,"Performing MNI_LPI transform...\n"); /* apply the mni warp */ if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "LPI")) { fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName); exit(1); } sprintf(orsurf,"LPI"); } if (Doxmat) { fprintf (SUMA_STDOUT,"Performing affine transform...\n"); if (LocalHead) { for (i=0; i<3 ; ++i) { fprintf (SUMA_STDERR, "M[%d][:] = %f %f %f %f\n", i, xform[i][0], xform[i][1], xform[i][2], xform[i][3]); } fprintf (SUMA_STDERR,"Cen[:] %f %f %f\n", xcen[0], xcen[1], xcen[2]); } if (Docen) { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, xcen)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } else { if (!SUMA_Apply_Coord_xform( SO->NodeList, SO->N_Node, SO->NodeDim, xform, 0, NULL)) { SUMA_SL_Err("Failed to xform coordinates"); exit(1); } } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (orcode[0] != '\0') { SUMA_LHv("Changing coordinates from %s to %s\n", orsurf, orcode); if (!SUMA_CoordChange(orsurf, orcode, SO->NodeList, SO->N_Node)) { SUMA_S_Err("Failed to change coords."); exit(1); } SUMA_Blank_AfniSO_Coord_System(SO->aSO); } if (Do_p2s) { SUMA_SurfaceObject *SOold = SO; SUMA_LH("Changing patch to surface..."); SO = SUMA_Patch2Surf(SOold->NodeList, SOold->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SO) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } /* get rid of old surface object */ SUMA_Free_Surface_Object(SOold); } if (Do_native) { if (!SUMA_Delign_to_VolPar (SO, NULL)) { SUMA_S_Err("Failed to transform coordinates to native space"); exit(1); } } if (Do_NodeDepth) { float *dpth=NULL, mx=0.0; SUMA_PC_XYZ_PROJ *pcp=NULL; if (SUMA_NodeDepth(SO->NodeList, SO->N_Node, E1_DIR_PRJ, &dpth, 0.0, NULL, &mx, &pcp) < 0) { SUMA_S_Err("Failed to compute node depth"); exit(1); } else { if (!SUMA_WriteNodeDepth(NodeDepthpref,pcp,dpth, mx)) { SUMA_S_Err("Failed to write node depth"); exit(1); } } SUMA_ifree(dpth); pcp = SUMA_Free_PC_XYZ_Proj(pcp); } if (Do_PCproj > NO_PRJ) { SUMA_PC_XYZ_PROJ *pcp=NULL; pciref = 0; pcxyzref = NULL; if (!(pcp = SUMA_Project_Coords_PCA(SO->NodeList, SO->N_Node, pciref, pcxyzref, Do_PCproj, Do_PCrot, 1))) { SUMA_S_Err("Failed to project"); exit(1); } else { if (!SUMA_Write_PC_XYZ_Proj(pcp, PCprojpref)) { SUMA_S_Err("Failed to write out projections"); exit(1); } else { pcp = SUMA_Free_PC_XYZ_Proj(pcp); } exit(0); } } /* write the surface object */ if (SO_name) { if (LocalHead) SUMA_Print_Surface_Object (SO, stderr); fprintf (SUMA_STDOUT,"Writing surface...\n"); if (!(SUMA_Save_Surface_Object ( SO_name, SO, oType, oFormat, SOpar))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip); if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip); if (OF_name) SUMA_free(OF_name); if (OF_name2) SUMA_free(OF_name2); if (SF_name) SUMA_free(SF_name); if (SO_name) SUMA_free(SO_name); if (SO) SUMA_Free_Surface_Object(SO); if (SOpar) SUMA_Free_Surface_Object(SOpar); if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; return (0); }
int main( int argc , char * argv[] ) { THD_3dim_dataset *inset=NULL , *outset=NULL , *mask_dset=NULL ; MRI_IMAGE *fim=NULL ; float *far=NULL ; int iarg , ndset , nvox , ii , mcount=0 ; char *prefix = "rankizer" ; byte *mmm=NULL ; float brank=1.0f ; /*-- read command line arguments --*/ if( argc < 3 || strncmp(argv[1],"-help",5) == 0 ){ printf("Usage: 3dRankizer [options] dataset\n" "Output = Rank of each voxel as sorted into increasing value.\n" " - Ties get the average rank.\n" " - Not the same as 3dRank!\n" " - Only sub-brick #0 is processed at this time!\n" " - Ranks start at 1 and increase:\n" " Input = 0 3 4 4 7 9\n" " Output = 1 2 3.5 3.5 5 6\n" "Options:\n" " -brank bbb Set the 'base' rank to 'bbb' instead of 1.\n" " (You could also do this with 3dcalc.)\n" " -mask mset Means to use the dataset 'mset' as a mask:\n" " Only voxels with nonzero values in 'mset'\n" " will be used from 'dataset'. Voxels outside\n" " the mask will get rank 0.\n" " -prefix ppp Write results into float-format dataset 'ppp'\n" " Output is in float format to allow for\n" " non-integer ranks resulting from ties.\n" "\n" "Author: RW Cox [[a quick hack for his own purposes]]\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } /*---- official startup ---*/ PRINT_VERSION("3dRankizer"); mainENTRY("3dRankizer main"); machdep(); AFNI_logger("3dRankizer",argc,argv); AUTHOR("Zhark of the Ineffable Rank"); /*-- command line scan --*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-brank",5) == 0 ){ if( iarg+1 >= argc ) ERROR_exit("-brank option requires a following argument!") ; brank = (float)strtod(argv[++iarg],NULL) ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-mask",5) == 0 ){ if( mask_dset != NULL ) ERROR_exit("Cannot have two -mask options!") ; if( iarg+1 >= argc ) ERROR_exit("-mask option requires a following argument!") ; mask_dset = THD_open_dataset( argv[++iarg] ) ; if( mask_dset == NULL ) ERROR_exit("Cannot open mask dataset!") ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-prefix") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '-prefix'") ; prefix = strdup(argv[iarg]) ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal value after '-prefix'") ; iarg++ ; continue ; } ERROR_exit("Unknown option: %s",argv[iarg]) ; } /* should have 1 more arg */ ndset = argc - iarg ; if( ndset < 1 ) ERROR_exit("No input dataset!?") ; else if( ndset > 1 ) WARNING_message("Too many input datasets!") ; inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; fim = THD_extract_float_brick(0,inset) ; DSET_unload(inset) ; far = MRI_FLOAT_PTR(fim) ; nvox= DSET_NVOX(inset) ; /* make a byte mask from mask dataset */ if( mask_dset != NULL ){ if( DSET_NVOX(mask_dset) != nvox ) ERROR_exit("Input and mask datasets are not same dimensions!"); mmm = THD_makemask( mask_dset , 0 , 1.0f,-1.0f ) ; mcount = THD_countmask( nvox , mmm ) ; INFO_message("%d voxels in the mask",mcount) ; if( mcount <= 5 ) ERROR_exit("Mask is too small!") ; DSET_delete(mask_dset) ; } if( mmm == NULL ){ rank_order_float( nvox , far ) ; for( ii=0 ; ii < nvox ; ii++ ) far[ii] += brank ; } else { float fmin=far[0] ; for( ii=1 ; ii < nvox ; ii++ ) if( far[ii] < fmin ) fmin = far[ii] ; if( fmin > 0.0f ) fmin = 0.0f ; else if( fmin == 0.0f ) fmin = -1.0f ; else fmin = -2.0f*fmin-1.0f ; for( ii=0 ; ii < nvox ; ii++ ) if( !mmm[ii] ) far[ii] = fmin ; rank_order_float( nvox , far ) ; fmin = (nvox-mcount) - brank ; for( ii=0 ; ii < nvox ; ii++ ){ if( mmm[ii] ) far[ii] = far[ii] - fmin ; else far[ii] = 0.0f ; } } outset = EDIT_empty_copy( inset ) ; EDIT_dset_items( outset , ADN_prefix , prefix , ADN_brick_fac , NULL , ADN_nvals , 1 , ADN_ntt , 0 , ADN_none ) ; EDIT_substitute_brick( outset , 0 , MRI_float , far ) ; DSET_write(outset) ; WROTE_DSET(outset) ; exit(0) ; }
int main( int argc , char *argv[] ) { char *drive_afni[128] ; int ndrive=0 , iarg=1 ; char host[1024]="localhost", nsname[2048], *geomstr, *cpt, temp[32] ; int dt=1000 , ctold,ctnew , ctzero ; int verbose=0 , kk,nn , nvox,nval , do_accum=0 ; THD_3dim_dataset *dset ; NI_element *nel ; MRI_IMAGE *fim ; float *far ; char *targname="niml_feedme" ; /*-- help the ignorant user --*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "Usage: niml_feedme [options] dataset\n" "\n" "* Sends volumes from the dataset to AFNI via the NIML socket interface.\n" "* You must run AFNI with the command 'afni -niml' so that the program\n" " will be listening for the socket connection.\n" "* Inside AFNI, the transmitted dataset will be named 'niml_feedme'.\n" "* For another way to send image data to AFNI, see progam rtfeedme.\n" "* At present, there is no way to attach statistical parameters to\n" " a transmitted volume.\n" "* This program sends all volumes in float format, simply because\n" " that's easy for me. But you can also send byte, short, and\n" " complex valued volumes.\n" "* This program is really just a demo; it has little practical use.\n" "\n" "OPTIONS:\n" " -host sname = Send data, via TCP/IP, to AFNI running on the\n" " computer system 'sname'. By default, uses the\n" " current system (localhost), if you don't use this\n" " option.\n" "\n" " -dt ms = Tries to maintain an inter-transmit interval of 'ms'\n" " milliseconds. The default is 1000 msec per volume.\n" "\n" " -verb = Be (very) talkative about actions.\n" "\n" " -accum = Send sub-bricks so that they accumulate in AFNI.\n" " The default is to create only a 1 volume dataset\n" " inside AFNI, and each sub-brick just replaces\n" " that one volume when it is received.\n" "\n" " -target nam = Change the dataset name transmitted to AFNI from\n" " 'niml_feedme' to 'nam'.\n" "\n" " -drive cmd = Send 'cmd' as a DRIVE_AFNI command.\n" " * If cmd contains blanks, it must be in 'quotes'.\n" " * Multiple -drive options may be used.\n" " * These commands will be sent to AFNI just after\n" " the first volume is transmitted.\n" " * See file README.driver for a list of commands.\n" "\n" "EXAMPLE: Send volumes from a 3D+time dataset to AFNI:\n" "\n" " niml_feedme -dt 1000 -verb -accum -target Elvis \\\n" " -drive 'OPEN_WINDOW axialimage' \\\n" " -drive 'OPEN_WINDOW axialgraph' \\\n" " -drive 'SWITCH_UNDERLAY Elvis' \\\n" " timeseries+orig\n" "\n" "Author: RW Cox -- July 2009\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("niml_feedme") ; /*-- scan arguments --*/ while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-target",5) == 0 ){ targname = strdup(argv[++iarg]) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-drive") == 0 ){ drive_afni[ndrive++] = argv[++iarg] ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-host") == 0 ){ strcpy( host , argv[++iarg] ) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-dt") == 0 ){ dt = (int)strtod(argv[++iarg],NULL) ; if( dt < 9 ) dt = 9 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-verbose",4) == 0 ){ verbose = 1 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-accum",4) == 0 ){ do_accum = 1 ; iarg++ ; continue ; } ERROR_exit("Unrecognized option: %s",argv[iarg]) ; } if( iarg >= argc ) ERROR_exit("No dataset on command line?!") ; /*-- read in the dataset --*/ dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ) ERROR_exit("Can't open dataset '%s'",argv[iarg]) ; DSET_load(dset) ; if( !DSET_LOADED(dset) ) ERROR_exit("Can't load dataset '%s'",argv[iarg]) ; cpt = EDIT_get_geometry_string(dset) ; geomstr = strdup(cpt) ; /* describes geometry of dataset grid */ if( verbose ) INFO_message("geometry string = '%s'",geomstr) ; nvox = DSET_NVOX(dset); /* number of voxels in dataset */ nval = DSET_NVALS(dset); /* number of sub-bricks in dataset */ /*-- this stuff is one-time-only setup of the I/O to AFNI --*/ atexit(NF_exit) ; /* call this when program ends */ signal(SIGINT ,NF_sigfunc) ; /* setup signal handler */ signal(SIGBUS ,NF_sigfunc) ; /* for fatal errors */ signal(SIGSEGV,NF_sigfunc) ; signal(SIGTERM,NF_sigfunc) ; /* name of NIML stream (socket) to open */ sprintf( nsname , "tcp:%s:%d" , host , get_port_named("AFNI_DEFAULT_LISTEN_NIML")); /* open the socket (i.e., dial the telephone call) */ fprintf(stderr,"opening NIML stream '%s' ",nsname) ; NF_stream = NI_stream_open( nsname , "w" ) ; /* loop until AFNI connects (answers the call), printing a '.' every 1/2 second to keep the user happy */ while(1){ kk = NI_stream_writecheck( NF_stream , 500 ) ; if( kk == 1 ){ fprintf(stderr," connected!\n") ; break ; } if( kk < 0 ){ fprintf(stderr," ** connection fails **\n") ; exit(1) ; } fprintf(stderr,".") ; } /*-- Create VOLUME_DATA NIML element to hold the brick data --*/ nel = NI_new_data_element( "VOLUME_DATA" , nvox ) ; /* add attributes to the element to help AFNI construct the dataset */ /* define the grid of the dataset */ NI_set_attribute( nel , "geometry_string" , geomstr ) ; /* define the name of the dataset */ NI_set_attribute( nel , "target_name" , targname ) ; /* all sub-bricks in the input dataset will be sent to be sub-brick #0 in the dataset inside AFNI -- if you don't want this behavior, and want the dataset inside AFNI to keep growing, then don't set this attribute! */ if( !do_accum ) NI_set_attribute( nel , "index" , "0" ) ; /* +tlrc view? [default in AFNI is +orig view] */ if( dset->view_type == VIEW_TALAIRACH_TYPE ) NI_set_attribute( nel , "view" , "tlrc" ) ; /**-- loop over sub-bricks and send them to AFNI --*/ ctzero = NI_clock_time() ; /* for later reference */ if( verbose ) INFO_message("Starting sub-brick loop") ; for( kk=0 ; kk < nval ; kk++ ){ ctold = NI_clock_time() ; /* clock time at start of work (ms) */ /* get a float copy of the kk-th sub-brick */ fim = THD_extract_float_brick( kk , dset ) ; DSET_unload_one(dset,kk) ; /* unload this sub-brick now */ if( fim == NULL ){ /* should never happen */ ERROR_message("Can't get sub-brick #%d?? -- skipping",kk) ; NI_sleep(dt) ; continue ; } /* copy the float data into the NIML element for transmission */ far = MRI_FLOAT_PTR(fim) ; if( kk == 0 ) /* first time: create data column in element */ NI_add_column( nel , NI_FLOAT , far ) ; else /* later times: overwrite nel data column */ memcpy( nel->vec[0] , far , sizeof(float)*nvox ) ; mri_free(fim) ; /* done with this now [data all copied to nel] */ /* set sub-brick index in AFNI if doing accumulation */ if( do_accum ){ sprintf(temp,"%d",kk) ; NI_set_attribute( nel , "index" , temp ) ; } /*** send the data element to AFNI ***/ nn = NI_write_element( NF_stream , nel , NI_BINARY_MODE ) ; /* if something bad happened in the transmission, report it */ if( nn <= 0 ){ ERROR_message("Can't write sub-brick #%d to AFNI!",kk) ; break ; } /*** first time through ==> do the '-drive' commands now by sending processing instructions ***/ if( kk == 0 && ndrive > 0 ){ int ii ; NI_procins *npi ; if( verbose ) ININFO_message("Sending %d 'drive_afni' elements now",ndrive) ; npi = NI_new_processing_instruction( "DRIVE_AFNI" ) ; NI_sleep(1) ; /* give AFNI a msec to digest the data */ for( ii=0 ; ii < ndrive ; ii++ ){ NI_set_attribute( npi , "cmd" , drive_afni[ii] ) ; (void)NI_write_element( NF_stream , npi , NI_TEXT_MODE ) ; } NI_free_element(npi) ; /* delete this struct from the world! */ } ctnew = NI_clock_time() ; /* clock time now */ if( verbose ) ININFO_message("Sent %d bytes for sub-brick #%d in %d ms", nn , kk , ctnew-ctold ) ; NI_sleep( dt - (ctnew-ctold) ) ; /* sleep so that time delay is right */ } /* end of loop over sub-bricks */ /** summarize, do some cleanup, and exit stage left **/ if( verbose && kk > 0 ){ float dtav = (NI_clock_time()-ctzero) / (float)kk ; INFO_message("Transmission finished: %.1f ms = average time per volume",dtav) ; } NI_free_element(nel) ; /* destroy the data element */ DSET_delete(dset) ; /* destroy the dataset */ exit(0) ; }
int main( int argc , char * argv[] ) { THD_3dim_dataset * dset ; THD_dataxes * daxes ; FD_brick ** brarr , * baxi , * bsag , * bcor ; int iarg , ii ; Boolean ok ; MRI_IMAGE * pim , * flim , * slim ; float * flar ; dset_range dr ; float val , fimfac ; int ival,ityp , kk ; float xbot=BIGG,xtop=BIGG , ybot=BIGG,ytop=BIGG , zbot=BIGG,ztop=BIGG ; int xgood=0 , ygood=0 , zgood=0 , proj_code=PROJ_SUM , mirror_code=MIRR_NO , nsize=0 ; char root[THD_MAX_NAME] = "proj." ; char fname[THD_MAX_NAME] ; int ixbot=0,ixtop=0 , jybot=0,jytop=0 , kzbot=0,kztop=0 ; THD_fvec3 fv ; THD_ivec3 iv ; /*--- read command line arguments ---*/ WARNING_message("This program (3dproject) is old, not maintained, and probably useless!") ; if( argc < 2 || strncmp(argv[1],"-help",6) == 0 ) Syntax() ; INIT_EDOPT( &PRED_edopt ) ; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ DB("new arg:",argv[iarg]) ; /**** check for editing option ****/ ii = EDIT_check_argv( argc , argv , iarg , &PRED_edopt ) ; if( ii > 0 ){ iarg += ii ; continue ; } /**** -sum or -max ****/ if( strncmp(argv[iarg],"-sum",6) == 0 ){ proj_code = PROJ_SUM ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-max",6) == 0 ){ proj_code = PROJ_MMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-amax",6) == 0 ){ proj_code = PROJ_AMAX ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-smax",6) == 0 ){ proj_code = PROJ_SMAX ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-first") == 0 ){ /* 02 Nov 2000 */ proj_code = PROJ_FIRST ; first_thresh = strtod( argv[++iarg] , NULL ) ; iarg++ ; continue ; } /**** -mirror ****/ if( strncmp(argv[iarg],"-mirror",6) == 0 ){ mirror_code = MIRR_YES ; iarg++ ; continue ; } /**** -nsize ****/ if( strncmp(argv[iarg],"-nsize",6) == 0 ){ nsize = 1 ; iarg++ ; continue ; } /**** -output root ****/ if( strncmp(argv[iarg],"-output",6) == 0 || strncmp(argv[iarg],"-root",6) == 0 ){ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } MCW_strncpy( root , argv[++iarg] , THD_MAX_NAME-1 ) ; ii = strlen(root) ; if( ii == 0 ){ fprintf(stderr,"\n*** illegal rootname!\n") ; exit(-1) ; } if( root[ii-1] != '.' ){ root[ii] = '.' ; root[ii+1] = '\0' ; } iarg++ ; continue ; } /**** -ALL ****/ if( strncmp(argv[iarg],"-ALL",6) == 0 || strncmp(argv[iarg],"-all",6) == 0 ){ xgood = ygood = zgood = 1 ; xbot = ybot = zbot = -BIGG ; xtop = ytop = ztop = BIGG ; iarg++ ; continue ; } /**** -RL {all | x1 x2} ****/ if( strncmp(argv[iarg],"-RL",6) == 0 || strncmp(argv[iarg],"-LR",6) == 0 || strncmp(argv[iarg],"-rl",6) == 0 || strncmp(argv[iarg],"-lr",6) == 0 || strncmp(argv[iarg],"-sag",6)== 0 ){ char * cerr ; float tf ; xgood = 1 ; /* mark for x projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ xbot = -BIGG; xtop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } xbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'R' && xbot > 0.0 ) xbot = -xbot ; xtop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'R' && xtop > 0.0 ) xtop = -xtop ; if( xbot > xtop ){ tf = xbot ; xbot = xtop ; xtop = tf ; } iarg +=3 ; continue ; } /**** -AP {all | y1 y2} ****/ if( strncmp(argv[iarg],"-AP",6) == 0 || strncmp(argv[iarg],"-PA",6) == 0 || strncmp(argv[iarg],"-ap",6) == 0 || strncmp(argv[iarg],"-pa",6) == 0 || strncmp(argv[iarg],"-cor",6)== 0 ){ char * cerr ; float tf ; ygood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ ybot = -BIGG ; ytop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } ybot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'A' && ybot > 0.0 ) ybot = -ybot ; ytop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'A' && ytop > 0.0 ) ytop = -ytop ; if( ybot > ytop ){ tf = ybot ; ybot = ytop ; ytop = tf ; } iarg +=3 ; continue ; } /**** -IS {all | z1 z2} ****/ if( strncmp(argv[iarg],"-IS",6) == 0 || strncmp(argv[iarg],"-SI",6) == 0 || strncmp(argv[iarg],"-is",6) == 0 || strncmp(argv[iarg],"-si",6) == 0 || strncmp(argv[iarg],"-axi",6)== 0 ){ char * cerr ; float tf ; zgood = 1 ; /* mark for y projection */ if( iarg+1 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } if( strncmp(argv[iarg+1],"all",6) == 0 || strncmp(argv[iarg+1],"ALL",6) == 0 ){ zbot = -BIGG ; ztop = BIGG ; iarg += 2 ; continue ; } if( iarg+2 >= argc ){ fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ; exit(-1) ; } zbot = strtod( argv[iarg+1] , &cerr ) ; if( cerr == argv[iarg+1] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+1] ) ; exit(-1) ; } if( *cerr == 'I' && zbot > 0.0 ) zbot = -zbot ; ztop = strtod( argv[iarg+2] , &cerr ) ; if( cerr == argv[iarg+2] ){ fprintf(stderr,"\n*** illegal argument after %s: %s\n", argv[iarg],argv[iarg+2] ) ; exit(-1) ; } if( *cerr == 'I' && ztop > 0.0 ) ztop = -ztop ; if( zbot > ztop ){ tf = zbot ; zbot = ztop ; ztop = tf ; } iarg +=3 ; continue ; } /**** unknown option ****/ fprintf(stderr,"\n*** Unknown option: %s\n",argv[iarg]) ; exit(-1) ; } /* end of loop over input options */ if( ! xgood && ! ygood && ! zgood ){ fprintf(stderr,"\n*** No projections ordered!?\n") ; exit(-1) ; } /*--- open dataset and set up to extract data slices ---*/ dset = THD_open_dataset( argv[iarg] ) ; if( dset == NULL ){ fprintf(stderr,"\n*** Can't open dataset file %s\n",argv[iarg]) ; exit(-1) ; } if( DSET_NUM_TIMES(dset) > 1 ){ fprintf(stderr,"\n*** Can't project time-dependent dataset!\n") ; exit(1) ; } EDIT_one_dataset( dset, &PRED_edopt ) ; daxes = dset->daxes ; brarr = THD_setup_bricks( dset ) ; baxi = brarr[0] ; bsag = brarr[1] ; bcor = brarr[2] ; /*--- determine index range for each direction ---*/ dr = PR_get_range( dset ) ; if( xgood ){ if( xbot < dr.xbot ) xbot = dr.xbot ; if( xtop > dr.xtop ) xtop = dr.xtop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xbot,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xtop,0,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bsag , iv ) ; ixtop = iv.ijk[2] ; if( ixbot > ixtop ) { ii = ixbot ; ixbot = ixtop ; ixtop = ii ; } if( ixbot < 0 ) ixbot = 0 ; if( ixtop >= bsag->n3 ) ixtop = bsag->n3 - 1 ; } if( ygood ){ if( ybot < dr.ybot ) ybot = dr.ybot ; if( ytop > dr.ytop ) ytop = dr.ytop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ybot,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jybot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ytop,0) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( bcor , iv ) ; jytop = iv.ijk[2] ; if( jybot > jytop ) { ii = jybot ; jybot = jytop ; jytop = ii ; } if( jybot < 0 ) jybot = 0 ; if( jytop >= bcor->n3 ) jytop = bcor->n3 - 1 ; } if( zgood ){ if( zbot < dr.zbot ) zbot = dr.zbot ; if( ztop > dr.ztop ) ztop = dr.ztop ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,zbot) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kzbot = iv.ijk[2] ; fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,ztop) ) ; iv = THD_3dmm_to_3dind ( dset , fv ) ; iv = THD_3dind_to_fdind( baxi , iv ) ; kztop = iv.ijk[2] ; if( kzbot > kztop ) { ii = kzbot ; kzbot = kztop ; kztop = ii ; } if( kzbot < 0 ) kzbot = 0 ; if( kztop >= baxi->n3 ) kztop = baxi->n3 - 1 ; } ival = DSET_PRINCIPAL_VALUE(dset) ; /* index to project */ ityp = DSET_BRICK_TYPE(dset,ival) ; /* type of this data */ fimfac = DSET_BRICK_FACTOR(dset,ival) ; /* scale factor of this data */ /*--- project the x direction, if desired ---*/ if( xgood ){ int n1 = bsag->n1 , n2 = bsag->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=ixbot ; ss <= ixtop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bsag ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Sagittal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Sagittal projection min = %g max = %g\n",fmin,fmax) ; strcpy(fname,root) ; strcat(fname,"sag") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the y direction, if desired ---*/ if( ygood ){ int n1 = bcor->n1 , n2 = bcor->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=jybot ; ss <= jytop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , bcor ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Coronal projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Coronal projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"cor") ; mri_write( fname, pim ) ; mri_free(pim) ; } /*--- project the z direction, if desired ---*/ if( zgood ){ int n1 = baxi->n1 , n2 = baxi->n2 ; int ss , npix ; float fmax , fmin , scl ; /*-- set up --*/ npix = n1*n2 ; flim = mri_new( n1 , n2 , MRI_float ) ; flar = mri_data_pointer( flim ) ; for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ; /*-- actually project --*/ for( ss=kzbot ; ss <= kztop ; ss++ ){ slim = FD_brick_to_mri( ss , ival , baxi ) ; if( slim->kind != MRI_float ){ pim = mri_to_float( slim ) ; mri_free( slim ) ; slim = pim ; } PR_one_slice( proj_code , slim , flim ) ; mri_free( slim ) ; } /*-- form output --*/ if( fimfac != 0.0 && fimfac != 1.0 ){ slim = mri_scale_to_float( 1.0/fimfac , flim ) ; mri_free(flim) ; flim = slim ; } scl = PR_type_scale( ityp , flim ) ; pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ; if( nsize ){ slim = mri_nsize( pim ) ; if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; } } if( scl != 1.0 ) printf("Axial projection pixels scaled by %g to avoid overflow!\n", scl ) ; fmax = mri_max(pim) ; fmin = mri_min(pim) ; printf("Axial projection min = %g max = %g\n",fmin,fmax) ; if( mirror_code == MIRR_YES ){ slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ; mri_free(pim) ; pim = slim ; } strcpy(fname,root) ; strcat(fname,"axi") ; mri_write( fname, pim ) ; mri_free(pim) ; } exit(0) ; }
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[] ) { 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 main( int argc , char *argv[] ) { THD_3dim_dataset *dset_in=NULL , *dset_out ; int Lxx=-1 , Lyy=-1 , Lzz=-1 , Mode=FFT_ABS , Sign=-1 , do_alt=0 ; char *prefix = "FFTout" ; int iarg ; MRI_IMAGE *inim , *outim ; float fac ; int nx,ny,nz ; THD_ivec3 iv ; if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dFFT [options] dataset\n" "\n" "* Does the FFT of the input dataset in 3 directions (x,y,z) and\n" " produces the output dataset.\n" "\n" "* Why you'd want to do this is an interesting question.\n" "\n" "* Program 3dcalc can operate on complex-valued datasets, but\n" " only on one component at a time (cf. the '-cx2r' option).\n" "\n" "* Most other AFNI programs can only operate on real-valued\n" " datasets.\n" "\n" "* You could use 3dcalc (twice) to split a complex-valued dataset\n" " into two real-valued datasets, do your will on those with other\n" " AFNI programs, then merge the results back into a complex-valued\n" " dataset with 3dTwotoComplex.\n" "\n" "Options\n" "=======\n" " -abs = Outputs the magnitude of the FFT [default]\n" " -phase = Outputs the phase of the FFT (-PI..PI == no unwrapping!)\n" " -complex = Outputs the complex-valued FFT\n" " -inverse = Does the inverse FFT instead of the forward FFT\n" "\n" " -Lx xx = Use FFT of length 'xx' in the x-direction\n" " -Ly yy = Use FFT of length 'yy' in the y-direction\n" " -Lz zz = Use FFT of length 'zz' in the z-direction\n" " * Set a length to 0 to skip the FFT in that direction\n" "\n" " -altIN = Alternate signs of input data before FFT, to bring\n" " zero frequency from edge of FFT-space to center of grid\n" " for cosmetic purposes.\n" " -altOUT = Alternate signs of output data after FFT. If you\n" " use '-altI' on the forward transform, then you should\n" " use '-altO' an the inverse transform, to get the\n" " signs of the recovered image correct.\n" " **N.B.: You cannot use '-altIN' and '-altOUT' in the same run!\n" "\n" " -input dd = Read the input dataset from 'dd', instead of\n" " from the last argument on the command line.\n" "\n" " -prefix pp = Use 'pp' for the output dataset prefix.\n" "\n" "Notes\n" "=====\n" " * In the present avatar, only 1 sub-brick will be processed.\n" "\n" #if 0 " * The program can only do FFT lengths that are factorable\n" " into a product of powers of 2, 3, and 5, and are even.\n" " + The largest power of 3 that is allowed is 3^3 = 27.\n" " + The largest power of 5 that is allowed is 5^3 = 125.\n" " + e.g., FFT of length 3*5*8=120 is possible.\n" " + e.g., FFT of length 4*31 =124 is not possible.\n" #else " * The program can only do FFT lengths that are positive\n" " even integers.\n" #endif "\n" " * The 'x', 'y', and 'z' axes here refer to the order the\n" " data is stored, not DICOM coordinates; cf. 3dinfo.\n" "\n" " * If you force (via '-Lx' etc.) an FFT length that is not\n" " allowed, the program will stop with an error message.\n" "\n" " * If you force an FFT length that is shorter than an dataset\n" " axis dimension, the program will stop with an error message.\n" "\n" " * If you don't force an FFT length along a particular axis,\n" " the program will pick the smallest legal value that is\n" " greater than or equal to the corresponding dataset dimension.\n" #if 0 " + e.g., 124 would be increased to 128.\n" #else " + e.g., 123 would be increased to 124.\n" #endif "\n" " * If an FFT length is longer than an axis length, then the\n" " input data in that direction is zero-padded at the end.\n" "\n" " * For -abs and -phase, the output dataset is in float format.\n" "\n" " * If you do the forward and inverse FFT, then you should get back\n" " the original dataset, except for roundoff error and except that\n" " the new dataset axis dimensions may be longer than the original.\n" "\n" " * Forward FFT = sum_{k=0..N-1} [ exp(-2*PI*i*k/N) * data(k) ]\n" "\n" " * Inverse FFT = sum_{k=0..N-1} [ exp(+2*PI*i*k/N) * data(k) ] / N\n" "\n" " * Started a long time ago, but only finished in Aug 2009 at the\n" " request of John Butman, because he asked so nicely. (Now pay up!)\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } PRINT_VERSION("3dFFT") ; mainENTRY("3dFFT main") ; machdep() ; AUTHOR("RW Cox") ; AFNI_logger("3dFFT",argc,argv) ; /*--- scan args ---*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncasecmp(argv[iarg],"-altI",5) == 0 ){ do_alt = 1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-altOUT",5) == 0 ){ do_alt = -1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-inverse",4) == 0 ){ Sign = +1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-abs",4) == 0 ){ Mode = FFT_ABS ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-phase",4) == 0 ){ Mode = FFT_PHASE ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-complex",4) == 0 ){ Mode = FFT_COMPLEX ; iarg++ ; continue ; } if( strlen(argv[iarg]) == 3 && strncmp(argv[iarg],"-L",2) == 0 ){ int lll=-1 , mmm ; char *ept ; iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after option %s",argv[iarg-1]) ; lll = strtol( argv[iarg] , &ept , 10 ) ; if( *ept != '\0' ) ERROR_exit("bad argument after option %s",argv[iarg-1]) ; if( lll > 0 && (mmm = csfft_nextup_even(lll)) != lll ) ERROR_exit( "'%s %d' is not a legal FFT length here: next largest legal value = %d" , argv[iarg-1] , lll , mmm ) ; switch( argv[iarg-1][2] ){ case 'x': case 'X': Lxx = lll ; break ; case 'y': case 'Y': Lyy = lll ; break ; case 'z': case 'Z': Lzz = lll ; break ; default: ERROR_exit("unknown option '%s'",argv[iarg-1]) ; } iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-prefix",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; prefix = strdup( argv[iarg] ) ; if( !THD_filename_ok(prefix) ) ERROR_exit("bad argument after %s\n",argv[iarg-1]) ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-input",4) == 0 ){ iarg++ ; if( iarg >= argc ) ERROR_exit("need an argument after %s\n",argv[iarg-1]) ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); iarg++ ; continue ; } ERROR_exit("unknown option '%s'\n",argv[iarg]) ; } /* check for simple errors */ if( Lxx == 0 && Lyy == 0 && Lzz == 0 ) ERROR_exit("-Lx, -Ly, -Lz all given as zero?!") ; /* open input dataset */ if( dset_in == NULL ){ if( iarg >= argc ) ERROR_exit("no input dataset on command line?!\n") ; dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]); } nx = DSET_NX(dset_in) ; ny = DSET_NY(dset_in) ; nz = DSET_NZ(dset_in) ; if( DSET_NVALS(dset_in) > 1 ) WARNING_message("only 3dFFT-ing sub-brick #0 of input dataset") ; /* establish actual FFT lengths now (0 ==> no FFT) */ if( nx == 1 ) Lxx = 0 ; /* can't FFT if dataset is shrimpy! */ if( ny == 1 ) Lyy = 0 ; if( nz == 1 ) Lzz = 0 ; if( Lxx < 0 ) Lxx = csfft_nextup_even(nx) ; /* get FFT length from */ if( Lyy < 0 ) Lyy = csfft_nextup_even(ny) ; /* dataset dimensions */ if( Lzz < 0 ) Lzz = csfft_nextup_even(nz) ; INFO_message("x-axis length=%d ; FFT length=%d %s",nx,Lxx,(Lxx==0)?"==> none":"\0") ; INFO_message("y-axis length=%d ; FFT length=%d %s",ny,Lyy,(Lyy==0)?"==> none":"\0") ; INFO_message("z-axis length=%d ; FFT length=%d %s",nz,Lzz,(Lzz==0)?"==> none":"\0") ; if( Lxx > 0 && Lxx < nx ) ERROR_exit("x-axis FFT length too short for data!") ; if( Lyy > 0 && Lyy < ny ) ERROR_exit("y-axis FFT length too short for data!") ; if( Lzz > 0 && Lzz < nz ) ERROR_exit("z-axis FFT length too short for data!") ; /* extract sub-brick #0 */ DSET_load(dset_in) ; CHECK_LOAD_ERROR(dset_in) ; inim = mri_to_complex( DSET_BRICK(dset_in,0) ) ; /* convert input to complex */ fac = DSET_BRICK_FACTOR(dset_in,0) ; if( fac > 0.0f && fac != 1.0f ){ /* scale it if needed */ int ii , nvox = nx*ny*nz ; complex *car = MRI_COMPLEX_PTR(inim) ; for( ii=0 ; ii < nvox ; ii++ ){ car[ii].r *= fac ; car[ii].i *= fac ; } } DSET_unload(dset_in) ; /* input data is all copied now */ /* FFT to get output image */ csfft_scale_inverse(1) ; /* scale by 1/N for inverse FFTs */ outim = mri_fft_3D( Sign , inim , Lxx,Lyy,Lzz , do_alt ) ; mri_free(inim) ; /* post-process output? */ switch( Mode ){ case FFT_ABS:{ MRI_IMAGE *qim = mri_complex_abs(outim) ; mri_free(outim) ; outim = qim ; } break ; case FFT_PHASE:{ MRI_IMAGE *qim = mri_complex_phase(outim) ; mri_free(outim) ; outim = qim ; } break ; } /* create and write output dataset */ dset_out = EDIT_empty_copy( dset_in ) ; tross_Copy_History( dset_in , dset_out ) ; tross_Make_History( "3dFFT" , argc,argv , dset_out ) ; LOAD_IVEC3( iv , outim->nx , outim->ny , outim->nz ) ; EDIT_dset_items( dset_out , ADN_prefix , prefix , ADN_nvals , 1 , ADN_ntt , 0 , ADN_nxyz , iv , /* change dimensions, possibly */ ADN_none ) ; EDIT_BRICK_FACTOR( dset_out , 0 , 0.0 ) ; EDIT_substitute_brick( dset_out , 0 , outim->kind , mri_data_pointer(outim) ) ; DSET_write(dset_out) ; WROTE_DSET(dset_out) ; DSET_unload(dset_out) ; exit(0) ; }
void BUCK_read_opts( int argc , char * argv[] ) { int nopt = 1 , ii ; char dname[THD_MAX_NAME] ; char subv[THD_MAX_NAME] ; char *cpt ; THD_3dim_dataset *dset , *fset=NULL ; int *svar ; char *str; int ok, ilen, nlen; INIT_3DARR(BUCK_dsar) ; INIT_XTARR(BUCK_subv) ; while( nopt < argc ){ if( strcmp(argv[nopt],"-help") == 0 || strcmp(argv[nopt],"-h") == 0) { BUCK_Syntax(strlen(argv[nopt])>3?2:1) ; exit(0); } /**** -prefix prefix ****/ if( strncmp(argv[nopt],"-prefix",6) == 0 || strncmp(argv[nopt],"-output",6) == 0 ){ if (BUCK_glue){ fprintf(stderr,"-prefix and -glueto options are not compatible\n"); exit(1) ; } nopt++ ; if( nopt >= argc ){ fprintf(stderr,"need argument after -prefix!\n") ; exit(1) ; } MCW_strncpy( BUCK_output_prefix , argv[nopt++] , THD_MAX_PREFIX ) ; continue ; } /**** -session directory ****/ if( strncmp(argv[nopt],"-session",6) == 0 ){ if (BUCK_glue){ fprintf(stderr, "-session and -glueto options are not compatible\n"); exit(1) ; } nopt++ ; if( nopt >= argc ){ fprintf(stderr,"need argument after -session!\n") ; exit(1) ; } MCW_strncpy( BUCK_session , argv[nopt++] , THD_MAX_NAME ) ; continue ; } if( strncmp(argv[nopt],"-dry",3) == 0 ){ BUCK_dry = BUCK_verb = 1 ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-fbuc",4) == 0 ){ BUCK_type = HEAD_FUNC_TYPE ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-abuc",4) == 0 ){ BUCK_type = HEAD_ANAT_TYPE ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-verb",5) == 0 ){ BUCK_verb = 1 ; nopt++ ; continue ; } if( strncmp(argv[nopt],"-glueto",5) == 0 || strncmp(argv[nopt],"-aglueto",5) == 0){ /* ZSS April 16 2010 */ if( strncmp(BUCK_output_prefix, "buck", 5) != 0 ){ fprintf(stderr, "-prefix, -glueto, and -aglueto options are not compatible\n"); exit(1) ; } if( strncmp(BUCK_session, "./", 5) != 0 ){ fprintf(stderr, "-session, -glueto, and -aglueto options are not compatible\n"); exit(1) ; } nopt++ ; if( nopt >= argc ){ fprintf(stderr,"need argument after -glueto or -aglueto!\n") ; exit(1) ; } if (strncmp(argv[nopt-1],"-aglueto",5) == 0) { /* ZSS April 16 2010 */ THD_3dim_dataset *ddd = THD_open_dataset( argv[nopt] ); if( !ISVALID_DSET(ddd) ){ /* treat as -prefix */ MCW_strncpy( BUCK_output_prefix , argv[nopt++] , THD_MAX_PREFIX ) ; continue ; } else { /* go on as standard -glueto option */ } } BUCK_glue = 1 ; /*----- Verify that file name ends in View Type -----*/ ok = 1; nlen = strlen(argv[nopt]); if (nlen <= 5) ok = 0; if (ok) { #if 0 /* old code - scan from end, instead */ for (ilen = 0; ilen < nlen; ilen++) { str = argv[nopt] + ilen; if (str[0] == '+') break; } if (ilen == nlen) ok = 0; #endif /* scan from end for view type extension, require one char */ /* 30 Oct 2003 [rickr] */ for (ilen = nlen - 1; ilen > 0; ilen--) { str = argv[nopt] + ilen; if (str[0] == '+') break; } if (ilen == 0) ok = 0; } if (ok) { str = argv[nopt] + ilen + 1; for (ii=FIRST_VIEW_TYPE ; ii <= LAST_VIEW_TYPE ; ii++) if (! strncmp(str,VIEW_codestr[ii],4)) break ; if( ii > LAST_VIEW_TYPE ) ok = 0; } if (! ok) { fprintf(stderr, "File name must end in +orig, +acpc, or +tlrc after -glueto\n" "(consider: 3dbucket -prefix dsetA -overwrite dsetA dsetB ...)\n"); exit(1); } /*----- Remove View Type from string to make output prefix -----*/ MCW_strncpy( BUCK_output_prefix , argv[nopt] , ilen+1) ; /*----- Note: no "continue" statement here. File name will now be processed as an input dataset -----*/ } if( strncmp(argv[nopt],"-aglueto",5) == 0 ){ if( strncmp(BUCK_output_prefix, "buck", 5) != 0 ){ fprintf(stderr,"-prefix and -aglueto options are not compatible.\n" "Make sure you do not have two -agluto options on command.\n"); exit(1) ; } if( strncmp(BUCK_session, "./", 5) != 0 ){ fprintf(stderr, "-session and -aglueto options are not compatible\n"); exit(1) ; } BUCK_glue = 1 ; nopt++ ; if( nopt >= argc ){ fprintf(stderr,"need argument after -glueto!\n") ; exit(1) ; } /*----- Verify that file name ends in View Type -----*/ ok = 1; nlen = strlen(argv[nopt]); if (nlen <= 5) ok = 0; if (ok) { #if 0 /* old code - scan from end, instead */ for (ilen = 0; ilen < nlen; ilen++) { str = argv[nopt] + ilen; if (str[0] == '+') break; } if (ilen == nlen) ok = 0; #endif /* scan from end for view type extension, require one char */ /* 30 Oct 2003 [rickr] */ for (ilen = nlen - 1; ilen > 0; ilen--) { str = argv[nopt] + ilen; if (str[0] == '+') break; } if (ilen == 0) ok = 0; } if (ok) { str = argv[nopt] + ilen + 1; for (ii=FIRST_VIEW_TYPE ; ii <= LAST_VIEW_TYPE ; ii++) if (! strncmp(str,VIEW_codestr[ii],4)) break ; if( ii > LAST_VIEW_TYPE ) ok = 0; } if (! ok) { fprintf(stderr, "File name must end in +orig, +acpc, or +tlrc after -glueto\n" "(consider: 3dbucket -prefix dsetA -overwrite dsetA dsetB ...)\n"); exit(1); } /*----- Remove View Type from string to make output prefix -----*/ MCW_strncpy( BUCK_output_prefix , argv[nopt] , ilen+1) ; /*----- Note: no "continue" statement here. File name will now be processed as an input dataset -----*/ } if( argv[nopt][0] == '-' ){ fprintf(stderr,"Unknown option: %s\n",argv[nopt]) ; suggest_best_prog_option(argv[0], argv[nopt]); exit(1) ; } /**** read dataset ****/ cpt = strstr(argv[nopt],"[") ; if( cpt == NULL ){ if (strlen(argv[nopt]) > THD_MAX_NAME-1) { ERROR_exit( "Too long a filename for '%s'\n" "Maximum limit is %d\n", argv[nopt], THD_MAX_NAME-1); } strcpy(dname,argv[nopt]) ; subv[0] = '\0' ; /* make sure subv is reset ZSS Nov. 2010*/ } else if( cpt == argv[nopt] ){ fprintf(stderr,"illegal dataset specifier: %s\n",argv[nopt]) ; exit(1) ; } else { ii = cpt - argv[nopt] ; if (ii > THD_MAX_NAME-1) { ERROR_exit( "Too long a filename for '%s'\n" "Maximum character limit is %d, have %d\\n", argv[nopt], THD_MAX_NAME-1, ii); } if (strlen(argv[nopt])-ii > THD_MAX_NAME-1) { ERROR_exit( "Too long a sub-brick selection for '%s'\n" "Maximum limit is %d, have %d\n" "Consider using '[1dcat FF.1D]' or '[count ...]' methods\n" "for sub-brick selection. See 3dTcat -help for details.\n", argv[nopt], THD_MAX_NAME-1, strlen(argv[nopt])-ii); } memcpy(dname,argv[nopt],ii) ; dname[ii] = '\0' ; strcpy(subv,cpt) ; } nopt++ ; dset = THD_open_one_dataset( dname ) ; if( dset == NULL ){ fprintf(stderr,"can't open dataset %s\n",dname) ; exit(1) ; } THD_force_malloc_type( dset->dblk , DATABLOCK_MEM_MALLOC ) ; if( BUCK_type < 0 ) BUCK_type = dset->type ; BUCK_ccode = COMPRESS_filecode(dset->dblk->diskptr->brick_name) ; /* 16 Mar 2010 */ ii = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz ; if( BUCK_nvox < 0 ){ BUCK_nvox = ii ; fset = dset ; } else if( ii != BUCK_nvox ){ ERROR_exit("Dataset %s differs in size from first one",dname); } else if( !EQUIV_GRIDS(dset,fset) ){ WARNING_message("Dataset %s grid differs from first one",dname) ; } ADDTO_3DARR(BUCK_dsar,dset) ; if (subv == NULL || subv[0] == '\0') { /* lazy way for 3dbucket special */ svar = BUCK_get_subv( DSET_NVALS(dset) , subv ) ; /* ZSS Dec 09 */ } else { svar = MCW_get_thd_intlist (dset, subv); /* ZSS Dec 09 */ } if( svar == NULL || svar[0] <= 0 ){ fprintf(stderr,"can't decipher index codes from %s%s\n",dname,subv) ; exit(1) ; } ADDTO_XTARR(BUCK_subv,svar) ; } /* end of loop over command line arguments */ if( argc < 2) { ERROR_message("Too few options"); BUCK_Syntax(0) ; exit(1); } return ; }
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() ) ; }
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; }