Exemple #1
0
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) ;
   }            

}
Exemple #2
0
int main(int argc, char *argv[]) 
{  
   int CHECK = 0;
	int iarg;
   char *Fname_input = NULL;
   char *Fname_output = NULL;
   char *Fname_outputBV = NULL;
   char *Fname_bval = NULL;
   int opt;
   FILE *fin=NULL, *fout=NULL, *finbv=NULL, *foutBV=NULL;
   int i,j,k;
   int BZER=0,idx=0,idx2=0;

   MRI_IMAGE *flim=NULL;
   MRI_IMAGE *preREADIN=NULL;
   MRI_IMAGE *preREADBVAL=NULL;
   float *READIN=NULL;
   float *READBVAL=NULL;

   float OUT_MATR[MAXGRADS][7]; // b- or g-matrix
   float OUT_GRAD[MAXGRADS][4]; // b- or g-matrix

   int INV[3] = {1,1,1}; // if needing to switch
   int FLAG[MAXGRADS];
   float temp;
   int YES_B = 0;
   int EXTRA_ZEROS=0;
   int HAVE_BVAL = 0;
   int BVAL_OUT = 0; 
   int BVAL_OUT_SEP = 0; 
   float BMAX_REF = 1; // i.e., essentially zero
   int IN_FORM = 0; // 0 for row, 1 for col
   int OUT_FORM = 1; // 1 for col, 2 for bmatr 
   int HAVE_BMAX_REF=0 ; // referring to user input value
   int count_in=0, count_out=0;

	THD_3dim_dataset *dwset=NULL, *dwout=NULL; 
   int Nbrik = 0;
	char *prefix=NULL ;
   float **temp_arr=NULL, **temp_grad=NULL;
   int Ndwi = 0, dwi=0, Ndwout = 0, Ndwi_final = 0, Ndwout_final = 0;
   int Nvox = 0;
   int DWI_COMP_FAC = 0;
   int ct_dwi = 0;
   float MaxDP = 0;

	mainENTRY("1dDW_Grad_o_Mat"); machdep();
    
   if (argc == 1) { usage_1dDW_Grad_o_Mat(1); exit(0); }

   iarg = 1;
	while( iarg < argc && argv[iarg][0] == '-' ){
		if( strcmp(argv[iarg],"-help") == 0 || 
			 strcmp(argv[iarg],"-h") == 0 ) {
         usage_1dDW_Grad_o_Mat(strlen(argv[iarg])>3 ? 2:1);
			exit(0);
		}
      
      if( strcmp(argv[iarg],"-flip_x") == 0) {
			INV[0] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-flip_y") == 0) {
			INV[1] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-flip_z") == 0) {
			INV[2] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-keep_b0s") == 0) {
			YES_B = 1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-put_zeros_top") == 0) {
			EXTRA_ZEROS = 1;
			iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-in_grad_rows") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_grad_rows'\n") ;

         Fname_input = argv[iarg];
         count_in++;

         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_grad_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_grad_cols'\n") ;

         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 1;

         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_gmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matT_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 2;
         
         iarg++ ; continue ;
		} 
      if( strcmp(argv[iarg],"-in_gmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matA_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 3;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_bmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matT_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 4;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_bmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matA_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 5;
         
         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-out_grad_rows") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_grad_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 0;

         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-out_grad_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_grad_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 1;

         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-out_gmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_gmatT_cols'\n") ;
         
         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 2;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-out_gmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_gmatA_cols'\n") ;
         
         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 3;
         
         iarg++ ; continue ;
		}  
      if( strcmp(argv[iarg],"-out_bmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bmatT_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 4;
         
         iarg++ ; continue ;
		}
      
      if( strcmp(argv[iarg],"-out_bmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bmatA_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 5;
         
         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-in_bvals") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_bvals'\n") ;
         
         Fname_bval = argv[iarg];
         HAVE_BVAL = 1;

         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-bmax_ref") == 0) { 
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-bmax_ref'\n");
         
         BMAX_REF = atof(argv[iarg]);
         HAVE_BMAX_REF = 1;
         
         iarg++ ; continue ;
		}
      
      if( strcmp(argv[iarg],"-out_bval_col") == 0) {
			BVAL_OUT = 1;
			iarg++ ; continue ;
		}

      // May,2015
      if( strcmp(argv[iarg],"-out_bval_row_sep") == 0) {
         if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bval_row_sep'\n") ;
         
         Fname_outputBV = argv[iarg];
         BVAL_OUT_SEP = 1;
         
         iarg++ ; continue ;
		}
      
		if( strcmp(argv[iarg],"-proc_dset") == 0 ){ // in DWIs
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-proc_dset'") ;
			dwset = THD_open_dataset( argv[iarg] ) ;
			if( dwset == NULL ) 
				ERROR_exit("Can't open DWI dataset '%s'", argv[iarg]) ;
			DSET_load(dwset) ; CHECK_LOAD_ERROR(dwset) ;
			
			iarg++ ; continue ;
		}
		
      if( strcmp(argv[iarg],"-pref_dset") == 0 ){ // will be output
			iarg++ ; if( iarg >= argc ) 
							ERROR_exit("Need argument after '-pref_dset'");
			prefix = strdup(argv[iarg]) ;
			if( !THD_filename_ok(prefix) ) 
				ERROR_exit("Illegal name after '-pref_dset'");
			iarg++ ; continue ;
		}
		
      if( strcmp(argv[iarg],"-dwi_comp_fac") == 0) { 
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-dwi_comp_fac'\n");
         
         DWI_COMP_FAC = atoi(argv[iarg]);
         if (DWI_COMP_FAC <=1)
            ERROR_exit("The compression factor after '-dwi_comp_fac'"
                       "must be >1!");

         iarg++ ; continue ;
		}

      ERROR_message("Bad option '%s'\n",argv[iarg]) ;
		suggest_best_prog_option(argv[0], argv[iarg]);
		exit(1);
      
   }

   //  * * * * * * * * * * * * * * * * * * * * * * * * * * * 

   if( (Fname_input == NULL) ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Option '-in_*' requires argument.\n");
      exit(1);
   }
   if( (Fname_output == NULL) ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Option '-out_*' requires arg.\n");
      exit(2);
   }

   if( count_in > 1 ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Can't have >1 vec file input.\n");
      exit(3);
   }
   if( count_out > 1 ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Can't have >1 output file opt.\n");
      exit(4);
   }

   if(YES_B && dwset) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have '-keep_b0s' and '-proc_dset' together.\n");
      exit(5);
   }
   
   if( !prefix && dwset) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Need an output '-pref_dset' when using '-proc_dset'.\n");
      exit(6);
   }
   
   if(YES_B && DWI_COMP_FAC) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have '-keep_b0s' and '-dwi_comp_fac' together.\n");
      exit(7);
   }
   

   if(!HAVE_BVAL && (BVAL_OUT || BVAL_OUT_SEP)) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have ask for outputting bvals with no '-in_bvals FILE'.\n");
      exit(8);
   }


   // ********************************************************************
   // ************************* start reading ****************************
   // ********************************************************************

   flim = mri_read_1D (Fname_input);
   if (flim == NULL) {
         ERROR_exit("Error reading gradient vector file");
      }
   if( IN_FORM )
      preREADIN = mri_transpose(flim); // effectively *undoes* autotranspose
   else
      preREADIN = mri_copy(flim);
   mri_free(flim);
   idx = preREADIN->ny;

   if( HAVE_BVAL ) {
      flim = mri_read_1D (Fname_bval);
      if (flim == NULL) {
         ERROR_exit("Error reading b-value file");
      }
      if( flim->ny == 1)
         preREADBVAL = mri_transpose(flim); // effectively *undoes* autotransp
      else
         preREADBVAL = mri_copy(flim); 
      mri_free(flim);
      idx2 = preREADBVAL->ny;

   }

   if(idx>= MAXGRADS ) {
      printf("Error, too many input grads.\n");
      mri_free (preREADIN);
      if( HAVE_BVAL ) mri_free (preREADBVAL);
      exit(4);
   }

   if( ( (preREADIN->nx != 3 ) && (preREADIN->ny != 3 )) &&
       (preREADIN->nx != 6 ) )
      printf("Probably an error, "
             "because there aren't 3 or 6 numbers in columns!\n");

   if( HAVE_BVAL && ( idx != idx2 ) ) {
      printf("Error, because the number of bvecs (%d)\n"
             "and bvals (%d) don't appear to match!\n", idx, idx2);
      mri_free (preREADIN);
      mri_free (preREADBVAL);
      exit(3);
   }

   if(dwset) {
      Nbrik = DSET_NVALS(dwset);

      if( idx != Nbrik ) {
         fprintf(stderr,
                 "\n** ERROR: the number of bvecs (%d) does not match the "
                 "number of briks in '-proc_dset' (%d).\n", idx, Nbrik);
         exit(4);
      }
   }

   READIN = MRI_FLOAT_PTR( preREADIN );
   if( HAVE_BVAL )
      READBVAL = MRI_FLOAT_PTR( preREADBVAL );


   // 0 is grad row;  
   // 1 is grad col;
   // 2 is gmatrRow col T;
   // 3 is gmatrDiag col A;
   // 4 is bmatrRow col T;
   // 5 is bmatrDiag col A;

   //if( IN_FORM == 0 ) // grad rows, no binfo
   // for( i=0; i<idx ; i++ ) 
   //    for ( j=0; j<3 ; j++ )
   //       OUT_GRAD[i][j+1] = *(READIN +j*idx +i) ;
   //else 
   if ( IN_FORM <= 1 )  // grad cols, no binfo
      for( i=0; i<idx ; i++ ) 
         for ( j=0; j<3 ; j++ )
            OUT_GRAD[i][j+1] = *(READIN + 3*i+j);
   
   // A/row/3dDWItoDT: Bxx, Byy, Bzz, Bxy, Bxz, Byz
   // T/diag/TORTOISE:  b_xx 2b_xy 2b_xz b_yy 2b_yz b_zz
   else if ( (IN_FORM == 3) || (IN_FORM ==5 ) ) { // diag matr
      for( i=0; i<idx ; i++ ) { 
         for( j=0; j<3 ; j++ ) {
            OUT_MATR[i][j+1] = *(READIN+6*i+j);
            OUT_MATR[i][3+j+1] = *(READIN+6*i+3+j);
         }

         for( j=0; j<3 ; j++ ) 
            if(OUT_MATR[i][j] < 0 )
               CHECK++;
      }
      if(CHECK > 0)
         INFO_message("Warning: you *said* you input a mat'T',"
                      " but the matr diagonals don't appear to be uniformly"
                      " positive. If input cols 0, 3 and 5 are positive,"
                      " then you might have meant mat'A'?");
   }
   else if ( (IN_FORM ==2 ) || (IN_FORM ==4 ) ) { // row matr
      CHECK = 0;
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][1] = *(READIN +6*i);
         OUT_MATR[i][2] = *(READIN +6*i+3);
         OUT_MATR[i][3] = *(READIN +6*i+5);
         OUT_MATR[i][4] = *(READIN +6*i+1)/2.;
         OUT_MATR[i][5] = *(READIN +6*i+2)/2.;
         OUT_MATR[i][6] = *(READIN +6*i+4)/2.;
      }
      for( i=0; i<idx ; i++ ) 
         for( j=0; j<3 ; j++ ) 
            if(OUT_MATR[i][j] < 0 )
               CHECK++;
      if(CHECK > 0)
         INFO_message("Warning: you *said* you input a mat'A',"
                      " but the matr diagonals don't appear to be uniformly"
                      " positive. If input cols 0, 1 and 2 are positive,"
                      " then you might have meant mat'T'?");
   }
   else{
      fprintf(stderr, "Coding error with format number (%d), not allowed.\n",
              IN_FORM);
      exit(2);
   }
   
   // get bval info
   if( ( (IN_FORM ==4 ) || (IN_FORM ==5 ) ) ) { //bval
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][0] = OUT_GRAD[i][0] =
            OUT_MATR[i][1] + OUT_MATR[i][2] + OUT_MATR[i][3];
         if( OUT_MATR[i][0] > 0.000001)
            for( j=1 ; j<7 ; j++ )
               OUT_MATR[i][j]/= OUT_MATR[i][0];
      }
   }
   else if ( HAVE_BVAL )
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][0] = OUT_GRAD[i][0] =  *(READBVAL + i);
      }
   else if ( OUT_FORM > 3 || BVAL_OUT ||  BVAL_OUT_SEP || HAVE_BMAX_REF ) {
      fprintf(stderr, "ERROR:  you asked for b-value dependent output, "
              "but gave me no bvals to work with.\n");
      exit(2);
   }
      
   // * * *  ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * *
   // at this point, all IN_FORM >1 cases which need bval have led to:
   //    + grad[0] has bval
   //    + matr[0] has bval
   //    + matr file normalized and in diagonal form
   // * * *  ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * *

   for( i=0; i<idx ; i++ ) 
      if( IN_FORM > 1)
         j = GradConv_Gsign_from_BmatA( OUT_GRAD[i]+1, OUT_MATR[i]+1);
      else
         j = GradConv_BmatA_from_Gsign( OUT_MATR[i]+1, OUT_GRAD[i]+1);


   // flip if necessary
   for( i=0 ; i<idx ; i++) {
      for( j=0 ; j<3 ; j++) 
         OUT_GRAD[i][j+1]*= INV[j];
      OUT_MATR[i][4]*= INV[0]*INV[1];
      OUT_MATR[i][5]*= INV[0]*INV[2];
      OUT_MATR[i][6]*= INV[1]*INV[2];
   }
   
   BZER=0;
   for( i=0 ; i<idx ; i++) {
      if( HAVE_BVAL || (IN_FORM ==4) || (IN_FORM ==5) )
         if( OUT_GRAD[i][0] >= BMAX_REF ) 
            FLAG[i] = 1;
         else{
            if( YES_B ) 
               FLAG[i] = 1;
            BZER++;
         }
      else {
         temp = 0.;
         for( j=1 ; j<4 ; j++) 
            temp+= pow(OUT_GRAD[i][j],2);
         
         if( temp > 0.1 )
            FLAG[i] = 1;
         else{
            if( YES_B ) 
               FLAG[i] = 1;
            BZER++;
         }
      }
   }
   
   if(YES_B) {
      printf("\tChose to *keep* %d b0s,\tas well as  \t%d grads\n",
             BZER,idx-BZER);
      BZER=0;
   }
   else {
      printf("\tGetting rid of %d b0s,\tleaving the %d grads\n",
             BZER,idx-BZER);
      Ndwi = idx-BZER;
   }
   Ndwi_final = idx-BZER; // default:  all DWIs

   if( DWI_COMP_FAC ) {
      if( Ndwi % DWI_COMP_FAC != 0 ) {
         fprintf(stderr, "\n** ERROR can't compress: "
                 "Ndwi=%d, and %d/%d has a nonzero remainder (=%d).\n",
                 Ndwi,Ndwi,DWI_COMP_FAC, Ndwi % DWI_COMP_FAC );
         exit(1);
      }
      else {
         Ndwi_final = Ndwi/DWI_COMP_FAC;
         INFO_message("You have chosen a compression factor of %d, "
                      "with %d DWIs,\n"
                      "\tso that afterward there will be %d DWIs.",
                      DWI_COMP_FAC, Ndwi, Ndwi_final);
      }
   }

   if(BVAL_OUT_SEP)
      if( (foutBV = fopen(Fname_outputBV, "w")) == NULL) {
         fprintf(stderr, "\n\nError opening file %s.\n",Fname_outputBV);
         exit(1);
      }

   if( (fout = fopen(Fname_output, "w")) == NULL) {
      fprintf(stderr, "\n\nError opening file %s.\n",Fname_output);
      exit(1);
   }

   // 0 is grad row;  
   // 1 is grad col;
   // 2 is gmatrRow col T;
   // 3 is gmatrDiag col A;
   // 4 is bmatrRow col T;
   // 5 is bmatrDiag col A;

   if( OUT_FORM>0) {
      if( EXTRA_ZEROS ) {
         if( BVAL_OUT )
            fprintf(fout,"%8d  ", 0);
         if( BVAL_OUT_SEP )
            fprintf(foutBV,"%8d  ", 0);

         if( OUT_FORM == 1 )
            for( k=1 ; k<4 ; k++ )
               fprintf(fout,"%11.5f  ", 0.0);
         else if ( OUT_FORM > 1 ) // bit superfluous at this point
            for( k=1 ; k<7 ; k++ )
               fprintf(fout,"%11.5f  ", 0.0);
         fprintf(fout,"\n");
      }

      ct_dwi = 0;
      for(i=0 ; i<idx ; i++){ 
         if(FLAG[i]) {
            
            if( BVAL_OUT )
               fprintf(fout,"%8d  ", (int) OUT_GRAD[i][0]);
            if( BVAL_OUT_SEP )
               fprintf(foutBV,"%8d  ", (int) OUT_GRAD[i][0]);

            if( (OUT_FORM == 4) || (OUT_FORM ==5) )
               for( k=1 ; k<7 ; k++ )
                  OUT_MATR[i][k]*= OUT_MATR[i][0];
            
            if( OUT_FORM == 1 ) // grad col
               for( k=1 ; k<4 ; k++ )
                  fprintf(fout,"%11.5f  ", OUT_GRAD[i][k]);
            
            else if( (OUT_FORM == 3) || (OUT_FORM == 5) ) { // gmat
               for( k=1 ; k<6 ; k++ )
                  fprintf(fout,"%11.5f  ", OUT_MATR[i][k]);
               fprintf(fout,"%11.5f", OUT_MATR[i][k]);
            }
            else if ( (OUT_FORM == 2 ) || (OUT_FORM ==4)) { // bmat
               fprintf(fout,"%11.5f  ", OUT_MATR[i][1]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][4]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][5]);
               fprintf(fout,"%11.5f  ", OUT_MATR[i][2]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][6]);
               fprintf(fout,"%11.5f",   OUT_MATR[i][3]);
            }
            
            fprintf(fout,"\n");
            ct_dwi++;
         }
         if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) {
            INFO_message("Reached compression level:  DWI number %d",
                         Ndwi_final);
            break;
         }
      }
   }
   else if(OUT_FORM ==0) {
      if(BVAL_OUT)
         WARNING_message("Ignoring '-out_bval_col' option, since "
                         " you are outputting in rows.");
      
      for( k=1 ; k<4 ; k++ ) {
         if(EXTRA_ZEROS){
            fprintf(fout,"% -11.5f  ", 0.0);
            if( (k==1) && BVAL_OUT_SEP ) // only output 1 zeroin bval file
               fprintf(foutBV,"%8d  ", 0);
         }
         ct_dwi = 0;
         for(i=0 ; i<idx ; i++) {
            if(FLAG[i]) {
               fprintf(fout,"% -11.5f  ", OUT_GRAD[i][k]);
               if( (k==1) && BVAL_OUT_SEP )// only output 1 zeroin bval file
                  fprintf(foutBV,"%8d  ", (int) OUT_GRAD[i][0]);
               ct_dwi++;
            }
            if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) {
               INFO_message("Reached compression level:  DWI number %d",
                            Ndwi_final);
               break;
            }
         }
         fprintf(fout,"\n");
      }
   }

   fclose(fout);
   if( BVAL_OUT_SEP ) {
      fprintf(foutBV,"\n");
      fclose(foutBV);
   }

   if(dwset) {
      INFO_message("Processing the B0+DWI file now.");
      if(!BZER) {
         fprintf(stderr, "\n** Error in processing data set: "
                 "no b=0 values from bvecs/bval info!\n");
         exit(5);
      }

      // FLAG marks where DWIs are if not using '-keep_b0s'!

      Nvox = DSET_NVOX(dwset);
      Ndwout = Ndwi+1;

      temp_arr = calloc( Ndwout,sizeof(temp_arr));
      for( i=0 ; i<Ndwout ; i++) 
         temp_arr[i] = calloc( Nvox,sizeof(float)); 
      temp_grad = calloc( Ndwi,sizeof(temp_grad));
      for( i=0 ; i<Ndwi ; i++) 
         temp_grad[i] = calloc( 3,sizeof(float)); 

      if( (temp_arr == NULL) || (temp_grad == NULL) ) {
            fprintf(stderr, "\n\n MemAlloc failure.\n\n");
            exit(123);
      }

      dwi = 0; // keep track of DWI contraction
      for( i=0 ; i<Nbrik ; i++)
         if( !FLAG[i] ) // b=0
            for( j=0 ; j<Nvox ; j++)
               temp_arr[0][j]+= THD_get_voxel(dwset,j,i);
         else {
            for( j=0 ; j<3 ; j++)
               temp_grad[dwi][j]= OUT_GRAD[i][j+1];
            dwi++;
            for( j=0 ; j<Nvox ; j++)
               temp_arr[dwi][j]+= THD_get_voxel(dwset,j,i);
         }
      if( dwi != Ndwi ) {
         fprintf(stderr, "\n** Mismatch in internal DWI counting!\n");
         exit(6);
      }

      // average the values
      for( j=0 ; j<Nvox ; j++)
         temp_arr[0][j]/= BZER; // can't be zero here.
      
      if( DWI_COMP_FAC ) {
         INFO_message("Compressing DWI file");

         for( k=1 ; k<DWI_COMP_FAC ; k++)
            for( i=0 ; i<Ndwi_final ; i++)
               for( j=0 ; j<Nvox ; j++)
                  temp_arr[1+i][j]+= temp_arr[1+k*Ndwi_final+i][j];
         
         for( i=0 ; i<Ndwi_final ; i++)
            for( j=0 ; j<Nvox ; j++)
               temp_arr[1+i][j]/= DWI_COMP_FAC;

         INFO_message("Checking closeness of compressed gradient values");
         MaxDP = GradCloseness(temp_grad, Ndwi, DWI_COMP_FAC);

         INFO_message("The max angular difference between matched/compressed\n"
                      "\tgradients is: %f", MaxDP);
         if( MaxDP > 2)
            WARNING_message("The max angular difference seem kinda big-- you\n"
                            " sure about the compression factor?");
      }

      Ndwout_final = Ndwi_final + 1;
      INFO_message("Writing the processed data set.");
      dwout = EDIT_empty_copy( dwset ); 
      EDIT_dset_items(dwout,
                      ADN_nvals, Ndwout_final,
                      ADN_ntt, 0,
                      ADN_datum_all, MRI_float , 
                      ADN_prefix, prefix,
                      ADN_none );

      for( i=0; i<Ndwout_final ; i++) {
         EDIT_substitute_brick(dwout, i, MRI_float, temp_arr[i]);
         temp_arr[i]=NULL;
      }

      // if necessary
      for( i=Ndwout_final ; i<Ndwout ; i++)
         temp_arr[i]=NULL;

      THD_load_statistics( dwout );
      if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(dwout)) )
         ERROR_exit("Can't overwrite existing dataset '%s'",
                    DSET_HEADNAME(dwout));
      tross_Make_History("1dDW_Grad_o_Mat", argc, argv, dwout);
      THD_write_3dim_dataset(NULL, NULL, dwout, True);
      DSET_delete(dwout); 
      free(dwout); 
      DSET_delete(dwset); 
      free(dwset); 

      for( i=0 ; i<Ndwout_final ; i++)
         free(temp_arr[i]);
      free(temp_arr);
   }

   mri_free(preREADIN);
   if( HAVE_BVAL )
      mri_free(preREADBVAL);
   if(prefix)
      free(prefix);

   

   printf("\n\tDone. Check output file '%s' for results",Fname_output);
   if(dwset) {
      printf("\n\t-> as well as the data_set '%s'",DSET_FILECODE(dwout));
   }
   if(BVAL_OUT_SEP)
      printf("\n\t-> and even the b-value rows '%s'",Fname_outputBV);
   printf("\n\n");

   exit(0);   
}
Exemple #3
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) ;
}
Exemple #4
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);
}
Exemple #5
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 ;
}
Exemple #7
0
int main( int argc , char * argv[] )
{
   int iarg ;
   THD_3dim_dataset *inset , *outset ;
   int add_I=0 , add_S=0 , add_A=0 , add_P=0 , add_L=0 , add_R=0 ;
   int RLsiz=0, APsiz=0, ISsiz=0 ; /* 23 Mar 2004 */
   char * prefix="zeropad" ;

   int add_z=0 ;   /* 07 Feb 2001 */
   int mm_flag=0 ; /* 13 Feb 2001 */
   int flag ;

   THD_3dim_dataset *mset=NULL ; /* 14 May 2002 */

   /*-- help? --*/
   mainENTRY("3dZeropad main"); machdep(); AFNI_logger("3dZeropad",argc,argv);
   PRINT_VERSION("3dZeropad") ;

   /*-- read command line options --*/
   if( argc == 1){ usage_3dZeropad(1); exit(0); } /* Bob's help shortcut */

   iarg = 1 ;
   while( iarg < argc && argv[iarg][0] == '-' ){

      if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
         usage_3dZeropad(strlen(argv[iarg])>3 ? 2:1);
         exit(0);
      }

      /*- -I, -S, etc. -*/

      if( strlen(argv[iarg]) == 2 ){
         switch( argv[iarg][1] ){
            case 'I': add_I = (int) strtod(argv[++iarg],NULL) ; break ;
            case 'S': add_S = (int) strtod(argv[++iarg],NULL) ; break ;
            case 'A': add_A = (int) strtod(argv[++iarg],NULL) ; break ;
            case 'P': add_P = (int) strtod(argv[++iarg],NULL) ; break ;
            case 'L': add_L = (int) strtod(argv[++iarg],NULL) ; break ;
            case 'R': add_R = (int) strtod(argv[++iarg],NULL) ; break ;

            /* 07 Feb 2001: slice-direction is special */

            case 'z':
            case 'Z': add_z = (int) strtod(argv[++iarg],NULL) ; break ;

            default:
               fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; exit(1) ;
         }

         if( mset != NULL ){
           fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg-1]) ;
           exit(1) ;
         }

         iarg++ ; continue ;  /* skip to next argument */
      }

      /*- -RL, -AP, -IS [23 Mar 2004] -*/

      if( strcmp(argv[iarg],"-RL") == 0 || strcmp(argv[iarg],"-LR") == 0 ){
        if( add_R || add_L || mset != NULL ){
          fprintf(stderr,"** 3dZeropad: Can't use -RL with -R, -L, or -master!\n");
          exit(1) ;
        }
        RLsiz = (int) strtod(argv[++iarg],NULL) ;
        if( RLsiz < 1 ){
          fprintf(stderr,"** 3dZeropad: value after -RL is illegal!\n") ;
          exit(1) ;
        }
        iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-AP") == 0 || strcmp(argv[iarg],"-PA") == 0 ){
        if( add_A || add_P || mset != NULL ){
          fprintf(stderr,"** 3dZeropad: Can't use -AP with -A, -P, or -master!\n");
          exit(1) ;
        }
        APsiz = (int) strtod(argv[++iarg],NULL) ;
        if( APsiz < 1 ){
          fprintf(stderr,"** 3dZeropad: value after -AP is illegal!\n") ;
          exit(1) ;
        }
        iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-IS") == 0 || strcmp(argv[iarg],"-SI") == 0 ){
        if( add_S || add_I || mset != NULL ){
          fprintf(stderr,"** 3dZeropad: Can't use -IS with -I, -S, or -master!\n");
          exit(1) ;
        }
        ISsiz = (int) strtod(argv[++iarg],NULL) ;
        if( ISsiz < 1 ){
          fprintf(stderr,"** 3dZeropad: value after -IS is illegal!\n") ;
          exit(1) ;
        }
        iarg++ ; continue ;
      }

      /*- -mm -*/

      if( strcmp(argv[iarg],"-mm") == 0 ){
         if( mset != NULL ){
           fprintf(stderr,"** 3dZeropad: Can't use %s with -master!\n",argv[iarg]) ;
           exit(1) ;
         }
         mm_flag = 1 ;
         iarg++ ; continue ;
      }

      /*- -prefix -*/

      if( strcmp(argv[iarg],"-prefix") == 0 ){
         prefix = argv[++iarg] ;
         if( !THD_filename_ok(prefix) ){
            fprintf(stderr,"** 3dZeropad: Illegal string after -prefix!\n"); exit(1) ;
         }
         iarg++ ; continue ;
      }

      /*-- -master [14 May 2002] --*/

      if( strcmp(argv[iarg],"-master") == 0 ){
        if( add_I || add_S || add_A || mm_flag ||
            add_P || add_R || add_L || add_z   ||
            RLsiz || APsiz || ISsiz              ){

          fprintf(stderr,"** 3dZeropad: Can't use -master with -I,-S,-A,-P,-R,-L, or -mm!\n");
          exit(1) ;
        }
        if( mset != NULL ){
          fprintf(stderr,"** 3dZeropad: Can't use -master twice!\n"); exit(1);
        }

        mset = THD_open_dataset( argv[++iarg] ) ;
        if( !ISVALID_DSET(mset) ){
          fprintf(stderr,"** 3dZeropad: Can't open -master %s\n",argv[iarg]); exit(1);
        }
        THD_make_cardinal(mset);    /* deoblique    21 Oct, 2011 [rickr] */
         iarg++ ; continue ;
      }

      /*- what the hell? -*/

      fprintf(stderr,"** 3dZeropad: Illegal option: %s\n",argv[iarg]) ; 
      suggest_best_prog_option(argv[0], argv[iarg]);
      exit(1) ;
   }

   if (iarg < 2) {
      ERROR_message("Too few options, try %s -help for details\n",argv[0]);
      exit(1);
   }
   
   /*- check to see if the user asked for something, anything -*/

   if( mset == NULL ){
    if( add_I==0 && add_S==0 && add_P==0 &&
        add_A==0 && add_L==0 && add_R==0 && add_z==0 &&
        RLsiz==0 && APsiz==0 && ISsiz==0               ){

      fprintf(stderr,"++ 3dZeropad: All inputs are zero? Making a copy!\n") ;
    }
   }

   /* check for conflicts [23 Mar 2004] */

   if( RLsiz > 0 && (add_R || add_L || add_z) ){
     fprintf(stderr,"** 3dZeropad: Can't use -R or -L or -z with -RL!\n"); exit(1);
   }
   if( APsiz > 0 && (add_A || add_P || add_z) ){
     fprintf(stderr,"** 3dZeropad: Can't use -A or -P or -z with -AP!\n"); exit(1);
   }
   if( ISsiz > 0 && (add_I || add_S || add_z) ){
     fprintf(stderr,"** 3dZeropad: Can't use -I or -S or -z with -IS!\n"); exit(1);
   }

   /*-- read the input dataset --*/

   if( iarg >= argc ){
      fprintf(stderr,"** 3dZeropad: No input dataset on command line!\n"); exit(1);
   }

#if 0
   if( strncmp(argv[iarg],"3dcalc(",7) == 0 ){
      fprintf(stderr,"** 3dZeropad: Can't use '3dcalc()' input datasets here!\n"); exit(1);
   }
#endif

   inset = THD_open_dataset( argv[iarg] ) ;
   if( inset == NULL ){
      fprintf(stderr,"** 3dZeropad: Can't open dataset %s\n",argv[iarg]); exit(1);
   }
   THD_make_cardinal(inset);    /* deoblique    21 Oct, 2011 [rickr] */

#if 0
   if( DSET_IS_MASTERED(inset) ){
      fprintf(stderr,"** 3dZeropad: Can't use partial datasets!\n"); exit(1);
   }
#endif

   /*-- 14 May 2002: use master dataset now? --*/

   if( mset != NULL ){
     THD_dataxes *max=mset->daxes, *iax=inset->daxes ;
     int nerr=0 ;
     float mxbot,mybot,mzbot , mxtop,mytop,mztop , mdx,mdy,mdz ;
     float ixbot,iybot,izbot , ixtop,iytop,iztop , idx,idy,idz ;
     int   mnx,mny,mnz , inx,iny,inz ;
     int   add_xb,add_xt , add_yb,add_yt , add_zb,add_zt ;

     /* check if datasets are oriented the same */

     if( max->xxorient != iax->xxorient ||
         max->yyorient != iax->yyorient ||
         max->zzorient != iax->zzorient   ){

       fprintf(stderr,
   "** 3dZeropad: Master (%s) and Input (%s) dataset not oriented the same!\n",
               DSET_PREFIX(mset), DSET_PREFIX(inset));
       nerr++ ;
     }

     /* check if datasets have same voxel dimensions */

     mdx = max->xxdel ; mdy = max->yydel ; mdz = max->zzdel ;
     idx = iax->xxdel ; idy = iax->yydel ; idz = iax->zzdel ;
     mnx = max->nxx   ; mny = max->nyy   ; mnz = max->nzz   ;
     inx = iax->nxx   ; iny = iax->nyy   ; inz = iax->nzz   ;

     if( fabs(mdx-idx) > 0.01*fabs(mdx) ||
         fabs(mdy-idy) > 0.01*fabs(mdy) ||
         fabs(mdz-idz) > 0.01*fabs(mdz)   ){

       fprintf(stderr,"** 3dZeropad: Master and Input datasets don't have same voxel size!\n");
       nerr++ ;
     }

     if( nerr ) exit(1) ;

     /* calculate coords at top and bottom of each dataset */

     mxbot = max->xxorg ; mxtop = mxbot + mnx*mdx ;
     mybot = max->yyorg ; mytop = mybot + mny*mdy ;
     mzbot = max->zzorg ; mztop = mzbot + mnz*mdz ;

     ixbot = iax->xxorg ; ixtop = ixbot + inx*idx ;
     iybot = iax->yyorg ; iytop = iybot + iny*idy ;
     izbot = iax->zzorg ; iztop = izbot + inz*idz ;

     /* calculate amount to add/trim at each face */

     add_xb = (int) rint((ixbot-mxbot)/idx) ;
     add_xt = (int) rint((mxtop-ixtop)/idx) ;
     add_yb = (int) rint((iybot-mybot)/idy) ;
     add_yt = (int) rint((mytop-iytop)/idy) ;
     add_zb = (int) rint((izbot-mzbot)/idz) ;
     add_zt = (int) rint((mztop-iztop)/idz) ;

     /* map trims from x,y,z to RL,AP,IS coords */

     switch( iax->xxorient ){
       case ORI_R2L_TYPE: add_R = add_xb ; add_L = add_xt ; break ;
       case ORI_L2R_TYPE: add_L = add_xb ; add_R = add_xt ; break ;
       case ORI_I2S_TYPE: add_I = add_xb ; add_S = add_xt ; break ;
       case ORI_S2I_TYPE: add_S = add_xb ; add_I = add_xt ; break ;
       case ORI_A2P_TYPE: add_A = add_xb ; add_P = add_xt ; break ;
       case ORI_P2A_TYPE: add_P = add_xb ; add_A = add_xt ; break ;
     }

     switch( iax->yyorient ){
       case ORI_R2L_TYPE: add_R = add_yb ; add_L = add_yt ; break ;
       case ORI_L2R_TYPE: add_L = add_yb ; add_R = add_yt ; break ;
       case ORI_I2S_TYPE: add_I = add_yb ; add_S = add_yt ; break ;
       case ORI_S2I_TYPE: add_S = add_yb ; add_I = add_yt ; break ;
       case ORI_A2P_TYPE: add_A = add_yb ; add_P = add_yt ; break ;
       case ORI_P2A_TYPE: add_P = add_yb ; add_A = add_yt ; break ;
     }

     switch( iax->zzorient ){
       case ORI_R2L_TYPE: add_R = add_zb ; add_L = add_zt ; break ;
       case ORI_L2R_TYPE: add_L = add_zb ; add_R = add_zt ; break ;
       case ORI_I2S_TYPE: add_I = add_zb ; add_S = add_zt ; break ;
       case ORI_S2I_TYPE: add_S = add_zb ; add_I = add_zt ; break ;
       case ORI_A2P_TYPE: add_A = add_zb ; add_P = add_zt ; break ;
       case ORI_P2A_TYPE: add_P = add_zb ; add_A = add_zt ; break ;
     }

     fprintf(stderr,"++ 3dZeropad -master => -I %d -S %d -A %d -P %d -R %d -L %d\n",
             add_I,add_S,add_A,add_P,add_R,add_L ) ;

     DSET_delete(mset) ;
   }

   /*-- 07 Feb 2001: if -z was used, fix that now --*/

   if( add_z != 0 ){
      switch( inset->daxes->zzorient ){
         case ORI_R2L_TYPE:
         case ORI_L2R_TYPE:
            if( add_R != 0 && add_R != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -R\n");
            if( add_L != 0 && add_L != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -L\n");
            add_R = add_L = add_z ;
         break ;

         case ORI_P2A_TYPE:
         case ORI_A2P_TYPE:
            if( add_P != 0 && add_P != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -P\n");
            if( add_A != 0 && add_A != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -A\n");
            add_P = add_A = add_z ;
         break ;

         case ORI_I2S_TYPE:
         case ORI_S2I_TYPE:
            if( add_I != 0 && add_I != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -I\n");
            if( add_I != 0 && add_S != add_z ) fprintf(stderr,"++ 3dZeropad: -z overrides -S\n");
            add_I = add_S = add_z ;
         break ;
      }
   }

   /*-- 23 Mar 2004: expand/contract if ordered --*/

   if( RLsiz > 0 ){
     int nold=0 ;
          if( inset->daxes->xxorient == ORI_R2L_TYPE || inset->daxes->xxorient == ORI_L2R_TYPE )
       nold = inset->daxes->nxx ;
     else if( inset->daxes->yyorient == ORI_R2L_TYPE || inset->daxes->yyorient == ORI_L2R_TYPE )
       nold = inset->daxes->nyy ;
     else if( inset->daxes->zzorient == ORI_R2L_TYPE || inset->daxes->zzorient == ORI_L2R_TYPE )
       nold = inset->daxes->nzz ;
     if( nold > 0 ){
       add_R = (RLsiz-nold) / 2 ;
       add_L = RLsiz-(nold+add_R) ;
     }
   }

   if( APsiz > 0 ){
     int nold=0 ;
          if( inset->daxes->xxorient == ORI_A2P_TYPE || inset->daxes->xxorient == ORI_P2A_TYPE )
       nold = inset->daxes->nxx ;
     else if( inset->daxes->yyorient == ORI_A2P_TYPE || inset->daxes->yyorient == ORI_P2A_TYPE )
       nold = inset->daxes->nyy ;
     else if( inset->daxes->zzorient == ORI_A2P_TYPE || inset->daxes->zzorient == ORI_P2A_TYPE )
       nold = inset->daxes->nzz ;
     if( nold > 0 ){
       add_A = (APsiz-nold) / 2 ;
       add_P = APsiz-(nold+add_A) ;
     }
   }

   if( ISsiz > 0 ){
     int nold=0 ;
          if( inset->daxes->xxorient == ORI_I2S_TYPE || inset->daxes->xxorient == ORI_S2I_TYPE )
       nold = inset->daxes->nxx ;
     else if( inset->daxes->yyorient == ORI_I2S_TYPE || inset->daxes->yyorient == ORI_S2I_TYPE )
       nold = inset->daxes->nyy ;
     else if( inset->daxes->zzorient == ORI_I2S_TYPE || inset->daxes->zzorient == ORI_S2I_TYPE )
       nold = inset->daxes->nzz ;
     if( nold > 0 ){
       add_I = (ISsiz-nold) / 2 ;
       add_S = ISsiz-(nold+add_I) ;
     }
   }

   /*-- 04 Oct 2000: all the real work is now in thd_zeropad.c --*/

   flag = ZPAD_PURGE ;
   if( mm_flag ) flag |= ZPAD_MM ;

   outset = THD_zeropad( inset ,
                         add_I, add_S, add_A, add_P, add_L, add_R,
                         prefix , flag ) ;

   if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) ){
      fprintf(stderr,
              "** 3dZeropad: output file %s already exists - FATAL ERROR!\n",
              DSET_HEADNAME(outset) ) ;
      exit(1) ;
   }

   if( outset == NULL ){
      fprintf(stderr,"** 3dZeropad: Some error occurred in processing!\n") ;
      exit(1) ;
   }

   tross_Copy_History( inset , outset ) ;             /* 31 Jan 2001 - RWCox */
   tross_Make_History( "3dZeropad" , argc,argv , outset ) ;

   if (DSET_write(outset) != False) {
      fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ;
      exit(0) ;
   } else {
      fprintf(stderr,
              "** 3dZeropad: Failed to write output!\n" ) ;
      exit(1) ;
   }
   
}
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);
}
Exemple #9
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) ;
}
Exemple #10
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) ;
}
Exemple #11
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) ;
}
Exemple #13
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);
}
Exemple #14
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) ;
}
Exemple #15
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 ;
}
Exemple #16
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset , *oset=NULL , *tset=NULL ;
   int nvals , iv , nxyz , ii,jj,kk , iarg , kz,kzold ;
   float cut1=2.5,cut2=4.0 , sq2p,sfac , fq ;
   MRI_IMAGE *flim ;
   char *prefix="despike" , *tprefix=NULL ;

   int corder=-1 , nref , ignore=0 , polort=2 , nuse , nomask=0 ;
   int nspike, nbig, nproc ;
   float **ref ;
   float  c21,ic21 , pspike,pbig ;
   short  *sar , *qar ;
   byte   *tar , *mask=NULL ;
   float  *zar , *yar ;
   int     datum ;
   int     localedit=0 ;  /* 04 Apr 2007 */
   int     verb=1 ;

   int     do_NEW = 0 ;   /* 29 Nov 2013 */
   MRI_IMAGE *NEW_psinv=NULL ;
   int     dilate = 4 ;   /* 04 Dec 2013 */
   int     ctim   = 0 ;

   /*----- Read command line -----*/

   AFNI_SETUP_OMP(0) ;  /* 24 Jun 2013 */

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: 3dDespike [options] dataset\n"
             "Removes 'spikes' from the 3D+time input dataset and writes\n"
             "a new dataset with the spike values replaced by something\n"
             "more pleasing to the eye.\n"
             "\n"
             "Method:\n"
             " * L1 fit a smooth-ish curve to each voxel time series\n"
             "    [see -corder option for description of the curve]\n"
             "    [see -NEW option for a different & faster fitting method]\n"
             " * Compute the MAD of the difference between the curve and\n"
             "    the data time series (the residuals).\n"
             " * Estimate the standard deviation 'sigma' of the residuals\n"
             "    as sqrt(PI/2)*MAD.\n"
             " * For each voxel value, define s = (value-curve)/sigma.\n"
             " * Values with s > c1 are replaced with a value that yields\n"
             "    a modified s' = c1+(c2-c1)*tanh((s-c1)/(c2-c1)).\n"
             " * c1 is the threshold value of s for a 'spike' [default c1=2.5].\n"
             " * c2 is the upper range of the allowed deviation from the curve:\n"
             "    s=[c1..infinity) is mapped to s'=[c1..c2)   [default c2=4].\n"
             "\n"
             "Options:\n"
             " -ignore I  = Ignore the first I points in the time series:\n"
             "               these values will just be copied to the\n"
             "               output dataset [default I=0].\n"
             " -corder L  = Set the curve fit order to L:\n"
             "               the curve that is fit to voxel data v(t) is\n"
             "\n"
             "                       k=L [        (2*PI*k*t)          (2*PI*k*t) ]\n"
             " f(t) = a+b*t+c*t*t + SUM  [ d * sin(--------) + e * cos(--------) ]\n"
             "                       k=1 [  k     (    T   )    k     (    T   ) ]\n"
             "\n"
             "               where T = duration of time series;\n"
             "               the a,b,c,d,e parameters are chosen to minimize\n"
             "               the sum over t of |v(t)-f(t)| (L1 regression);\n"
             "               this type of fitting is is insensitive to large\n"
             "               spikes in the data.  The default value of L is\n"
             "               NT/30, where NT = number of time points.\n"
             "\n"
             " -cut c1 c2 = Alter default values for the spike cut values\n"
             "               [default c1=2.5, c2=4.0].\n"
             " -prefix pp = Save de-spiked dataset with prefix 'pp'\n"
             "               [default pp='despike']\n"
             " -ssave ttt = Save 'spikiness' measure s for each voxel into a\n"
             "               3D+time dataset with prefix 'ttt' [default=no save]\n"
             " -nomask    = Process all voxels\n"
             "               [default=use a mask of high-intensity voxels, ]\n"
             "               [as created via '3dAutomask -dilate 4 dataset'].\n"
             " -dilate nd = Dilate 'nd' times (as in 3dAutomask).  The default\n"
             "               value of 'nd' is 4.\n"
             " -q[uiet]   = Don't print '++' informational messages.\n"
             "\n"
             " -localedit = Change the editing process to the following:\n"
             "                If a voxel |s| value is >= c2, then replace\n"
             "                the voxel value with the average of the two\n"
             "                nearest non-spike (|s| < c2) values; the first\n"
             "                one previous and the first one after.\n"
             "                Note that the c1 cut value is not used here.\n"
             "\n"
             " -NEW       = Use the 'new' method for computing the fit, which\n"
             "              should be faster than the L1 method for long time\n"
             "              series (200+ time points); however, the results\n"
             "              are similar but NOT identical. [29 Nov 2013]\n"
             "              * You can also make the program use the 'new'\n"
             "                method by setting the environment variable\n"
             "                  AFNI_3dDespike_NEW\n"
             "                to the value YES; as in\n"
             "                  setenv AFNI_3dDespike_NEW YES  (csh)\n"
             "                  export AFNI_3dDespike_NEW=YES  (bash)\n"
             "              * If this variable is set to YES, you can turn off\n"
             "                the '-NEW' processing by using the '-OLD' option.\n"
             "          -->>* For time series more than 500 points long, the\n"
             "                '-OLD' algorithm is tremendously slow.  You should\n"
             "                use the '-NEW' algorith in such cases.\n"
             "             ** At some indeterminate point in the future, the '-NEW'\n"
             "                method will become the default!\n"
             "          -->>* As of 29 Sep 2016, '-NEW' is the default if there\n"
             "                is more than 500 points in the time series dataset.\n"
             "\n"
             " -NEW25     = A slightly more aggressive despiking approach than\n"
             "              the '-NEW' method.\n"
             "\n"
             "Caveats:\n"
             "* Despiking may interfere with image registration, since head\n"
             "   movement may produce 'spikes' at the edge of the brain, and\n"
             "   this information would be used in the registration process.\n"
             "   This possibility has not been explored or calibrated.\n"
             "* [LATER] Actually, it seems like the registration problem\n"
             "   does NOT happen, and in fact, despiking seems to help!\n"
             "* Check your data visually before and after despiking and\n"
             "   registration!\n"
             "   [Hint: open 2 AFNI controllers, and turn Time Lock on.]\n"
            ) ;

      PRINT_AFNI_OMP_USAGE("3dDespike",NULL) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   /** AFNI package setup and logging **/

   mainENTRY("3dDespike main"); machdep(); AFNI_logger("3dDespike",argc,argv);
   PRINT_VERSION("3dDespike") ; AUTHOR("RW Cox") ;

   /** parse options **/

   if( AFNI_yesenv("AFNI_3dDespike_NEW") ) do_NEW = 1 ;  /* 29 Nov 2013 */

   iarg = 1 ;
   while( iarg < argc && argv[iarg][0] == '-' ){

      if( strncmp(argv[iarg],"-q",2) == 0 ){       /* 04 Apr 2007 */
        verb = 0 ; iarg++ ; continue ;
      }
      if( strncmp(argv[iarg],"-v",2) == 0 ){
        verb++ ; iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-NEW") == 0 ){       /* 29 Nov 2013 */
        do_NEW = 1 ; iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-NEW25") == 0 ){     /* 29 Sep 2016 */
        do_NEW = 1 ; use_des25 = 1 ; cut1 = 2.5f ; cut2 = 3.2f ; iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-OLD") == 0 ){
        do_NEW = 0 ; iarg++ ; continue ;
      }

      /** -localedit **/

      if( strcmp(argv[iarg],"-localedit") == 0 ){  /* 04 Apr 2007 */
        localedit = 1 ; iarg++ ; continue ;
      }

      /** don't use masking **/

      if( strcmp(argv[iarg],"-nomask") == 0 ){
        nomask = 1 ; iarg++ ; continue ;
      }

      /** dilation count [04 Dec 2013] **/

      if( strcmp(argv[iarg],"-dilate") == 0 ){
        dilate = (int)strtod(argv[++iarg],NULL) ;
             if( dilate <=  0 ) dilate = 1 ;
        else if( dilate >  99 ) dilate = 99 ;
        iarg++ ; continue ;
      }

      /** output dataset prefix **/

      if( strcmp(argv[iarg],"-prefix") == 0 ){
        prefix = argv[++iarg] ;
        if( !THD_filename_ok(prefix) ) ERROR_exit("-prefix is not good");
        iarg++ ; continue ;
      }

      /** ratio dataset prefix **/

      if( strcmp(argv[iarg],"-ssave") == 0 ){
        tprefix = argv[++iarg] ;
        if( !THD_filename_ok(tprefix) ) ERROR_exit("-ssave prefix is not good");
        iarg++ ; continue ;
      }

      /** trigonometric polynomial order **/

      if( strcmp(argv[iarg],"-corder") == 0 ){
        corder = strtol( argv[++iarg] , NULL , 10 ) ;
        if( corder < 0 ) ERROR_exit("Illegal value of -corder");
        iarg++ ; continue ;
      }

      /** how much to ignore at start **/

      if( strcmp(argv[iarg],"-ignore") == 0 ){
        ignore = strtol( argv[++iarg] , NULL , 10 ) ;
        if( ignore < 0 ) ERROR_exit("Illegal value of -ignore");
        iarg++ ; continue ;
      }

      /** thresholds for s ratio **/

      if( strcmp(argv[iarg],"-cut") == 0 ){
        cut1 = strtod( argv[++iarg] , NULL ) ;
        cut2 = strtod( argv[++iarg] , NULL ) ;
        if( cut1 < 1.0 || cut2 < cut1+0.5 )
          ERROR_exit("Illegal values after -cut");
        iarg++ ; continue ;
      }

      ERROR_exit("Unknown option: %s",argv[iarg]) ;
   }

   c21 = cut2-cut1 ; ic21 = 1.0/c21 ;

   /*----- read input dataset -----*/

   if( iarg >= argc ) ERROR_exit("No input dataset!!??");

   dset = THD_open_dataset( argv[iarg] ) ;
   CHECK_OPEN_ERROR(dset,argv[iarg]) ;
   datum = DSET_BRICK_TYPE(dset,0) ;
   if( (datum != MRI_short && datum != MRI_float) || !DSET_datum_constant(dset) )
     ERROR_exit("Can't process non-short, non-float dataset!") ;

   if( verb ) INFO_message("Input data type = %s\n",MRI_TYPE_name[datum]) ;
   nvals = DSET_NUM_TIMES(dset) ; nuse = nvals - ignore ;
   if( nuse < 15 )
     ERROR_exit("Can't use dataset with < 15 time points per voxel!") ;

   if( nuse > 500 && !do_NEW ){
     INFO_message("Switching to '-NEW' method since number of time points = %d > 500",nuse) ;
     do_NEW = 1 ;
   }
   if( use_des25 && nuse < 99 ) use_des25 = 0 ;

   if( verb ) INFO_message("ignoring first %d time points, using last %d",ignore,nuse);
   if( corder > 0 && 4*corder+2 > nuse ){
     ERROR_exit("-corder %d is too big for NT=%d",corder,nvals) ;
   } else if( corder < 0 ){
     corder = rint(nuse/30.0) ; if( corder > 50 && !do_NEW ) corder = 50 ;
     if( verb ) INFO_message("using %d time points => -corder %d",nuse,corder) ;
   } else {
     if( verb ) INFO_message("-corder %d set from command line",corder) ;
   }
   nxyz = DSET_NVOX(dset) ;
   if( verb ) INFO_message("Loading dataset %s",argv[iarg]) ;
   DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;

   /*-- create automask --*/

   if( !nomask ){
     mask = THD_automask( dset ) ;
     if( verb ){
       ii = THD_countmask( DSET_NVOX(dset) , mask ) ;
       INFO_message("%d voxels in the automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ;
     }
     for( ii=0 ; ii < dilate ; ii++ )
       THD_mask_dilate( DSET_NX(dset), DSET_NY(dset), DSET_NZ(dset), mask, 3 ) ;
     if( verb ){
       ii = THD_countmask( DSET_NVOX(dset) , mask ) ;
       INFO_message("%d voxels in the dilated automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ;
     }
   } else {
     if( verb ) INFO_message("processing all %d voxels in dataset",DSET_NVOX(dset)) ;
   }

   /*-- create empty despiked dataset --*/

   oset = EDIT_empty_copy( dset ) ;
   EDIT_dset_items( oset ,
                      ADN_prefix    , prefix ,
                      ADN_brick_fac , NULL ,
                      ADN_datum_all , datum ,
                    ADN_none ) ;

   if( THD_deathcon() && THD_is_file(DSET_HEADNAME(oset)) )
     ERROR_exit("output dataset already exists: %s",DSET_HEADNAME(oset));

   tross_Copy_History( oset , dset ) ;
   tross_Make_History( "3dDespike" , argc , argv , oset ) ;

   /* create bricks (will be filled with zeros) */

   for( iv=0 ; iv < nvals ; iv++ )
     EDIT_substitute_brick( oset , iv , datum , NULL ) ;

   /* copy the ignored bricks */

   switch( datum ){
     case MRI_short:
       for( iv=0 ; iv < ignore ; iv++ ){
         sar = DSET_ARRAY(oset,iv) ;
         qar = DSET_ARRAY(dset,iv) ;
         memcpy( sar , qar , DSET_BRICK_BYTES(dset,iv) ) ;
         DSET_unload_one(dset,iv) ;
       }
     break ;
     case MRI_float:
       for( iv=0 ; iv < ignore ; iv++ ){
         zar = DSET_ARRAY(oset,iv) ;
         yar = DSET_ARRAY(dset,iv) ;
         memcpy( zar , yar , DSET_BRICK_BYTES(dset,iv) ) ;
         DSET_unload_one(dset,iv) ;
       }
     break ;
   }

   /*-- setup to save a threshold statistic dataset, if desired --*/

   if( tprefix != NULL ){
     float *fac ;
     tset = EDIT_empty_copy( dset ) ;
     fac  = (float *) malloc( sizeof(float) * nvals ) ;
     for( ii=0 ; ii < nvals ; ii++ ) fac[ii] = TFAC ;
     EDIT_dset_items( tset ,
                        ADN_prefix    , tprefix ,
                        ADN_brick_fac , fac ,
                        ADN_datum_all , MRI_byte ,
                        ADN_func_type , FUNC_FIM_TYPE ,
                      ADN_none ) ;
     free(fac) ;

     tross_Copy_History( tset , dset ) ;
     tross_Make_History( "3dDespike" , argc , argv , tset ) ;

#if 0
     if( THD_is_file(DSET_HEADNAME(tset)) )
       ERROR_exit("-ssave dataset already exists");
#endif

     tross_Copy_History( tset , dset ) ;
     tross_Make_History( "3dDespike" , argc , argv , tset ) ;

     for( iv=0 ; iv < nvals ; iv++ )
       EDIT_substitute_brick( tset , iv , MRI_byte , NULL ) ;
   }

   /*-- setup to find spikes --*/

   sq2p  = sqrt(0.5*PI) ;
   sfac  = sq2p / 1.4826f ;

   /* make ref functions */

   nref = 2*corder+3 ;
   ref  = (float **) malloc( sizeof(float *) * nref ) ;
   for( jj=0 ; jj < nref ; jj++ )
     ref[jj] = (float *) malloc( sizeof(float) * nuse ) ;

   /* r(t) = 1 */

   for( iv=0 ; iv < nuse ; iv++ ) ref[0][iv] = 1.0 ;
   jj = 1 ;

   /* r(t) = t - tmid */

   { float tm = 0.5 * (nuse-1.0) ; float fac = 2.0 / nuse ;
     for( iv=0 ; iv < nuse ; iv++ ) ref[1][iv] = (iv-tm)*fac ;
     jj = 2 ;

     /* r(t) = (t-tmid)**jj */

     for( ; jj <= polort ; jj++ )
       for( iv=0 ; iv < nuse ; iv++ )
         ref[jj][iv] = pow( (iv-tm)*fac , (double)jj ) ;
   }

   for( kk=1 ; kk <= corder ; kk++ ){
     fq = (2.0*PI*kk)/nuse ;

     /* r(t) = sin(2*PI*k*t/N) */

     for( iv=0 ; iv < nuse ; iv++ )
       ref[jj][iv] = sin(fq*iv) ;
     jj++ ;

     /* r(t) = cos(2*PI*k*t/N) */

     for( iv=0 ; iv < nuse ; iv++ )
       ref[jj][iv] = cos(fq*iv) ;
     jj++ ;
   }

   /****** setup for the NEW solution method [29 Nov 2013] ******/

   if( do_NEW ){
     NEW_psinv = DES_get_psinv(nuse,nref,ref) ;
     INFO_message("Procesing time series with NEW model fit algorithm") ;
   } else {
     INFO_message("Procesing time series with OLD model fit algorithm") ;
   }

   /*--- loop over voxels and do work ---*/

#define Laplace_t2p(val) ( 1.0 - nifti_stat2cdf( (val), 15, 0.0, 1.4427 , 0.0 ) )

   if( verb ){
    if( !localedit ){
      INFO_message("smash edit thresholds: %.1f .. %.1f MADs",cut1*sq2p,cut2*sq2p) ;
      ININFO_message("  [ %.3f%% .. %.3f%% of normal distribution]",
                     200.0*qg(cut1*sfac) , 200.0*qg(cut2*sfac) ) ;
      ININFO_message("  [ %.3f%% .. %.3f%% of Laplace distribution]" ,
                   100.0*Laplace_t2p(cut1) , 100.0*Laplace_t2p(cut2) ) ;
    } else {
      INFO_message("local edit threshold:  %.1f MADS",cut2*sq2p) ;
      ININFO_message("  [ %.3f%% of normal distribution]",
                    200.0*qg(cut2*sfac) ) ;
      ININFO_message("  [ %.3f%% of Laplace distribution]",
                   100.0*Laplace_t2p(cut1) ) ;
    }
    INFO_message("%d slices to process",DSET_NZ(dset)) ;
   }
   kzold  = -1 ;
   nspike =  0 ; nbig = 0 ; nproc = 0 ; ctim = NI_clock_time() ;

 AFNI_OMP_START ;
#pragma omp parallel if( nxyz > 6666 )
 { int ii , iv , iu , id , jj ;
   float *far , *dar , *var , *fitar , *ssp , *fit , *zar ;
   short *sar , *qar ; byte *tar ;
   float fsig , fq , cls , snew , val ;
   float *NEW_wks=NULL ;

#pragma omp critical (DESPIKE_malloc)
  { far   = (float *) malloc( sizeof(float) * nvals ) ;
    dar   = (float *) malloc( sizeof(float) * nvals ) ;
    var   = (float *) malloc( sizeof(float) * nvals ) ;
    fitar = (float *) malloc( sizeof(float) * nvals ) ;
    ssp   = (float *) malloc( sizeof(float) * nvals ) ;
    fit   = (float *) malloc( sizeof(float) * nref  ) ;
    if( do_NEW ) NEW_wks = (float *)malloc(sizeof(float)*DES_workspace_size(nuse,nref)) ;
  }

#ifdef USE_OMP
   INFO_message("start OpenMP thread #%d",omp_get_thread_num()) ;
#endif

#pragma omp for
   for( ii=0 ; ii < nxyz ; ii++ ){   /* ii = voxel index */

      if( mask != NULL && mask[ii] == 0 ) continue ;   /* skip this voxel */

#ifndef USE_OMP
      kz = DSET_index_to_kz(dset,ii) ;       /* starting a new slice */
      if( kz != kzold ){
        if( verb ){
          fprintf(stderr, "++ start slice %2d",kz ) ;
          if( nproc > 0 ){
            pspike = (100.0*nspike)/nproc ;
            pbig   = (100.0*nbig  )/nproc ;
            fprintf(stderr,
                    "; so far %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]",
                    nproc,nspike,pspike,nbig,pbig ) ;
          }
          fprintf(stderr,"\n") ;
        }
        kzold = kz ;
      }
#else
      if( verb && ii % 2345 == 1234 ) fprintf(stderr,".") ;
#endif

      /*** extract ii-th time series into far[] ***/

      switch( datum ){
        case MRI_short:
          for( iv=0 ; iv < nuse ; iv++ ){
            qar = DSET_ARRAY(dset,iv+ignore) ;   /* skip ignored data */
            far[iv] = (float)qar[ii] ;
          }
        break ;
        case MRI_float:
          for( iv=0 ; iv < nuse ; iv++ ){
            zar = DSET_ARRAY(dset,iv+ignore) ;
            far[iv] = zar[ii] ;
          }
        break ;
      }

      AAmemcpy(dar,far,sizeof(float)*nuse) ;   /* copy time series into dar[] */

      /*** solve for L1 fit ***/

      if( do_NEW )
        cls = DES_solve( NEW_psinv , far , fit , NEW_wks ) ; /* 29 Nov 2013 */
      else
        cls = cl1_solve( nuse , nref , far , ref , fit,0 ) ; /* the slow part */

      if( cls < 0.0f ){                      /* fit failed! */
#if 0
        fprintf(stderr,"curve fit fails at voxel %d %d %d\n",
                DSET_index_to_ix(dset,ii) ,
                DSET_index_to_jy(dset,ii) ,
                DSET_index_to_kz(dset,ii)  ) ;
#endif
        continue ;                           /* skip this voxel */
      }

      for( iv=0 ; iv < nuse ; iv++ ){        /* detrend */
        val =  fit[0]
             + fit[1]*ref[1][iv]             /* quadratic part of curve fit */
             + fit[2]*ref[2][iv] ;
        for( jj=3 ; jj < nref ; jj++ )       /* rest of curve fit */
          val += fit[jj] * ref[jj][iv] ;

        fitar[iv] = val ;                    /* save curve fit value */
        var[iv]   = dar[iv]-val ;            /* remove fitted value = resid */
        far[iv]   = fabsf(var[iv]) ;         /* abs value of resid */
      }

      /*** compute estimate standard deviation of detrended data ***/

      fsig = sq2p * qmed_float(nuse,far) ;   /* also mangles far array */

      /*** process time series for spikes, editing data in dar[] ***/

      if( fsig > 0.0f ){                     /* data wasn't fit perfectly */

        /* find spikiness for each point in time */

        fq = 1.0f / fsig ;
        for( iv=0 ; iv < nuse ; iv++ ){
          ssp[iv] = fq * var[iv] ;           /* spikiness s = how many sigma out */
        }

        /* save spikiness in -ssave datset */

        if( tset != NULL ){
          for( iv=0 ; iv < nuse ; iv++ ){
            tar     = DSET_ARRAY(tset,iv+ignore) ;
            snew    = ITFAC*fabsf(ssp[iv]) ;  /* scale for byte storage */
            tar[ii] = BYTEIZE(snew) ;         /* cf. mrilib.h */
          }
        }

        /* process values of |s| > cut1, editing dar[] */

        for( iv=0 ; iv < nuse ; iv++ ){ /* loop over time points */
          if( !localedit ){             /** classic 'smash' edit **/
            if( ssp[iv] > cut1 ){
              snew = cut1 + c21*mytanh((ssp[iv]-cut1)*ic21) ;   /* edit s down */
              dar[iv] = fitar[iv] + snew*fsig ;
#pragma omp critical (DESPIKE_counter)
              { nspike++ ; if( ssp[iv] > cut2 ) nbig++ ; }
            } else if( ssp[iv] < -cut1 ){
              snew = -cut1 + c21*mytanh((ssp[iv]+cut1)*ic21) ;  /* edit s up */
              dar[iv] = fitar[iv] + snew*fsig ;
#pragma omp critical (DESPIKE_counter)
              { nspike++ ; if( ssp[iv] < -cut2 ) nbig++ ; }
            }
          } else {                      /** local edit: 04 Apr 2007 **/
            if( ssp[iv] >= cut2 || ssp[iv] <= -cut2 ){
              for( iu=iv+1 ; iu < nuse ; iu++ )  /* find non-spike above */
                if( ssp[iu] < cut2 && ssp[iu] > -cut2 ) break ;
              for( id=iv-1 ; id >= 0   ; id-- )  /* find non-spike below */
                if( ssp[id] < cut2 && ssp[id] > -cut2 ) break ;
              switch( (id>=0) + 2*(iu<nuse) ){   /* compute replacement val */
                case 3: val = 0.5*(dar[iu]+dar[id]); break; /* iu and id OK */
                case 2: val =      dar[iu]         ; break; /* only iu OK   */
                case 1: val =              dar[id] ; break; /* only id OK   */
               default: val = fitar[iv]            ; break; /* shouldn't be */
              }
              dar[iv] = val ;
#pragma omp critical (DESPIKE_counter)
              { nspike++ ; nbig++ ; }
            }
          }
        } /* end of loop over time points */
#pragma omp atomic
        nproc += nuse ;  /* number data points processed */

      } /* end of processing time series when fsig is positive */

      /* put dar[] time series (possibly edited above) into output bricks */

      switch( datum ){
        case MRI_short:
          for( iv=0 ; iv < nuse ; iv++ ){
            sar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */
            sar[ii] = (short)dar[iv] ;         /* original or mutated data */
          }
        break ;
        case MRI_float:
          for( iv=0 ; iv < nuse ; iv++ ){
            zar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */
            zar[ii] = dar[iv] ;                /* original or mutated data */
          }
        break ;
      }

   } /* end of loop over voxels #ii */

#pragma omp critical (DESPIKE_malloc)
   { free(fit); free(ssp); free(fitar); free(var); free(dar); free(far);
     if( do_NEW ) free(NEW_wks) ; }

 } /* end OpenMP */
 AFNI_OMP_END ;

#ifdef USE_OMP
   if( verb ) fprintf(stderr,"\n") ;
#endif
   ctim = NI_clock_time() - ctim ;
   INFO_message( "Elapsed despike time = %s" , nice_time_string(ctim) ) ;
   if( ctim > 345678 && !do_NEW )
     ININFO_message("That was SLOW -- try the '-NEW' option for a speedup") ;

#ifdef USE_OMP
   if( verb ) fprintf(stderr,"\n") ;
#endif

   /*--- finish up ---*/

   if( do_NEW ) mri_free(NEW_psinv) ;

   DSET_delete(dset) ; /* delete input dataset */

   if( verb ){
     if( nproc > 0 ){
       pspike = (100.0*nspike)/nproc ;
       pbig   = (100.0*nbig  )/nproc ;
       INFO_message("FINAL: %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]",
               nproc,nspike,pspike,nbig,pbig ) ;
     } else {
       INFO_message("FINAL: no good voxels found to process!!??") ;
     }
   }

   /* write results */

   DSET_write(oset) ;
   if( verb ) WROTE_DSET(oset) ;
   DSET_delete(oset) ;

   if( tset != NULL ){
     DSET_write(tset) ;
     if( verb ) WROTE_DSET(tset) ;
     DSET_delete(tset) ;
   }

   exit( THD_get_write_error_count() ) ;
}
Exemple #17
0
int main(int argc, char *argv[]) {
   int i,j,k,l,m,n,mm,ii;
   int idx;
   int iarg;
   THD_3dim_dataset *insetTIME = NULL;
   // THD_3dim_dataset *inset0 = NULL;
   THD_3dim_dataset *MASK=NULL;
   char *prefix="REHO" ;
   char in_name[300];
   char in_mask[300];
   
   THD_3dim_dataset *outset=NULL;
   char outname[300];

   int NIFTI_OUT=0;
   int DTYPE=0;

   int HAVE_MASK = 0;
   int ***mskd; // define mask of where time series are nonzero
   double temp_sum;

   // FILE *fout0, *fout1;
   int Nvox=-1;   // tot number vox
   int Dim[4]={0,0,0,0};
   
   float fbot = -1., ftop = -1;
   float delF = -1;
   float *allF=NULL;

   float **allPar=NULL;
   int Npar=NRSFC;   // currently... see list below
   char *namePar[NRSFC]={"ALFF", "MALFF", "FALFF",
                         "RSFA", "MRSFA", "FRSFA"};

   int MIN_full=0, MAX_full=-1; // indices of full spect
   int MIN_bp=0, MAX_bp = -1; // indices of lff/bp region

   mainENTRY("3dAmpToRSFC"); machdep(); 
  
   // ****************************************************************
   // ****************************************************************
   //                    load AFNI stuff
   // ****************************************************************
   // ****************************************************************

   // INFO_message("version: NU");
	
   /** scan args **/
   if (argc == 1) { usage_AmpToRSFC(1); exit(0); }
   iarg = 1; 
   while( iarg < argc && argv[iarg][0] == '-' ){
      if( strcmp(argv[iarg],"-help") == 0 || 
          strcmp(argv[iarg],"-h") == 0 ) {
         usage_AmpToRSFC(strlen(argv[iarg])>3 ? 2:1);
         exit(0);
      }
		
      if( strncmp(argv[iarg],"-band",5) == 0 ){
         if( ++iarg >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ;

         fbot = strtod(argv[iarg++],NULL) ;
         ftop = strtod(argv[iarg++],NULL) ;
         continue ;
      }

      if( strcmp(argv[iarg],"-mask") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-mask'");
         HAVE_MASK=1;

         sprintf(in_mask,"%s", argv[iarg]); 
         MASK = THD_open_dataset(in_mask) ;
         if( (MASK == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_mask);

         DSET_load(MASK); CHECK_LOAD_ERROR(MASK);
			
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-prefix") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-prefix'");
         prefix = strdup(argv[iarg]) ;
         if( !THD_filename_ok(prefix) ) 
            ERROR_exit("Illegal name after '-prefix'");
         iarg++ ; continue ;
      }
	 
      if( strcmp(argv[iarg],"-in_amp") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-in_amp'");

         sprintf(in_name,"%s", argv[iarg]); 
         DTYPE = 1; // for amps

         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-in_pow") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-in_pow'");
         
         sprintf(in_name,"%s", argv[iarg]); 
         DTYPE = 2; // for pow
         
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-mask") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-mask'");
         HAVE_MASK=1;

         sprintf(in_mask,"%s", argv[iarg]); 
         MASK = THD_open_dataset(in_mask) ;
         if( (MASK == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_mask);

         DSET_load(MASK); CHECK_LOAD_ERROR(MASK);
			
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-nifti") == 0) {
         NIFTI_OUT=1;
         iarg++ ; continue ;
      }

      ERROR_message("Bad option '%s'\n",argv[iarg]) ;
      suggest_best_prog_option(argv[0], argv[iarg]);
      exit(1);
   }
	
   // ---------------------------------------------------------------

   // TEST BASIC INPUT PROPERTIES
   if (iarg < 3) {
      ERROR_message("Too few options. Try -help for details.\n");
      exit(1);
   }

   if( !DTYPE ) {
      ERROR_message("Think somebody forgot to specify an input file"
                    " using '-in_amp ...' or '-in_pow ...'.");
      exit(12);
   }
   else{
         insetTIME = THD_open_dataset(in_name) ;
         if( (insetTIME == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_name);
         
         DSET_load(insetTIME); CHECK_LOAD_ERROR(insetTIME);

         Nvox = DSET_NVOX(insetTIME) ;
         Dim[0] = DSET_NX(insetTIME); Dim[1] = DSET_NY(insetTIME); 
         Dim[2] = DSET_NZ(insetTIME); Dim[3]= DSET_NVALS(insetTIME); 
         delF = DSET_TR(insetTIME);
   }

   if( (fbot<0) || (ftop<0) ) {
      ERROR_message("Think somebody forgot to specify upper and lower"
                    " frequency bounds using '-band ... ...'.");
      exit(11);
   }
   if( fbot > ftop )
      ERROR_exit("Can't have ftop < fbot! Try entering frequency"
                    "band limits again");
   if( MASK ) 
      if ( Dim[0] != DSET_NX(MASK) || Dim[1] != DSET_NY(MASK) ||
           Dim[2] != DSET_NZ(MASK) ) {
         ERROR_message("Mask and inset don't appear to have the same "
                       "dimensions.\n");
         exit(1);
      }
  

	
   // ****************************************************************
   // ****************************************************************
   //                    pre-stuff, make storage
   // ****************************************************************
   // ****************************************************************

   // array of freqs-- starts at delta F, not zero, as the current
   // input data sets must!
   allF = (float *)calloc(Dim[3], sizeof(float));

   // will be the output
   allPar = calloc(Npar,sizeof(allPar)); 
   for(i=0 ; i<Npar ; i++) 
      allPar[i] = calloc(Nvox,sizeof(float)); 

   // MASK
   mskd = (int ***) calloc( Dim[0], sizeof(int **) );
   for ( i = 0 ; i < Dim[0] ; i++ ) 
      mskd[i] = (int **) calloc( Dim[1], sizeof(int *) );
   for ( i = 0 ; i < Dim[0] ; i++ ) 
      for ( j = 0 ; j < Dim[1] ; j++ ) 
         mskd[i][j] = (int *) calloc( Dim[2], sizeof(int) );

   if( (mskd == NULL) || (allF == NULL) || (allPar == NULL) ) {
      fprintf(stderr, "\n\n MemAlloc failure (mask).\n\n");
      exit(33);
   }


   // *************************************************************
   // *************************************************************
   //                    Beginning of main loops
   // *************************************************************
   // *************************************************************

   // Populate freq bands. For now, delF is constant.  Later.... who
   // knows, so make flexible
   allF[0] = DSET_TIMEORIGIN(insetTIME);
   if( allF[0] < EPS_V )
      ERROR_exit("The t-axis (here, frequency) origin is 0!"
                 "\n\t-> but you shouldn't have a baseline 0-frequency!");
   for( i=1 ; i<Dim[3] ; i++ )
      allF[i] = allF[i-1] + delF;

   // fill in rest of freq ranges; MIN_full=0 already
   MAX_full = Dim[3]-1;
   // these should be in order, so we can pass through like this.
   for( i=0 ; i<Dim[3] ; i++ ) {
      ii = Dim[3] - 1 - i;
      if( allF[ii] >= fbot )
         MIN_bp = ii;
      if( allF[i] <= ftop )
         MAX_bp = i;
   }
   if(MAX_bp < MIN_bp) // shouldn't happen...
      ERROR_exit("Something went horribly wrong with reading in the "
                 "bandpass limits! bot:%f, top:%f",MIN_bp, MAX_bp);

   INFO_message("Actual BP range: indices [%d, %d] -> "
                "freqs [%.4f, %.4f]", MIN_bp, MAX_bp, 
                allF[MIN_bp], allF[MAX_bp]);
   INFO_message("Full freq range: indices [%d, %d] -> "
                "freqs [%.4f, %.4f]", MIN_full, MAX_full, 
                allF[MIN_full], allF[MAX_full]);
   
   // go through once: define data vox
   idx = 0;
   for( k=0 ; k<Dim[2] ; k++ ) 
      for( j=0 ; j<Dim[1] ; j++ ) 
         for( i=0 ; i<Dim[0] ; i++ ) {
            if( HAVE_MASK ) {
               if( THD_get_voxel(MASK,idx,0)>0 )
                  mskd[i][j][k] = 1;
            }
            else {
               temp_sum = 0.;
               for ( l=0 ; l<Dim[3] ; l++ )
                  temp_sum+= abs(THD_get_voxel(insetTIME,idx,l));
               if ( temp_sum > EPS_V )
                  mskd[i][j][k] = 1;
            }
            idx++;
         }
   INFO_message("Done masking.");

   Spect_to_RSFC( insetTIME,
                  DTYPE,
                  Dim,
                  mskd,
                  MIN_bp, MAX_bp, 
                  MIN_full, MAX_full,
                  allPar,
                  Npar
                  );

   INFO_message("Done calculating parameters.");

   // **************************************************************
   // **************************************************************
   //                 Store and output
   // **************************************************************
   // **************************************************************

   for( m=0; m<Npar ; m++) {
      outset = EDIT_empty_copy(insetTIME) ;
      if(NIFTI_OUT)
         sprintf(outname,"%s_%s.nii.gz",prefix, namePar[m]);
      else
         sprintf(outname,"%s_%s",prefix, namePar[m]);
      
      INFO_message(" writing: %s %s", prefix, outname);
      
      EDIT_dset_items( outset,
                       ADN_nvals     , 1 ,
                       ADN_datum_all , MRI_float , 
                       ADN_prefix    , outname ,
                       ADN_none ) ;
      if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outset)) )
         ERROR_exit("Can't overwrite existing dataset '%s'",
                    DSET_HEADNAME(outset));
      EDIT_substitute_brick(outset, 0, MRI_float, allPar[m]); 
      allPar[m]=NULL;
      THD_load_statistics(outset);
      tross_Make_History("3dAmpToRSFC", argc, argv, outset);
      THD_write_3dim_dataset(NULL, NULL, outset, True);
      
      if(outset) {
         DSET_delete(outset);
         free(outset);
      }
   }



   // ************************************************************
   // ************************************************************
   //                    Freeing
   // ************************************************************
   // ************************************************************
	
   if(allF)
      free(allF);

   if(MASK) {
      DSET_delete(MASK);
      free(MASK);
   }
   if(insetTIME) {
      DSET_delete(insetTIME);
      free(insetTIME);
   }
  
   if(mskd) {
      for( i=0 ; i<Dim[0] ; i++) 
         for( j=0 ; j<Dim[1] ; j++) 
            free(mskd[i][j]);
      for( i=0 ; i<Dim[0] ; i++) 
         free(mskd[i]);
      free(mskd);
   }



   if(allPar) { // have freed other parts of this above
      free(allPar);
   }


   return 0;
}