Пример #1
0
int main
(
  int argc,                /* number of input arguments */
  char ** argv             /* array of input arguments */ 
)

{

  /*----- Identify software -----*/
#if 0
  printf ("\n\n");
  printf ("Program: %s \n", PROGRAM_NAME);
  printf ("Author:  %s \n", PROGRAM_AUTHOR);
  printf ("Date:    %s \n", PROGRAM_DATE);
  printf ("\n");
#endif

   PRINT_VERSION("3destpdf") ; AUTHOR(PROGRAM_AUTHOR) ;mainENTRY("3destpdf main") ; machdep() ;
  
  /*----- Program initialization -----*/
  initialize_program (argc, argv);

  

}
Пример #2
0
/*--------------- main routine ---------------*/
int main( int argc, char *argv[] )
{
   options_t * opts = &g_opts;
   int         rv;

   if( argc < 2 ) { show_help();  return 0; }

   mainENTRY("3dTto1D main"); machdep(); AFNI_logger("3dTto1D",argc,argv);

   /* process command line arguments (and read dataset and mask) */
   rv = process_opts(opts, argc, argv);
   if( rv ) RETURN(rv < 0); /* only a negative return is considered failure */

   if( check_dims(opts) ) RETURN(1);

   /* evaluation of rv now depends on the method, usually non-zero is bad */
   rv = compute_results(opts);

   /* for 4095_warn, return now, regardless */
   if( opts->method == T21_METH_4095_WARN ) RETURN(rv);

   /* otherwise, any non-zero return is a failure */
   if ( rv ) RETURN(1);

   if( write_results(opts) ) RETURN(1);

   RETURN(0);
}
Пример #3
0
int main( int argc , char * argv[] )
{
   THD_3dim_dataset * dset ;
   int iarg ;
   MCW_idcode idc ;
   char str[256] ;

   if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) Syntax() ;

   iarg = 1 ;

   mainENTRY("3dnewid main"); machdep();

   if( strcmp(argv[1],"-fun") == 0 ){         /* 22 May 2000: for fun */
      int nid=0 , ii ;
      char *eee = getenv("UUID") ;
      if( argc > 2 ) nid = strtol(argv[2],NULL,10) ;
      if( nid <= 0 ) nid = 1 ;
      if( eee == NULL ){
        for( ii=0 ; ii < nid ; ii++ ){
          idc = MCW_new_idcode() ; printf("%s\n",idc.str) ;
        }
      } else {                                /* 20 Aug 2002: test of niml.c */
        for( ii=0 ; ii < nid ; ii++ ){
          eee = UUID_idcode(); printf("%s\n",eee); free(eee);
        }
      }
      exit(0) ;
   } else if ( strcmp(argv[1],"-hash") == 0 ){ /* Oct. 2011:for repeatable fun */
      if( argc != 3 ) {
         ERROR_message("You need a string following -hash");
         exit(1);
      }
      printf("%s\n", UNIQ_hashcode(argv[2]));  
      exit(0) ;
   }       

   /*-- OK, not for fun --*/

   AFNI_logger("3dnewid",argc,argv) ;

   for( ; iarg < argc ; iarg++ ){
      dset = THD_open_one_dataset( argv[iarg] ) ;
      if( dset == NULL ){
         fprintf(stderr,"** Skipping dataset %s\n",argv[iarg]) ;
         continue ;
      }
      dset->idcode = MCW_new_idcode() ;
      sprintf(str,"3dnewid %s\n",argv[iarg]) ;
      tross_Append_History( dset , str) ;
      putenv("AFNI_DECONFLICT=OVERWRITE") ;
      THD_write_3dim_dataset( NULL , NULL , dset , False ) ;
      THD_delete_3dim_dataset( dset , False ) ;
   }
   exit(0) ;
}
Пример #4
0
/*--------------- main routine ---------------*/
int main( int argc, char *argv[] )
{
   THD_3dim_dataset * countset=NULL;
   param_t          * params = &g_params;
   int                rv, limit;

   if( argc < 1 ) { show_help();  return 0; }

   /* general stuff */
   mainENTRY("3dmask_tool"); machdep(); AFNI_logger("3dmask_tool",argc,argv);
   enable_mcw_malloc();

   /* process options: a negative return is considered an error */
   rv = process_opts(params, argc, argv);
   if( rv ) RETURN(rv < 0);

   /* open, convert to byte, zeropad, dilate, unzeropad */
   if( process_input_dsets(params) ) RETURN(1);

   /* create mask count dataset and return num volumes (delete old dsets) */
   if( count_masks(params->dsets, params->ndsets, params->verb,
                   &countset, &params->nvols) ) RETURN(1);

   /* limit to frac of nvols (if not counting, convert to 0/1 mask) */
   limit = ceil((params->frac>1) ? params->frac : params->nvols*params->frac );
   if( params->verb )
      INFO_message("frac %g over %d volumes gives min count %d\n",
                   params->frac, params->nvols, limit);
   if( limit <= 0 ) limit = 1;

   /* if not counting, result is binary 0/1 */
   if( limit_to_frac(countset, limit, params->count, params->verb) )
      RETURN(1);

   /* maybe apply dilations to output */
   if( params->RESD.num > 0 ) {
      countset = apply_dilations(countset, &params->RESD, 0, params->verb);
      if( !countset ) RETURN(1);
   }

   /* maybe fill any remaining holes */
   if( params->fill )
      if ( fill_holes(countset, params->verb) ) RETURN(1);

   /* create output */
   if( write_result(params, countset, argc, argv) ) RETURN(1);

   /* clean up a little memory */
   DSET_delete(countset);
   free(params->dsets);

   RETURN(0);
}
Пример #5
0
int main( int argc , char *argv[] )
{
   line_opt  opt ;               /* holds data constructed from command line */
   THD_3dim_dataset * new_dset;  /* functional data set to be calculated */
   Boolean ok;                   /* true if 3d write is successful */
   

   /*----- Identify software -----*/
#if 0
   printf ("\n\n");
   printf ("Program: %s \n", PROGRAM_NAME);
   printf ("Author:  %s \n", PROGRAM_AUTHOR);
   printf ("Initial Release:  %s \n", PROGRAM_INITIAL);
   printf ("Latest Revision:  %s \n", PROGRAM_LATEST);
   printf ("\n");
#endif

   PRINT_VERSION("3dfim") ; AUTHOR(PROGRAM_AUTHOR) ;
   mainENTRY("3dfim main") ; machdep() ;

   /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/

   { int new_argc ; char ** new_argv ;
     addto_args( argc , argv , &new_argc , &new_argv ) ;
     if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
   }


   /* --- read command line --- */
   get_line_opt( argc , argv , &opt ) ;

   /* --- calculate functional image --- */
   new_dset = fim3d_fimmer_compute (opt.dset, opt.idts, opt.ortts, 
				    opt.first_im, opt.prefix_name, 
				    opt.max_percent);  /* 19 May 1997 */

   /*----- Record history of dataset -----*/
   tross_Copy_History( opt.dset , new_dset ) ;
   tross_Make_History( PROGRAM_NAME , argc , argv , new_dset ) ;
   
   /* --- write 3d functional image data --- */
   ok = THD_write_3dim_dataset ("", opt.prefix_name, new_dset, TRUE);
   if (!ok)  Syntax ("Failure to write functional data set.");
   
   /* --- cleanup --- */
   THD_delete_3dim_dataset (new_dset, FALSE);
   
   return (0);
}
Пример #6
0
int main( int argc , char *argv[] )
{
   int ndset=0 , ii ;
   THD_3dim_dataset **dset ;

   if( argc < 3 || strcasecmp(argv[1],"-help") == 0 ){
     printf(
       "** Program 3dConformist reads in a collection of datasets and\n"
       "   zero pads them to the same size.\n"
       "** The output volume size is the smallest region that includes\n"
       "   all datasets (i.e., the minimal covering box).\n"
       "** If the datasets cannot be processed (e.g., different grid\n"
       "   spacings), then nothing will happen except for error messages.\n"
       "** The purpose of this program is to be used in scripts that\n"
       "   process lots of datasets and needs to make them all conform\n"
       "   to the same size for collective voxel-wise analyses.\n"
       "** The input datasets ARE ALTERED (embiggened)! <<<<<<------******\n"
       "   Therefore, don't use this program casually.\n"
     ) ;
     exit(0) ;
   }

   mainENTRY("3dConformist") ; machdep() ; PRINT_VERSION("3dConformist") ;

   ndset = argc-1 ;
   dset  = (THD_3dim_dataset **)malloc(sizeof(THD_3dim_dataset *)*ndset) ;
   for( ii=0 ; ii < ndset ; ii++ ){
     dset[ii] = THD_open_dataset(argv[ii+1]) ;
     CHECK_OPEN_ERROR(dset[ii],argv[ii+1]) ;
   }

   ii = THD_conformist(ndset,dset,CONFORM_REWRITE,NULL) ;

   switch(ii){
     default: INFO_message ("3dConformist: Re-wrote %d datasets",ii) ; break ;
     case  0: INFO_message ("3dConformist: all datasets matched OK") ; break ;
     case -1: ERROR_message("3dConformist: bad input")               ; break ;
     case -2: ERROR_message("3dConformist: bad inputs")              ; break ;
     case -3: ERROR_message("3dConformist: can't match grids")       ; break ;
   }

   exit(0) ;
}
Пример #7
0
int main( int argc , char * argv[] )

{
  THD_3dim_dataset * new_dset = NULL;      /* output bucket dataset */
  

  /*----- Identify software -----*/
#if 0
  printf ("\n\n");
  printf ("Program:          %s \n", PROGRAM_NAME);
  printf ("Author:           %s \n", PROGRAM_AUTHOR); 
  printf ("Initial Release:  %s \n", PROGRAM_INITIAL);
  printf ("Latest Revision:  %s \n", PROGRAM_LATEST);
  printf ("\n");
#endif

  PRINT_VERSION("3dFDR") ; AUTHOR(PROGRAM_AUTHOR); mainENTRY("3dFDR main") ; machdep() ;

  /*----- Initialize program:  get all operator inputs; 
    create mask for voxels above mask threshold -----*/
  initialize_program (argc, argv);


  if (FDR_input1D_filename != NULL)
    {
      /*----- Process list of p-values -----*/
      process_1ddata ();
    }
  else
    {
      /*----- Process 3d dataset -----*/
      new_dset = process_dataset ();

      /*----- Output the results as a bucket dataset -----*/
      output_results (new_dset);
    }
  
  exit(0) ;
}
Пример #8
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset=NULL ;
   MCW_cluster *nbhd=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ;
   char *prefix="./LocalCormat" ;
   int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ;
   int mmlag=10 , ii,jj , do_arma=0 , nvout ;
   MRI_IMAGE *concim=NULL ; float *concar=NULL ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "Usage: 3dLocalCORMAT [options] inputdataset\n"
       "\n"
       "Compute the correlation matrix (in time) of the input dataset,\n"
       "up to lag given by -maxlag.  The matrix is averaged over the\n"
       "neighborhood specified by the -nbhd option, and then the entries\n"
       "are output at each voxel in a new dataset.\n"
       "\n"
       "Normally, the input to this program would be the -errts output\n"
       "from 3dDeconvolve, or the equivalent residuals from some other\n"
       "analysis.  If you input a non-residual time series file, you at\n"
       "least should use an appropriate -polort level for detrending!\n"
       "\n"
       "Options:\n"
       "  -input inputdataset\n"
       "  -prefix ppp\n"
       "  -mask mset    {these 2 options are}\n"
       "  -automask     {mutually exclusive.}\n"
       "  -nbhd nnn     [e.g., 'SPHERE(9)' for 9 mm radius]\n"
       "  -polort ppp   [default = 0, which is reasonable for -errts output]\n"
       "  -concat ccc   [as in 3dDeconvolve]\n"
       "  -maxlag mmm   [default = 10]\n"
       "  -ARMA         [estimate ARMA(1,1) parameters into last 2 sub-bricks]\n"
       "\n"
       "A quick hack for my own benignant purposes -- RWCox -- June 2008\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*---- official startup ---*/

   PRINT_VERSION("3dLocalCormat"); mainENTRY("3dLocalCormat main"); machdep();
   AFNI_logger("3dLocalCormat",argc,argv); AUTHOR("Zhark the Toeplitzer");

   /*---- loop over options ----*/

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

#if 0
fprintf(stderr,"argv[%d] = %s\n",iarg,argv[iarg]) ;
#endif

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

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *cpt ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       pport = (int)strtod(argv[iarg],&cpt) ;
       if( *cpt != '\0' )
         WARNING_message("Illegal non-numeric value after -polort") ;
       if( pport > 3 ){
         pport = 3 ; WARNING_message("-polort set to 3 == max implemented") ;
       } else if( pport < 0 ){
         pport = 0 ; WARNING_message("-polort set to 0 == min implemented") ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       iarg++ ; continue ;
     }

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

     if( strcmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ; int mmm ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ;
       mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       INFO_message("Number of voxels in mask = %d",mmm) ;
       if( mmm < 2 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have -automask and -mask") ;
       automask = 1 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-nbhd") == 0 ){
       char *cpt ;
       if( ntype  >  0    ) ERROR_exit("Can't have 2 '-nbhd' options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-nbhd'") ;

       cpt = argv[iarg] ;
       if( strncasecmp(cpt,"SPHERE",6) == 0 ){
         sscanf( cpt+7 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a SPHERE of radius 0") ;
         ntype = NTYPE_SPHERE ;
       } else if( strncasecmp(cpt,"RECT",4) == 0 ){
         sscanf( cpt+5 , "%f,%f,%f" , &na,&nb,&nc ) ;
         if( na == 0.0f && nb == 0.0f && nc == 0.0f )
           ERROR_exit("'RECT(0,0,0)' is not a legal neighborhood") ;
         ntype = NTYPE_RECT ;
       } else if( strncasecmp(cpt,"RHDD",4) == 0 ){
         sscanf( cpt+5 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a RHDD of radius 0") ;
         ntype = NTYPE_RHDD ;
       } else {
          ERROR_exit("Unknown -nbhd shape: '%s'",cpt) ;
       }
       iarg++ ; continue ;
     }
       
     if( strcmp(argv[iarg],"-maxlag") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       mmlag = (int)strtod(argv[iarg],NULL) ;
       iarg++ ; continue ;
     }   

     if( strcmp(argv[iarg],"-concat") == 0 ){
       if( concim != NULL )
         ERROR_exit("Can't have two %s options!",argv[iarg]) ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after option %s",argv[iarg-1]) ;
       concim = mri_read_1D( argv[iarg] ) ;
       if( concim == NULL )
         ERROR_exit("Can't read -concat file '%s'",argv[iarg]) ;
       if( concim->nx < 2 )
         ERROR_exit("-concat file '%s' must have at least 2 entries!",
                    argv[iarg]) ;
       concar = MRI_FLOAT_PTR(concim) ;
       for( ii=1 ; ii < concim->nx ; ii++ )
         if( (int)concar[ii-1] >= (int)concar[ii] )
           ERROR_exit("-concat file '%s' is not ordered increasingly!",
                      argv[iarg]) ;
       iarg++ ; continue ;
     }

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

   } /*--- end of loop over options ---*/

   if( do_arma && mmlag > 0 && mmlag < 5 )
     ERROR_exit("Can't do -ARMA with -maxlag %d",mmlag) ;

   /*---- deal with input dataset ----*/

   if( inset == NULL ){
     if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ;
     inset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(inset,argv[iarg]) ;
   }
   ntime = DSET_NVALS(inset) ;
   if( ntime < 9 )
     ERROR_exit("Must have at least 9 values per voxel") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

   if( mask != NULL ){
     if( mask_nx != DSET_NX(inset) ||
         mask_ny != DSET_NY(inset) ||
         mask_nz != DSET_NZ(inset)   )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( automask ){
     int mmm ;
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     mmm = THD_countmask( DSET_NVOX(inset) , mask ) ;
     INFO_message("Number of voxels in automask = %d",mmm) ;
     if( mmm < 2 ) ERROR_exit("Automask is too small to process") ;
   }

   /*-- set up blocks of continuous time data --*/
       
   if( DSET_IS_TCAT(inset) ){
     if( concim != NULL ){
       WARNING_message("Ignoring -concat, since dataset is auto-catenated") ;
       mri_free(concim) ;
     }
     concim = mri_new(inset->tcat_num,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim) ;
     concar[0] = 0.0 ;
     for( ii=0 ; ii < inset->tcat_num-1 ; ii++ )
       concar[ii+1] = concar[ii] + inset->tcat_len[ii] ;
   } else if( concim == NULL ){ 
     concim = mri_new(1,1,MRI_float) ;
     concar = MRI_FLOAT_PTR(concim)  ; concar[0] = 0 ;
   }
   nbk = concim->nx ;
   bk  = (int *)malloc(sizeof(int)*(nbk+1)) ;
   for( ii=0 ; ii < nbk ; ii++ ) bk[ii] = (int)concar[ii] ;
   bk[nbk] = ntime ;
   mri_free(concim) ;
   mlag = DSET_NVALS(inset) ;
   for( ii=0 ; ii < nbk ; ii++ ){
     jj = bk[ii+1]-bk[ii] ; if( jj < mlag ) mlag = jj ;
     if( bk[ii] < 0 || jj < 9 )
       ERROR_exit("something is rotten in the dataset run lengths") ;
   }
   mlag-- ;
   if( mmlag > 0 && mlag > mmlag ) mlag = mmlag ;
   else                            INFO_message("Max lag set to %d",mlag) ;

   if( do_arma && mlag < 5 )
     ERROR_exit("Can't do -ARMA with maxlag=%d",mlag) ;

   /*---- create neighborhood (as a cluster) -----*/

   if( ntype <= 0 ){         /* default neighborhood */
     ntype = NTYPE_SPHERE ; na = -1.01f ;
     INFO_message("Using default neighborhood = self + 6 neighbors") ;
   }

   switch( ntype ){
     default:
       ERROR_exit("WTF?  ntype=%d",ntype) ;

     case NTYPE_SPHERE:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_spheremask( dx,dy,dz , na ) ;
     }
     break ;

     case NTYPE_RECT:{
       if( na < 0.0f ){ dx = 1.0f; na = -na; } else dx = fabsf(DSET_DX(inset));
       if( nb < 0.0f ){ dy = 1.0f; nb = -nb; } else dy = fabsf(DSET_DY(inset));
       if( nc < 0.0f ){ dz = 1.0f; nc = -nc; } else dz = fabsf(DSET_DZ(inset));
       nbhd = MCW_rectmask( dx,dy,dz , na,nb,nc ) ;
     }
     break ;

     case NTYPE_RHDD:{
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(inset)) ;
                        dy = fabsf(DSET_DY(inset)) ;
                        dz = fabsf(DSET_DZ(inset)) ; }
       nbhd = MCW_rhddmask( dx,dy,dz , na ) ;
     }
     break ;
   }
   MCW_radsort_cluster( nbhd , dx,dy,dz ) ;  /* 26 Feb 2008 */

   INFO_message("Neighborhood comprises %d voxels",nbhd->num_pt) ;

   /** create output dataset **/

   outset = EDIT_empty_copy(inset) ;
   nvout  = mlag ; if( do_arma ) nvout += 2 ;
   EDIT_dset_items( outset,
                      ADN_prefix   , prefix,
                      ADN_brick_fac, NULL  ,
                      ADN_nvals    , nvout ,
                      ADN_ntt      , nvout ,
                    ADN_none );
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dLocalCormat" , argc,argv , outset ) ;
   for( kk=0 ; kk < nvout ; kk++ )
     EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ;

   nx = DSET_NX(outset) ;
   ny = DSET_NY(outset) ; nxy  = nx*ny  ;
   nz = DSET_NZ(outset) ; nxyz = nxy*nz ;
   vstep = (verb && nxyz > 999) ? nxyz/50 : 0 ;
   if( vstep ) fprintf(stderr,"++ voxel loop: ") ;

   /** actually do the long long slog through all voxels **/

   for( kk=0 ; kk < nxyz ; kk++ ){
     if( vstep && kk%vstep==vstep-1 ) vstep_print() ;
     if( !INMASK(kk) ) continue ;
     IJK_TO_THREE( kk , xx,yy,zz , nx,nxy ) ;
     imar = THD_get_dset_nbhd_array( inset , mask , xx,yy,zz , nbhd ) ;
     if( imar == NULL ) continue ;
     pim = mri_cormat_vector(imar) ; DESTROY_IMARR(imar) ;
     if( pim == NULL ) continue ;
     THD_insert_series( kk, outset, pim->nx, MRI_float, MRI_FLOAT_PTR(pim), 0 ) ;

     if( do_arma ){  /* estimate ARMA(1,1) params and store those, too */
       float_pair ab ;
       float *aa=DSET_ARRAY(outset,mlag), *bb=DSET_ARRAY(outset,mlag+1) ;
       ab = estimate_arma11( pim->nx , MRI_FLOAT_PTR(pim) ) ;
       aa[kk] = ab.a ; bb[kk] = ab.b ;
     }

     mri_free(pim) ;
   }
   if( vstep ) fprintf(stderr,"\n") ;

   DSET_delete(inset) ;
   DSET_write(outset) ;
   WROTE_DSET(outset) ;

   exit(0) ;
}
Пример #9
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *xset , *cset, *mset=NULL ;
   int nopt=1 , method=PEARSON , do_autoclip=0 ;
   int nvox , nvals , ii, jj, kout, kin, polort=1 ;
   int ix1,jy1,kz1, ix2, jy2, kz2 ;
   char *prefix = "degree_centrality" ;
   byte *mask=NULL;
   int   nmask , abuc=1 ;
   int   all_source=0;        /* output all source voxels  25 Jun 2010 [rickr] */
   char str[32] , *cpt ;
   int *imap = NULL ; MRI_vectim *xvectim ;
   float (*corfun)(int,float *,float*) = NULL ;
   /* djc - add 1d file output for similarity matrix */
   FILE *fout1D=NULL;

   /* CC - we will have two subbricks: binary and weighted centrality */
   int nsubbriks = 2;
   int subbrik = 0;
   float * bodset;
   float * wodset;

   int nb_ctr = 0;

   /* CC - added flags for thresholding correlations */
   double thresh = 0.0;
   double othresh = 0.0;
   int dothresh = 0;
   double sparsity = 0.0;
   int dosparsity = 0;
  
   /* variables for calculating degree centrality */
   long * binaryDC = NULL;
   double * weightedDC = NULL;

   /* variables for histogram */
   hist_node_head* histogram=NULL;
   hist_node* hptr=NULL;
   hist_node* pptr=NULL;
   int bottom_node_idx = 0;
   int totNumCor = 0;
   long totPosCor = 0;
   int ngoal = 0;
   int nretain = 0;
   float binwidth = 0.0;
   int nhistnodes = 50;

   /*----*/

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

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf(
"Usage: 3dDegreeCentrality [options] dset\n"
"  Computes voxelwise weighted and binary degree centrality and\n"
"  stores the result in a new 3D bucket dataset as floats to\n"
"  preserve their values. Degree centrality reflects the strength and\n"
"  extent of the correlation of a voxel with every other voxel in\n"
"  the brain.\n\n"
"  Conceptually the process involves: \n"
"      1. Calculating the correlation between voxel time series for\n"
"         every pair of voxels in the brain (as determined by masking)\n"
"      2. Applying a threshold to the resulting correlations to exclude\n"
"         those that might have arisen by chance, or to sparsify the\n"
"         connectivity graph.\n"
"      3. At each voxel, summarizing its correlation with other voxels\n"
"         in the brain, by either counting the number of voxels correlated\n"
"         with the seed voxel (binary) or by summing the correlation \n"
"         coefficients (weighted).\n"
"   Practically the algorithm is ordered differently to optimize for\n"
"   computational time and memory usage.\n\n"
"   The threshold can be supplied as a correlation coefficient, \n"
"   or a sparsity threshold. The sparsity threshold reflects the fraction\n"
"   of connections that should be retained after the threshold has been\n"
"   applied. To minimize resource consumption, using a sparsity threshold\n"
"   involves a two-step procedure. In the first step, a correlation\n"
"   coefficient threshold is applied to substantially reduce the number\n"
"   of correlations. Next, the remaining correlations are sorted and a\n"
"   threshold is calculated so that only the specified fraction of \n"
"   possible correlations are above threshold. Due to ties between\n"
"   correlations, the fraction of correlations that pass the sparsity\n"
"   threshold might be slightly more than the number specified.\n\n"
"   Regardless of the thresholding procedure employed, negative \n"
"   correlations are excluded from the calculations.\n" 
"\n"
"Options:\n"
"  -pearson  = Correlation is the normal Pearson (product moment)\n"
"               correlation coefficient [default].\n"
   #if 0
"  -spearman = Correlation is the Spearman (rank) correlation\n"
"               coefficient.\n"
"  -quadrant = Correlation is the quadrant correlation coefficient.\n"
   #else
"  -spearman AND -quadrant are disabled at this time :-(\n"
   #endif
"\n"
"  -thresh r = exclude correlations <= r from calculations\n"
"  -sparsity s = only use top s percent of correlations in calculations\n"
"                s should be an integer between 0 and 100. Uses an\n"
"                an adaptive thresholding procedure to reduce memory.\n"
"                The speed of determining the adaptive threshold can\n"
"                be improved by specifying an initial threshold with\n"
"                the -thresh flag.\n"
"\n"
"  -polort m = Remove polynomical trend of order 'm', for m=-1..3.\n"
"               [default is m=1; removal is by least squares].\n"
"               Using m=-1 means no detrending; this is only useful\n"
"               for data/information that has been pre-processed.\n"
"\n"
"  -autoclip = Clip off low-intensity regions in the dataset,\n"
"  -automask =  so that the correlation is only computed between\n"
"               high-intensity (presumably brain) voxels.  The\n"
"               mask is determined the same way that 3dAutomask works.\n"
"\n"
"  -mask mmm = Mask to define 'in-brain' voxels. Reducing the number\n"
"               the number of voxels included in the calculation will\n"
"               significantly speedup the calculation. Consider using\n"
"               a mask to constrain the calculations to the grey matter\n"
"               rather than the whole brain. This is also preferrable\n"
"               to using -autoclip or -automask.\n"
"\n"
"  -prefix p = Save output into dataset with prefix 'p', this file will\n"
"               contain bricks for both 'weighted' or 'degree' centrality\n"
"               [default prefix is 'deg_centrality'].\n"
"\n"
"  -out1D f = Save information about the above threshold correlations to\n"
"              1D file 'f'. Each row of this file will contain:\n"
"               Voxel1 Voxel2 i1 j1 k1 i2 j2 k2 Corr\n"
"              Where voxel1 and voxel2 are the 1D indices of the pair of\n"
"              voxels, i j k correspond to their 3D coordinates, and Corr\n"
"              is the value of the correlation between the voxel time courses.\n" 
"\n"
"Notes:\n"
" * The output dataset is a bucket type of floats.\n"
" * The program prints out an estimate of its memory used\n"
"    when it ends.  It also prints out a progress 'meter'\n"
"    to keep you pacified.\n"
"\n"
"-- RWCox - 31 Jan 2002 and 16 Jul 2010\n"
"-- Cameron Craddock - 26 Sept 2015 \n"
            ) ;
      PRINT_AFNI_OMP_USAGE("3dDegreeCentrality",NULL) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   mainENTRY("3dDegreeCentrality main"); machdep(); PRINT_VERSION("3dDegreeCentrality");
   AFNI_logger("3dDegreeCentrality",argc,argv);

   /*-- option processing --*/

   while( nopt < argc && argv[nopt][0] == '-' ){

      if( strcmp(argv[nopt],"-time") == 0 ){
         abuc = 0 ; nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-autoclip") == 0 ||
          strcmp(argv[nopt],"-automask") == 0   ){

         do_autoclip = 1 ; nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-mask") == 0 ){
         mset = THD_open_dataset(argv[++nopt]);
         CHECK_OPEN_ERROR(mset,argv[nopt]);
         nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-pearson") == 0 ){
         method = PEARSON ; nopt++ ; continue ;
      }

#if 0
      if( strcmp(argv[nopt],"-spearman") == 0 ){
         method = SPEARMAN ; nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-quadrant") == 0 ){
         method = QUADRANT ; nopt++ ; continue ;
      }
#endif

      if( strcmp(argv[nopt],"-eta2") == 0 ){
         method = ETA2 ; nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-prefix") == 0 ){
         prefix = strdup(argv[++nopt]) ;
         if( !THD_filename_ok(prefix) ){
            ERROR_exit("Illegal value after -prefix!") ;
         }
         nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-thresh") == 0 ){
         double val = (double)strtod(argv[++nopt],&cpt) ;
         if( *cpt != '\0' || val >= 1.0 || val < 0.0 ){
            ERROR_exit("Illegal value (%f) after -thresh!", val) ;
         }
         dothresh = 1;
         thresh = val ; othresh = val ; nopt++ ; continue ;
      }
      if( strcmp(argv[nopt],"-sparsity") == 0 ){
         double val = (double)strtod(argv[++nopt],&cpt) ;
         if( *cpt != '\0' || val > 100 || val <= 0 ){
            ERROR_exit("Illegal value (%f) after -sparsity!", val) ;
         }
         if( val > 5.0 )
         {
             WARNING_message("Sparsity %3.2f%% is large and will require alot of memory and time, consider using a smaller value. ", val);
         }
         dosparsity = 1 ;
         sparsity = val ; nopt++ ; continue ;
      }
      if( strcmp(argv[nopt],"-polort") == 0 ){
         int val = (int)strtod(argv[++nopt],&cpt) ;
         if( *cpt != '\0' || val < -1 || val > 3 ){
            ERROR_exit("Illegal value after -polort!") ;
         }
         polort = val ; nopt++ ; continue ;
      }
      if( strcmp(argv[nopt],"-mem_stat") == 0 ){
         MEM_STAT = 1 ; nopt++ ; continue ;
      }
      if( strncmp(argv[nopt],"-mem_profile",8) == 0 ){
         MEM_PROF = 1 ; nopt++ ; continue ;
      }
      /* check for 1d argument */
      if ( strcmp(argv[nopt],"-out1D") == 0 ){
          if (!(fout1D = fopen(argv[++nopt], "w"))) {
             ERROR_message("Failed to open %s for writing", argv[nopt]);
             exit(1);
          }
          nopt++ ; continue ;
      }

      ERROR_exit("Illegal option: %s",argv[nopt]) ;
   }

   /*-- open dataset, check for legality --*/

   if( nopt >= argc ) ERROR_exit("Need a dataset on command line!?") ;

   xset = THD_open_dataset(argv[nopt]); CHECK_OPEN_ERROR(xset,argv[nopt]);


   if( DSET_NVALS(xset) < 3 )
     ERROR_exit("Input dataset %s does not have 3 or more sub-bricks!",argv[nopt]) ;
   DSET_load(xset) ; CHECK_LOAD_ERROR(xset) ;

   /*-- compute mask array, if desired --*/
   nvox = DSET_NVOX(xset) ; nvals = DSET_NVALS(xset) ;
   INC_MEM_STATS((nvox * nvals * sizeof(double)), "input dset");
   PRINT_MEM_STATS("inset");

   /* if a mask was specified make sure it is appropriate */
   if( mset ){

      if( DSET_NVOX(mset) != nvox )
         ERROR_exit("Input and mask dataset differ in number of voxels!") ;
      mask  = THD_makemask(mset, 0, 1.0, 0.0) ;

      /* update running memory statistics to reflect loading the image */
      INC_MEM_STATS( mset->dblk->total_bytes, "mask dset" );
      PRINT_MEM_STATS( "mset load" );

      nmask = THD_countmask( nvox , mask ) ;
      INC_MEM_STATS( nmask * sizeof(byte), "mask array" );
      PRINT_MEM_STATS( "mask" );

      INFO_message("%d voxels in -mask dataset",nmask) ;
      if( nmask < 2 ) ERROR_exit("Only %d voxels in -mask, exiting...",nmask);

      /* update running memory statistics to reflect loading the image */
      DEC_MEM_STATS( mset->dblk->total_bytes, "mask dset" );
      DSET_unload(mset) ;
      PRINT_MEM_STATS( "mset unload" );
   } 
   /* if automasking is requested, handle that now */
   else if( do_autoclip ){
      mask  = THD_automask( xset ) ;
      nmask = THD_countmask( nvox , mask ) ;
      INFO_message("%d voxels survive -autoclip",nmask) ;
      if( nmask < 2 ) ERROR_exit("Only %d voxels in -automask!",nmask);
   }
   /* otherwise we use all of the voxels in the image */
   else {
      nmask = nvox ;
      INFO_message("computing for all %d voxels",nmask) ;
   }
   
   if( method == ETA2 && polort >= 0 )
      WARNING_message("Polort for -eta2 should probably be -1...");

    /* djc - 1d file out init */
    if (fout1D != NULL) {
        /* define affine matrix */
        mat44 affine_mat = xset->daxes->ijk_to_dicom;

        /* print command line statement */
        fprintf(fout1D,"#Similarity matrix from command:\n#");
        for(ii=0; ii<argc; ++ii) fprintf(fout1D,"%s ", argv[ii]);

        /* Print affine matrix */
        fprintf(fout1D,"\n");
        fprintf(fout1D,"#[ ");
        int mi, mj;
        for(mi = 0; mi < 4; mi++) {
            for(mj = 0; mj < 4; mj++) {
                fprintf(fout1D, "%.6f ", affine_mat.m[mi][mj]);
            }
        }
        fprintf(fout1D, "]\n");

        /* Print image extents*/
        THD_dataxes *xset_daxes = xset->daxes;
        fprintf(fout1D, "#Image dimensions:\n");
        fprintf(fout1D, "#[%d, %d, %d]\n",
                xset_daxes->nxx, xset_daxes->nyy, xset_daxes->nzz);

        /* Similarity matrix headers */
        fprintf(fout1D,"#Voxel1 Voxel2 i1 j1 k1 i2 j2 k2 Corr\n");
    }


   /* CC calculate the total number of possible correlations, will be 
       usefule down the road */
   totPosCor = (.5*((float)nmask))*((float)(nmask-1));

   /**  For the case of Pearson correlation, we make sure the  **/
   /**  data time series have their mean removed (polort >= 0) **/
   /**  and are normalized, so that correlation = dot product, **/
   /**  and we can use function zm_THD_pearson_corr for speed. **/

   switch( method ){
     default:
     case PEARSON: corfun = zm_THD_pearson_corr ; break ;
     case ETA2:    corfun = my_THD_eta_squared  ; break ;
   }

   /*-- create vectim from input dataset --*/
   INFO_message("vectim-izing input dataset") ;

   /*-- CC added in mask to reduce the size of xvectim -- */
   xvectim = THD_dset_to_vectim( xset , mask , 0 ) ;
   if( xvectim == NULL ) ERROR_exit("Can't create vectim?!") ;

   /*-- CC update our memory stats to reflect vectim -- */
   INC_MEM_STATS((xvectim->nvec*sizeof(int)) +
                       ((xvectim->nvec)*(xvectim->nvals))*sizeof(float) +
                       sizeof(MRI_vectim), "vectim");
   PRINT_MEM_STATS( "vectim" );

   /*--- CC the vectim contains a mapping between voxel index and mask index, 
         tap into that here to avoid duplicating memory usage ---*/

   if( mask != NULL )
   {
       imap = xvectim->ivec;

       /* --- CC free the mask */
       DEC_MEM_STATS( nmask*sizeof(byte), "mask array" );
       free(mask); mask=NULL;
       PRINT_MEM_STATS( "mask unload" );
   }

   /* -- CC unloading the dataset to reduce memory usage ?? -- */
   DEC_MEM_STATS((DSET_NVOX(xset) * DSET_NVALS(xset) * sizeof(double)), "input dset");
   DSET_unload(xset) ;
   PRINT_MEM_STATS("inset unload");

   /* -- CC configure detrending --*/
   if( polort < 0 && method == PEARSON ){
     polort = 0; WARNING_message("Pearson correlation always uses polort >= 0");
   }
   if( polort >= 0 ){
     for( ii=0 ; ii < xvectim->nvec ; ii++ ){  /* remove polynomial trend */
       DETREND_polort(polort,nvals,VECTIM_PTR(xvectim,ii)) ;
     }
   }


   /* -- this procedure does not change time series that have zero variance -- */
   if( method == PEARSON ) THD_vectim_normalize(xvectim) ;  /* L2 norm = 1 */

    /* -- CC create arrays to hold degree and weighted centrality while
          they are being calculated -- */
    if( dosparsity == 0 )
    {
        if( ( binaryDC = (long*)calloc( nmask, sizeof(long) )) == NULL )
        {
            ERROR_message( "Could not allocate %d byte array for binary DC calculation\n",
                nmask*sizeof(long)); 
        }

        /* -- update running memory estimate to reflect memory allocation */ 
        INC_MEM_STATS( nmask*sizeof(long), "binary DC array" );
        PRINT_MEM_STATS( "binaryDC" );

        if( ( weightedDC = (double*)calloc( nmask, sizeof(double) )) == NULL )
        {
            if (binaryDC){ free(binaryDC); binaryDC = NULL; }
            ERROR_message( "Could not allocate %d byte array for weighted DC calculation\n",
                nmask*sizeof(double)); 
        }
        /* -- update running memory estimate to reflect memory allocation */ 
        INC_MEM_STATS( nmask*sizeof(double), "weighted DC array" );
        PRINT_MEM_STATS( "weightedDC" );
    }


    /* -- CC if we are using a sparsity threshold, build a histogram to calculate the 
         threshold */
    if (dosparsity == 1)
    {
        /* make sure that there is a bin for correlation values that == 1.0 */
        binwidth = (1.005-thresh)/nhistnodes;

        /* calculate the number of correlations we wish to retain */
        ngoal = nretain = (int)(((double)totPosCor)*((double)sparsity) / 100.0);

        /* allocate memory for the histogram bins */
        if(( histogram = (hist_node_head*)malloc(nhistnodes*sizeof(hist_node_head))) == NULL )
        {
            /* if the allocation fails, free all memory and exit */
            if (binaryDC){ free(binaryDC); binaryDC = NULL; }
            if (weightedDC){ free(weightedDC); weightedDC = NULL; }
            ERROR_message( "Could not allocate %d byte array for histogram\n",
                nhistnodes*sizeof(hist_node_head)); 
        }
        else {
            /* -- update running memory estimate to reflect memory allocation */ 
            INC_MEM_STATS( nhistnodes*sizeof(hist_node_head), "hist bins" );
            PRINT_MEM_STATS( "hist1" );
        }

        /* initialize history bins */
        for( kout = 0; kout < nhistnodes; kout++ )
        {
            histogram[ kout ].bin_low = thresh+kout*binwidth;
            histogram[ kout ].bin_high = histogram[ kout ].bin_low+binwidth;
            histogram[ kout ].nbin = 0;
            histogram[ kout ].nodes = NULL; 
            /*INFO_message("Hist bin %d [%3.3f, %3.3f) [%d, %p]\n",
                kout, histogram[ kout ].bin_low, histogram[ kout ].bin_high,
                histogram[ kout ].nbin, histogram[ kout ].nodes );*/
        }
    }

    /*-- tell the user what we are about to do --*/
    if (dosparsity == 0 )
    {
        INFO_message( "Calculating degree centrality with threshold = %f.\n", thresh);
    }
    else
    {
        INFO_message( "Calculating degree centrality with threshold = %f and sparsity = %3.2f%% (%d)\n",
            thresh, sparsity, nretain);
    }

    /*---------- loop over mask voxels, correlate ----------*/
    AFNI_OMP_START ;
#pragma omp parallel if( nmask > 999 )
    {
       int lii,ljj,lin,lout,ithr,nthr,vstep,vii ;
       float *xsar , *ysar ;
       hist_node* new_node = NULL ;
       hist_node* tptr = NULL ;
       hist_node* rptr = NULL ;
       int new_node_idx = 0;
       double car = 0.0 ; 

       /*-- get information about who we are --*/
#ifdef USE_OMP
       ithr = omp_get_thread_num() ;
       nthr = omp_get_num_threads() ;
       if( ithr == 0 ) INFO_message("%d OpenMP threads started",nthr) ;
#else
       ithr = 0 ; nthr = 1 ;
#endif

       /*-- For the progress tracker, we want to print out 50 numbers,
            figure out a number of loop iterations that will make this easy */
       vstep = (int)( nmask / (nthr*50.0f) + 0.901f ) ; vii = 0 ;
       if((MEM_STAT==0) && (ithr == 0 )) fprintf(stderr,"Looping:") ;

#pragma omp for schedule(static, 1)
       for( lout=0 ; lout < xvectim->nvec ; lout++ ){  /*----- outer voxel loop -----*/

          if( ithr == 0 && vstep > 2 ) /* allow small dsets 16 Jun 2011 [rickr] */
          { vii++ ; if( vii%vstep == vstep/2 && MEM_STAT == 0 ) vstep_print(); }

          /* get ref time series from this voxel */
          xsar = VECTIM_PTR(xvectim,lout) ;

          /* try to make calculation more efficient by only calculating the unique 
             correlations */
          for( lin=(lout+1) ; lin < xvectim->nvec ; lin++ ){  /*----- inner loop over voxels -----*/

             /* extract the voxel time series */
             ysar = VECTIM_PTR(xvectim,lin) ;

             /* now correlate the time series */
             car = (double)(corfun(nvals,xsar,ysar)) ;

             if ( car <= thresh )
             {
                 continue ;
             }

/* update degree centrality values, hopefully the pragma
   will handle mutual exclusion */
#pragma omp critical(dataupdate)
             {
                 /* if the correlation is less than threshold, ignore it */
                 if ( car > thresh )
                 {
                     totNumCor += 1;
               
                     if ( dosparsity == 0 )
                     { 
                         binaryDC[lout] += 1; binaryDC[lin] += 1;
                         weightedDC[lout] += car; weightedDC[lin] += car;

                         /* print correlation out to the 1D file */
                         if ( fout1D != NULL )
                         {
                             /* determine the i,j,k coords */
                             ix1 = DSET_index_to_ix(xset,lii) ;
                             jy1 = DSET_index_to_jy(xset,lii) ;
                             kz1 = DSET_index_to_kz(xset,lii) ;
                             ix2 = DSET_index_to_ix(xset,ljj) ;
                             jy2 = DSET_index_to_jy(xset,ljj) ;
                             kz2 = DSET_index_to_kz(xset,ljj) ;
                             /* add source, dest, correlation to 1D file */
                             fprintf(fout1D, "%d %d %d %d %d %d %d %d %.6f\n",
                                lii, ljj, ix1, jy1, kz1, ix2, jy2, kz2, car);
                        }
                    }
                    else
                    {
                        /* determine the index in the histogram to add the node */
                        new_node_idx = (int)floor((double)(car-othresh)/(double)binwidth);
                        if ((new_node_idx > nhistnodes) || (new_node_idx < bottom_node_idx))
                        {
                            /* this error should indicate a programming error and should not happen */
                            WARNING_message("Node index %d is out of range [%d,%d)!",new_node_idx,
                            bottom_node_idx, nhistnodes);
                        }
                        else
                        {
                            /* create a node to add to the histogram */
                            new_node = (hist_node*)calloc(1,sizeof(hist_node));
                            if( new_node == NULL )
                            {
                                /* allocate memory for this node, rather than fiddling with 
                                   error handling here, lets just move on */
                                WARNING_message("Could not allocate a new node!");
                            }
                            else
                            {
                 
                                /* populate histogram node */
                                new_node->i = lout; 
                                new_node->j = lin;
                                new_node->corr = car;
                                new_node->next = NULL;

                                /* -- update running memory estimate to reflect memory allocation */ 
                                INC_MEM_STATS( sizeof(hist_node), "hist nodes" );
                                if ((totNumCor % (1024*1024)) == 0) PRINT_MEM_STATS( "hist nodes" );

                                /* populate histogram */
                                new_node->next = histogram[new_node_idx].nodes;
                                histogram[new_node_idx].nodes = new_node;
                                histogram[new_node_idx].nbin++; 

                                /* see if there are enough correlations in the histogram
                                   for the sparsity */
                                if ((totNumCor - histogram[bottom_node_idx].nbin) > nretain)
                                { 
                                    /* delete the list of nodes */
                                    rptr = histogram[bottom_node_idx].nodes;
                                    while(rptr != NULL)
                                    {
                                        tptr = rptr;
                                        rptr = rptr->next;
                                        /* check that the ptr is not null before freeing it*/
                                        if(tptr!= NULL)
                                        {
                                            DEC_MEM_STATS( sizeof(hist_node), "hist nodes" );
                                            free(tptr);
                                        }
                                    }
                                    PRINT_MEM_STATS( "unloaded hist nodes - thresh increase" );

                                    histogram[bottom_node_idx].nodes = NULL;
                                    totNumCor -= histogram[bottom_node_idx].nbin;
                                    histogram[bottom_node_idx].nbin=0;
 
                                    /* get the new threshold */
                                    thresh = (double)histogram[++bottom_node_idx].bin_low;
                                    if(MEM_STAT == 1) INFO_message("Increasing threshold to %3.2f (%d)\n",
                                        thresh,bottom_node_idx); 
                                }

                            } /* else, newptr != NULL */
                        } /* else, new_node_idx in range */
                    } /* else, do_sparsity == 1 */
                 } /* car > thresh */
             } /* this is the end of the critical section */
          } /* end of inner loop over voxels */
       } /* end of outer loop over ref voxels */

       if( ithr == 0 ) fprintf(stderr,".\n") ;

    } /* end OpenMP */
    AFNI_OMP_END ;

    /* update the user so that they know what we are up to */
    INFO_message ("AFNI_OMP finished\n");
    INFO_message ("Found %d (%3.2f%%) correlations above threshold (%f)\n",
       totNumCor, 100.0*((float)totNumCor)/((float)totPosCor), thresh);

   /*----------  Finish up ---------*/

   /*if( dosparsity == 1 )
   {
       for( kout = 0; kout < nhistnodes; kout++ )
       {
           INFO_message("Hist bin %d [%3.3f, %3.3f) [%d, %p]\n",
                kout, histogram[ kout ].bin_low, histogram[ kout ].bin_high,
                histogram[ kout ].nbin, histogram[ kout ].nodes );
       }
   }*/

   /*-- create output dataset --*/
   cset = EDIT_empty_copy( xset ) ;

   /*-- configure the output dataset */
   if( abuc ){
     EDIT_dset_items( cset ,
                        ADN_prefix    , prefix         ,
                        ADN_nvals     , nsubbriks      , /* 2 subbricks, degree and weighted centrality */
                        ADN_ntt       , 0              , /* no time axis */
                        ADN_type      , HEAD_ANAT_TYPE ,
                        ADN_func_type , ANAT_BUCK_TYPE ,
                        ADN_datum_all , MRI_float      ,
                      ADN_none ) ;
   } else {
     EDIT_dset_items( cset ,
                        ADN_prefix    , prefix         ,
                        ADN_nvals     , nsubbriks      , /* 2 subbricks, degree and weighted centrality */
                        ADN_ntt       , nsubbriks      ,  /* num times */
                        ADN_ttdel     , 1.0            ,  /* fake TR */
                        ADN_nsl       , 0              ,  /* no slice offsets */
                        ADN_type      , HEAD_ANAT_TYPE ,
                        ADN_func_type , ANAT_EPI_TYPE  ,
                        ADN_datum_all , MRI_float      ,
                      ADN_none ) ;
   }

   /* add history information to the hearder */
   tross_Make_History( "3dDegreeCentrality" , argc,argv , cset ) ;

   ININFO_message("creating output dataset in memory") ;

   /* -- Configure the subbriks: Binary Degree Centrality */
   subbrik = 0;
   EDIT_BRICK_TO_NOSTAT(cset,subbrik) ;                     /* stat params  */
   /* CC this sets the subbrik scaling factor, which we will probably want
      to do again after we calculate the voxel values */
   EDIT_BRICK_FACTOR(cset,subbrik,1.0) ;                 /* scale factor */

   sprintf(str,"Binary Degree Centrality") ;

   EDIT_BRICK_LABEL(cset,subbrik,str) ;
   EDIT_substitute_brick(cset,subbrik,MRI_float,NULL) ;   /* make array   */


   /* copy measure data into the subbrik */
   bodset = DSET_ARRAY(cset,subbrik);
 
   /* -- Configure the subbriks: Weighted Degree Centrality */
   subbrik = 1;
   EDIT_BRICK_TO_NOSTAT(cset,subbrik) ;                     /* stat params  */
   /* CC this sets the subbrik scaling factor, which we will probably want
      to do again after we calculate the voxel values */
   EDIT_BRICK_FACTOR(cset,subbrik,1.0) ;                 /* scale factor */

   sprintf(str,"Weighted Degree Centrality") ;

   EDIT_BRICK_LABEL(cset,subbrik,str) ;
   EDIT_substitute_brick(cset,subbrik,MRI_float,NULL) ;   /* make array   */

   /* copy measure data into the subbrik */
   wodset = DSET_ARRAY(cset,subbrik);

   /* increment memory stats */
   INC_MEM_STATS( (DSET_NVOX(cset)*DSET_NVALS(cset)*sizeof(float)), "output dset");
   PRINT_MEM_STATS( "outset" );

   /* pull the values out of the histogram */
   if( dosparsity == 0 )
   {
       for( kout = 0; kout < nmask; kout++ )
       {
          if ( imap != NULL )
          {
              ii = imap[kout] ;  /* ii= source voxel (we know that ii is in the mask) */
          }
          else
          {
              ii = kout ;
          }
   
          if( ii >= DSET_NVOX(cset) )
          {
              WARNING_message("Avoiding bodset, wodset overflow %d > %d (%s,%d)\n",
                  ii,DSET_NVOX(cset),__FILE__,__LINE__ );
          }
          else
          {
              bodset[ ii ] = (float)(binaryDC[kout]);
              wodset[ ii ] = (float)(weightedDC[kout]);
          }
       }

       /* we are done with this memory, and can kill it now*/
       if(binaryDC)
       {
           free(binaryDC);
           binaryDC=NULL;
           /* -- update running memory estimate to reflect memory allocation */ 
           DEC_MEM_STATS( nmask*sizeof(long), "binary DC array" );
           PRINT_MEM_STATS( "binaryDC" );
       }
       if(weightedDC)
       {
           free(weightedDC);
           weightedDC=NULL;
           /* -- update running memory estimate to reflect memory allocation */ 
           DEC_MEM_STATS( nmask*sizeof(double), "weighted DC array" );
           PRINT_MEM_STATS( "weightedDC" );
       }
   }
   else
   {

       /* add in the values from the histogram, this is a two stage procedure:
             at first we add in values a whole bin at the time until we get to a point
             where we need to add in a partial bin, then we create a new histogram
             to sort the values in the bin and then add those bins at a time */
       kout = nhistnodes - 1;
       while (( histogram[kout].nbin < nretain ) && ( kout >= 0 ))
       {
           hptr = pptr = histogram[kout].nodes;
           while( hptr != NULL )
           {

               /* determine the indices corresponding to this node */
               if ( imap != NULL )
               {
                   ii = imap[hptr->i] ;  /* ii= source voxel (we know that ii is in the mask) */
               }
               else 
               {
                   ii = hptr->i ;
               }
               if ( imap != NULL )
               {
                   jj = imap[hptr->j] ;  /* ii= source voxel (we know that ii is in the mask) */
               }
               else
               {
                   jj = hptr->j ;
               }

               /* add in the values */
               if(( ii >= DSET_NVOX(cset) ) || ( jj >= DSET_NVOX(cset)))
               {
                   if( ii >= DSET_NVOX(cset))
                   {
                       WARNING_message("Avoiding bodset, wodset overflow (ii) %d > %d\n (%s,%d)\n",
                           ii,DSET_NVOX(cset),__FILE__,__LINE__ );
                   }
                   if( jj >= DSET_NVOX(cset))
                   {
                       WARNING_message("Avoiding bodset, wodset overflow (jj) %d > %d\n (%s,%d)\n",
                           jj,DSET_NVOX(cset),__FILE__,__LINE__ );
                   }
               }
               else
               {
                   bodset[ ii ] += 1.0 ;
                   wodset[ ii ] += (float)(hptr->corr);
                   bodset[ jj ] += 1.0 ;
                   wodset[ jj ] += (float)(hptr->corr);
               }

               if( fout1D != NULL )
               {
                   /* add source, dest, correlation to 1D file */
                   ix1 = DSET_index_to_ix(cset,ii) ;
                   jy1 = DSET_index_to_jy(cset,ii) ;
                   kz1 = DSET_index_to_kz(cset,ii) ;
                   ix2 = DSET_index_to_ix(cset,jj) ;
                   jy2 = DSET_index_to_jy(cset,jj) ;
                   kz2 = DSET_index_to_kz(cset,jj) ;
                   fprintf(fout1D, "%d %d %d %d %d %d %d %d %.6f\n",
                           ii, jj, ix1, jy1, kz1, ix2, jy2, kz2, (float)(hptr->corr));
               }

               /* increment node pointers */
               pptr = hptr;
               hptr = hptr->next;

               /* delete the node */
               if(pptr)
               {
                   /* -- update running memory estimate to reflect memory allocation */ 
                   DEC_MEM_STATS(sizeof( hist_node ), "hist nodes" );
                   /* free the mem */
                   free(pptr);
                   pptr=NULL;
               }
           } 
           /* decrement the number of correlations we wish to retain */
           nretain -= histogram[kout].nbin;
           histogram[kout].nodes = NULL;

           /* go on to the next bin */
           kout--;
       }
       PRINT_MEM_STATS( "hist1 bins free - inc into output" );

        /* if we haven't used all of the correlations that are available, go through and 
           add a subset of the voxels from the remaining bin */
        if(( nretain > 0 ) && (kout >= 0))
        {

            hist_node_head* histogram2 = NULL; 
            hist_node_head* histogram2_save = NULL; 
            int h2nbins = 100;
            float h2binwidth = 0.0;
            int h2ndx=0;

            h2binwidth = (((1.0+binwidth/((float)h2nbins))*histogram[kout].bin_high) - histogram[kout].bin_low) /
               ((float)h2nbins);

            /* allocate the bins */
            if(( histogram2 = (hist_node_head*)malloc(h2nbins*sizeof(hist_node_head))) == NULL )
            {
                if (binaryDC){ free(binaryDC); binaryDC = NULL; }
                if (weightedDC){ free(weightedDC); weightedDC = NULL; }
                if (histogram){ histogram = free_histogram(histogram, nhistnodes); }
                ERROR_message( "Could not allocate %d byte array for histogram2\n",
                    h2nbins*sizeof(hist_node_head)); 
            }
            else {
                /* -- update running memory estimate to reflect memory allocation */ 
                histogram2_save = histogram2;
                INC_MEM_STATS(( h2nbins*sizeof(hist_node_head )), "hist bins");
                PRINT_MEM_STATS( "hist2" );
            }
   
            /* initiatize the bins */ 
            for( kin = 0; kin < h2nbins; kin++ )
            {
                histogram2[ kin ].bin_low = histogram[kout].bin_low + kin*h2binwidth;
                histogram2[ kin ].bin_high = histogram2[ kin ].bin_low + h2binwidth;
                histogram2[ kin ].nbin = 0;
                histogram2[ kin ].nodes = NULL; 
                /*INFO_message("Hist2 bin %d [%3.3f, %3.3f) [%d, %p]\n",
                    kin, histogram2[ kin ].bin_low, histogram2[ kin ].bin_high,
                    histogram2[ kin ].nbin, histogram2[ kin ].nodes );*/
            }

            /* move correlations from histogram to histgram2 */
            INFO_message ("Adding %d nodes from histogram to histogram2",histogram[kout].nbin);
            while ( histogram[kout].nodes != NULL )
            {
                hptr = histogram[kout].nodes;
                h2ndx = (int)floor((double)(hptr->corr - histogram[kout].bin_low)/(double)h2binwidth);
                if(( h2ndx < h2nbins ) && ( h2ndx >= 0 ))
                {
                    histogram[kout].nodes = hptr->next;
                    hptr->next = histogram2[h2ndx].nodes;
                    histogram2[h2ndx].nodes = hptr; 
                    histogram2[h2ndx].nbin++;
                    histogram[kout].nbin--;
                }
                else
                {
                    WARNING_message("h2ndx %d is not in range [0,%d) :: %.10f,%.10f\n",h2ndx,h2nbins,hptr->corr, histogram[kout].bin_low);
                }
               
            }

            /* free the remainder of histogram */
            {
                int nbins_rem = 0;
                for(ii = 0; ii < nhistnodes; ii++) nbins_rem+=histogram[ii].nbin;
                histogram = free_histogram(histogram, nhistnodes);
                PRINT_MEM_STATS( "free remainder of histogram1" );
            }

            kin = h2nbins - 1;
            while (( nretain > 0 ) && ( kin >= 0 ))
            {
                hptr = pptr = histogram2[kin].nodes;
                while( hptr != NULL )
                {
     
                    /* determine the indices corresponding to this node */
                    if ( imap != NULL )
                    {
                        ii = imap[hptr->i] ;  
                    }
                    else
                    {
                        ii = hptr->i ;
                    }
                    if ( imap != NULL )
                    {
                        jj = imap[hptr->j] ; 
                    }
                    else
                    {
                        jj = hptr->j ;
                    }

                    /* add in the values */
                    if(( ii >= DSET_NVOX(cset) ) || ( jj >= DSET_NVOX(cset)))
                    {
                        if( ii >= DSET_NVOX(cset))
                        {
                            WARNING_message("Avoiding bodset, wodset overflow (ii) %d > %d\n (%s,%d)\n",
                                ii,DSET_NVOX(cset),__FILE__,__LINE__ );
                        }
                        if( jj >= DSET_NVOX(cset))
                        {
                            WARNING_message("Avoiding bodset, wodset overflow (jj) %d > %d\n (%s,%d)\n",
                                jj,DSET_NVOX(cset),__FILE__,__LINE__ );
                        }
                    }
                    else
                    {
                        bodset[ ii ] += 1.0 ;
                        wodset[ ii ] += (float)(hptr->corr);
                        bodset[ jj ] += 1.0 ;
                        wodset[ jj ] += (float)(hptr->corr);
                    }
                    if( fout1D != NULL )
                    {
                        /* add source, dest, correlation to 1D file */
                        ix1 = DSET_index_to_ix(cset,ii) ;
                        jy1 = DSET_index_to_jy(cset,ii) ;
                        kz1 = DSET_index_to_kz(cset,ii) ;
                        ix2 = DSET_index_to_ix(cset,jj) ;
                        jy2 = DSET_index_to_jy(cset,jj) ;
                        kz2 = DSET_index_to_kz(cset,jj) ;
                        fprintf(fout1D, "%d %d %d %d %d %d %d %d %.6f\n",
                            ii, jj, ix1, jy1, kz1, ix2, jy2, kz2, (float)(hptr->corr));
                    }

                    /* increment node pointers */
                    pptr = hptr;
                    hptr = hptr->next;

                    /* delete the node */
                    if(pptr)
                    {
                        free(pptr);
                        DEC_MEM_STATS(( sizeof(hist_node) ), "hist nodes");
                        pptr=NULL;
                    }
                }
 
                /* decrement the number of correlations we wish to retain */
                nretain -= histogram2[kin].nbin;
                histogram2[kin].nodes = NULL;

                /* go on to the next bin */
                kin--;
            }
            PRINT_MEM_STATS("hist2 nodes free - incorporated into output");

            /* we are finished with histogram2 */
            {
                histogram2 = free_histogram(histogram2, h2nbins);
                /* -- update running memory estimate to reflect memory allocation */ 
                PRINT_MEM_STATS( "free hist2" );
            }

            if (nretain < 0 )
            {
                WARNING_message( "Went over sparsity goal %d by %d, with a resolution of %f",
                      ngoal, -1*nretain, h2binwidth);
            }
        }
        if (nretain > 0 )
        {
            WARNING_message( "Was not able to meet goal of %d (%3.2f%%) correlations, %d (%3.2f%%) correlations passed the threshold of %3.2f, maybe you need to change the threshold or the desired sparsity?",
                  ngoal, 100.0*((float)ngoal)/((float)totPosCor), totNumCor, 100.0*((float)totNumCor)/((float)totPosCor),  thresh);
        }
   }

   INFO_message("Done..\n") ;

   /* update running memory statistics to reflect freeing the vectim */
   DEC_MEM_STATS(((xvectim->nvec*sizeof(int)) +
                       ((xvectim->nvec)*(xvectim->nvals))*sizeof(float) +
                       sizeof(MRI_vectim)), "vectim");

   /* toss some trash */
   VECTIM_destroy(xvectim) ;
   DSET_delete(xset) ;
   if(fout1D!=NULL)fclose(fout1D);

   PRINT_MEM_STATS( "vectim unload" );

   if (weightedDC) free(weightedDC) ; weightedDC = NULL;
   if (binaryDC) free(binaryDC) ; binaryDC = NULL;
   
   /* finito */
   INFO_message("Writing output dataset to disk [%s bytes]",
                commaized_integer_string(cset->dblk->total_bytes)) ;

   /* write the dataset */
   DSET_write(cset) ;
   WROTE_DSET(cset) ;

   /* increment our memory stats, since we are relying on the header for this
      information, we update the stats before actually freeing the memory */
   DEC_MEM_STATS( (DSET_NVOX(cset)*DSET_NVALS(cset)*sizeof(float)), "output dset");

   /* free up the output dataset memory */
   DSET_unload(cset) ;
   DSET_delete(cset) ;

   /* force a print */
   MEM_STAT = 1;
   PRINT_MEM_STATS( "Fin" );

   exit(0) ;
}
Пример #10
0
int main( int argc , char *argv[] )
{
   int nx,ny,nz , nxyz , ii,kk , num1,num2 , num_tt=0 , iv ,
       piece , fim_offset;
   float dx,dy,dz , dxyz ,
         num1_inv=0.0 , num2_inv , num1m1_inv=0.0 , num2m1_inv , dof ,
         dd,tt,q1,q2 , f1,f2 , tt_max=0.0 ;
   THD_3dim_dataset *dset=NULL , *new_dset=NULL ;
   THD_3dim_dataset * base_dset;
   float *av1 , *av2 , *sd1 , *sd2 , *ffim , *gfim ;
   float *base_ary=NULL;

   void  *vsp ;
   void  *vdif ;           /* output mean difference */
   char  cbuf[THD_MAX_NAME] ;
   float fbuf[MAX_STAT_AUX] , fimfac ;
   int   output_datum ;
   float npiece , memuse ;

   float *dofbrik=NULL , *dofar=NULL ;
   THD_3dim_dataset *dof_dset=NULL ;

   /*-- read command line arguments --*/

   if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ) TT_syntax(NULL) ;

   /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/

   mainENTRY("3dttest main"); machdep() ; PRINT_VERSION("3dttest") ;
   INFO_message("For most purposes, 3dttest++ should be used instead of 3dttest!") ;

   { int new_argc ; char ** new_argv ;
     addto_args( argc , argv , &new_argc , &new_argv ) ;
     if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
   }

   AFNI_logger("3dttest",argc,argv) ;

   TT_read_opts( argc , argv ) ;

   if( ! TT_be_quiet )
      printf("3dttest: t-tests of 3D datasets, by RW Cox\n") ;

   /*-- read first dataset in set2 to get dimensions, etc. --*/

   dset = THD_open_dataset( TT_set2->ar[0] ) ;  /* 20 Dec 1999  BDW */
   if( ! ISVALID_3DIM_DATASET(dset) )
     ERROR_exit("Unable to open dataset file %s",TT_set2->ar[0]);

   nx = dset->daxes->nxx ;
   ny = dset->daxes->nyy ;
   nz = dset->daxes->nzz ;         nxyz = nx * ny * nz ;
   dx = fabs(dset->daxes->xxdel) ;
   dy = fabs(dset->daxes->yydel) ;
   dz = fabs(dset->daxes->zzdel) ; dxyz = dx * dy * dz ;

#ifdef TTDEBUG
printf("*** nx=%d ny=%d nz=%d\n",nx,ny,nz) ;
#endif

   /*-- make an empty copy of this dataset, for eventual output --*/

#ifdef TTDEBUG
printf("*** making empty dataset\n") ;
#endif

   new_dset = EDIT_empty_copy( dset ) ;

   tross_Make_History( "3dttest" , argc,argv , new_dset ) ;

   strcpy( cbuf , dset->self_name ) ; strcat( cbuf , "+TT" ) ;

   iv = DSET_PRINCIPAL_VALUE(dset) ;

   if( TT_datum >= 0 ){
      output_datum = TT_datum ;
   } else {
      output_datum = DSET_BRICK_TYPE(dset,iv) ;
      if( output_datum == MRI_byte ) output_datum = MRI_short ;
   }

#ifdef TTDEBUG
printf(" ** datum = %s\n",MRI_TYPE_name[output_datum]) ;
#endif

   iv = EDIT_dset_items( new_dset ,
                           ADN_prefix , TT_prefix ,
                           ADN_label1 , TT_prefix ,
                           ADN_directory_name , TT_session ,
                           ADN_self_name , cbuf ,
                           ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
                           ADN_func_type , FUNC_TT_TYPE ,
                           ADN_nvals , FUNC_nvals[FUNC_TT_TYPE] ,
                           ADN_ntt , 0 ,                           /* 07 Jun 2007 */
                           ADN_datum_all , output_datum ,
                         ADN_none ) ;

   if( iv > 0 )
     ERROR_exit("%d errors in attempting to create output dataset!",iv ) ;

   if( THD_deathcon() && THD_is_file(new_dset->dblk->diskptr->header_name) )
      ERROR_exit(
              "Output dataset file %s already exists--cannot continue!\a",
              new_dset->dblk->diskptr->header_name ) ;

#ifdef TTDEBUG
printf("*** deleting exemplar dataset\n") ;
#endif

   THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

/** macro to test a malloc-ed pointer for validity **/

#define MTEST(ptr) \
   if((ptr)==NULL) \
      ( fprintf(stderr,"*** Cannot allocate memory for statistics!\n"), exit(0) )

   /*-- make space for the t-test computations --*/

   /* (allocate entire volumes) 13 Dec 2005 [rickr] */
                              npiece  = 3.0 ;  /* need at least this many */
   if( TT_paired )            npiece += 1.0 ;
   else if( TT_set1 != NULL ) npiece += 2.0 ;

   npiece += mri_datum_size(output_datum) / (float) sizeof(float) ;
   npiece += mri_datum_size(output_datum) / (float) sizeof(float) ;

#if 0
   piece_size = TT_workmem * MEGA / ( npiece * sizeof(float) ) ;
   if( piece_size > nxyz ) piece_size = nxyz ;

#ifdef TTDEBUG
printf("*** malloc-ing space for statistics: %g float arrays of length %d\n",
       npiece,piece_size) ;
#endif
#endif

   av2  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av2) ;
   sd2  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd2) ;
   ffim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(ffim) ;
   num2 = TT_set2->num ;

   if( TT_paired ){
      av1  = sd1 = NULL ;
      gfim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(gfim) ;
      num1 = num2 ;
   } else if( TT_set1 != NULL ){
      av1  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av1) ;
      sd1  = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd1) ;
      gfim = NULL ;
      num1 = TT_set1->num ;
   } else {
      av1  = sd1 = NULL ;
      gfim = NULL ;
      num1 = 0 ;
   }

   vdif = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vdif) ;
   vsp  = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vsp)  ;

   /* 27 Dec 2002: make DOF dataset (if prefix is given, and unpooled is on) */

   if( TT_pooled == 0 && TT_dof_prefix[0] != '\0' ){
     dofbrik = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(dofbrik) ;

     dof_dset = EDIT_empty_copy( new_dset ) ;

     tross_Make_History( "3dttest" , argc,argv , dof_dset ) ;

     EDIT_dset_items( dof_dset ,
                       ADN_prefix , TT_dof_prefix ,
                       ADN_directory_name , TT_session ,
                       ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE,
                       ADN_func_type , FUNC_BUCK_TYPE ,
                       ADN_nvals , 1 ,
                       ADN_datum_all , MRI_float ,
                      ADN_none ) ;

     if( THD_is_file(dof_dset->dblk->diskptr->header_name) )
        ERROR_exit(
                "-dof_prefix dataset file %s already exists--cannot continue!\a",
                dof_dset->dblk->diskptr->header_name ) ;

     EDIT_substitute_brick( dof_dset , 0 , MRI_float , dofbrik ) ;
   }

   /* print out memory usage to edify the user */

   if( ! TT_be_quiet ){
      memuse =    sizeof(float) * nxyz * npiece
              + ( mri_datum_size(output_datum) + sizeof(short) ) * nxyz ;

      if( dofbrik != NULL ) memuse += sizeof(float) * nxyz ;  /* 27 Dec 2002 */

      printf("--- allocated %d Megabytes memory for internal use (%d volumes)\n",
             (int)(memuse/MEGA), (int)npiece) ;
   }

   mri_fix_data_pointer( vdif , DSET_BRICK(new_dset,0) ) ;  /* attach bricks */
   mri_fix_data_pointer( vsp  , DSET_BRICK(new_dset,1) ) ;  /* to new dataset */

   /** only short and float are allowed for output **/
   if( output_datum != MRI_short && output_datum != MRI_float )
      ERROR_exit("Illegal output data type %d = %s",
                 output_datum , MRI_TYPE_name[output_datum] ) ;

   num2_inv = 1.0 / num2 ;  num2m1_inv = 1.0 / (num2-1) ;
   if( num1 > 0 ){
      num1_inv = 1.0 / num1 ;  num1m1_inv = 1.0 / (num1-1) ;
   }

   /*----- loop over pieces to process the input datasets with -----*/

/** macro to open a dataset and make it ready for processing **/

#define DOPEN(ds,name)                                                            \
   do{ int pv ; (ds) = THD_open_dataset((name)) ;  /* 16 Sep 1999 */              \
       if( !ISVALID_3DIM_DATASET((ds)) )                                          \
          ERROR_exit("Can't open dataset: %s",(name)) ;                           \
       if( (ds)->daxes->nxx!=nx || (ds)->daxes->nyy!=ny || (ds)->daxes->nzz!=nz ) \
          ERROR_exit("Axes size mismatch: %s",(name)) ;                           \
       if( !EQUIV_GRIDS((ds),new_dset) )                                          \
          WARNING_message("Grid mismatch: %s",(name)) ;                           \
       if( DSET_NUM_TIMES((ds)) > 1 )                                             \
         ERROR_exit("Can't use time-dependent data: %s",(name)) ;                 \
       if( TT_use_editor ) EDIT_one_dataset( (ds), &TT_edopt ) ;                  \
       else                DSET_load((ds)) ;                                      \
       pv = DSET_PRINCIPAL_VALUE((ds)) ;                                          \
       if( DSET_ARRAY((ds),pv) == NULL )                                          \
          ERROR_exit("Can't access data: %s",(name)) ;                            \
       if( DSET_BRICK_TYPE((ds),pv) == MRI_complex )                              \
          ERROR_exit("Can't use complex data: %s",(name)) ;                       \
       break ; } while (0)

#if 0   /* can do it directly now (without offsets)  13 Dec 2005 [rickr] */
/** macro to return pointer to correct location in brick for current processing **/

#define SUB_POINTER(ds,vv,ind,ptr)                                            \
   do{ switch( DSET_BRICK_TYPE((ds),(vv)) ){                                  \
         default: ERROR_exit("Illegal datum! ***");                           \
            case MRI_short:{ short * fim = (short *) DSET_ARRAY((ds),(vv)) ;  \
                            (ptr) = (void *)( fim + (ind) ) ;                 \
            } break ;                                                         \
            case MRI_byte:{ byte * fim = (byte *) DSET_ARRAY((ds),(vv)) ;     \
                            (ptr) = (void *)( fim + (ind) ) ;                 \
            } break ;                                                         \
            case MRI_float:{ float * fim = (float *) DSET_ARRAY((ds),(vv)) ;  \
                             (ptr) = (void *)( fim + (ind) ) ;                \
            } break ; } break ; } while(0)
#endif

   /** number of pieces to process **/
   /* num_piece = (nxyz + piece_size - 1) / nxyz ; */

#if 0
   nice(2) ;  /** lower priority a little **/
#endif


   /* possibly open TT_base_dset now, and convert to floats */
   if( TT_base_dname ) {
      DOPEN(base_dset, TT_base_dname) ;
      base_ary = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(base_ary) ;
      EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(base_dset,0) ,
              DSET_BRICK_TYPE(base_dset,0),DSET_ARRAY(base_dset,0), /* input */
              MRI_float ,base_ary  ) ;                              /* output */
      THD_delete_3dim_dataset( base_dset , False ) ; base_dset = NULL ;
   }

   /* only 1 'piece' now   13 Dec 2005 [rickr] */
   for( piece=0 ; piece < 1 ; piece++ ){

      fim_offset = 0 ;

#ifdef TTDEBUG
printf("*** start of piece %d: length=%d offset=%d\n",piece,nxyz,fim_offset) ;
#else
      if( ! TT_be_quiet ){
         printf("--- starting piece %d/%d (%d voxels) ",piece+1,1,nxyz) ;
         fflush(stdout) ;
      }
#endif

      /** process set2 (and set1, if paired) **/

      for( ii=0 ; ii < nxyz ; ii++ ) av2[ii] = 0.0 ;
      for( ii=0 ; ii < nxyz ; ii++ ) sd2[ii] = 0.0 ;

      for( kk=0 ; kk < num2 ; kk++ ){

         /** read in the data **/

         DOPEN(dset,TT_set2->ar[kk]) ;
         iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** opened dataset file %s\n",TT_set2->ar[kk]);
#endif

#if 0 /* fimfac will be compute when the results are ready */
         if( piece == 0 && kk == 0 ){
            fimfac = DSET_BRICK_FACTOR(dset,iv) ;
            if( fimfac == 0.0 ) fimfac = 1.0 ;
            fimfacinv = 1.0 / fimfac ;
#ifdef TTDEBUG
printf(" ** set fimfac = %g\n",fimfac) ;
#endif
         }
#endif

         /** convert it to floats (in ffim) **/
         EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                                DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                                MRI_float ,ffim  ) ;                         /* output */
         THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

         /** get the paired dataset, if present **/

         if( TT_paired ){
            DOPEN(dset,TT_set1->ar[kk]) ;
            iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
        printf(" ** opened dataset file %s\n",TT_set1->ar[kk]);
#endif

            EDIT_coerce_scale_type(
                        nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                        DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                        MRI_float ,gfim  ) ;                         /* output */
            THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

            if( TT_voxel >= 0 )
              fprintf(stderr,"-- paired values #%02d: %f, %f\n",
                      kk,ffim[TT_voxel],gfim[TT_voxel]) ;

            for( ii=0 ; ii < nxyz ; ii++ ) ffim[ii] -= gfim[ii] ;
         } else if( TT_voxel >= 0 )
            fprintf(stderr,"-- set2 value #%02d: %f\n",kk,ffim[TT_voxel]);

#ifdef TTDEBUG
printf("  * adding into av2 and sd2\n") ;
#endif

         /* accumulate into av2 and sd2 */

         for( ii=0 ; ii < nxyz ; ii++ ){
            dd = ffim[ii] ; av2[ii] += dd ; sd2[ii] += dd * dd ;
         }

      }  /* end of loop over set2 datasets */

      /** form the mean and stdev of set2 **/

#ifdef TTDEBUG
printf(" ** forming mean and sigma of set2\n") ;
#endif

      for( ii=0 ; ii < nxyz ; ii++ ){
         av2[ii] *= num2_inv ;
         dd       = (sd2[ii] - num2*av2[ii]*av2[ii]) ;
         sd2[ii]  = (dd > 0.0) ? sqrt( num2m1_inv * dd ) : 0.0 ;
      }
      if( TT_voxel >= 0 )
         fprintf(stderr,"-- s2 mean = %g, sd = %g\n",
                 av2[TT_voxel],sd2[TT_voxel]) ;

      /** if set1 exists but is not paired with set2, process it now **/

      if( ! TT_paired && TT_set1 != NULL ){

         for( ii=0 ; ii < nxyz ; ii++ ) av1[ii] = 0.0 ;
         for( ii=0 ; ii < nxyz ; ii++ ) sd1[ii] = 0.0 ;

         for( kk=0 ; kk < num1 ; kk++ ){
            DOPEN(dset,TT_set1->ar[kk]) ;
            iv = DSET_PRINCIPAL_VALUE(dset) ;

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** opened dataset file %s\n",TT_set1->ar[kk]);
#endif

            EDIT_coerce_scale_type(
                                nxyz , DSET_BRICK_FACTOR(dset,iv) ,
                                DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */
                                MRI_float ,ffim  ) ;                         /* output */
            THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

#ifdef TTDEBUG
printf("  * adding into av1 and sd1\n") ;
#endif

            for( ii=0 ; ii < nxyz ; ii++ ){
               dd = ffim[ii] ; av1[ii] += dd ; sd1[ii] += dd * dd ;
            }
            if( TT_voxel >= 0 )
               fprintf(stderr,"-- set1 value #%02d: %g\n",kk,ffim[TT_voxel]) ;
         }  /* end of loop over set1 datasets */

         /** form the mean and stdev of set1 **/

#ifdef TTDEBUG
printf(" ** forming mean and sigma of set1\n") ;
#endif

         for( ii=0 ; ii < nxyz ; ii++ ){
            av1[ii] *= num1_inv ;
            dd       = (sd1[ii] - num1*av1[ii]*av1[ii]) ;
            sd1[ii]  = (dd > 0.0) ? sqrt( num1m1_inv * dd ) : 0.0 ;
         }
         if( TT_voxel >= 0 )
            fprintf(stderr,"-- s1 mean = %g, sd = %g\n",
                    av1[TT_voxel], sd1[TT_voxel]) ;
      }  /* end of processing set1 by itself */

      /***** now form difference and t-statistic *****/

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf("+") ; fflush(stdout) ; }  /* progress */
#else
         printf(" ** computing t-tests next\n") ;
#endif

#if 0 /* will do at end using EDIT_convert_dtype  13 Dec 2005 [rickr] */

      /** macro to assign difference value to correct type of array **/
#define DIFASS switch( output_datum ){                                        \
                 case MRI_short: sdar[ii] = (short) (fimfacinv*dd) ; break ;  \
                 case MRI_float: fdar[ii] = (float) dd             ; break ; }
#define TOP_SS  32700
#define TOP_TT (32700.0/FUNC_TT_SCALE_SHORT)

#endif

      if( TT_paired || TT_use_bval == 1 ){ /** case 1: paired estimate or 1-sample **/

        if( TT_paired || TT_n1 == 0 ){       /* the olde waye: 1 sample test */
          f2 = 1.0 / sqrt( (double) num2 ) ;
          for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ;  /* final mean */
            if( sd2[ii] > 0.0 ){
               num_tt++ ;
               tt      = av2[ii] / (f2 * sd2[ii]) ;
               sd2[ii] = tt;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
               sd2[ii] = 0.0;
            }
          }
          if( TT_voxel >= 0 )
             fprintf(stderr,"-- paired/bval mean = %g, t = %g\n",
                     av2[TT_voxel], sd2[TT_voxel]) ;

        } else {  /* 10 Oct 2007: -sdn1 was used with -base1: 'two' sample test */
          f1 = (TT_n1-1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ;
          f2 = (num2 -1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ;
          for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ;  /* final mean */
            q1 = f1 * TT_sd1*TT_sd1 + f2 * sd2[ii]*sd2[ii] ;
            if( q1 > 0.0 ){
              num_tt++ ;
              tt = av2[ii] / sqrt(q1) ;
              sd2[ii] = tt ;      /* final t-stat */
              tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
              sd2[ii] = 0.0 ;
            }
          }
        } /* end of -sdn1 special case */
#ifdef TTDEBUG
printf(" ** paired or bval test: num_tt = %d\n",num_tt) ;
#endif

      } else if( TT_pooled ){ /** case 2: unpaired 2-sample, pooled variance **/

         f1 = (num1-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ;
         f2 = (num2-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ;
         for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= av1[ii] ;        /* final mean */
            q1 = f1 * sd1[ii]*sd1[ii] + f2 * sd2[ii]*sd2[ii] ;
            if( q1 > 0.0 ){
               num_tt++ ;
               tt = av2[ii] / sqrt(q1) ;
               sd2[ii] = tt ;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;
            } else {
               sd2[ii] = 0.0 ;
            }
         }

         if( TT_voxel >= 0 )
            fprintf(stderr,"-- unpaired, pooled mean = %g, t = %g\n",
                    av2[TT_voxel], sd2[TT_voxel]) ;
#ifdef TTDEBUG
printf(" ** pooled test: num_tt = %d\n",num_tt) ;
#endif

      } else { /** case 3: unpaired 2-sample, unpooled variance **/
               /** 27 Dec 2002: modified to save DOF into dofar **/

         if( dofbrik != NULL ) dofar = dofbrik + fim_offset ;  /* 27 Dec 2002 */

         for( ii=0 ; ii < nxyz ; ii++ ){
            av2[ii] -= av1[ii] ;
            q1 = num1_inv * sd1[ii]*sd1[ii] ;
            q2 = num2_inv * sd2[ii]*sd2[ii] ;
            if( q1>0.0 && q2>0.0 ){               /* have positive variances? */
               num_tt++ ;
               tt = av2[ii] / sqrt(q1+q2) ;
               sd2[ii] = tt ;      /* final t-stat */

               tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ;

               if( dofar != NULL )                             /* 27 Dec 2002 */
                 dofar[ii] =  (q1+q2)*(q1+q2)
                            / (num1m1_inv*q1*q1 + num2m1_inv*q2*q2) ;
            } else {
               sd2[ii] = 0.0 ;
               if( dofar != NULL ) dofar[ii] = 1.0 ;           /* 27 Dec 2002 */
            }
         }

         if( TT_voxel >= 0 )
            fprintf(stderr,"-- unpaired, unpooled mean = %g, t = %g\n",
                    av2[TT_voxel], sd2[TT_voxel]) ;
#ifdef TTDEBUG
printf(" ** unpooled test: num_tt = %d\n",num_tt) ;
#endif
      }

#ifndef TTDEBUG
         if( ! TT_be_quiet ){ printf("\n") ; fflush(stdout) ; }
#endif

   }  /* end of loop over pieces of the input */

   if( TT_paired ){
      printf("--- Number of degrees of freedom = %d (paired test)\n",num2-1) ;
      dof = num2 - 1 ;
   } else if( TT_use_bval == 1 ){
      if( TT_n1 == 0 ){
        printf("--- Number of degrees of freedom = %d (1-sample test)\n",num2-1) ;
        dof = num2 - 1 ;
      } else {
        dof = TT_n1+num2-2 ;
        printf("--- Number of degrees of freedom = %d (-sdn1 2-sample test)\n",(int)dof) ;
      }
   } else {
      printf("--- Number of degrees of freedom = %d (2-sample test)\n",num1+num2-2) ;
      dof = num1+num2-2 ;
      if( ! TT_pooled )
         printf("    (For unpooled variance estimate, this is only approximate!)\n") ;
   }

   printf("--- Number of t-tests performed  = %d out of %d voxels\n",num_tt,nxyz) ;
   printf("--- Largest |t| value found      = %g\n",tt_max) ;

   kk = sizeof(ptable) / sizeof(float) ;
   for( ii=0 ; ii < kk ; ii++ ){
      tt = student_p2t( ptable[ii] , dof ) ;
      printf("--- Double sided tail p = %8f at t = %8f\n" , ptable[ii] , tt ) ;
   }

   /**----------------------------------------------------------------------**/
   /** now convert data to output format                13 Dec 2005 [rickr] **/

   /* first set mean */
   fimfac = EDIT_convert_dtype(nxyz , MRI_float,av2 , output_datum,vdif , 0.0) ;
   DSET_BRICK_FACTOR(new_dset, 0) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ;
   dd = fimfac; /* save for debug output */

   /* if output is of type short, limit t-stat magnitude to 32.7 */
   if( output_datum == MRI_short ){
     for( ii=0 ; ii < nxyz ; ii++ ){
       if     ( sd2[ii] >  32.7 ) sd2[ii] =  32.7 ;
       else if( sd2[ii] < -32.7 ) sd2[ii] = -32.7 ;
     }
   }

   fimfac = EDIT_convert_dtype(nxyz , MRI_float,sd2 , output_datum,vsp , 0.0) ;
   DSET_BRICK_FACTOR(new_dset, 1) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ;

#ifdef TTDEBUG
printf(" ** fimfac for mean, t-stat = %g, %g\n",dd, fimfac) ;
#endif
   /**----------------------------------------------------------------------**/

   INFO_message("Writing combined dataset into %s\n", DSET_BRIKNAME(new_dset) ) ;

   fbuf[0] = dof ;
   for( ii=1 ; ii < MAX_STAT_AUX ; ii++ ) fbuf[ii] = 0.0 ;
   (void) EDIT_dset_items( new_dset , ADN_stat_aux , fbuf , ADN_none ) ;

#if 0 /* factors already set */
   fbuf[0] = (output_datum == MRI_short && fimfac != 1.0 ) ? fimfac                    : 0.0 ;
   fbuf[1] = (output_datum == MRI_short                  ) ? 1.0 / FUNC_TT_SCALE_SHORT : 0.0 ;
   (void) EDIT_dset_items( new_dset , ADN_brick_fac , fbuf , ADN_none ) ;
#endif

   if( !AFNI_noenv("AFNI_AUTOMATIC_FDR") ) ii = THD_create_all_fdrcurves(new_dset) ;
   else                                    ii = 0 ;
   THD_load_statistics( new_dset ) ;
   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
   if( ii > 0 ) ININFO_message("created %d FDR curves in header",ii) ;

   if( dof_dset != NULL ){                                  /* 27 Dec 2002 */
     DSET_write( dof_dset ) ;
     WROTE_DSET( dof_dset ) ;
   }

   exit(0) ;
}
Пример #11
0
int main( int argc , char *argv[] )
{
   int iarg=1 , ii , do_iwarp=0 ;
   char *prefix = "NwarpCat" ;
   mat44 wmat , smat , qmat ;
   THD_3dim_dataset *oset=NULL ;
   char *cwarp_all=NULL ; int ntot=0 ;

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

   if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ) NWC_help() ;

   /*-- bureaucracy --*/

   mainENTRY("3dNwarpCat"); machdep();
   AFNI_logger("3dNwarpCat",argc,argv);
   PRINT_VERSION("3dNwarpCat"); AUTHOR("Zhark the Warper");
   (void)COX_clock_time() ;
   putenv("AFNI_WSINC5_SILENT=YES") ;

   /*-- initialization --*/

   CW_no_expad = 1 ;  /* don't allow automatic padding of input warp */
   Hverb = 0 ;        /* don't be verbose inside mri_nwarp.c */
   for( ii=0 ; ii < NWMAX ; ii++ ) cwarp[ii] = NULL ;

   /*-- scan args --*/

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

     /*---------------*/

     if( strcasecmp(argv[iarg],"-iwarp") == 0 ){
       do_iwarp = 1 ; iarg++ ; continue ;
     }

     /*---------------*/

     if( strcasecmp(argv[iarg],"-space") == 0 ){
       sname = strdup(argv[++iarg]) ; iarg++ ; continue ;
     }

     /*---------------*/

     if( strcasecmp(argv[iarg],"-NN") == 0 || strncasecmp(argv[iarg],"-nearest",6) == 0 ){
       WARNING_message("NN interpolation not legal here -- switched to linear") ;
       interp_code = MRI_LINEAR ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-linear",4)==0 || strncasecmp(argv[iarg],"-trilinear",6)==0 ){
       interp_code = MRI_LINEAR ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-cubic",4)==0 || strncasecmp(argv[iarg],"-tricubic",6)==0 ){
       WARNING_message("cubic interplation not legal here -- switched to quintic") ;
       interp_code = MRI_QUINTIC ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-quintic",4)==0 || strncasecmp(argv[iarg],"-triquintic",6)==0 ){
       interp_code = MRI_QUINTIC ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-wsinc",5) == 0 ){
       interp_code = MRI_WSINC5 ; iarg++ ; continue ;
     }

     /*---------------*/

     if( strcasecmp(argv[iarg],"-expad") == 0 ){
       int expad ;
       if( ++iarg >= argc ) ERROR_exit("no argument after '%s' :-(",argv[iarg-1]) ;
       expad = (int)strtod(argv[iarg],NULL) ;
       if( expad < 0 ){
         WARNING_message("-expad %d is illegal and is set to zero",expad) ;
         expad = 0 ;
       }
       CW_extra_pad = expad ;  /* this is how we force extra padding */
       iarg++ ; continue ;
     }

     /*---------------*/

     if( strncasecmp(argv[iarg],"-interp",5)==0 ){
       char *inam ;
       if( ++iarg >= argc ) ERROR_exit("no argument after '%s' :-(",argv[iarg-1]) ;
       inam = argv[iarg] ; if( *inam == '-' ) inam++ ;
       if( strcasecmp(inam,"NN")==0 || strncasecmp(inam,"nearest",5)==0 ){
         WARNING_message("NN interpolation not legal here -- changed to linear") ;
         interp_code = MRI_LINEAR ;
       } else if( strncasecmp(inam,"linear",3)==0 || strncasecmp(inam,"trilinear",5)==0 ){
         interp_code = MRI_LINEAR ;
       } else if( strncasecmp(inam,"cubic",3)==0 || strncasecmp(inam,"tricubic",5)==0 ){
         WARNING_message("cubic interplation not legal here -- changed to quintic") ;
         interp_code = MRI_QUINTIC ;
       } else if( strncasecmp(inam,"quintic",3)==0 || strncasecmp(inam,"triquintic",5)==0 ){
         interp_code = MRI_QUINTIC ;
       } else if( strncasecmp(inam,"wsinc",4)==0 ){
         interp_code = MRI_WSINC5 ;
       } else {
         ERROR_exit("Unknown code '%s' after '%s' :-(",argv[iarg],argv[iarg-1]) ;
       }
       iarg++ ; continue ;
     }

     /*---------------*/

     if( strcasecmp(argv[iarg],"-verb") == 0 ){
       verb++ ; NwarpCalcRPN_verb(verb) ; iarg++ ; continue ;
     }

     /*---------------*/

     if( strcasecmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("no argument after '%s' :-(",argv[iarg-1]) ;
       prefix = argv[iarg] ;
       if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal name after '%s'",argv[iarg-1]) ;
       iarg++ ; continue ;
     }

     /*---------------*/

     if( strncasecmp(argv[iarg],"-warp",5) == 0 ){
       int nn ;
       if( iarg >= argc-1 ) ERROR_exit("no argument after '%s' :-(",argv[iarg]) ;
       if( !isdigit(argv[iarg][5]) ) ERROR_exit("illegal format for '%s' :-(",argv[iarg]) ;
       nn = (int)strtod(argv[iarg]+5,NULL) ;
       if( nn <= 0 || nn > NWMAX )
         ERROR_exit("illegal warp index in '%s' :-(",argv[iarg]) ;
       if( cwarp[nn-1] != NULL )
         ERROR_exit("'%s': you can't specify warp #%d more than once :-(",argv[iarg],nn) ;
       cwarp[nn-1] = strdup(argv[++iarg]) ;
       if( nn > nwtop ) nwtop = nn ;
       iarg++ ; continue ;
     }

     /*---------------*/

     ERROR_message("Confusingly Unknown option '%s' :-(",argv[iarg]) ;
     suggest_best_prog_option(argv[0],argv[iarg]) ;
     exit(1) ;

   }

   /*-- load any warps left on the command line, after options --*/

   for( ; iarg < argc && nwtop < NWMAX-1 ; iarg++ )
     cwarp[nwtop++] = strdup(argv[iarg]) ;

   /*-- check if all warp strings are affine matrices --*/

#undef  AFFINE_WARP_STRING
#define AFFINE_WARP_STRING(ss)     \
  ( strstr((ss)," ") == NULL &&    \
    ( strcasestr((ss),".1D") != NULL || strcasestr((ss),".txt") != NULL ) )

   for( ntot=ii=0 ; ii < nwtop ; ii++ ){
     if( cwarp[ii] == NULL ) continue ;
     ntot += strlen(cwarp[ii]) ;
     if( ! AFFINE_WARP_STRING(cwarp[ii]) ) break ;  /* not affine */
   }
   if( ntot == 0 ) ERROR_exit("No warps on command line?!") ;

   if( ii == nwtop ){  /* all are affine (this is for Ziad) */
     char *fname = malloc(sizeof(char)*(strlen(prefix)+16)) ; FILE *fp ;
     float a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34 ;

     LOAD_IDENT_MAT44(wmat) ;
     for( ii=0 ; ii < nwtop ; ii++ ){
       if( cwarp[ii] == NULL ) continue ;
       smat = CW_read_affine_warp_OLD(cwarp[ii]) ;
       qmat = MAT44_MUL(smat,wmat) ; wmat = qmat ;
     }

     if( strcmp(prefix,"-") == 0 || strncmp(prefix,"stdout",6) == 0 ){
       fp = stdout ; strcpy(fname,"stdout") ;
     } else {
       strcpy(fname,prefix) ;
       if( strstr(fname,".1D") == NULL ) strcat(fname,".aff12.1D") ;
       fp = fopen(fname,"w") ;
       if( fp == NULL ) ERROR_exit("Can't open output matrix file %s",fname) ;
     }
     if( do_iwarp ){
       qmat = MAT44_INV(wmat) ; wmat = qmat ;
     }
     UNLOAD_MAT44(wmat,a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34) ;
     fprintf(fp,
             " %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g %13.6g\n",
             a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34 ) ;
     if( verb && fp != stdout ) INFO_message("Wrote matrix to %s",fname) ;
     if( fp != stdout ) fclose(fp) ;
     exit(0) ;
   }

   /*** at least one nonlinear warp ==> cat all strings, use library function to read ***/

   cwarp_all = (char *)calloc(sizeof(char),(ntot+NWMAX)*2) ;
   for( ii=0 ; ii < nwtop ; ii++ ){
     if( cwarp[ii] != NULL ){ strcat(cwarp_all,cwarp[ii]) ; strcat(cwarp_all," ") ; }
   }

   oset = IW3D_read_catenated_warp( cwarp_all ) ;  /* process all of them at once */

   if( do_iwarp ){            /* 18 Jul 2014 */
     THD_3dim_dataset *qwarp ;
     if( verb ) fprintf(stderr,"Applying -iwarp option") ;
     qwarp = THD_nwarp_invert(oset) ;
     DSET_delete(oset) ;
     oset = qwarp ;
     if( verb ) fprintf(stderr,"\n") ;
   }
   tross_Make_History( "3dNwarpCat" , argc,argv , oset ) ;
   if( sname != NULL ) MCW_strncpy( oset->atlas_space , sname , THD_MAX_NAME ) ;
   EDIT_dset_items( oset , ADN_prefix,prefix , ADN_none ) ;
   DSET_write(oset) ; WROTE_DSET(oset) ;

   /*--- run away screaming into the night, never to be seen again ---*/

   INFO_message("total CPU time = %.1f sec  Elapsed = %.1f\n",
                COX_cpu_time() , COX_clock_time() ) ;

   exit(0) ;
}
Пример #12
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *yset=NULL , *aset=NULL , *mset=NULL , *wset=NULL ;
   MRI_IMAGE *fim=NULL, *qim,*tim, *pfim=NULL , *vim     , *wim=NULL  ;
   float     *flar    , *qar,*tar, *par=NULL  , *var     , *war=NULL  ;
   MRI_IMARR *fimar=NULL ;
   MRI_IMAGE *aim , *yim ; float *aar , *yar ;
   int nt=0 , nxyz=0 , nvox=0 , nparam=0 , nqbase , polort=0 , ii,jj,kk,bb ;
   byte *mask=NULL ; int nmask=0 , iarg ;
   char *fname_out="-" ;   /** equiv to stdout **/

   float alpha=0.0f ;
   int   nfir =0 ; float firwt[5]={0.09f,0.25f,0.32f,0.25f,0.09f} ;
   int   nmed =0 ;
   int   nwt  =0 ;

#define METHOD_C  3
#define METHOD_K 11
   int   method = METHOD_C ;

   /**--- help the pitiful user? ---**/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 3dInvFMRI [options]\n"
      "Program to compute stimulus time series, given a 3D+time dataset\n"
      "and an activation map (the inverse of the usual FMRI analysis problem).\n"
      "-------------------------------------------------------------------\n"
      "OPTIONS:\n"
      "\n"
      " -data yyy  =\n"
      "   *OR*     = Defines input 3D+time dataset [a non-optional option].\n"
      " -input yyy =\n"
      "\n"
      " -map  aaa  = Defines activation map; 'aaa' should be a bucket dataset,\n"
      "                each sub-brick of which defines the beta weight map for\n"
      "                an unknown stimulus time series [also non-optional].\n"
      "\n"
      " -mapwt www = Defines a weighting factor to use for each element of\n"
      "                the map.  The dataset 'www' can have either 1 sub-brick,\n"
      "                or the same number as in the -map dataset.  In the\n"
      "                first case, in each voxel, each sub-brick of the map\n"
      "                gets the same weight in the least squares equations.\n"
      "                  [default: all weights are 1]\n"
      "\n"
      " -mask mmm  = Defines a mask dataset, to restrict input voxels from\n"
      "                -data and -map.  [default: all voxels are used]\n"
      "\n"
      " -base fff  = Each column of the 1D file 'fff' defines a baseline time\n"
      "                series; these columns should be the same length as\n"
      "                number of time points in 'yyy'.  Multiple -base options\n"
      "                can be given.\n"
      " -polort pp = Adds polynomials of order 'pp' to the baseline collection.\n"
      "                The default baseline model is '-polort 0' (constant).\n"
      "                To specify no baseline model at all, use '-polort -1'.\n"
      "\n"
      " -out vvv   = Name of 1D output file will be 'vvv'.\n"
      "                [default = '-', which is stdout; probably not good]\n"
      "\n"
      " -method M  = Determines the method to use.  'M' is a single letter:\n"
      "               -method C = least squares fit to data matrix Y [default]\n"
      "               -method K = least squares fit to activation matrix A\n"
      "\n"
      " -alpha aa  = Set the 'alpha' factor to 'aa'; alpha is used to penalize\n"
      "                large values of the output vectors.  Default is 0.\n"
      "                A large-ish value for alpha would be 0.1.\n"
      "\n"
      " -fir5     = Smooth the results with a 5 point lowpass FIR filter.\n"
      " -median5  = Smooth the results with a 5 point median filter.\n"
      "               [default: no smoothing; only 1 of these can be used]\n"
      "-------------------------------------------------------------------\n"
      "METHODS:\n"
      " Formulate the problem as\n"
      "    Y = V A' + F C' + errors\n"
      " where Y = data matrix      (N x M) [from -data]\n"
      "       V = stimulus         (N x p) [to -out]\n"
      "       A = map matrix       (M x p) [from -map]\n"
      "       F = baseline matrix  (N x q) [from -base and -polort]\n"
      "       C = baseline weights (M x q) [not computed]\n"
      "       N = time series length = length of -data file\n"
      "       M = number of voxels in mask\n"
      "       p = number of stimulus time series to estimate\n"
      "         = number of parameters in -map file\n"
      "       q = number of baseline parameters\n"
      "   and ' = matrix transpose operator\n"
      " Next, define matrix Z (Y detrended relative to columns of F) by\n"
      "                       -1\n"
      "   Z = [I - F(F'F)  F']  Y\n"
      "-------------------------------------------------------------------\n"
      " The method C solution is given by\n"
      "                 -1\n"
      "   V0 = Z A [A'A]\n"
      "\n"
      " This solution minimizes the sum of squares over the N*M elements\n"
      " of the matrix   Y - V A' + F C'   (N.B.: A' means A-transpose).\n"
      "-------------------------------------------------------------------\n"
      " The method K solution is given by\n"
      "             -1                            -1\n"
      "   W = [Z Z']  Z A   and then   V = W [W'W]\n"
      "\n"
      " This solution minimizes the sum of squares of the difference between\n"
      " the A(V) predicted from V and the input A, where A(V) is given by\n"
      "                    -1\n"
      "   A(V) = Z' V [V'V]   = Z'W\n"
      "-------------------------------------------------------------------\n"
      " Technically, the solution is unidentfiable up to an arbitrary\n"
      " multiple of the columns of F (i.e., V = V0 + F G, where G is\n"
      " an arbitrary q x p matrix); the solution above is the solution\n"
      " that is orthogonal to the columns of F.\n"
      "\n"
      "-- RWCox - March 2006 - purely for experimental purposes!\n"
     ) ;

     printf("\n"
     "===================== EXAMPLE USAGE =====================================\n"
     "** Step 1: From a training dataset, generate activation map.\n"
     "  The input dataset has 4 runs, each 108 time points long.  3dDeconvolve\n"
     "  is used on the first 3 runs (time points 0..323) to generate the\n"
     "  activation map.  There are two visual stimuli (Complex and Simple).\n"
     "\n"
     "  3dDeconvolve -x1D xout_short_two.1D -input rall_vr+orig'[0..323]'   \\\n"
     "      -num_stimts 2                                                   \\\n"
     "      -stim_file 1 hrf_complex.1D               -stim_label 1 Complex \\\n"
     "      -stim_file 2 hrf_simple.1D                -stim_label 2 Simple  \\\n"
     "      -concat '1D:0,108,216'                                          \\\n"
     "      -full_first -fout -tout                                         \\\n"
     "      -bucket func_ht2_short_two -cbucket cbuc_ht2_short_two\n"
     "\n"
     "  N.B.: You may want to de-spike, smooth, and register the 3D+time\n"
     "        dataset prior to the analysis (as usual).  These steps are not\n"
     "        shown here -- I'm presuming you know how to use AFNI already.\n"
     "\n"
     "** Step 2: Create a mask of highly activated voxels.\n"
     "  The F statistic threshold is set to 30, corresponding to a voxel-wise\n"
     "  p = 1e-12 = very significant.  The mask is also lightly clustered, and\n"
     "  restricted to brain voxels.\n"
     "\n"
     "  3dAutomask -prefix Amask rall_vr+orig\n"
     "  3dcalc -a 'func_ht2_short+orig[0]' -b Amask+orig -datum byte \\\n"
     "         -nscale -expr 'step(a-30)*b' -prefix STmask300\n"
     "  3dmerge -dxyz=1 -1clust 1.1 5 -prefix STmask300c STmask300+orig\n"
     "\n"
     "** Step 3: Run 3dInvFMRI to estimate the stimulus functions in run #4.\n"
     "  Run #4 is time points 324..431 of the 3D+time dataset (the -data\n"
     "  input below).  The -map input is the beta weights extracted from\n"
     "  the -cbucket output of 3dDeconvolve.\n"
     "\n"
     "  3dInvFMRI -mask STmask300c+orig                       \\\n"
     "            -data rall_vr+orig'[324..431]'              \\\n"
     "            -map cbuc_ht2_short_two+orig'[6..7]'        \\\n"
     "            -polort 1 -alpha 0.01 -median5 -method K    \\\n"
     "            -out ii300K_short_two.1D\n"
     "\n"
     "  3dInvFMRI -mask STmask300c+orig                       \\\n"
     "            -data rall_vr+orig'[324..431]'              \\\n"
     "            -map cbuc_ht2_short_two+orig'[6..7]'        \\\n"
     "            -polort 1 -alpha 0.01 -median5 -method C    \\\n"
     "            -out ii300C_short_two.1D\n"
     "\n"
     "** Step 4: Plot the results, and get confused.\n"
     "\n"
     "  1dplot -ynames VV KK CC -xlabel Run#4 -ylabel ComplexStim \\\n"
     "         hrf_complex.1D'{324..432}'                         \\\n"
     "         ii300K_short_two.1D'[0]'                           \\\n"
     "         ii300C_short_two.1D'[0]'\n"
     "\n"
     "  1dplot -ynames VV KK CC -xlabel Run#4 -ylabel SimpleStim \\\n"
     "         hrf_simple.1D'{324..432}'                         \\\n"
     "         ii300K_short_two.1D'[1]'                          \\\n"
     "         ii300C_short_two.1D'[1]'\n"
     "\n"
     "  N.B.: I've found that method K works better if MORE voxels are\n"
     "        included in the mask (lower threshold) and method C if\n"
     "        FEWER voxels are included.  The above threshold gave 945\n"
     "        voxels being used to determine the 2 output time series.\n"
     "=========================================================================\n"
     ) ;

     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /**--- bureaucracy ---**/

   mainENTRY("3dInvFMRI main"); machdep();
   PRINT_VERSION("3dInvFMRI"); AUTHOR("Zhark");
   AFNI_logger("3dInvFMRI",argc,argv) ;

   /**--- scan command line ---**/

   iarg = 1 ;
   while( iarg < argc ){

     if( strcmp(argv[iarg],"-method") == 0 ){
       switch( argv[++iarg][0] ){
         default:
           WARNING_message("Ignoring illegal -method '%s'",argv[iarg]) ;
         break ;
         case 'C': method = METHOD_C ; break ;
         case 'K': method = METHOD_K ; break ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-fir5") == 0 ){
       if( nmed > 0 ) WARNING_message("Ignoring -fir5 in favor of -median5") ;
       else           nfir = 5 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-median5") == 0 ){
       if( nfir > 0 ) WARNING_message("Ignoring -median5 in favor of -fir5") ;
       else           nmed = 5 ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-alpha") == 0 ){
       alpha = (float)strtod(argv[++iarg],NULL) ;
       if( alpha <= 0.0f ){
         alpha = 0.0f ; WARNING_message("-alpha '%s' ignored!",argv[iarg]) ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-data") == 0 || strcmp(argv[iarg],"-input") == 0 ){
       if( yset != NULL ) ERROR_exit("Can't input 2 3D+time datasets") ;
       yset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(yset,argv[iarg]) ;
       nt = DSET_NVALS(yset) ;
       if( nt < 2 ) ERROR_exit("Only 1 sub-brick in dataset %s",argv[iarg]) ;
       nxyz = DSET_NVOX(yset) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-map") == 0 ){
       if( aset != NULL ) ERROR_exit("Can't input 2 -map datasets") ;
       aset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(aset,argv[iarg]) ;
       nparam = DSET_NVALS(aset) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mapwt") == 0 ){
       if( wset != NULL ) ERROR_exit("Can't input 2 -mapwt datasets") ;
       wset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(wset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       if( mset != NULL ) ERROR_exit("Can't input 2 -mask datasets") ;
       mset = THD_open_dataset(argv[++iarg]) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *cpt ;
       polort = (int)strtod(argv[++iarg],&cpt) ;
       if( *cpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-out") == 0 ){
       fname_out = strdup(argv[++iarg]) ;
       if( !THD_filename_ok(fname_out) )
         ERROR_exit("Bad -out filename '%s'",fname_out) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-base") == 0 ){
       if( fimar == NULL ) INIT_IMARR(fimar) ;
       qim = mri_read_1D( argv[++iarg] ) ;
       if( qim == NULL ) ERROR_exit("Can't read 1D file %s",argv[iarg]) ;
       ADDTO_IMARR(fimar,qim) ;
       iarg++ ; continue ;
     }

     ERROR_exit("Unrecognized option '%s'",argv[iarg]) ;
   }

   /**--- finish up processing options ---**/

   if( yset == NULL ) ERROR_exit("No input 3D+time dataset?!") ;
   if( aset == NULL ) ERROR_exit("No input FMRI -map dataset?!") ;

   if( DSET_NVOX(aset) != nxyz )
     ERROR_exit("Grid mismatch between -data and -map") ;

   INFO_message("Loading dataset for Y") ;
   DSET_load(yset); CHECK_LOAD_ERROR(yset) ;
   INFO_message("Loading dataset for A") ;
   DSET_load(aset); CHECK_LOAD_ERROR(aset) ;

   if( wset != NULL ){
     if( DSET_NVOX(wset) != nxyz )
       ERROR_exit("Grid mismatch between -data and -mapwt") ;
     nwt = DSET_NVALS(wset) ;
     if( nwt > 1 && nwt != nparam )
       ERROR_exit("Wrong number of values=%d in -mapwt; should be 1 or %d",
                  nwt , nparam ) ;
     INFO_message("Loading dataset for mapwt") ;
     DSET_load(wset); CHECK_LOAD_ERROR(wset) ;
   }

   if( mset != NULL ){
     if( DSET_NVOX(mset) != nxyz )
       ERROR_exit("Grid mismatch between -data and -mask") ;
     INFO_message("Loading dataset for mask") ;
     DSET_load(mset); CHECK_LOAD_ERROR(mset) ;
     mask  = THD_makemask( mset , 0 , 1.0f,-1.0f ); DSET_delete(mset);
     nmask = THD_countmask( nxyz , mask ) ;
     if( nmask < 3 ){
       WARNING_message("Mask has %d voxels -- ignoring!",nmask) ;
       free(mask) ; mask = NULL ; nmask = 0 ;
     }
   }

   nvox = (nmask > 0) ? nmask : nxyz ;
   INFO_message("N = time series length  = %d",nt    ) ;
   INFO_message("M = number of voxels    = %d",nvox  ) ;
   INFO_message("p = number of params    = %d",nparam) ;

   /**--- set up baseline funcs in one array ---*/

   nqbase = (polort >= 0 ) ? polort+1 : 0 ;
   if( fimar != NULL ){
     for( kk=0 ; kk < IMARR_COUNT(fimar) ; kk++ ){
       qim = IMARR_SUBIMAGE(fimar,kk) ;
       if( qim != NULL && qim->nx != nt )
         WARNING_message("-base #%d length=%d; data length=%d",kk+1,qim->nx,nt) ;
       nqbase += qim->ny ;
     }
   }

   INFO_message("q = number of baselines = %d",nqbase) ;

#undef  F
#define F(i,j) flar[(i)+(j)*nt]   /* nt X nqbase */
   if( nqbase > 0 ){
     fim  = mri_new( nt , nqbase , MRI_float ) ;   /* F matrix */
     flar = MRI_FLOAT_PTR(fim) ;
     bb = 0 ;
     if( polort >= 0 ){                /** load polynomial baseline **/
       double a = 2.0/(nt-1.0) ;
       for( jj=0 ; jj <= polort ; jj++ ){
         for( ii=0 ; ii < nt ; ii++ )
           F(ii,jj) = (float)Plegendre( a*ii-1.0 , jj ) ;
       }
       bb = polort+1 ;
     }
#undef  Q
#define Q(i,j) qar[(i)+(j)*qim->nx]  /* qim->nx X qim->ny */

     if( fimar != NULL ){             /** load -base baseline columns **/
       for( kk=0 ; kk < IMARR_COUNT(fimar) ; kk++ ){
         qim = IMARR_SUBIMAGE(fimar,kk) ; qar = MRI_FLOAT_PTR(qim) ;
         for( jj=0 ; jj < qim->ny ; jj++ ){
           for( ii=0 ; ii < nt ; ii++ )
             F(ii,bb+jj) = (ii < qim->nx) ? Q(ii,jj) : 0.0f ;
         }
         bb += qim->ny ;
       }
       DESTROY_IMARR(fimar) ; fimar=NULL ;
     }

     /* remove mean from each column after first? */

     if( polort >= 0 && nqbase > 1 ){
       float sum ;
       for( jj=1 ; jj < nqbase ; jj++ ){
         sum = 0.0f ;
         for( ii=0 ; ii < nt ; ii++ ) sum += F(ii,jj) ;
         sum /= nt ;
         for( ii=0 ; ii < nt ; ii++ ) F(ii,jj) -= sum ;
       }
     }

     /* compute pseudo-inverse of baseline matrix,
        so we can project it out from the data time series */

     /*      -1          */
     /* (F'F)  F' matrix */

     INFO_message("Computing pseudo-inverse of baseline matrix F") ;
     pfim = mri_matrix_psinv(fim,NULL,0.0f) ; par = MRI_FLOAT_PTR(pfim) ;

#undef  P
#define P(i,j) par[(i)+(j)*nqbase]   /* nqbase X nt */

#if 0
     qim = mri_matrix_transpose(pfim) ;    /** save to disk? **/
     mri_write_1D( "Fpsinv.1D" , qim ) ;
     mri_free(qim) ;
#endif
   }

   /**--- set up map image into aim/aar = A matrix ---**/

#undef  GOOD
#define GOOD(i) (mask==NULL || mask[i])

#undef  A
#define A(i,j) aar[(i)+(j)*nvox]   /* nvox X nparam */

   INFO_message("Loading map matrix A") ;
   aim = mri_new( nvox , nparam , MRI_float ); aar = MRI_FLOAT_PTR(aim);
   for( jj=0 ; jj < nparam ; jj++ ){
     for( ii=kk=0 ; ii < nxyz ; ii++ ){
       if( GOOD(ii) ){ A(kk,jj) = THD_get_voxel(aset,ii,jj); kk++; }
   }}
   DSET_unload(aset) ;

   /**--- set up map weight into wim/war ---**/

#undef  WT
#define WT(i,j) war[(i)+(j)*nvox]   /* nvox X nparam */

   if( wset != NULL ){
     int numneg=0 , numpos=0 ;
     float fac ;

     INFO_message("Loading map weight matrix") ;
     wim = mri_new( nvox , nwt , MRI_float ) ; war = MRI_FLOAT_PTR(wim) ;
     for( jj=0 ; jj < nwt ; jj++ ){
       for( ii=kk=0 ; ii < nxyz ; ii++ ){
         if( GOOD(ii) ){
           WT(kk,jj) = THD_get_voxel(wset,ii,jj);
                if( WT(kk,jj) > 0.0f ){ numpos++; WT(kk,jj) = sqrt(WT(kk,jj)); }
           else if( WT(kk,jj) < 0.0f ){ numneg++; WT(kk,jj) = 0.0f;            }
           kk++;
         }
     }}
     DSET_unload(wset) ;
     if( numpos <= nparam )
       WARNING_message("Only %d positive weights found in -wtmap!",numpos) ;
     if( numneg > 0 )
       WARNING_message("%d negative weights found in -wtmap!",numneg) ;

     for( jj=0 ; jj < nwt ; jj++ ){
       fac = 0.0f ;
       for( kk=0 ; kk < nvox ; kk++ ) if( WT(kk,jj) > fac ) fac = WT(kk,jj) ;
       if( fac > 0.0f ){
         fac = 1.0f / fac ;
         for( kk=0 ; kk < nvox ; kk++ ) WT(kk,jj) *= fac ;
       }
     }
   }

   /**--- set up data image into yim/yar = Y matrix ---**/

#undef  Y
#define Y(i,j) yar[(i)+(j)*nt]   /* nt X nvox */

   INFO_message("Loading data matrix Y") ;
   yim = mri_new( nt , nvox , MRI_float ); yar = MRI_FLOAT_PTR(yim);
   for( ii=0 ; ii < nt ; ii++ ){
     for( jj=kk=0 ; jj < nxyz ; jj++ ){
       if( GOOD(jj) ){ Y(ii,kk) = THD_get_voxel(yset,jj,ii); kk++; }
   }}
   DSET_unload(yset) ;

   /**--- project baseline out of data image = Z matrix ---**/

   if( pfim != NULL ){
#undef  T
#define T(i,j) tar[(i)+(j)*nt]  /* nt X nvox */
     INFO_message("Projecting baseline out of Y") ;
     qim = mri_matrix_mult( pfim , yim ) ;   /* nqbase X nvox */
     tim = mri_matrix_mult(  fim , qim ) ;   /* nt X nvox */
     tar = MRI_FLOAT_PTR(tim) ;              /* Y projected onto baseline */
     for( jj=0 ; jj < nvox ; jj++ )
       for( ii=0 ; ii < nt ; ii++ ) Y(ii,jj) -= T(ii,jj) ;
     mri_free(tim); mri_free(qim); mri_free(pfim); mri_free(fim);
   }

   /***** At this point:
             matrix A is in aim,
             matrix Z is in yim.
          Solve for V into vim, using the chosen method *****/

   switch( method ){
     default: ERROR_exit("Illegal method code!  WTF?") ; /* Huh? */

     /*.....................................................................*/
     case METHOD_C:
       /**--- compute pseudo-inverse of A map ---**/

       INFO_message("Method C: Computing pseudo-inverse of A") ;
       if( wim != NULL ) WARNING_message("Ignoring -mapwt dataset") ;
       pfim = mri_matrix_psinv(aim,NULL,alpha) ;  /* nparam X nvox */
       if( pfim == NULL ) ERROR_exit("mri_matrix_psinv() fails") ;
       mri_free(aim) ;

       /**--- and apply to data to get results ---*/

       INFO_message("Computing result V") ;
       vim = mri_matrix_multranB( yim , pfim ) ; /* nt x nparam */
       mri_free(pfim) ; mri_free(yim) ;
     break ;

     /*.....................................................................*/
     case METHOD_K:
       /**--- compute pseudo-inverse of transposed Z ---*/

       INFO_message("Method K: Computing pseudo-inverse of Z'") ;
       if( nwt > 1 ){
         WARNING_message("Ignoring -mapwt dataset: more than 1 sub-brick") ;
         nwt = 0 ; mri_free(wim) ; wim = NULL ; war = NULL ;
       }

       if( nwt == 1 ){
         float fac ;
         for( kk=0 ; kk < nvox ; kk++ ){
           fac = war[kk] ;
           for( ii=0 ; ii < nt     ; ii++ ) Y(ii,kk) *= fac ;
           for( ii=0 ; ii < nparam ; ii++ ) A(kk,ii) *= fac ;
         }
       }

       tim  = mri_matrix_transpose(yim)        ; mri_free(yim) ;
       pfim = mri_matrix_psinv(tim,NULL,alpha) ; mri_free(tim) ;
       if( pfim == NULL ) ERROR_exit("mri_matrix_psinv() fails") ;

       INFO_message("Computing W") ;
       tim = mri_matrix_mult( pfim , aim ) ;
       mri_free(aim) ; mri_free(pfim) ;

       INFO_message("Computing result V") ;
       pfim = mri_matrix_psinv(tim,NULL,0.0f) ; mri_free(tim) ;
       vim  = mri_matrix_transpose(pfim)      ; mri_free(pfim);
     break ;

   } /* end of switch on method */

   if( wim != NULL ) mri_free(wim) ;

   /**--- smooth? ---**/

   if( nfir > 0 && vim->nx > nfir ){
     INFO_message("FIR-5-ing result") ;
     var = MRI_FLOAT_PTR(vim) ;
     for( jj=0 ; jj < vim->ny ; jj++ )
       linear_filter_reflect( nfir,firwt , vim->nx , var + (jj*vim->nx) ) ;
   }

   if( nmed > 0 && vim->nx > nmed ){
     INFO_message("Median-5-ing result") ;
     var = MRI_FLOAT_PTR(vim) ;
     for( jj=0 ; jj < vim->ny ; jj++ )
       median5_filter_reflect( vim->nx , var + (jj*vim->nx) ) ;
   }

   /**--- write results ---**/

   INFO_message("Writing result to '%s'",fname_out) ;
   mri_write_1D( fname_out , vim ) ;
   exit(0) ;
}
Пример #13
0
int main( int argc , char * argv[] )
{
   Widget rc , lab ;
   int ww , uu ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: Xphace im1 [im2]\n"
             "Interactive image mergerizing via FFTs.\n"
             "Image files are in PGM or JPEG format.\n") ; exit(0) ;
   }

   mainENTRY("Xphace main") ; machdep() ;

   ww = PH_loadim( argv[1] ) ;
   if( ww < 0 ) exit(1) ;
   if( argc > 2 ){
      ww = PH_loadim( argv[2] ) ;
      if( ww < 0 ) exit(1) ;
   } else {
      PH_loadim( "noise=1" ) ;
   }

   MAIN_shell = XtVaAppInitialize( &MAIN_app , "AFNI" , NULL , 0 ,
                                   &argc , argv , FALLback , NULL ) ;

   if( MAIN_shell == NULL ){
      fprintf(stderr,"\n*** Cannot initialize X11 ***\n") ; exit(1) ;
   }

   MAIN_dc = MCW_new_DC( MAIN_shell , 32 , 0 , NULL,NULL , 1.0 , 0 ) ;

   XtVaSetValues( XmGetXmDisplay(XtDisplay(MAIN_shell)) ,
                    XmNdragInitiatorProtocolStyle , XmDRAG_NONE ,
                    XmNdragReceiverProtocolStyle  , XmDRAG_NONE ,
                  NULL ) ;

   MAIN_rc = XtVaCreateWidget( "AFNI" , xmRowColumnWidgetClass , MAIN_shell ,
                                 XmNpacking     , XmPACK_TIGHT ,
                                 XmNorientation , XmVERTICAL   ,
                                 XmNtraversalOn , True ,
                               NULL ) ;

   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   rc = XtVaCreateWidget( "AFNI" , xmRowColumnWidgetClass , MAIN_rc ,
                            XmNpacking     , XmPACK_TIGHT ,
                            XmNorientation , XmHORIZONTAL ,
                            XmNtraversalOn , True ,
                          NULL ) ;

   lab = XtVaCreateManagedWidget( "AFNI" , xmLabelWidgetClass , rc ,
                                    LABEL_ARG( "Magn. " ) ,
                                    XmNmarginHeight, 0 ,
                                    XmNmarginWidth , 0 ,
                                  NULL ) ;

   MAGN_scale = XtVaCreateManagedWidget( "AFNI" , xmScaleWidgetClass , rc ,
                                            XmNminimum       , 0 ,
                                            XmNmaximum       , 100 ,
                                            XmNvalue         , 0 ,
                                            XmNwidth         , P_swide ,
                                            XmNshowValue     , True ,
                                            XmNscaleMultiple , 10 ,
                                            XmNorientation   , XmHORIZONTAL ,
                                            XmNtraversalOn , True ,
                                         NULL ) ;

   XtAddCallback( MAGN_scale , XmNvalueChangedCallback , PH_scale_CB , NULL ) ;
   XtManageChild( rc ) ;

   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   rc = XtVaCreateWidget( "AFNI" , xmRowColumnWidgetClass , MAIN_rc ,
                            XmNpacking     , XmPACK_TIGHT ,
                            XmNorientation , XmHORIZONTAL ,
                            XmNtraversalOn , True ,
                          NULL ) ;

   lab = XtVaCreateManagedWidget( "AFNI" , xmLabelWidgetClass , rc ,
                                    LABEL_ARG( "Phase " ) ,
                                    XmNmarginHeight, 0 ,
                                    XmNmarginWidth , 0 ,
                                  NULL ) ;

   PHASE_scale = XtVaCreateManagedWidget( "AFNI" , xmScaleWidgetClass , rc ,
                                            XmNminimum       , 0 ,
                                            XmNmaximum       , 100 ,
                                            XmNvalue         , 0 ,
                                            XmNwidth         , P_swide ,
                                            XmNshowValue     , True ,
                                            XmNscaleMultiple , 10 ,
                                            XmNorientation   , XmHORIZONTAL ,
                                            XmNtraversalOn , True ,
                                         NULL ) ;

   XtAddCallback( PHASE_scale , XmNvalueChangedCallback , PH_scale_CB , NULL ) ;
   XtManageChild( rc ) ;

   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   XtManageChild( MAIN_rc ) ;
   XtRealizeWidget( MAIN_shell ) ; NI_sleep(1) ;

#if 0
   XtVaSetValues( MAIN_rc     , XmNwidth , P_swide , NULL ) ;
   XtVaSetValues( MAGN_scale  , XmNwidth , P_swide , NULL ) ;
   XtVaSetValues( PHASE_scale , XmNwidth , P_swide , NULL ) ;
#endif

   XtVaSetValues( MAIN_shell ,
                    XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU ,
                    XmNmwmFunctions  , MWM_FUNC_MOVE | MWM_FUNC_CLOSE ,
                    XmNtitle         , "Xphace Controls" ,
                  NULL ) ;

   (void) XtAppAddTimeOut( MAIN_app , 1234 , PH_startup_timeout_CB , NULL ) ;
   XtAppMainLoop( MAIN_app ) ;
   exit(0) ;
}
Пример #14
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset ;
   THD_3dim_dataset **insar=NULL ; int nsar=0 ;
   int iarg=1 , ii,kk , ids ;
   MCW_cluster *nbhd=NULL ;
   char *prefix="./localhistog" ;
   int ntype=0 ; float na=0.0f,nb=0.0f,nc=0.0f ;
   int verb=1 , do_prob=0 ;
   int nx=0,ny=0,nz=0,nvox=0, rbot,rtop ;
   char *labfile=NULL ; NI_element *labnel=NULL ;
   int nlab=0 , *labval=NULL ; char **lablab=NULL ; char buf[THD_MAX_SBLABEL] ;
   UINT32 *ohist , *mhist=NULL ; char *ohist_name=NULL ; int ohzadd=0 ;
   int *rlist , numval ; float mincount=0.0f ; int mcc ;
   int *exlist=NULL, numex=0 ;
   int do_excNONLAB=0 ;

   /*---- for the clueless who wish to become clued-in ----*/

   if( argc == 1 ){ usage_3dLocalHistog(1); exit(0); } /* Bob's help shortcut */

   /*---- official startup ---*/

#if defined(USING_MCW_MALLOC) && !defined(USE_OMP)
   enable_mcw_malloc() ;
#endif

   PRINT_VERSION("3dLocalHistog"); mainENTRY("3dLocalHistog main"); machdep();
   AFNI_logger("3dLocalHistog",argc,argv);
   if( getpid()%2 ) AUTHOR("Bilbo Baggins"); else AUTHOR("Thorin Oakenshield");
   AFNI_SETUP_OMP(0) ;  /* 24 Jun 2013 */

   /*---- loop over options ----*/

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

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

     if( strncmp(argv[iarg],"-qu",3) == 0 ){
       verb = 0 ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-verb",5) == 0 ){
       verb++ ; iarg++ ; continue ;
     }

#ifdef ALLOW_PROB
     if( strncmp(argv[iarg],"-prob",5) == 0 ){
       do_prob = 1 ; iarg++ ; continue ;
     }
#endif

     if( strcmp(argv[iarg],"-exclude") == 0 ){
       int ebot=-6666666,etop=-6666666 , ee ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-exclude'") ;
       sscanf(argv[iarg],"%d..%d",&ebot,&etop) ;
       if( ebot >= -TWO15 && ebot <= TWO15 ){
         if( etop < -TWO15 || etop > TWO15 || etop < ebot ) etop = ebot ;
         exlist = (int *)realloc(exlist,sizeof(int)*(etop-ebot+1+numex+1)) ;
         for( ee=ebot ; ee <= etop ; ee++ ){ if( ee != 0 ) exlist[numex++] = ee ; }
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-excNONLAB") == 0 ){
       do_excNONLAB = 1 ; 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("Bad -prefix!") ;
       iarg++ ; continue ;
     }

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

     if( strcmp(argv[iarg],"-mincount") == 0 ){
       char *cpt ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mincount'") ;
       mincount = (float)strtod(argv[iarg],&cpt) ;
#if 0
       if( mincount > 0.0f && mincount < 50.0f && *cpt == '%' )  /* percentage */
         mincount = -0.01f*mincount ;
#endif
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-nbhd") == 0 ){
       char *cpt ;
       if( ntype  >  0    ) ERROR_exit("Can't have 2 '-nbhd' options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-nbhd'") ;

       cpt = argv[iarg] ;
       if( strncasecmp(cpt,"SPHERE",6) == 0 ){
         sscanf( cpt+7 , "%f" , &na ) ;
         ntype = NTYPE_SPHERE ;
       } else if( strncasecmp(cpt,"RECT",4) == 0 ){
         sscanf( cpt+5 , "%f,%f,%f" , &na,&nb,&nc ) ;
         if( na == 0.0f && nb == 0.0f && nc == 0.0f )
           ERROR_exit("'RECT(0,0,0)' is not a legal neighborhood") ;
         ntype = NTYPE_RECT ;
       } else if( strncasecmp(cpt,"RHDD",4) == 0 ){
         sscanf( cpt+5 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a RHDD of radius 0") ;
         ntype = NTYPE_RHDD ;
       } else if( strncasecmp(cpt,"TOHD",4) == 0 ){
         sscanf( cpt+5 , "%f" , &na ) ;
         if( na == 0.0f ) ERROR_exit("Can't have a TOHD of radius 0") ;
         ntype = NTYPE_TOHD ;
       } else {
         ERROR_exit("Unknown -nbhd shape: '%s'",cpt) ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-lab_file") == 0 || strcmp(argv[iarg],"-labfile") == 0 ){
       char **labnum ; int nbad=0 ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       if( labfile != NULL ) ERROR_exit("Can't use '%s' twice!",argv[iarg-1]) ;
       labfile = strdup(argv[iarg]) ;
       labnel = THD_string_table_read(labfile,0) ;
       if( labnel == NULL || labnel->vec_num < 2 )
         ERROR_exit("Can't read label file '%s'",labfile) ;
       nlab   = labnel->vec_len ;
       labnum = (char **)labnel->vec[0] ;
       lablab = (char **)labnel->vec[1] ;
       labval = (int *)calloc(sizeof(int),nlab) ;
       for( ii=0 ; ii < nlab ; ii++ ){
         if( labnum[ii] != NULL ){
           labval[ii] = (int)strtod(labnum[ii],NULL) ;
           if( labval[ii] < -TWO15 || labval[ii] > TWO15 ){ labval[ii] = 0; nbad++; }
         }
       }
       if( nbad > 0 )
         ERROR_message("%d label values are outside the range %d..%d :-(" ,
         nbad , -TWO15 , TWO15 ) ;
       iarg++ ; continue ;
     }

     ERROR_message("** 3dLocalHistog: Illegal option: '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1) ;

   } /*--- end of loop over options ---*/

   /*---- check for stupid user inputs ----*/

   if( iarg >= argc ) ERROR_exit("No datasets on command line?") ;

   if( ohist_name == NULL && strcmp(prefix,"NULL") == 0 )
     ERROR_exit("-prefix NULL is only meaningful if you also use -hsave :-(") ;

   /*------------ scan input datasets, built overall histogram ------------*/

   nsar  = argc - iarg ;
   insar = (THD_3dim_dataset **)malloc(sizeof(THD_3dim_dataset *)*nsar) ;

   if( verb ) fprintf(stderr,"Scanning %d datasets ",nsar) ;

   ohist = (UINT32 *)calloc(sizeof(UINT32),TWO16) ;

   for( ids=iarg ; ids < argc ; ids++ ){                      /* dataset loop */
     insar[ids-iarg] = inset = THD_open_dataset(argv[ids]) ;
     CHECK_OPEN_ERROR(inset,argv[ids]) ;
     if( ids == iarg ){
       nx = DSET_NX(inset); ny = DSET_NY(inset); nz = DSET_NZ(inset); nvox = nx*ny*nz;
     } else if( nx != DSET_NX(inset) ||
                ny != DSET_NY(inset) || nz != DSET_NZ(inset) ){
       ERROR_exit("Dataset %s grid doesn't match!",argv[ids]) ;
     }
     if( !THD_datum_constant(inset->dblk) )
       ERROR_exit("Dataset %s doesn't have a fixed data type! :-(",argv[ids]) ;
     if( THD_need_brick_factor(inset) )
       ERROR_exit("Dataset %s has scale factors! :-(",argv[ids]) ;
     if( DSET_BRICK_TYPE(inset,0) != MRI_byte  &&
         DSET_BRICK_TYPE(inset,0) != MRI_short &&
         DSET_BRICK_TYPE(inset,0) != MRI_float    )
       ERROR_exit("Dataset %s is not byte- or short-valued! :-(",argv[ids]) ;
     DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

     for( ii=0 ; ii < DSET_NVALS(inset) ; ii++ ){ /* add to overall histogram */
       if( verb ) fprintf(stderr,".") ;
       switch( DSET_BRICK_TYPE(inset,ii) ){
         case MRI_short:{
           short *sar = (short *)DSET_BRICK_ARRAY(inset,ii) ;
           for( kk=0 ; kk < nvox ; kk++ ) ohist[ sar[kk]+TWO15 ]++ ;
         }
         break ;
         case MRI_byte:{
           byte *bar = (byte *)DSET_BRICK_ARRAY(inset,ii) ;
           for( kk=0 ; kk < nvox ; kk++ ) ohist[ bar[kk]+TWO15 ]++ ;
         }
         break ;
         case MRI_float:{
           float *far = (float *)DSET_BRICK_ARRAY(inset,ii) ; short ss ;
           for( kk=0 ; kk < nvox ; kk++ ){ ss = SHORTIZE(far[kk]); ohist[ss+TWO15]++; }
         }
         break ;
       }
     } /* end of sub-brick loop */

     DSET_unload(inset) ;  /* will re-load later, as needed */

   } /* end of dataset loop */

   if( verb ) fprintf(stderr,"\n") ;

   /*-------------- process overall histogram for fun and profit -------------*/

   /* if we didn't actually find 0, put it in the histogram now */

   if( ohist[0+TWO15] == 0 ){ ohist[0+TWO15] = 1 ; ohzadd = 1 ; }

   /* excNONLAB? */

   if( nlab > 0 && do_excNONLAB ){
     byte *klist = (byte *)calloc(sizeof(byte),TWO16) ; int nee ;
     for(     ii=0 ; ii < nlab  ; ii++ ){ if( labval[ii] != 0 ) klist[labval[ii]+TWO15] = 1 ; }
     for( nee=ii=0 ; ii < TWO16 ; ii++ ){ if( !klist[ii] ) nee++ ; }
     exlist = (int *)realloc(exlist,sizeof(int)*(numex+nee+1)) ;
     for(     ii=0 ; ii < TWO16 ; ii++ ){ if( ii != TWO15 && !klist[ii] ) exlist[numex++] = ii-TWO15 ; }
     free(klist) ;
   }

   /* make a copy of ohist and edit it for mincount, etc */

   mhist = (UINT32 *)malloc(sizeof(UINT32)*TWO16) ;
   memcpy(mhist,ohist,sizeof(UINT32)*TWO16) ;
   mcc = (mincount < 0.0f) ? (int)(-mincount*nvox) : (int)mincount ;
   if( mcc > 1 ){
     for( ids=ii=0 ; ii < TWO16 ; ii++ ){
       if( ii != TWO15 && mhist[ii] > 0 && mhist[ii] < mcc ){ mhist[ii] = 0; ids++; }
     }
     if( ids > 0 && verb )
       INFO_message("Edited out %d values with overall histogram counts less than %d",ids,mcc) ;
   }
   if( numex > 0 ){
     int ee ;
     for( ids=0,ii=0 ; ii < numex ; ii++ ){
       ee = exlist[ii] ;
       if( mhist[ee+TWO15] > 0 ){ mhist[ee+TWO15] = 0; ids++; }
     }
     free(exlist) ;
     if( ids > 0 && verb )
       INFO_message("Edited out %d values from the exclude list",ids) ;
   }

   /* count number of values with nonzero (edited) counts */

   numval = 0 ;
   for( ii=0 ; ii < TWO16 ; ii++ ) if( mhist[ii] != 0 ) numval++ ;

   if( numval == 0 ) ERROR_exit("Nothing found! WTF?") ;  /* should not happen */

   /* make list of all values with nonzero (edited) count */

   rlist = (int *)malloc(sizeof(int)*numval) ;
   if( verb > 1 ) fprintf(stderr,"++ Include list:") ;
   for( ii=kk=0 ; ii < TWO16 ; ii++ ){
     if( mhist[ii] != 0 ){
       rlist[kk++] = ii-TWO15 ;
       if( verb > 1 ) fprintf(stderr," %d[%u]",ii-TWO15,mhist[ii]) ;
     }
   }
   if( verb > 1 ) fprintf(stderr,"\n") ;

   rbot = rlist[0] ; rtop = rlist[numval-1] ; /* smallest and largest values found */

   if( rbot == rtop ) ERROR_exit("Only one value (%d) found in all inputs!",rbot) ;

   /* if 0 isn't first in rlist, then
      put it in first place and move negative values up by one spot */

   if( rbot < 0 ){
     for( kk=0 ; kk < numval && rlist[kk] != 0 ; kk++ ) ; /*nada*/
     if( kk < numval ){   /* should always be true */
       for( ii=kk-1 ; ii >= 0 ; ii-- ) rlist[ii+1] = rlist[ii] ;
       rlist[0] = 0 ;
     }
   }

   if( verb )
     INFO_message("Value range = %d..%d (%d distinct values)",rbot,rtop,numval );

   /* save overall histogram? */

   if( ohist_name != NULL ){
     FILE *fp = fopen(ohist_name,"w") ; int nl=0 ;
     if( fp == NULL ) ERROR_exit("Can't open -hsave '%s' for output!",ohist_name) ;
     if( ohzadd ) ohist[0+TWO15] = 0 ;
     for( ii=0 ; ii < TWO16 ; ii++ ){
       if( ohist[ii] != 0 ){ fprintf(fp,"%6d %u\n",ii-TWO15,ohist[ii]); nl++; }
     }
     fclose(fp) ;
     if( verb ) INFO_message("Wrote %d lines to -hsave file %s",nl,ohist_name) ;
   }

   free(ohist) ; free(mhist) ; mhist = ohist = NULL ;  /* done with this */

   if( strcmp(prefix,"NULL") == 0 ) exit(0) ;   /* special case */

   /*----------- build the neighborhood mask -----------*/

   if( ntype <= 0 ){         /* default neighborhood */
     ntype = NTYPE_SPHERE ; na = 0.0f ;
     if( verb ) INFO_message("Using default neighborhood = self") ;
   }

   switch( ntype ){
     default:
       ERROR_exit("WTF?  ntype=%d",ntype) ;  /* should not happen */

     case NTYPE_SPHERE:{
       float dx , dy , dz ;
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(insar[0])) ;
                        dy = fabsf(DSET_DY(insar[0])) ;
                        dz = fabsf(DSET_DZ(insar[0])) ; }
       nbhd = MCW_spheremask( dx,dy,dz , na ) ;
     }
     break ;

     case NTYPE_RECT:{
       float dx , dy , dz ;
       if( na < 0.0f ){ dx = 1.0f; na = -na; } else dx = fabsf(DSET_DX(insar[0]));
       if( nb < 0.0f ){ dy = 1.0f; nb = -nb; } else dy = fabsf(DSET_DY(insar[0]));
       if( nc < 0.0f ){ dz = 1.0f; nc = -nc; } else dz = fabsf(DSET_DZ(insar[0]));
       nbhd = MCW_rectmask( dx,dy,dz , na,nb,nc ) ;
     }
     break ;

     case NTYPE_RHDD:{
       float dx , dy , dz ;
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(insar[0])) ;
                        dy = fabsf(DSET_DY(insar[0])) ;
                        dz = fabsf(DSET_DZ(insar[0])) ; }
       nbhd = MCW_rhddmask( dx,dy,dz , na ) ;
     }
     break ;

     case NTYPE_TOHD:{
       float dx , dy , dz ;
       if( na < 0.0f ){ dx = dy = dz = 1.0f ; na = -na ; }
       else           { dx = fabsf(DSET_DX(insar[0])) ;
                        dy = fabsf(DSET_DY(insar[0])) ;
                        dz = fabsf(DSET_DZ(insar[0])) ; }
       nbhd = MCW_tohdmask( dx,dy,dz , na ) ;
     }
     break ;
   }

   if( verb ) INFO_message("Neighborhood comprises %d voxels",nbhd->num_pt) ;

   /*------- actually do some work for a change (is it lunchtime yet?) -------*/

   if( verb ) fprintf(stderr,"Voxel-wise histograms ") ;

   outset = THD_localhistog( nsar,insar , numval,rlist , nbhd , do_prob,verb ) ;

   if( outset == NULL ) ERROR_exit("Function THD_localhistog() fails?!") ;

   /*---- save resulting dataset ----*/

   EDIT_dset_items( outset , ADN_prefix,prefix , ADN_none ) ;

   tross_Copy_History( insar[0] , outset ) ;
   tross_Make_History( "3dLocalHistog" , argc,argv , outset ) ;

   /* but first attach labels to sub-bricks */

   EDIT_BRICK_LABEL(outset,0,"0:Other") ;
   for( kk=1 ; kk < numval ; kk++ ){
     sprintf(buf,"%d:",rlist[kk]) ;
     for( ii=0 ; ii < nlab ; ii++ ){
       if( labval[ii] == rlist[kk] && lablab[ii] != NULL ){
         ids = strlen(buf) ;
         MCW_strncpy(buf+ids,lablab[ii],THD_MAX_SBLABEL-ids) ;
         break ;
       }
     }
     EDIT_BRICK_LABEL(outset,kk,buf) ;
   }

   DSET_write( outset ) ;
   if( verb ) WROTE_DSET( outset ) ;
   exit(0) ;
}
Пример #15
0
int main( int argc , char *argv[] )
{
   MRI_shindss *shd ;
   int ids , nopt , kk ;
   char *prefix = "EIC" ;
   char *fname=NULL , *buf ;
   MRI_vectim *mv ; THD_3dim_dataset *dset ;

   /*--- official AFNI startup stuff ---*/

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

   /*-- process options --*/

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

     if( strcasecmp(argv[nopt],"-prefix") == 0 ){
       nopt++ ;
       if( strcasecmp(argv[nopt],"NULL") == 0 ) prefix = NULL ;
       else                                     prefix = strdup(argv[nopt]) ;
       nopt++ ; continue ;
     }

     ERROR_message("Unknown option: '%s'",argv[nopt]) ;
     suggest_best_prog_option(argv[0], argv[nopt]);
     exit(1);
   }

   if( argc < 2 ){ usage_3dExtractGroupInCorr(2) ; exit(0) ; }

   /* check for errors */

   if( nopt >= argc ) ERROR_exit("No input filename on command line?!") ;

   /*-- read input file --*/

   fname = strdup(argv[nopt]) ;
   if( STRING_HAS_SUFFIX(fname,".data") ){
     strcpy(fname+strlen(fname)-5,".niml") ;
     WARNING_message("EIC: Replaced '.data' with '.niml' in filename") ;
   } else if( STRING_HAS_SUFFIX(fname,".grpincorr") ){
     fname = (char *)realloc(fname,strlen(fname)+16) ;
     strcat(fname,".niml") ;
     INFO_message("EIC: Added '.niml' to end of filename") ;
   } else if( STRING_HAS_SUFFIX(fname,".grpincorr.") ){
     fname = (char *)realloc(fname,strlen(fname)+16) ;
     strcat(fname,"niml") ;
     INFO_message("EIC: Added 'niml' to end of filename") ;
   }
   shd = GRINCOR_read_input( fname ) ;
   if( shd == NULL ) ERROR_exit("EIC: Cannot continue after input error") ;
   INFO_message("EIC: file opened, contains %d datasets, %d time series, %s bytes",
                shd->ndset , shd->nvec , commaized_integer_string(shd->nbytes) ) ;

   /*-- process input file --*/

   fprintf(stderr,"++ %d datasets: ",shd->ndset) ;
   for( ids=0 ; ids < shd->ndset ; ids++ ){
                                                          fprintf(stderr,"%d",ids+1) ;
     dset = GRINCOR_extract_dataset( shd, ids, prefix ) ; fprintf(stderr,".") ;
     DSET_write(dset) ;
     DSET_delete(dset) ;
   }
   fprintf(stderr,"\n") ; exit(0) ;
}
Пример #16
0
int main( int argc , char * argv[] )
{
   int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ;
   float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ;
   MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ;
   THD_3dim_dataset **ortset=NULL ; int nortset=0 ;
   THD_3dim_dataset *inset=NULL , *outset ;
   char *prefix="bandpass" ;
   byte *mask=NULL ;
   int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , 
       nx,ny,nz,nvox , nfft=0 , kk ;
   float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime  ;
   MRI_vectim *mrv ;
   float pvrad=0.0f ; int nosat=0 ;
   int do_despike=0 ;

   /*-- help? --*/

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

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "\n"
       "** NOTA BENE:  For the purpose of preparing resting-state FMRI datasets **\n"
       "** for analysis (e.g., with 3dGroupInCorr),  this program is now mostly **\n"
       "** superseded by the afni_proc.py script.  See the 'afni_proc.py -help' **\n"
       "** section 'Resting state analysis (modern)' to get our current rs-FMRI **\n"
       "** pre-processing recommended sequence of steps. -- RW Cox, et alii.    **\n"
       "\n"
       "Usage: 3dBandpass [options] fbot ftop dataset\n"
       "\n"
       "* One function of this program is to prepare datasets for input\n"
       "   to 3dSetupGroupInCorr.  Other uses are left to your imagination.\n"
       "\n"
       "* 'dataset' is a 3D+time sequence of volumes\n"
       "   ++ This must be a single imaging run -- that is, no discontinuities\n"
       "       in time from 3dTcat-ing multiple datasets together.\n"
       "\n"
       "* fbot = lowest frequency in the passband, in Hz\n"
       "   ++ fbot can be 0 if you want to do a lowpass filter only;\n"
       "       HOWEVER, the mean and Nyquist freq are always removed.\n"
       "\n"
       "* ftop = highest frequency in the passband (must be > fbot)\n"
       "   ++ if ftop > Nyquist freq, then it's a highpass filter only.\n"
       "\n"
       "* Set fbot=0 and ftop=99999 to do an 'allpass' filter.\n"
       "  ++ Except for removal of the 0 and Nyquist frequencies, that is.\n"
       "\n"
       "* You cannot construct a 'notch' filter with this program!\n"
       "  ++ You could use 3dBandpass followed by 3dcalc to get the same effect.\n"
       "  ++ If you are understand what you are doing, that is.\n"
       "  ++ Of course, that is the AFNI way -- if you don't want to\n"
       "     understand what you are doing, use Some other PrograM, and\n"
       "     you can still get Fine StatisticaL maps.\n"
       "\n"
       "* 3dBandpass will fail if fbot and ftop are too close for comfort.\n"
       "  ++ Which means closer than one frequency grid step df,\n"
       "     where df = 1 / (nfft * dt) [of course]\n"
       "\n"
       "* The actual FFT length used will be printed, and may be larger\n"
       "   than the input time series length for the sake of efficiency.\n"
       "  ++ The program will use a power-of-2, possibly multiplied by\n"
       "     a power of 3 and/or 5 (up to and including the 3rd power of\n"
       "     each of these: 3, 9, 27, and 5, 25, 125).\n"
       "\n"
       "* Note that the results of combining 3dDetrend and 3dBandpass will\n"
       "   depend on the order in which you run these programs.  That's why\n"
       "   3dBandpass has the '-ort' and '-dsort' options, so that the\n"
       "   time series filtering can be done properly, in one place.\n"
       "\n"
       "* The output dataset is stored in float format.\n"
       "\n"
       "* The order of processing steps is the following (most are optional):\n"
       " (0) Check time series for initial transients [does not alter data]\n"
       " (1) Despiking of each time series\n"
       " (2) Removal of a constant+linear+quadratic trend in each time series\n"
       " (3) Bandpass of data time series\n"
       " (4) Bandpass of -ort time series, then detrending of data\n"
       "      with respect to the -ort time series\n"
       " (5) Bandpass and de-orting of the -dsort dataset,\n"
       "      then detrending of the data with respect to -dsort\n"
       " (6) Blurring inside the mask [might be slow]\n"
       " (7) Local PV calculation     [WILL be slow!]\n"
       " (8) L2 normalization         [will be fast.]\n"
       "\n"
       "--------\n"
       "OPTIONS:\n"
       "--------\n"
       " -despike        = Despike each time series before other processing.\n"
       "                   ++ Hopefully, you don't actually need to do this,\n"
       "                      which is why it is optional.\n"
       " -ort f.1D       = Also orthogonalize input to columns in f.1D\n"
       "                   ++ Multiple '-ort' options are allowed.\n"
       " -dsort fset     = Orthogonalize each voxel to the corresponding\n"
       "                    voxel time series in dataset 'fset', which must\n"
       "                    have the same spatial and temporal grid structure\n"
       "                    as the main input dataset.\n"
       "                   ++ At present, only one '-dsort' option is allowed.\n"
       " -nodetrend      = Skip the quadratic detrending of the input that\n"
       "                    occurs before the FFT-based bandpassing.\n"
       "                   ++ You would only want to do this if the dataset\n"
       "                      had been detrended already in some other program.\n"
       " -dt dd          = set time step to 'dd' sec [default=from dataset header]\n"
       " -nfft N         = set the FFT length to 'N' [must be a legal value]\n"
       " -norm           = Make all output time series have L2 norm = 1\n"
       "                   ++ i.e., sum of squares = 1\n"
       " -mask mset      = Mask dataset\n"
       " -automask       = Create a mask from the input dataset\n"
       " -blur fff       = Blur (inside the mask only) with a filter\n"
       "                    width (FWHM) of 'fff' millimeters.\n"
       " -localPV rrr    = Replace each vector by the local Principal Vector\n"
       "                    (AKA first singular vector) from a neighborhood\n"
       "                    of radius 'rrr' millimiters.\n"
       "                   ++ Note that the PV time series is L2 normalized.\n"
       "                   ++ This option is mostly for Bob Cox to have fun with.\n"
       "\n"
       " -input dataset  = Alternative way to specify input dataset.\n"
       " -band fbot ftop = Alternative way to specify passband frequencies.\n"
       "\n"
       " -prefix ppp     = Set prefix name of output dataset.\n"
       " -quiet          = Turn off the fun and informative messages. (Why?)\n"
       "\n"
       " -notrans        = Don't check for initial positive transients in the data:\n"
       "  *OR*             ++ The test is a little slow, so skipping it is OK,\n"
       " -nosat               if you KNOW the data time series are transient-free.\n"
       "                   ++ Or set AFNI_SKIP_SATCHECK to YES.\n"
       "                   ++ Initial transients won't be handled well by the\n"
       "                      bandpassing algorithm, and in addition may seriously\n"
       "                      contaminate any further processing, such as inter-voxel\n"
       "                      correlations via InstaCorr.\n"
       "                   ++ No other tests are made [yet] for non-stationary behavior\n"
       "                      in the time series data.\n"
     ) ;
     PRINT_AFNI_OMP_USAGE(
       "3dBandpass" ,
       "* At present, the only part of 3dBandpass that is parallelized is the\n"
       "  '-blur' option, which processes each sub-brick independently.\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*-- startup --*/

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

   nosat =  AFNI_yesenv("AFNI_SKIP_SATCHECK") ;

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

     if( strcmp(argv[nopt],"-despike") == 0 ){  /* 08 Oct 2010 */
       do_despike++ ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-nfft") == 0 ){
       int nnup ;
       if( ++nopt >= argc ) ERROR_exit("need an argument after -nfft!") ;
       nfft = (int)strtod(argv[nopt],NULL) ;
       nnup = csfft_nextup_even(nfft) ;
       if( nfft < 16 || nfft != nnup )
         ERROR_exit("value %d after -nfft is illegal! Next legal value = %d",nfft,nnup) ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-blur") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("need an argument after -blur!") ;
       blur = strtod(argv[nopt],NULL) ;
       if( blur <= 0.0f ) WARNING_message("non-positive blur?!") ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-localPV") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("need an argument after -localpv!") ;
       pvrad = strtod(argv[nopt],NULL) ;
       if( pvrad <= 0.0f ) WARNING_message("non-positive -localpv?!") ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-prefix") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("need an argument after -prefix!") ;
       prefix = strdup(argv[nopt]) ;
       if( !THD_filename_ok(prefix) ) ERROR_exit("bad -prefix option!") ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't use -mask AND -automask!") ;
       do_automask = 1 ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-mask") == 0 ){
       THD_3dim_dataset *mset ;
       if( ++nopt >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || do_automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[nopt] ) ;
       CHECK_OPEN_ERROR(mset,argv[nopt]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[nopt]) ;
       nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ;
       if( nmask < 1 ) ERROR_exit("Mask is too small to process") ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-norm") == 0 ){
       do_norm = 1 ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-quiet") == 0 ){
       verb = 0 ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-notrans") == 0 || strcmp(argv[nopt],"-nosat") == 0 ){
       nosat = 1 ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-ort") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("need an argument after -ort!") ;
       if( ortar == NULL ) INIT_IMARR(ortar) ;
       ortim = mri_read_1D( argv[nopt] ) ;
       if( ortim == NULL ) ERROR_exit("can't read from -ort '%s'",argv[nopt]) ;
       mri_add_name(argv[nopt],ortim) ;
       ADDTO_IMARR(ortar,ortim) ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-dsort") == 0 ){
       THD_3dim_dataset *qset ;
       if( ++nopt >= argc ) ERROR_exit("need an argument after -dsort!") ;
       if( nortset > 0 ) ERROR_exit("only 1 -dsort option is allowed!") ;
       qset = THD_open_dataset(argv[nopt]) ;
       CHECK_OPEN_ERROR(qset,argv[nopt]) ;
       ortset = (THD_3dim_dataset **)realloc(ortset,
                                       sizeof(THD_3dim_dataset *)*(nortset+1)) ;
       ortset[nortset++] = qset ;
       nopt++ ; continue ;
     }

     if( strncmp(argv[nopt],"-nodetrend",6) == 0 ){
       qdet = 0 ; nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-dt") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("need an argument after -dt!") ;
       dt = (float)strtod(argv[nopt],NULL) ;
       if( dt <= 0.0f ) WARNING_message("value after -dt illegal!") ;
       nopt++ ; continue ;
     }

     if( strcmp(argv[nopt],"-input") == 0 ){
       if( inset != NULL ) ERROR_exit("Can't have 2 -input options!") ;
       if( ++nopt >= argc ) ERROR_exit("need an argument after -input!") ;
       inset = THD_open_dataset(argv[nopt]) ;
       CHECK_OPEN_ERROR(inset,argv[nopt]) ;
       nopt++ ; continue ;
     }

     if( strncmp(argv[nopt],"-band",5) == 0 ){
       if( ++nopt >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ;
       if( have_freq ) WARNING_message("second -band option replaces first one!") ;
       fbot = strtod(argv[nopt++],NULL) ;
       ftop = strtod(argv[nopt++],NULL) ;
       have_freq = 1 ; continue ;
     }

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

   /** check inputs for reasonablositiness **/

   if( !have_freq ){
     if( nopt+1 >= argc )
       ERROR_exit("Need frequencies on command line after options!") ;
     fbot = (float)strtod(argv[nopt++],NULL) ;
     ftop = (float)strtod(argv[nopt++],NULL) ;
   }

   if( inset == NULL ){
     if( nopt >= argc )
       ERROR_exit("Need input dataset name on command line after options!") ;
     inset = THD_open_dataset(argv[nopt]) ;
     CHECK_OPEN_ERROR(inset,argv[nopt]) ; nopt++ ;
   }
   DSET_UNMSEC(inset) ;

   if( fbot < 0.0f  ) ERROR_exit("fbot value can't be negative!") ;
   if( ftop <= fbot ) ERROR_exit("ftop value %g must be greater than fbot value %g!",ftop,fbot) ;

   ntime = DSET_NVALS(inset) ;
   if( ntime < 9 ) ERROR_exit("Input dataset is too short!") ;

   if( nfft <= 0 ){
     nfft = csfft_nextup_even(ntime) ;
     if( verb ) INFO_message("Data length = %d  FFT length = %d",ntime,nfft) ;
     (void)THD_bandpass_set_nfft(nfft) ;
   } else if( nfft < ntime ){
     ERROR_exit("-nfft %d is less than data length = %d",nfft,ntime) ;
   } else {
     kk = THD_bandpass_set_nfft(nfft) ;
     if( kk != nfft && verb )
       INFO_message("Data length = %d  FFT length = %d",ntime,kk) ;
   }

   if( dt <= 0.0f ){
     dt = DSET_TR(inset) ;
     if( dt <= 0.0f ){
       WARNING_message("Setting dt=1.0 since input dataset lacks a time axis!") ;
       dt = 1.0f ;
     }
   }

   if( !THD_bandpass_OK(ntime,dt,fbot,ftop,1) ) ERROR_exit("Can't continue!") ;

   nx = DSET_NX(inset); ny = DSET_NY(inset); nz = DSET_NZ(inset); nvox = nx*ny*nz;

   /* check mask, or create it */

   if( verb ) INFO_message("Loading input dataset time series" ) ;
   DSET_load(inset) ;

   if( mask != NULL ){
     if( mask_nx != nx || mask_ny != ny || mask_nz != nz )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( do_automask ){
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     nmask = THD_countmask( DSET_NVOX(inset) , mask ) ;
     if( verb ) INFO_message("Number of voxels in automask = %d",nmask);
     if( nmask < 1 ) ERROR_exit("Automask is too small to process") ;

   } else {
     mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ;
     memset(mask,1,sizeof(byte)*nvox) ;
     if( verb ) INFO_message("No mask ==> processing all %d voxels",nvox);
   }

   /* A simple check of dataset quality [08 Feb 2010] */

   if( !nosat ){
     float val ;
     INFO_message(
      "Checking dataset for initial transients [use '-notrans' to skip this test]") ;
     val = THD_saturation_check(inset,mask,0,0) ; kk = (int)(val+0.54321f) ;
     if( kk > 0 )
       ININFO_message(
        "Looks like there %s %d non-steady-state initial time point%s :-(" ,
        ((kk==1) ? "is" : "are") , kk , ((kk==1) ? " " : "s") ) ;
     else if( val > 0.3210f )  /* don't ask where this threshold comes from! */
       ININFO_message(
        "MAYBE there's an initial positive transient of 1 point, but it's hard to tell\n") ;
     else
       ININFO_message("No widespread initial positive transient detected :-)") ;
   }

   /* check -dsort inputs for match to inset */

   for( kk=0 ; kk < nortset ; kk++ ){
     if( DSET_NX(ortset[kk])    != nx ||
         DSET_NY(ortset[kk])    != ny ||
         DSET_NZ(ortset[kk])    != nz ||
         DSET_NVALS(ortset[kk]) != ntime )
       ERROR_exit("-dsort %s doesn't match input dataset grid" ,
                  DSET_BRIKNAME(ortset[kk]) ) ;
   }

   /* convert input dataset to a vectim, which is more fun */

   mrv = THD_dset_to_vectim( inset , mask , 0 ) ;
   if( mrv == NULL ) ERROR_exit("Can't load time series data!?") ;
   DSET_unload(inset) ;

   /* similarly for the ort vectors */

   if( ortar != NULL ){
     for( kk=0 ; kk < IMARR_COUNT(ortar) ; kk++ ){
       ortim = IMARR_SUBIM(ortar,kk) ;
       if( ortim->nx < ntime )
         ERROR_exit("-ort file %s is shorter than input dataset time series",
                    ortim->name ) ;
       ort  = (float **)realloc( ort , sizeof(float *)*(nort+ortim->ny) ) ;
       for( vv=0 ; vv < ortim->ny ; vv++ )
         ort[nort++] = MRI_FLOAT_PTR(ortim) + ortim->nx * vv ;
     }
   }

   /* check whether processing leaves any DoF remaining  18 Mar 2015 [rickr] */
   {
      int nbprem = THD_bandpass_remain_dim(ntime, dt, fbot, ftop, 1);
      int bpused, nremain;
      int wlimit;               /* warning limit */

      bpused = ntime - nbprem;  /* #dim lost in bandpass step */

      nremain = nbprem - nort;  /* #dim left in output */
      if( nortset == 1 ) nremain--;
      nremain -= (qdet+1);

      if( verb ) INFO_message("%d dimensional data reduced to %d by:\n"
                    "    %d (bandpass), %d (-ort), %d (-dsort), %d (detrend)",
                    ntime, nremain, bpused, nort, nortset?1:0, qdet+1);

      /* possibly warn (if 95% lost) user or fail */
      wlimit = ntime/20;
      if( wlimit < 3 ) wlimit = 3;
      if( nremain < wlimit && nremain > 0 )
         WARNING_message("dimensionality reduced from %d to %d, be careful!",
                         ntime, nremain);
      if( nremain <= 0 ) /* FAILURE */
         ERROR_exit("dimensionality reduced from %d to %d, failing!",
                    ntime, nremain);
   }

   /* all the real work now */

   if( do_despike ){
     int_pair nsp ;
     if( verb ) INFO_message("Testing data time series for spikes") ;
     nsp = THD_vectim_despike9( mrv ) ;
     if( verb ) ININFO_message(" -- Squashed %d spikes from %d voxels",nsp.j,nsp.i) ;
   }

   if( verb ) INFO_message("Bandpassing data time series") ;
   (void)THD_bandpass_vectim( mrv , dt,fbot,ftop , qdet , nort,ort ) ;

   /* OK, maybe a little more work */

   if( nortset == 1 ){
     MRI_vectim *orv ;
     orv = THD_dset_to_vectim( ortset[0] , mask , 0 ) ;
     if( orv == NULL ){
       ERROR_message("Can't load -dsort %s",DSET_BRIKNAME(ortset[0])) ;
     } else {
       float *dp , *mvv , *ovv , ff ;
       if( verb ) INFO_message("Orthogonalizing to bandpassed -dsort") ;
       (void)THD_bandpass_vectim( orv , dt,fbot,ftop , qdet , nort,ort ) ;
       THD_vectim_normalize( orv ) ;
       dp = malloc(sizeof(float)*mrv->nvec) ;
       THD_vectim_vectim_dot( mrv , orv , dp ) ;
       for( vv=0 ; vv < mrv->nvec ; vv++ ){
         ff = dp[vv] ;
         if( ff != 0.0f ){
           mvv = VECTIM_PTR(mrv,vv) ; ovv = VECTIM_PTR(orv,vv) ;
           for( kk=0 ; kk < ntime ; kk++ ) mvv[kk] -= ff*ovv[kk] ;
         }
       }
       VECTIM_destroy(orv) ; free(dp) ;
     }
   }

   if( blur > 0.0f ){
     if( verb )
       INFO_message("Blurring time series data spatially; FWHM=%.2f",blur) ;
     mri_blur3D_vectim( mrv , blur ) ;
   }
   if( pvrad > 0.0f ){
     if( verb )
       INFO_message("Local PV-ing time series data spatially; radius=%.2f",pvrad) ;
     THD_vectim_normalize( mrv ) ;
     THD_vectim_localpv( mrv , pvrad ) ;
   }
   if( do_norm && pvrad <= 0.0f ){
     if( verb ) INFO_message("L2 normalizing time series data") ;
     THD_vectim_normalize( mrv ) ;
   }

   /* create output dataset, populate it, write it, then quit */

   if( verb ) INFO_message("Creating output dataset in memory, then writing it") ;
   outset = EDIT_empty_copy(inset) ;
   /* do not copy scalars    11 Sep 2015 [rickr] */
   EDIT_dset_items( outset , ADN_prefix,prefix ,
                             ADN_brick_fac,NULL ,
                    ADN_none ) ;
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dBandpass" , argc,argv , outset ) ;

   for( vv=0 ; vv < ntime ; vv++ )
     EDIT_substitute_brick( outset , vv , MRI_float , NULL ) ;

#if 1
   THD_vectim_to_dset( mrv , outset ) ;
#else
 AFNI_OMP_START ;
#pragma omp parallel
 { float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ;
#pragma omp for
   for( vv=0 ; vv < ntime ; vv++ ){
     far = DSET_BRICK_ARRAY(outset,vv) ; var = mrv->fvec + vv ;
     for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ;
   }
 }
 AFNI_OMP_END ;
#endif
   VECTIM_destroy(mrv) ;
   DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ;

   exit(0) ;
}
Пример #17
0
int main(int argc, char *argv[]) {
	int i,j,k,m,n,aa,ii,jj,kk,mm,rr;
	int iarg;
	int nmask1=0;
	int nmask2=0;
	THD_3dim_dataset *insetFA = NULL, *insetV1 = NULL, 
		*insetMD = NULL, *insetL1 = NULL;
	THD_3dim_dataset *insetEXTRA=NULL; 
	THD_3dim_dataset *mset2=NULL; 
	THD_3dim_dataset *mset1=NULL; 
	THD_3dim_dataset *outsetMAP=NULL, *outsetMASK=NULL;
	char *prefix="tracky";
	int LOG_TYPE=0;
	char in_FA[300];
	char in_V1[300];
	char in_MD[300];
	char in_L1[300];
	int EXTRAFILE=0; // switch for whether other file is input as WM map

	char OUT_bin[300];
	char OUT_tracstat[300];
	char prefix_mask[300];
	char prefix_map[300];

	// FACT algopts
	FILE *fout0;
	float MinFA=0.2,MaxAngDeg=45,MinL=20.0;
	float MaxAng;
	int SeedPerV[3]={2,2,2};
	int ArrMax=0;
	float tempvmagn;
  
	int Nvox=-1;   // tot number vox
	int Dim[3]={0,0,0}; // dim in each dir
	int Nseed=0,M=30,bval=1000;
	int DimSeed[3]; // number of seeds there will be
	float Ledge[3]; // voxel edge lengths

	int *ROI1, *ROI2;
	short int *temp_arr;
	char *temp_byte; 
	int **Tforw, **Tback;
	int **Ttot;
	float **flTforw, **flTback;
	float ****coorded;
	int ****INDEX;
	int len_forw, len_back; // int count of num of squares through
	float phys_forw[1], phys_back[1];
	int idx;

	float ave_tract_len, ave_tract_len_phys;
	int inroi1, inroi2, KEEPIT; // switches for detecting
	int in[3]; // to pass to trackit
	float physin[3]; // also for trackit, physical loc, 
	int totlen; 
	float totlen_phys;
	int Numtract;

	int READS_in;
	float READS_fl;
	int end[2][3];
	int test_ind[2][3];

	int  roi3_ct=0, id=0;
	float roi3_mu_MD = 0.,roi3_mu_RD = 0.,roi3_mu_L1 = 0.,roi3_mu_FA = 0.;  
	float roi3_sd_MD = 0.,roi3_sd_RD = 0.,roi3_sd_L1 = 0.,roi3_sd_FA = 0.;  
	float tempMD,tempFA,tempRD,tempL1;
	char dset_or[4] = "RAI";
	THD_3dim_dataset *dsetn;
	int TV_switch[3] = {0,0,0};
	TAYLOR_BUNDLE *tb=NULL;
	TAYLOR_TRACT *tt=NULL;
	char *mode = "NI_fast_binary";
	NI_element *nel=NULL;
	int dump_opts=0;

	tv_io_header header1 = {.id_string = "TRACK\0", 
				.origin = {0,0,0},   
				.n_scalars = 3,
				.scal_n[0] = "FA",
				.scal_n[1] = "MD",
				.scal_n[2] = "L1",
				.n_properties = 0,
				.vox_to_ras = {{0.,0.,0.,0.},{0.,0.,0.,0.},
					       {0.,0.,0.,0.},{0.,0.,0.,0.}},
				// reset this later based on actual data set
				.voxel_order = "RAI\0", 
				.invert_x = 0,
				.invert_y = 0,
				.invert_z = 0,
				.swap_xy = 0,
				.swap_yz = 0,
				.swap_zx = 0,
				.n_count = 0,
				.version = 2,
				.hdr_size = 1000};
	
  	// for testing names...
	char *postfix[4]={"+orig.HEAD\0",".nii.gz\0",".nii\0","+tlrc.HEAD\0"};
  	int FOUND =-1;
	int RECORD_ORIG = 0; 
	float Orig[3] = {0.0,0.0,0.0};

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

	INFO_message("version: MU");

	/** scan args **/
	if (argc == 1) { usage_TrackID(1); exit(0); }
	iarg = 1;
	while( iarg < argc && argv[iarg][0] == '-' ){
		if( strcmp(argv[iarg],"-help") == 0 || 
			 strcmp(argv[iarg],"-h") == 0 ) {
			usage_TrackID(strlen(argv[iarg])>3 ? 2:1);
			exit(0);
		}
    
		if( strcmp(argv[iarg],"-verb") == 0) {
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-verb'") ;
			set_tract_verb(atoi(argv[iarg]));
			iarg++ ; continue ;
		}

		if( strcmp(argv[iarg],"-write_opts") == 0) {
			dump_opts=1;
			iarg++ ; continue ;
		}
    
		if( strcmp(argv[iarg],"-rec_orig") == 0) {
			RECORD_ORIG=1;
			iarg++ ; continue ;
		}
    
		if( strcmp(argv[iarg],"-tract_out_mode") == 0) {
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-tract_out_mode'") ;
			if (strcmp(argv[iarg], "NI_fast_binary") &&
				 strcmp(argv[iarg], "NI_fast_text") &&
				 strcmp(argv[iarg], "NI_slow_binary") &&
				 strcmp(argv[iarg], "NI_slow_text") ) {
				ERROR_message("Bad value (%s) for -tract_out_mode",argv[iarg]);
				exit(1);
			}  
			mode = argv[iarg];
			iarg++ ; continue ;
		}
    
		if( strcmp(argv[iarg],"-mask1") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-mask1'") ;
			mset1 = THD_open_dataset( argv[iarg] ) ;
			if( mset1 == NULL ) 
				ERROR_exit("Can't open mask1 dataset '%s'", argv[iarg]) ;
			DSET_load(mset1) ; CHECK_LOAD_ERROR(mset1) ;
			nmask1 = DSET_NVOX(mset1) ;

			iarg++ ; continue ;
		}
		if( strcmp(argv[iarg],"-mask2") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-mask2'") ;
			mset2 = THD_open_dataset( argv[iarg] ) ;
			if( mset2 == NULL ) 
				ERROR_exit("Can't open mask2 dataset '%s'",
							  argv[iarg]) ;
			DSET_load(mset2) ; CHECK_LOAD_ERROR(mset2) ;
			nmask2 = DSET_NVOX(mset2) ;
		
			iarg++ ; continue ;
		}
	 
		if( strcmp(argv[iarg],"-prefix") == 0 ){
			iarg++ ; if( iarg >= argc ) 
							ERROR_exit("Need argument after '-prefix'");
			prefix = strdup(argv[iarg]) ;
			if( !THD_filename_ok(prefix) ) 
				ERROR_exit("Illegal name after '-prefix'");
			iarg++ ; continue ;
		}
	 
		if( strcmp(argv[iarg],"-input") == 0 ){
			iarg++ ; if( iarg >= argc ) 
							ERROR_exit("Need argument after '-input'");

			for( i=0 ; i<4 ; i++) {
				sprintf(in_FA,"%s_FA%s", argv[iarg],postfix[i]); 
				if(THD_is_ondisk(in_FA)) {
					FOUND = i;
					break;
				}
			}
			insetFA = THD_open_dataset(in_FA) ;
			if( (insetFA == NULL ) || (FOUND==-1))
				ERROR_exit("Can't open dataset '%s': for FA.",in_FA);
			
			DSET_load(insetFA) ; CHECK_LOAD_ERROR(insetFA) ;
			Nvox = DSET_NVOX(insetFA) ;
			Dim[0] = DSET_NX(insetFA); Dim[1] = DSET_NY(insetFA); 
			Dim[2] = DSET_NZ(insetFA); 
			Ledge[0] = fabs(DSET_DX(insetFA)); Ledge[1] = fabs(DSET_DY(insetFA)); 
			Ledge[2] = fabs(DSET_DZ(insetFA)); 
			Orig[0] = DSET_XORG(insetFA); Orig[1] = DSET_YORG(insetFA);
			Orig[2] = DSET_ZORG(insetFA);

			// check tot num vox match (as proxy for dims...)
			if( (Nvox != nmask1) || (Nvox != nmask2) )
				ERROR_exit("Input dataset does not match both mask volumes!");
		
      
			// this stores the original data file orientation for later use,
			// as well since we convert everything to RAI temporarily, as
			// described below
			header1.voxel_order[0]=ORIENT_typestr[insetFA->daxes->xxorient][0];
			header1.voxel_order[1]=ORIENT_typestr[insetFA->daxes->yyorient][0];
			header1.voxel_order[2]=ORIENT_typestr[insetFA->daxes->zzorient][0];
			for( i=0 ; i<3 ; i++) {
				header1.dim[i] = Dim[i];
				header1.voxel_size[i] = Ledge[i];
				// will want this when outputting file later for TrackVis.
				TV_switch[i] = !(dset_or[i]==header1.voxel_order[i]);
			}
			dset_or[3]='\0';
      
			FOUND = -1;
			for( i=0 ; i<4 ; i++) {
				sprintf(in_V1,"%s_V1%s", argv[iarg],postfix[i]); 
				if(THD_is_ondisk(in_V1)) {
					FOUND = i;
					break;
				}
			}
			insetV1 = THD_open_dataset(in_V1);
			if( insetV1 == NULL ) 
				ERROR_exit("Can't open dataset '%s':V1",in_V1);
			DSET_load(insetV1) ; CHECK_LOAD_ERROR(insetV1) ;
		
			FOUND = -1;
			for( i=0 ; i<4 ; i++) {
				sprintf(in_L1,"%s_L1%s", argv[iarg],postfix[i]); 
				if(THD_is_ondisk(in_L1)) {
					FOUND = i;
					break;
				}
			}
			insetL1 = THD_open_dataset(in_L1);
			if( insetL1 == NULL ) 
				ERROR_exit("Can't open dataset '%s':L1",in_L1);
			DSET_load(insetL1) ; CHECK_LOAD_ERROR(insetL1) ;

			FOUND = -1;
			for( i=0 ; i<4 ; i++) {
				sprintf(in_MD,"%s_MD%s", argv[iarg],postfix[i]); 
				if(THD_is_ondisk(in_MD)) {
					FOUND = i;
					break;
				}
			}
			insetMD = THD_open_dataset(in_MD);
			if( insetMD == NULL ) 
				ERROR_exit("Can't open dataset '%s':MD",in_MD);
			DSET_load(insetMD) ; CHECK_LOAD_ERROR(insetMD) ;

			iarg++ ; continue ;
		}

		if( strcmp(argv[iarg],"-algopt") == 0 ){
			iarg++ ; 
			if( iarg >= argc ) 
				ERROR_exit("Need argument after '-algopt'");
		
			if (!(nel = ReadTractAlgOpts(argv[iarg]))) {
				ERROR_message("Failed to read options in %s\n", argv[iarg]);
				exit(19);
			}
			if (NI_getTractAlgOpts(nel, &MinFA, &MaxAngDeg, &MinL, 
										  SeedPerV, &M, &bval)) {
				ERROR_message("Failed to get options");
				exit(1);
			}
			NI_free_element(nel); nel=NULL;
      
			iarg++ ; continue ;
		}

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

			INFO_message("ROI logic type is: %s",argv[iarg]);
			if( strcmp(argv[iarg],"AND") == 0 ) 
				LOG_TYPE = 1;
			else if( strcmp(argv[iarg],"OR") == 0 ) 
				LOG_TYPE = 0;
			else if( strcmp(argv[iarg],"ALL") == 0 )
				LOG_TYPE = -1;
			else 
				ERROR_exit("Illegal after '-logic': need 'OR' or 'AND'");
			iarg++ ; continue ;
		}
    
		//@@
		if( strcmp(argv[iarg],"-extra_set") == 0) {
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-extra_set'");
			EXTRAFILE = 1; // switch on

			insetEXTRA = THD_open_dataset(argv[iarg]);
			if( (insetEXTRA == NULL ) )
				ERROR_exit("Can't open dataset '%s': for extra set.",argv[iarg]);
			DSET_load(insetEXTRA) ; CHECK_LOAD_ERROR(insetEXTRA) ;

			if( !((Dim[0] == DSET_NX(insetEXTRA)) && (Dim[1] == DSET_NY(insetEXTRA)) && (Dim[2] == DSET_NZ(insetEXTRA))))
				ERROR_exit("Dimensions of extra set '%s' don't match those of the DTI prop ones ('%s', etc.).",argv[iarg], in_FA);
			
			iarg++ ; continue ;
		}


		ERROR_message("Bad option '%s'\n",argv[iarg]) ;
		suggest_best_prog_option(argv[0], argv[iarg]);
		exit(1);
	}
	 
	if (iarg < 4) {
		ERROR_message("Too few options. Try -help for details.\n");
		exit(1);
	}
	 
	if (dump_opts) {
      nel = NI_setTractAlgOpts(NULL, &MinFA, &MaxAngDeg, &MinL, 
										 SeedPerV, &M, &bval);
      WriteTractAlgOpts(prefix, nel);
      NI_free_element(nel); nel=NULL;
	}
	 
        
	// Process the options a little 
	for( i=0 ; i<3 ; i++)
		DimSeed[i] = Dim[i]*SeedPerV[i];
	Nseed = Nvox*SeedPerV[0]*SeedPerV[1]*SeedPerV[2];
	 
	// convert to cos of rad value for comparisons, instead of using acos()
	MaxAng = cos(CONV*MaxAngDeg); 
	 
	// switch to add header-- option for now, added Sept. 2012
	// for use with map_TrackID to map tracks to different space
	if(RECORD_ORIG) {
		for( i=0 ; i<3 ; i++)
			header1.origin[i] = Orig[i];
	}
	 
	// at some point, we will have to convert indices into
	// pseudo-locations; being forced into this choice means that
	// different data set orientations would be represented differently
	// and incorrectly in some instances... so, for now, we'll resample
	// everything to RAI, and then resample back later.  guess this will
	// just slow things down slightly.
	 
	// have all be RAI for processing here
	if(TV_switch[0] || TV_switch[1] || TV_switch[2]) {
		dsetn = r_new_resam_dset(insetFA, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(insetFA); 
		insetFA=dsetn;
		dsetn=NULL;
		
		dsetn = r_new_resam_dset(insetMD, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(insetMD); 
		insetMD=dsetn;
		dsetn=NULL;
		
		dsetn = r_new_resam_dset(insetV1, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(insetV1); 
		insetV1=dsetn;
		dsetn=NULL;
		
		dsetn = r_new_resam_dset(insetL1, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(insetL1); 
		insetL1=dsetn;
		dsetn=NULL;
		
		dsetn = r_new_resam_dset(mset1, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(mset1); 
		mset1=dsetn;
		dsetn=NULL;
		
		dsetn = r_new_resam_dset(mset2, NULL, 0.0, 0.0, 0.0,
										 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
		DSET_delete(mset2); 
		mset2=dsetn;
		dsetn=NULL;

		if(EXTRAFILE) {
			dsetn = r_new_resam_dset(insetEXTRA, NULL, 0.0, 0.0, 0.0,
											 dset_or, RESAM_NN_TYPE, NULL, 1, 0);
			DSET_delete(insetEXTRA); 
			insetEXTRA=dsetn;
			dsetn=NULL;
		}


	}
	 
	 

	// ****************************************************************
	// ****************************************************************
	//                    make arrays for tracking
	// ****************************************************************
	// ****************************************************************

	// for temp storage array, just a multiple of longest dimension!
	if(Dim[0] > Dim[1])
		ArrMax = Dim[0] * 4;
	else
		ArrMax = Dim[1] * 4;
	if(4*Dim[2] > ArrMax)
		ArrMax = Dim[2] * 4;

	ROI1 = (int *)calloc(Nvox, sizeof(int)); 
	ROI2 = (int *)calloc(Nvox, sizeof(int)); 
	temp_arr = (short int *)calloc(Nvox, sizeof(short int)); 
	temp_byte = (char *)calloc(Nvox, sizeof(char)); 
	// temp storage whilst tracking
	Tforw = calloc(ArrMax, sizeof(Tforw)); 
	for(i=0 ; i<ArrMax ; i++) 
		Tforw[i] = calloc(3, sizeof(int)); 
	Ttot = calloc(2*ArrMax , sizeof(Ttot)); 
	for(i=0 ; i<2*ArrMax ; i++) 
		Ttot[i] = calloc(3, sizeof(int)); 
	Tback = calloc(ArrMax, sizeof(Tback)); 
	for(i=0 ; i<ArrMax ; i++) 
		Tback[i] = calloc(3, sizeof(int)); 
	// temp storage whilst tracking, physical loc
	flTforw = calloc(ArrMax, sizeof(flTforw)); 
	for(i=0 ; i<ArrMax ; i++) 
		flTforw[i] = calloc(3, sizeof(int)); 
	flTback = calloc(ArrMax,sizeof(flTback)); 
	for(i=0 ; i<ArrMax ; i++) 
		flTback[i] = calloc(3, sizeof(int)); 
	if( (ROI1 == NULL) || (ROI2 == NULL) || (temp_arr == NULL) 
		 || (Tforw == NULL) || (Tback == NULL) || (flTforw == NULL) 
		 || (flTback == NULL) || (Ttot == NULL)) {
		fprintf(stderr, "\n\n MemAlloc failure.\n\n");
		exit(12);
	}
  
	coorded = (float ****) calloc( Dim[0], sizeof(float ***) );
	for ( i = 0 ; i < Dim[0] ; i++ ) 
		coorded[i] = (float ***) calloc( Dim[1], sizeof(float **) );
	for ( i = 0 ; i < Dim[0] ; i++ ) 
		for ( j = 0 ; j < Dim[1] ; j++ ) 
			coorded[i][j] = (float **) calloc( Dim[2], sizeof(float *) );
	for ( i=0 ; i<Dim[0] ; i++ ) 
		for ( j=0 ; j<Dim[1] ; j++ ) 
			for ( k= 0 ; k<Dim[2] ; k++ ) //3 comp of V1 and FA
				coorded[i][j][k] = (float *) calloc( 4, sizeof(float) ); 
  
	INDEX = (int ****) calloc( Dim[0], sizeof(int ***) );
	for ( i = 0 ; i < Dim[0] ; i++ ) 
		INDEX[i] = (int ***) calloc( Dim[1], sizeof(int **) );
	for ( i = 0 ; i < Dim[0] ; i++ ) 
		for ( j = 0 ; j < Dim[1] ; j++ ) 
			INDEX[i][j] = (int **) calloc( Dim[2], sizeof(int *) );
	for ( i=0 ; i<Dim[0] ; i++ ) 
		for ( j=0 ; j<Dim[1] ; j++ ) 
			for ( k= 0 ; k<Dim[2] ; k++ ) 
				INDEX[i][j][k] = (int *) calloc( 4,  sizeof(int) );

	// this statement will never be executed if allocation fails above
	if( (INDEX == NULL) || (coorded == NULL) ) { 
		fprintf(stderr, "\n\n MemAlloc failure.\n\n");
		exit(122);
	}
  
	for(i=0 ; i<Nvox ; i++) {
		if(THD_get_voxel( mset1, i, 0) >0.5){
			ROI1[i] = 1;
		}
		if(THD_get_voxel( mset2, i, 0) >0.5)
			ROI2[i] = 1;
	}

	// set up eigvecs in 3D coord sys,
	// mark off where ROIs are and keep index handy
	idx=0;
	for( k=0 ; k<Dim[2] ; k++ ) 
		for( j=0 ; j<Dim[1] ; j++ ) 
			for( i=0 ; i<Dim[0] ; i++ ) {
				for( m=0 ; m<3 ; m++ ) 
					coorded[i][j][k][m] = THD_get_voxel(insetV1, idx, m);
				if(EXTRAFILE)
					coorded[i][j][k][3] = THD_get_voxel(insetEXTRA, idx, 0); 
				else
					coorded[i][j][k][3] = THD_get_voxel(insetFA, idx, 0); 
   
				// make sure that |V1| == 1 for all eigenvects, otherwise it's
				/// a problem in the tractography; currently, some from
				// 3dDWItoDT do not have this property...
				tempvmagn = sqrt(coorded[i][j][k][0]*coorded[i][j][k][0]+
									  coorded[i][j][k][1]*coorded[i][j][k][1]+
									  coorded[i][j][k][2]*coorded[i][j][k][2]);
				if( tempvmagn<0.99 ) 
					for( m=0 ; m<3 ; m++ ) 
						coorded[i][j][k][m]/= tempvmagn;
   
				INDEX[i][j][k][0] =idx; // first value is the index itself
				if( ROI1[idx]==1 ) 
					INDEX[i][j][k][1]=1; // second value identifies ROI1 mask
				else
					INDEX[i][j][k][1]=0;
				if( ROI2[idx]==1 )
					INDEX[i][j][k][2]=1; // third value identifies ROI2 mask
				else
					INDEX[i][j][k][2]=0;

				// fourth value will be counter for number of kept tracks
				// passing through
				INDEX[i][j][k][3] = 0;  
				idx+= 1;
			}
  
	// *************************************************************
	// *************************************************************
	//                    Beginning of main loop
	// *************************************************************
	// *************************************************************

	Numtract = 0;
	ave_tract_len = 0.;
	ave_tract_len_phys = 0.;
 
	sprintf(OUT_bin,"%s.trk",prefix);
	if( (fout0 = fopen(OUT_bin, "w")) == NULL) {
		fprintf(stderr, "Error opening file %s.",OUT_bin);
		exit(16);
	}
	fwrite(&header1,sizeof(tv_io_header),1,fout0);
  
	if (get_tract_verb()) {
		INFO_message("Begin tracking...");
	}

	tb = AppCreateBundle(NULL, 0, NULL, insetFA); // start bundle
	id = 0;
	for( k=0 ; k<Dim[2] ; k++ ) 
		for( j=0 ; j<Dim[1] ; j++ ) 
			for( i=0 ; i<Dim[0] ; i++ ) 
				if(coorded[i][j][k][3] >= MinFA) { 
					for( ii=0 ; ii<SeedPerV[0] ; ii++ ) 
						for( jj=0 ; jj<SeedPerV[1] ; jj++ ) 
							for( kk=0 ; kk<SeedPerV[2] ; kk++ ) {

								in[0] = i;
								in[1] = j;
								in[2] = k;
								physin[0] = ((float) in[0] + 
												 (0.5 + (float) ii)/SeedPerV[0])*Ledge[0];
								physin[1] = ((float) in[1] + 
												 (0.5 + (float) jj)/SeedPerV[1])*Ledge[1];
								physin[2] = ((float) in[2] + 
												 (0.5 + (float) kk)/SeedPerV[2])*Ledge[2];
      
								len_forw = TrackIt(coorded, in, physin, Ledge, Dim, 
														 MinFA, MaxAng, ArrMax, Tforw, 
														 flTforw, 1, phys_forw);
      
								// reset, because it's changed in TrackIt func
								in[0] = i; 
								in[1] = j;
								in[2] = k;

								physin[0] = ((float) in[0] + 
												 (0.5 + (float) ii)/SeedPerV[0])*Ledge[0];
								physin[1] = ((float) in[1] + 
												 (0.5 + (float) jj)/SeedPerV[1])*Ledge[1];
								physin[2] = ((float) in[2] + 
												 (0.5 + (float) kk)/SeedPerV[2])*Ledge[2];

								len_back = TrackIt(coorded, in, physin, Ledge, Dim, 
														 MinFA, MaxAng, ArrMax, Tback, 
														 flTback, -1, phys_back);
            
								KEEPIT = 0; // a simple switch

								totlen = len_forw+len_back-1; // NB: overlap of starts
								totlen_phys = phys_forw[0] + phys_back[0];
		
								if( totlen_phys >= MinL ) {
		  
									// glue together for simpler notation later
									for( n=0 ; n<len_back ; n++) { // all of this
										rr = len_back-n-1; // read in backward
										for(m=0;m<3;m++)
											Ttot[rr][m] = Tback[n][m];
									}
									for( n=1 ; n<len_forw ; n++){// skip first->overlap
										rr = n+len_back-1; // put after
										for(m=0;m<3;m++)
											Ttot[rr][m] = Tforw[n][m];
									}
									// <<So close and orthogonal condition>>:
									// test projecting ends, to see if they abut ROI.  
									for(m=0;m<3;m++) { 
										//actual projected ends
										end[1][m] = 2*Ttot[totlen-1][m]-Ttot[totlen-2][m];
										end[0][m] = 2*Ttot[0][m]-Ttot[1][m];
										// default choice, just retest known ends 
										// as default
										test_ind[1][m] = test_ind[0][m] = Ttot[0][m];
									}
		  
									tt = Create_Tract(len_back, flTback, len_forw, 
															flTforw, id, insetFA); ++id; 
        
									if (LOG_TYPE == -1) {
										KEEPIT = 1; 
									} else {
										inroi1 = 0;
										// check forw
										for( n=0 ; n<len_forw ; n++) {
											if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][1]==1){
												inroi1 = 1;
												break;
											} else
												continue;
										}
										if( inroi1==0 ){// after 1st half, check 2nd half
											for( m=0 ; m<len_back ; m++) {
												if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][1]==1){
													inroi1 = 1;
													break;
												} else
													continue;
											}
										}
										// after 1st&2nd halves, check bound/neigh
										if( inroi1==0 ) {
											if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][1]==1)
												inroi1 = 1;
											if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][1]==1)
												inroi1 = 1;
										}
			 
										if( ((LOG_TYPE ==0) && (inroi1 ==0)) || 
											 ((LOG_TYPE ==1) && (inroi1 ==1))) {
											// have to check in ROI2
				
											inroi2 = 0;
											// check forw
											for( n=0 ; n<len_forw ; n++) {
												if(INDEX[Tforw[n][0]][Tforw[n][1]][Tforw[n][2]][2]==1){
													inroi2 = 1;
													break;
												} else
													continue;
											}
											//after 1st half, check 2nd half
											if( inroi2==0 ) { 
												for( m=0 ; m<len_back ; m++) {
													if(INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][2]==1){
														inroi2 = 1;
														break;
													} else
														continue;
												}
											}
											// after 1st&2nd halves, check bound/neigh
											if( inroi2==0 ) { 
												if(INDEX[test_ind[1][0]][test_ind[1][1]][test_ind[1][2]][2]==1)
													inroi2 = 1;
												if(INDEX[test_ind[0][0]][test_ind[0][1]][test_ind[0][2]][2]==1)
													inroi2 = 1;
											}
				
											// for both cases, need to see it here to keep
											if( inroi2 ==1 )
												KEEPIT = 1; // otherwise, it's gone
				
										} else if((LOG_TYPE ==0) && (inroi1 ==1))
											KEEPIT = 1;
									}
								}
      
								// by now, we *know* if we're keeping this or not.
								if( KEEPIT == 1 ) {
									tb = AppCreateBundle(tb, 1, tt, NULL); 
									tt = Free_Tracts(tt, 1);
        
									READS_in = totlen;
									fwrite(&READS_in,sizeof(READS_in),1,fout0);
									for( n=0 ; n<len_back ; n++) {
										//put this one in backwords, to make it connect
										m = len_back - 1 - n; 
										for(aa=0 ; aa<3 ; aa++) {
											// recenter phys loc for trackvis, if nec...
											// just works this way (where they define 
											// origin)
											READS_fl = flTback[m][aa];
											if(!TV_switch[aa])
												READS_fl = Ledge[aa]*Dim[aa]-READS_fl;
											fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										}
										mm = INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][0];
										READS_fl =THD_get_voxel(insetFA, mm, 0); // FA
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										READS_fl =THD_get_voxel(insetMD, mm, 0); // MD
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										READS_fl =THD_get_voxel(insetL1, mm, 0); // L1
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										// count this voxel for having a tract
										INDEX[Tback[m][0]][Tback[m][1]][Tback[m][2]][3]+= 1; 
									}
        
									for( m=1 ; m<len_forw ; m++) {
										for(aa=0 ; aa<3 ; aa++) {
											// recenter phys loc for trackvis, if nec...
											READS_fl = flTforw[m][aa];
											if(!TV_switch[aa])
												READS_fl = Ledge[aa]*Dim[aa]-READS_fl;
											fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										}
										mm = INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][0];
										READS_fl =THD_get_voxel(insetFA, mm, 0); // FA
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										READS_fl =THD_get_voxel(insetMD, mm, 0); // MD
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										READS_fl =THD_get_voxel(insetL1, mm, 0); // L1 
										fwrite(&READS_fl,sizeof(READS_fl),1,fout0);
										// count this voxel for having a tract
										INDEX[Tforw[m][0]][Tforw[m][1]][Tforw[m][2]][3]+= 1; 
									}
        
									ave_tract_len+= totlen;
									ave_tract_len_phys+= totlen_phys;
									Numtract+=1;
								}   
							}
				}
	fclose(fout0); 
  
	if (get_tract_verb()) {
		INFO_message("Done tracking, have %d tracks.", tb->N_tracts);
		Show_Taylor_Bundle(tb, NULL, 3);
	}

	if (!Write_Bundle(tb,prefix,mode)) {
		ERROR_message("Failed to write the bundle");
	}
   
	// **************************************************************
	// **************************************************************
	//                    Some simple stats on ROIs and outputs
	// **************************************************************
	// **************************************************************

	for( k=0 ; k<Dim[2] ; k++ ) 
		for( j=0 ; j<Dim[1] ; j++ ) 
			for( i=0 ; i<Dim[0] ; i++ ) {
				if( INDEX[i][j][k][3]>=1 ) {
					tempMD = THD_get_voxel(insetMD,INDEX[i][j][k][0],0);
					tempFA = THD_get_voxel(insetFA,INDEX[i][j][k][0],0);
					tempL1 = THD_get_voxel(insetL1,INDEX[i][j][k][0],0);
					tempRD = 0.5*(3*tempMD-tempL1);
					roi3_mu_MD+= tempMD;
					roi3_mu_FA+= tempFA;
					roi3_mu_L1+= tempL1;
					roi3_mu_RD+= tempRD;
					roi3_sd_MD+= tempMD*tempMD;
					roi3_sd_FA+= tempFA*tempFA;
					roi3_sd_L1+= tempL1*tempL1;
					roi3_sd_RD+= tempRD*tempRD;
					roi3_ct+= 1;
				}
			}
  
	if(roi3_ct > 0 ) { // !!!! make into afni file
		roi3_mu_MD/= (float) roi3_ct; 
		roi3_mu_FA/= (float) roi3_ct;
		roi3_mu_L1/= (float) roi3_ct;
		roi3_mu_RD/= (float) roi3_ct;
    
		roi3_sd_MD-= roi3_ct*roi3_mu_MD*roi3_mu_MD;
		roi3_sd_FA-= roi3_ct*roi3_mu_FA*roi3_mu_FA;
		roi3_sd_L1-= roi3_ct*roi3_mu_L1*roi3_mu_L1;
		roi3_sd_RD-= roi3_ct*roi3_mu_RD*roi3_mu_RD;
		roi3_sd_MD/= (float) roi3_ct-1; 
		roi3_sd_FA/= (float) roi3_ct-1;
		roi3_sd_L1/= (float) roi3_ct-1;
		roi3_sd_RD/= (float) roi3_ct-1;
		roi3_sd_MD = sqrt(roi3_sd_MD); 
		roi3_sd_FA = sqrt(roi3_sd_FA);
		roi3_sd_L1 = sqrt(roi3_sd_L1);
		roi3_sd_RD = sqrt(roi3_sd_RD);
  
		sprintf(OUT_tracstat,"%s.stats",prefix);
		if( (fout0 = fopen(OUT_tracstat, "w")) == NULL) {
			fprintf(stderr, "Error opening file %s.",OUT_tracstat);
			exit(19);
		}
		fprintf(fout0,"%d\t%d\n",Numtract,roi3_ct);
		fprintf(fout0,"%.3f\t%.3f\n",ave_tract_len/Numtract,
				  ave_tract_len_phys/Numtract);
		// as usual, these next values would have to be divided by the
		// bval to get their actual value in standard phys units
		fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_FA,roi3_sd_FA);
		fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_MD,roi3_sd_MD);
		fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_RD,roi3_sd_RD);
		fprintf(fout0,"%.4f\t%.4f\n",roi3_mu_L1,roi3_sd_L1);
		fclose(fout0);

		sprintf(prefix_map,"%s_MAP",prefix); 
		sprintf(prefix_mask,"%s_MASK",prefix); 

		outsetMAP = EDIT_empty_copy( mset1 ) ;
		EDIT_dset_items( outsetMAP ,
							  ADN_datum_all , MRI_short , 
							  ADN_prefix    , prefix_map ,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetMAP));
    
		outsetMASK = EDIT_empty_copy( mset1 ) ;
		EDIT_dset_items( outsetMASK ,
							  ADN_datum_all , MRI_byte , 
							  ADN_prefix    , prefix_mask ,
							  ADN_none ) ;
		if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetMASK));
    
		m=0;
		for( k=0 ; k<Dim[2] ; k++ ) 
			for( j=0 ; j<Dim[1] ; j++ ) 
				for( i=0 ; i<Dim[0] ; i++ ) {
					temp_arr[m]=INDEX[i][j][k][3];
					if(temp_arr[m]>0.5)
						temp_byte[m]=1;
					else
						temp_byte[m]=0;
					m++;
				}
    
		// re-orient the data as original inputs 
		// (this function copies the pointer)
		EDIT_substitute_brick(outsetMAP, 0, MRI_short, temp_arr); 
		temp_arr=NULL;
		if(TV_switch[0] || TV_switch[1] || TV_switch[2]) {
			dsetn = r_new_resam_dset(outsetMAP, NULL, 0.0, 0.0, 0.0,
											 header1.voxel_order, RESAM_NN_TYPE, 
											 NULL, 1, 0);
			DSET_delete(outsetMAP); 
			outsetMAP=dsetn;
			dsetn=NULL;
		}
		EDIT_dset_items( outsetMAP ,
							  ADN_prefix , prefix_map ,
							  ADN_none ) ;
		THD_load_statistics(outsetMAP );
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMAP)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetMAP));
		tross_Make_History( "3dTrackID" , argc , argv ,  outsetMAP) ;
		THD_write_3dim_dataset(NULL, NULL, outsetMAP, True);
		// re-orient the data as original inputs
		EDIT_substitute_brick(outsetMASK, 0, MRI_byte, temp_byte);
		temp_byte=NULL;
		if(TV_switch[0] || TV_switch[1] || TV_switch[2]) {
			dsetn = r_new_resam_dset(outsetMASK, NULL, 0.0, 0.0, 0.0,
											 header1.voxel_order, RESAM_NN_TYPE, 
											 NULL, 1, 0);
			DSET_delete(outsetMASK); 
			outsetMASK=dsetn;
			dsetn=NULL;
		}
		EDIT_dset_items( outsetMASK ,
							  ADN_prefix , prefix_mask ,
							  ADN_none ) ;
		THD_load_statistics(outsetMASK);
		if(!THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetMASK)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetMASK));
		tross_Make_History( "3dTrackID" , argc , argv ,  outsetMASK) ;
		THD_write_3dim_dataset(NULL, NULL, outsetMASK, True);

		INFO_message("Number of tracts found = %d",Numtract) ;
	}
	else 
		INFO_message("\n No Tracts Found!!!\n");
  

	// ************************************************************
	// ************************************************************
	//                    Freeing
	// ************************************************************
	// ************************************************************

	// !!! need to free afni-sets?
	DSET_delete(insetFA);
	DSET_delete(insetMD);
	DSET_delete(insetL1);
	DSET_delete(insetV1);
	DSET_delete(insetEXTRA);
	//DSET_delete(outsetMAP);  
	//DSET_delete(outsetMASK);
	DSET_delete(mset2);
	DSET_delete(mset1);

	free(prefix);
	free(insetV1);
	free(insetFA);
	free(mset1);
	free(mset2);
  	free(insetEXTRA);

	free(ROI1);
	free(ROI2);
	free(temp_byte);
  
	for( i=0 ; i<ArrMax ; i++) {
		free(Tforw[i]);
		free(Tback[i]);
		free(flTforw[i]);
		free(flTback[i]);
	}
	free(Tforw);
	free(Tback);
	free(flTforw);
	free(flTback);
  
	for( i=0 ; i<Dim[0] ; i++) 
		for( j=0 ; j<Dim[1] ; j++) 
			for( k=0 ; k<Dim[2] ; k++) 
				free(coorded[i][j][k]);
	for( i=0 ; i<Dim[0] ; i++) 
		for( j=0 ; j<Dim[1] ; j++) 
			free(coorded[i][j]);
	for( i=0 ; i<Dim[0] ; i++) 
		free(coorded[i]);
	free(coorded);

	for( i=0 ; i<Dim[0] ; i++) 
		for( j=0 ; j<Dim[1] ; j++) 
			for( k=0 ; k<Dim[2] ; k++) 
				free(INDEX[i][j][k]);
	for( i=0 ; i<Dim[0] ; i++) 
		for( j=0 ; j<Dim[1] ; j++) 
			free(INDEX[i][j]);
	for( i=0 ; i<Dim[0] ; i++) 
		free(INDEX[i]);
	free(INDEX);

	free(temp_arr); // need to free
	for( i=0 ; i<2*ArrMax ; i++) 
		free(Ttot[i]);
	free(Ttot);

	//free(mode);
	
	return 0;
}
Пример #18
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL ;
   byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0 , automask=0 , masknum=0 ;
   int iarg=1 , verb=1 , ntype=0 , nev,kk,ii,nxyz,nt ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; int *ivox ; MRI_IMAGE *pim ;
   int do_vmean=0 , do_vnorm=0 , sval_itop=0 ;
   int polort=-1 ; float *ev ;
   MRI_IMARR *ortar ; MRI_IMAGE *ortim ; int nyort=0 ;
   float bpass_L=0.0f , bpass_H=0.0f , dtime ; int do_bpass=0 ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
       "Usage:  3dmaskSVD [options] inputdataset\n"
       "Author: Zhark the Gloriously Singular\n"
       "\n"
       "* Computes the principal singular vector of the time series\n"
       "    vectors extracted from the input dataset over the input mask.\n"
       "  ++ You can use the '-sval' option to change which singular\n"
       "     vectors are output.\n"
       "* The sign of the output vector is chosen so that the average\n"
       "    of arctanh(correlation coefficient) over all input data\n"
       "    vectors (from the mask) is positive.\n"
       "* The output vector is normalized: the sum of its components\n"
       "    squared is 1.\n"
       "* You probably want to use 3dDetrend (or something similar) first,\n"
       "    to get rid of annoying artifacts, such as motion, breathing,\n"
       "    dark matter interactions with the brain, etc.\n"
       "  ++ If you are lazy scum like Zhark, you might be able to get\n"
       "     away with using the '-polort' option.\n"
       "  ++ In particular, if your data time series has a nonzero mean,\n"
       "     then you probably want at least '-polort 0' to remove the\n"
       "     mean, otherwise you'll pretty much just get a constant\n"
       "     time series as the principal singular vector!\n"
       "* An alternative to this program would be 3dmaskdump followed\n"
       "    by 1dsvd, which could give you all the singular vectors you\n"
       "    could ever want, and much more -- enough to confuse you for days.\n"
       "  ++ In particular, although you COULD input a 1D file into\n"
       "     3dmaskSVD, the 1dsvd program would make much more sense.\n"
       "* This program will be pretty slow if there are over about 2000\n"
       "    voxels in the mask.  It could be made more efficient for\n"
       "    such cases, but you'll have to give Zhark some 'incentive'.\n"
       "* Result vector goes to stdout.  Redirect per your pleasures and needs.\n"
       "* Also see program 3dLocalSVD if you want to compute the principal\n"
       "    singular time series vector from a neighborhood of EACH voxel.\n"
       "  ++ (Which is a pretty slow operation!)\n"
       "* http://en.wikipedia.org/wiki/Singular_value_decomposition\n"
       "\n"
       "-------\n"
       "Options:\n"
       "-------\n"
       " -vnorm      = L2 normalize all time series before SVD [recommended!]\n"
       " -sval a     = output singular vectors 0 .. a [default a=0 = first one only]\n"
       " -mask mset  = define the mask [default is entire dataset == slow!]\n"
       " -automask   = you'll have to guess what this option does\n"
       " -polort p   = if you are lazy and didn't run 3dDetrend (like Zhark)\n"
       " -bpass L H  = bandpass [mutually exclusive with -polort]\n"
       " -ort xx.1D  = time series to remove from the data before SVD-ization\n"
       "               ++ You can give more than 1 '-ort' option\n"
       "               ++ 'xx.1D' can contain more than 1 column\n"
       " -input ddd  = alternative way to give the input dataset name\n"
       "\n"
       "-------\n"
       "Example:\n"
       "-------\n"
       " You have a mask dataset with discrete values 1, 2, ... 77 indicating\n"
       " some ROIs; you want to get the SVD from each ROI's time series separately,\n"
       " and then put these into 1 big 77 column .1D file.  You can do this using\n"
       " a csh shell script like the one below:\n"
       "\n"
       " # Compute the individual SVD vectors\n"
       " foreach mm ( `count 1 77` )\n"
       "   3dmaskSVD -vnorm -mask mymask+orig\"<${mm}..${mm}>\" epi+orig > qvec${mm}.1D\n"
       " end\n"
       " # Glue them together into 1 big file, then delete the individual files\n"
       " 1dcat qvec*.1D > allvec.1D\n"
       " /bin/rm -f qvec*.1D\n"
       " # Plot the results to a JPEG file, then compute their correlation matrix\n"
       " 1dplot -one -nopush -jpg allvec.jpg allvec.1D\n"
       " 1ddot -terse allvec.1D > allvec_COR.1D\n"
       "\n"
       " [[ If you use the bash shell,  you'll have to figure out the syntax ]]\n"
       " [[ yourself. Zhark has no sympathy for you bash shell infidels, and ]]\n"
       " [[ considers you only slightly better than those lowly Emacs users. ]]\n"
       " [[ And do NOT ever even mention 'nedit' in Zhark's august presence! ]]\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   /*---- official startup ---*/

   PRINT_VERSION("3dmaskSVD"); mainENTRY("3dmaskSVD main"); machdep();
   AFNI_logger("3dmaskSVD",argc,argv); AUTHOR("Zhark the Singular");

   /*---- loop over options ----*/

   INIT_IMARR(ortar) ;

   mpv_sign_meth = AFNI_yesenv("AFNI_3dmaskSVD_meansign") ;

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

     if( strcasecmp(argv[iarg],"-bpass") == 0 ){
       if( iarg+2 >= argc ) ERROR_exit("need 2 args after -bpass") ;
       bpass_L = (float)strtod(argv[++iarg],NULL) ;
       bpass_H = (float)strtod(argv[++iarg],NULL) ;
       if( bpass_L < 0.0f || bpass_H <= bpass_L )
         ERROR_exit("Illegal values after -bpass: %g %g",bpass_L,bpass_H) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-ort") == 0 ){  /* 01 Oct 2009 */
       int nx,ny ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-ort'") ;
       ortim = mri_read_1D( argv[iarg] ) ;
       if( ortim == NULL ) ERROR_exit("-ort '%s': Can't read 1D file",argv[iarg]) ;
       nx = ortim->nx ; ny = ortim->ny ;
       if( nx == 1 && ny > 1 ){
         MRI_IMAGE *tim=mri_transpose(ortim); mri_free(ortim); ortim = tim; ny = 1;
       }
       mri_add_name(argv[iarg],ortim) ; ADDTO_IMARR(ortar,ortim) ; nyort += ny ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-polort") == 0 ){
       char *qpt ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-polort'") ;
       polort = (int)strtod(argv[iarg],&qpt) ;
       if( *qpt != '\0' ) WARNING_message("Illegal non-numeric value after -polort") ;
       iarg++ ; continue ;
     }

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

     if( strcmp(argv[iarg],"-input") == 0 ){
       if( inset != NULL  ) ERROR_exit("Can't have two -input options") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-input'") ;
       inset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(inset,argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-sval") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-sval'") ;
       sval_itop = (int)strtod(argv[iarg],NULL) ;
       if( sval_itop < 0 ){ sval_itop = 0 ; WARNING_message("'-sval' reset to 0") ; }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-mask") == 0 ){
       THD_3dim_dataset *mset ; int mmm ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL || automask ) ERROR_exit("Can't have two mask inputs") ;
       mset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(mset,argv[iarg]) ;
       DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
       mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
       mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
       if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ;
       masknum = mmm = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
       INFO_message("Number of voxels in mask = %d",mmm) ;
       if( mmm < 2 ) ERROR_exit("Mask is too small to process") ;
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-automask") == 0 ){
       if( mask != NULL ) ERROR_exit("Can't have two mask inputs!") ;
       automask = 1 ; iarg++ ; continue ;
     }

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

   } /*--- end of loop over options ---*/

   /*---- deal with input dataset ----*/

   if( inset == NULL ){
     if( iarg >= argc ) ERROR_exit("No input dataset on command line?") ;
     inset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(inset,argv[iarg]) ;
   }
   nt = DSET_NVALS(inset) ;  /* vector lengths */
   if( nt < 9 )
     ERROR_exit("Must have at least 9 values per voxel") ;
   if( polort+1 >= nt )
     ERROR_exit("'-polort %d' too big for time series length = %d",polort,nt) ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   nxyz = DSET_NVOX(inset) ;

   DSET_UNMSEC(inset) ;
   dtime = DSET_TR(inset) ;
   if( dtime <= 0.0f ) dtime = 1.0f ;
   do_bpass = (bpass_L < bpass_H) ;
   if( do_bpass ){
     kk = THD_bandpass_OK( nt , dtime , bpass_L , bpass_H , 1 ) ;
     if( kk <= 0 ) ERROR_exit("Can't continue since -bpass setup is illegal") ;
     polort = -1 ;
   }

   /*--- deal with the masking ---*/

   if( mask != NULL ){
     if( mask_nx != DSET_NX(inset) ||
         mask_ny != DSET_NY(inset) ||
         mask_nz != DSET_NZ(inset)   )
       ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( automask ){
     int mmm ;
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset?") ;
     masknum = mmm = THD_countmask( DSET_NVOX(inset) , mask ) ;
     INFO_message("Number of voxels in automask = %d",mmm) ;
     if( mmm < 9 ) ERROR_exit("Automask is too small to process") ;
   } else {
     mask = (byte *)malloc(sizeof(byte)*nxyz) ; masknum = nxyz ;
     memset( mask , 1 , sizeof(byte)*nxyz ) ;
     INFO_message("Using all %d voxels in dataset",nxyz) ;
   }

   nev = MIN(nt,masknum) ;  /* max possible number of eigenvalues */
   if( sval_itop >= nev ){
     sval_itop = nev-1 ;
     WARNING_message("'-sval' reset to '%d'",sval_itop) ;
   }
   mri_principal_vector_params( 0 , do_vnorm , sval_itop ) ;
   mri_principal_setev(nev) ;

   /*-- get data vectors --*/

   ivox = (int *)malloc(sizeof(int)*masknum) ;
   for( kk=ii=0 ; ii < nxyz ; ii++ ) if( mask[ii] ) ivox[kk++] = ii ;
   INFO_message("Extracting data vectors") ;
   imar = THD_extract_many_series( masknum, ivox, inset ) ; DSET_unload(inset) ;
   if( imar == NULL ) ERROR_exit("Can't get data vector?!") ;

   /*-- detrending --*/

   if( polort >= 0 || nyort > 0 || do_bpass ){
     float **polref=NULL ; float *tsar ;
     int nort=IMARR_COUNT(ortar) , nref=0 ;

     if( polort >= 0 ){  /* polynomials */
       nref = polort+1 ; polref = THD_build_polyref(nref,nt) ;
     }

     if( nort > 0 ){     /* other orts */
       float *oar , *par ; int nx,ny , qq,tt ;
       for( kk=0 ; kk < nort ; kk++ ){  /* loop over input -ort files */
         ortim = IMARR_SUBIM(ortar,kk) ;
         nx = ortim->nx ; ny = ortim->ny ;
         if( nx < nt )
           ERROR_exit("-ort '%s' length %d shorter than dataset length %d" ,
                      ortim->name , nx , nt ) ;
         polref = (float **)realloc(polref,(nref+ny)*sizeof(float *)) ;
         oar    = MRI_FLOAT_PTR(ortim) ;
         for( qq=0 ; qq < ny ; qq++,oar+=nx ){
           par = polref[nref+qq] = (float *)malloc(sizeof(float)*nt) ;
           for( tt=0 ; tt < nt ; tt++ ) par[tt] = oar[tt] ;
                if( polort == 0 ) THD_const_detrend (nt,par,NULL) ;
           else if( polort >  0 ) THD_linear_detrend(nt,par,NULL,NULL) ;
         }
         nref += ny ;
       }
       DESTROY_IMARR(ortar) ;
     }

     if( !do_bpass ){            /* old style ort-ification */

       MRI_IMAGE *imq , *imp ; float *qar ;
       INFO_message("Detrending data vectors") ;
#if 1
       imq = mri_new( nt , nref , MRI_float) ; qar = MRI_FLOAT_PTR(imq) ;
       for( kk=0 ; kk < nref ; kk++ )
         memcpy( qar+kk*nt , polref[kk] , sizeof(float)*nt ) ;
       imp = mri_matrix_psinv( imq , NULL , 1.e-8 ) ;
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ ){
         mri_matrix_detrend( IMARR_SUBIM(imar,kk) , imq , imp ) ;
       }
       mri_free(imp) ; mri_free(imq) ;
#else
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ ){
         tsar = MRI_FLOAT_PTR(IMARR_SUBIM(imar,kk)) ;
         THD_generic_detrend_LSQ( nt , tsar , -1 , nref , polref , NULL ) ;
       }
#endif

     } else {                   /* bandpass plus (maybe) orts */

       float **vec = (float **)malloc(sizeof(float *)*IMARR_COUNT(imar)) ;
       INFO_message("Bandpassing data vectors") ;
       for( kk=0 ; kk < IMARR_COUNT(imar) ; kk++ )
         vec[kk] = MRI_FLOAT_PTR(IMARR_SUBIM(imar,kk)) ;
       (void)THD_bandpass_vectors( nt    , IMARR_COUNT(imar) , vec     ,
                                   dtime , bpass_L           , bpass_H ,
                                   2     , nref              , polref   ) ;
       free(vec) ;
     }

     for( kk=0 ; kk < nref; kk++ ) free(polref[kk]) ;
     free(polref) ;
   } /* end of detrendization */

   /*--- the actual work ---*/

   INFO_message("Computing SVD") ;
   pim  = mri_principal_vector( imar ) ; DESTROY_IMARR(imar) ;
   if( pim == NULL ) ERROR_exit("SVD failure!?!") ;
   ev = mri_principal_getev() ;
   switch(sval_itop+1){
     case 1:
       INFO_message("First singular value: %g",ev[0]) ; break ;
     case 2:
       INFO_message("First 2 singular values: %g %g",ev[0],ev[1]) ; break ;
     case 3:
       INFO_message("First 3 singular values: %g %g %g",ev[0],ev[1],ev[2]) ; break ;
     case 4:
       INFO_message("First 4 singular values: %g %g %g %g",ev[0],ev[1],ev[2],ev[3]) ; break ;
     default:
     case 5:
       INFO_message("First 5 singular values: %g %g %g %g %g",ev[0],ev[1],ev[2],ev[3],ev[4]) ; break ;
   }
   mri_write_1D(NULL,pim) ;

   exit(0) ;
}
Пример #19
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"
       " * The program can only do FFT lengths that are factorable\n"
       "    into a product of powers of 2, 3, and 5, and are even.\n"
       "   + The largest power of 3 that is allowed is 3^3 = 27.\n"
       "   + The largest power of 5 that is allowed is 5^3 = 125.\n"
       "   + e.g., FFT of length 3*5*8=120 is possible.\n"
       "   + e.g., FFT of length 4*31 =124 is not possible.\n"
       "\n"
       " * The 'x', 'y', and 'z' axes here refer to the order the\n"
       "    data is stored, not DICOM coordinates; cf. 3dinfo.\n"
       "\n"
       " * If you force (via '-Lx' etc.) an FFT length that is not\n"
       "    allowed, the program will stop with an error message.\n"
       "\n"
       " * If you force an FFT length that is shorter than an dataset\n"
       "    axis dimension, the program will stop with an error message.\n"
       "\n"
       " * If you don't force an FFT length along a particular axis,\n"
       "    the program will pick the smallest legal value that is\n"
       "    greater than or equal to the corresponding dataset dimension.\n"
       "   + e.g., 124 would be increased to 128.\n"
       "\n"
       " * If an FFT length is longer than an axis length, then the\n"
       "    input data in that direction is zero-padded at the end.\n"
       "\n"
       " * For -abs and -phase, the output dataset is in float format.\n"
       "\n"
       " * If you do the forward and inverse FFT, then you should get back\n"
       "    the original dataset, except for roundoff error and except that\n"
       "    the new dataset axis dimensions may be longer than the original.\n"
       "\n"
       " * Forward FFT = sum_{k=0..N-1} [ exp(-2*PI*i*k/N) * data(k) ]\n"
       "\n"
       " * Inverse FFT = sum_{k=0..N-1} [ exp(+2*PI*i*k/N) * data(k) ] / N\n"
       "\n"
       " * Started a long time ago, but only finished in Aug 2009 at the\n"
       "    request of John Butman, because he asked so nicely.  (Now pay up!)\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

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

   /*--- scan args ---*/

   iarg = 1 ;

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

     if( strncasecmp(argv[iarg],"-altI",5) == 0 ){
       do_alt = 1 ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-altOUT",5) == 0 ){
       do_alt = -1 ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-inverse",4) == 0 ){
       Sign = +1 ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-abs",4) == 0 ){
       Mode = FFT_ABS ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-phase",4) == 0 ){
       Mode = FFT_PHASE ; iarg++ ; continue ;
     }
     if( strncasecmp(argv[iarg],"-complex",4) == 0 ){
       Mode = FFT_COMPLEX ; iarg++ ; continue ;
     }

     if( strlen(argv[iarg]) == 3 && strncmp(argv[iarg],"-L",2) == 0 ){
       int lll=-1 , mmm ; char *ept ;
       iarg++ ;
       if( iarg >= argc )
         ERROR_exit("need an argument after option %s",argv[iarg-1]) ;

       lll = strtol( argv[iarg] , &ept , 10 ) ;
       if( *ept != '\0' )
         ERROR_exit("bad argument after option %s",argv[iarg-1]) ;
       if( lll > 0 && (mmm = csfft_nextup_even(lll)) != lll )
         ERROR_exit(
          "'%s %d' is not a legal FFT length here: next largest legal value = %d" ,
          argv[iarg-1] , lll , mmm ) ;
       switch( argv[iarg-1][2] ){
         case 'x': case 'X': Lxx = lll ; break ;
         case 'y': case 'Y': Lyy = lll ; break ;
         case 'z': case 'Z': Lzz = lll ; break ;
         default:  ERROR_exit("unknown option '%s'",argv[iarg-1]) ;
       }
       iarg++ ; continue ;
     }

     if( strncasecmp(argv[iarg],"-prefix",4) == 0 ){
       iarg++ ;
       if( iarg >= argc )
         ERROR_exit("need an argument after %s\n",argv[iarg-1]) ;
       prefix = strdup( argv[iarg] ) ;
       if( !THD_filename_ok(prefix) )
         ERROR_exit("bad argument after %s\n",argv[iarg-1]) ;
       iarg++ ; continue ;
     }

     if( strncasecmp(argv[iarg],"-input",4) == 0 ){
       iarg++ ;
       if( iarg >= argc )
         ERROR_exit("need an argument after %s\n",argv[iarg-1]) ;
       dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]);
       iarg++ ; continue ;
     }

     ERROR_exit("unknown option '%s'\n",argv[iarg]) ;
   }

   /* check for simple errors */

   if( Lxx == 0 && Lyy == 0 && Lzz == 0 )
     ERROR_exit("-Lx, -Ly, -Lz all given as zero?!") ;

   /* open input dataset */

   if( dset_in == NULL ){
     if( iarg >= argc ) ERROR_exit("no input dataset on command line?!\n") ;
     dset_in = THD_open_dataset(argv[iarg]); CHECK_OPEN_ERROR(dset_in,argv[iarg]);
   }

   nx = DSET_NX(dset_in) ; ny = DSET_NY(dset_in) ; nz = DSET_NZ(dset_in) ;

   if( DSET_NVALS(dset_in) > 1 )
     WARNING_message("only 3dFFT-ing sub-brick #0 of input dataset") ;

   /* establish actual FFT lengths now (0 ==> no FFT) */

   if( nx == 1 ) Lxx = 0 ;  /* can't FFT if dataset is shrimpy! */
   if( ny == 1 ) Lyy = 0 ;
   if( nz == 1 ) Lzz = 0 ;

   if( Lxx < 0 ) Lxx = csfft_nextup_even(nx) ;  /* get FFT length from */
   if( Lyy < 0 ) Lyy = csfft_nextup_even(ny) ;  /* dataset dimensions */
   if( Lzz < 0 ) Lzz = csfft_nextup_even(nz) ;

   INFO_message("x-axis length=%d ; FFT length=%d %s",nx,Lxx,(Lxx==0)?"==> none":"\0") ;
   INFO_message("y-axis length=%d ; FFT length=%d %s",ny,Lyy,(Lyy==0)?"==> none":"\0") ;
   INFO_message("z-axis length=%d ; FFT length=%d %s",nz,Lzz,(Lzz==0)?"==> none":"\0") ;

   if( Lxx > 0 && Lxx < nx ) ERROR_exit("x-axis FFT length too short for data!") ;
   if( Lyy > 0 && Lyy < ny ) ERROR_exit("y-axis FFT length too short for data!") ;
   if( Lzz > 0 && Lzz < nz ) ERROR_exit("z-axis FFT length too short for data!") ;

   /* extract sub-brick #0 */

   DSET_load(dset_in) ; CHECK_LOAD_ERROR(dset_in) ;

   inim = mri_to_complex( DSET_BRICK(dset_in,0) ) ; /* convert input to complex */
   fac  = DSET_BRICK_FACTOR(dset_in,0) ;
   if( fac > 0.0f && fac != 1.0f ){                 /* scale it if needed */
     int ii , nvox = nx*ny*nz ; complex *car = MRI_COMPLEX_PTR(inim) ;
     for( ii=0 ; ii < nvox ; ii++ ){ car[ii].r *= fac ; car[ii].i *= fac ; }
   }

   DSET_unload(dset_in) ;  /* input data is all copied now */

   /* FFT to get output image */

   csfft_scale_inverse(1) ;  /* scale by 1/N for inverse FFTs */

   outim = mri_fft_3D( Sign , inim , Lxx,Lyy,Lzz , do_alt ) ;

   mri_free(inim) ;

   /* post-process output? */

   switch( Mode ){
     case FFT_ABS:{
       MRI_IMAGE *qim = mri_complex_abs(outim) ;
       mri_free(outim) ; outim = qim ;
     }
     break ;

     case FFT_PHASE:{
       MRI_IMAGE *qim = mri_complex_phase(outim) ;
       mri_free(outim) ; outim = qim ;
     }
     break ;
   }

   /* create and write output dataset */

   dset_out = EDIT_empty_copy( dset_in ) ;
   tross_Copy_History( dset_in , dset_out ) ;
   tross_Make_History( "3dFFT" , argc,argv , dset_out ) ;
   LOAD_IVEC3( iv , outim->nx , outim->ny , outim->nz ) ;
   EDIT_dset_items( dset_out ,
                      ADN_prefix , prefix ,
                      ADN_nvals  , 1 ,
                      ADN_ntt    , 0 ,
                      ADN_nxyz   , iv ,  /* change dimensions, possibly */
                    ADN_none ) ;
   EDIT_BRICK_FACTOR( dset_out , 0 , 0.0 ) ;
   EDIT_substitute_brick( dset_out , 0 , outim->kind , mri_data_pointer(outim) ) ;
   DSET_write(dset_out) ; WROTE_DSET(dset_out) ; DSET_unload(dset_out) ;

   exit(0) ;
}
Пример #20
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *old_dset , *new_dset ;  /* input and output datasets */
   THD_3dim_dataset *mask_dset=NULL  ;
   float mask_bot=666.0 , mask_top=-666.0 ;
   byte *cmask=NULL ; int ncmask=0 ;
   byte *mmm   = NULL ;
   int mcount=0, verb=0;
   int nopt, nbriks, ii ;
   int addBriks = 0 ;   /* n-1 sub-bricks out */
   int fullBriks = 0 ;  /* n   sub-bricks out */
   int tsout = 0 ;      /* flag to output a time series (not a stat bucket) */
   int numMultBriks,methIndex,brikIndex;

   /*----- Help the pitiful user? -----*/


   /* bureaucracy */
   mainENTRY("3dTstat main"); machdep(); AFNI_logger("3dTstat",argc,argv);
   PRINT_VERSION("3dTstat"); AUTHOR("KR Hammett & RW Cox");

   /*--- scan command line for options ---*/

   if (argc == 1) { usage_3dTstat(1); exit(0); } /* Bob's help shortcut */
   nopt = 1 ;
   nbriks = 0 ;
   nmeths = 0 ;
   verb = 0;
   while( nopt < argc && argv[nopt][0] == '-' ){
      if (strcmp(argv[nopt], "-h") == 0 || strcmp(argv[nopt], "-help") == 0) {
         usage_3dTstat(strlen(argv[nopt]) > 3 ? 2:1);
         exit(0);
      }

      if( strcmp(argv[nopt],"-verb") == 0 ){
        verb++ ; nopt++ ; continue ;
      }
      
      /*-- methods --*/

      if( strcasecmp(argv[nopt],"-centromean") == 0 ){ /* 01 Nov 2010 */
         meth[nmeths++] = METH_CENTROMEAN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-bmv") == 0 ){
         meth[nmeths++] = METH_BMV ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-median") == 0 ){
         meth[nmeths++] = METH_MEDIAN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-nzmedian") == 0 ){
         meth[nmeths++] = METH_NZMEDIAN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-DW") == 0 ){
         meth[nmeths++] = METH_DW ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-zcount") == 0 ){
         meth[nmeths++] = METH_ZCOUNT ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-nzcount") == 0 ){
         meth[nmeths++] = METH_NZCOUNT ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-MAD") == 0 ){
         meth[nmeths++] = METH_MAD ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-mean") == 0 ){
         meth[nmeths++] = METH_MEAN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-sum") == 0 ){
         meth[nmeths++] = METH_SUM ;
         nbriks++ ;
         nopt++ ; continue ;
      }
      if( strcasecmp(argv[nopt],"-sos") == 0 ){
         meth[nmeths++] = METH_SUM_SQUARES ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-abssum") == 0 ){
         meth[nmeths++] = METH_ABSSUM ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-slope") == 0 ){
         meth[nmeths++] = METH_SLOPE ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-stdev") == 0 ||
          strcasecmp(argv[nopt],"-sigma") == 0   ){

         meth[nmeths++] = METH_SIGMA ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-cvar") == 0 ){
         meth[nmeths++] = METH_CVAR ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-cvarinv") == 0 ){
         meth[nmeths++] = METH_CVARINV ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-stdevNOD") == 0 ||
          strcasecmp(argv[nopt],"-sigmaNOD") == 0   ){  /* 07 Dec 2001 */

         meth[nmeths++] = METH_SIGMA_NOD ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-cvarNOD") == 0 ){     /* 07 Dec 2001 */
         meth[nmeths++] = METH_CVAR_NOD ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-cvarinvNOD") == 0 ){
         meth[nmeths++] = METH_CVARINVNOD ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-min") == 0 ){
         meth[nmeths++] = METH_MIN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-max") == 0 ){
         meth[nmeths++] = METH_MAX ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-absmax") == 0 ){
         meth[nmeths++] = METH_ABSMAX ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-signed_absmax") == 0 ){
         meth[nmeths++] = METH_SIGNED_ABSMAX ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argmin") == 0 ){
         meth[nmeths++] = METH_ARGMIN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argmin1") == 0 ){
         meth[nmeths++] = METH_ARGMIN1 ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argmax") == 0 ){
         meth[nmeths++] = METH_ARGMAX ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argmax1") == 0 ){
         meth[nmeths++] = METH_ARGMAX1 ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argabsmax") == 0 ){
         meth[nmeths++] = METH_ARGABSMAX ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-argabsmax1") == 0 ){
         meth[nmeths++] = METH_ARGABSMAX1;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-duration") == 0 ){
         meth[nmeths++] = METH_DURATION ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-onset") == 0 ){
         meth[nmeths++] = METH_ONSET ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-offset") == 0 ){
         meth[nmeths++] = METH_OFFSET ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-centroid") == 0 ){
         meth[nmeths++] = METH_CENTROID ;
         nbriks++ ;
         nopt++ ; continue ;
      }
      if( strcasecmp(argv[nopt],"-centduration") == 0 ){
         meth[nmeths++] = METH_CENTDURATION ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-nzmean") == 0 ){
         meth[nmeths++] = METH_NZMEAN ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      if( strncmp(argv[nopt],"-mask",5) == 0 ){
         if( mask_dset != NULL )
           ERROR_exit("Cannot have two -mask options!\n") ;
         if( nopt+1 >= argc )
           ERROR_exit("-mask option requires a following argument!\n");
         mask_dset = THD_open_dataset( argv[++nopt] ) ;
         if( mask_dset == NULL )
           ERROR_exit("Cannot open mask dataset!\n") ;
         if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex )
           ERROR_exit("Cannot deal with complex-valued mask dataset!\n");
         nopt++ ; continue ;
      }

      if( strncmp(argv[nopt],"-mrange",5) == 0 ){
         if( nopt+2 >= argc )
           ERROR_exit("-mrange option requires 2 following arguments!\n");
         mask_bot = strtod( argv[++nopt] , NULL ) ;
         mask_top = strtod( argv[++nopt] , NULL ) ;
         if( mask_top < mask_top )
           ERROR_exit("-mrange inputs are illegal!\n") ;
         nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-cmask") == 0 ){  /* 16 Mar 2000 */
         if( nopt+1 >= argc )
            ERROR_exit("-cmask option requires a following argument!\n");
         cmask = EDT_calcmask( argv[++nopt] , &ncmask, 0 ) ;
         if( cmask == NULL ) ERROR_exit("Can't compute -cmask!\n");
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-autocorr") == 0 ){
         meth[nmeths++] = METH_AUTOCORR ;
         if( ++nopt >= argc ) ERROR_exit("-autocorr needs an argument!\n");
         meth[nmeths++] = atoi(argv[nopt++]);
         if (meth[nmeths - 1] == 0) {
           addBriks++;
         } else {
           nbriks+=meth[nmeths - 1] ;
         }
         continue ;
      }

      if( strcasecmp(argv[nopt],"-autoreg") == 0 ){
         meth[nmeths++] = METH_AUTOREGP ;
         if( ++nopt >= argc ) ERROR_exit("-autoreg needs an argument!\n");
         meth[nmeths++] = atoi(argv[nopt++]);
         if (meth[nmeths - 1] == 0) {
           addBriks++;
         } else {
           nbriks+=meth[nmeths - 1] ;
         }
         continue ;
      }

      if( strcasecmp(argv[nopt],"-accumulate") == 0 ){  /* 4 Mar 2008 [rickr] */
         meth[nmeths++] = METH_ACCUMULATE ;
         meth[nmeths++] = -1;   /* flag to add N (not N-1) output bricks */
         fullBriks++;
         tsout = 1;             /* flag to output a timeseries */
         nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-l2norm") == 0 ){  /* 07 Jan 2013 [rickr] */
         meth[nmeths++] = METH_L2_NORM ;
         nbriks++ ;
         nopt++ ; continue ;
      }

      /*-- prefix --*/

      if( strcasecmp(argv[nopt],"-prefix") == 0 ){
         if( ++nopt >= argc ) ERROR_exit("-prefix needs an argument!\n");
         MCW_strncpy(prefix,argv[nopt],THD_MAX_PREFIX) ;
         if( !THD_filename_ok(prefix) )
           ERROR_exit("%s is not a valid prefix!\n",prefix);
         nopt++ ; continue ;
      }

      /*-- tdiff --*/

      if( strcasecmp(argv[nopt],"-tdiff") == 0 ){  /* 25 May 2011 */
        do_tdiff = 1 ; nopt++ ; continue ;
      }

      /*-- nscale --*/

      if( strcasecmp(argv[nopt],"-nscale") == 0 ){  /* 25 May 2011 */
        nscale = 1 ; nopt++ ; continue ;
      }
      
      /*-- datum --*/

      if( strcasecmp(argv[nopt],"-datum") == 0 ){
         if( ++nopt >= argc ) ERROR_exit("-datum needs an argument!\n");
         if( strcasecmp(argv[nopt],"short") == 0 ){
            datum = MRI_short ;
         } else if( strcasecmp(argv[nopt],"float") == 0 ){
            datum = MRI_float ;
         } else if( strcasecmp(argv[nopt],"byte") == 0 ){
            datum = MRI_byte ;
         } else {
            ERROR_exit("-datum of type '%s' is not supported!\n",
                       argv[nopt] ) ;
         }
         nopt++ ; continue ;
      }

     /* base percentage for duration calcs */
     if (strcasecmp (argv[nopt], "-basepercent") == 0) {
         if( ++nopt >= argc ) ERROR_exit("-basepercent needs an argument!\n");
         basepercent = strtod(argv[nopt], NULL);
         if(basepercent>1) basepercent /= 100.0;  /* assume integer percent if >1*/
         nopt++;  continue;
        }

      /*-- Quien sabe'? --*/

      ERROR_message("Unknown option: %s\n",argv[nopt]) ;
      suggest_best_prog_option(argv[0], argv[nopt]);
      exit(1);
   }

    if (argc < 2) {
      ERROR_message("Too few options, use -help for details");
      exit(1);
    }

   /*--- If no options selected, default to single stat MEAN -- KRH ---*/

   if (nmeths == 0) nmeths = 1;
   if (nbriks == 0 && addBriks == 0 && fullBriks == 0) nbriks = 1;

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

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

   old_dset = THD_open_dataset( argv[nopt] ) ;
   if( !ISVALID_DSET(old_dset) )
     ERROR_exit("Can't open dataset %s\n",argv[nopt]);

   nopt++ ;
   if( nopt < argc )
     WARNING_message("Trailing datasets on command line ignored: %s ...",argv[nopt]) ;

   if( DSET_NVALS(old_dset) == 1 ){
     WARNING_message("Input dataset has 1 sub-brick ==> -tdiff is turned off") ;
     do_tdiff = 0 ;
   }

   /* no input volumes is bad, 1 volume applies to only certain methods */
   /*                                                2 Nov 2010 [rickr] */
   if( DSET_NVALS(old_dset) == 0 ) {
      ERROR_exit("Time series is of length 0?\n") ;
   }
   else if( DSET_NVALS(old_dset) == 1 || (do_tdiff && DSET_NVALS(old_dset)==2) ) {
     int methOK, OK = 1;
     /* see if each method is valid for nvals == 1 */
     for( methIndex = 0; methIndex < nmeths; methIndex++ ) {
        methOK = 0;
        for( ii = 0; ii < NUM_1_INPUT_METHODS; ii++ ) {
            if( meth[methIndex] == valid_1_input_methods[ii] ) {
                methOK = 1;
                break;
            }
        }
        if( ! methOK )
           ERROR_exit("Can't use dataset with %d values per voxel!" ,
                      DSET_NVALS(old_dset) ) ;
     }
     /* tell the library function that this case is okay */
     g_thd_maker_allow_1brick = 1;
   }

   if( DSET_NUM_TIMES(old_dset) < 2 ){
     WARNING_message("Input dataset is not 3D+time; assuming TR=1.0") ;
     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 ) ;
   }

   /* If one or more of the -autocorr/-autoreg options was called with */
   /* an argument of 0, then I'll now add extra BRIKs for the N-1 data */
   /* output points for each.                                          */
   nbriks += ((DSET_NVALS(old_dset)-1) * addBriks);
   nbriks += ((DSET_NVALS(old_dset)  ) * fullBriks);

   /* ------------- Mask business -----------------*/
   if( mask_dset == NULL ){
      mmm = NULL ;
      if( verb )
         INFO_message("%d voxels in the entire dataset (no mask)\n",
                     DSET_NVOX(old_dset)) ;
   } else {
      if( DSET_NVOX(mask_dset) != DSET_NVOX(old_dset) )
        ERROR_exit("Input and mask datasets are not same dimensions!\n");
      mmm = THD_makemask( mask_dset , 0 , mask_bot, mask_top ) ;
      mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ;
      if( mcount <= 0 ) ERROR_exit("No voxels in the mask!\n") ;
      if( verb ) INFO_message("%d voxels in the mask\n",mcount) ;
      DSET_delete(mask_dset) ;
   }

   if( cmask != NULL ){
      if( ncmask != DSET_NVOX(old_dset) )
        ERROR_exit("Input and cmask datasets are not same dimensions!\n");
      if( mmm != NULL ){
         for( ii=0 ; ii < DSET_NVOX(old_dset) ; ii++ )
            mmm[ii] = (mmm[ii] && cmask[ii]) ;
         free(cmask) ;
         mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ;
         if( mcount <= 0 ) ERROR_exit("No voxels in the mask+cmask!\n") ;
         if( verb ) INFO_message("%d voxels in the mask+cmask\n",mcount) ;
      } else {
         mmm = cmask ;
         mcount = THD_countmask( DSET_NVOX(old_dset) , mmm ) ;
         if( mcount <= 0 ) ERROR_exit("No voxels in the cmask!\n") ;
         if( verb ) INFO_message("%d voxels in the cmask\n",mcount) ;
      }
   }

   /*------------- 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 */
                 STATS_tsfunc ,         /* timeseries processor */
                 NULL,                  /* data for tsfunc */
                 mmm,
                 nscale
              ) ;

   if( new_dset != NULL ){
      tross_Copy_History( old_dset , new_dset ) ;
      tross_Make_History( "3dTstat" , argc,argv , new_dset ) ;
      for (methIndex = 0,brikIndex = 0; methIndex < nmeths;
           methIndex++, brikIndex++) {
        if ((meth[methIndex] == METH_AUTOCORR)   ||
            (meth[methIndex] == METH_ACCUMULATE) ||
            (meth[methIndex] == METH_AUTOREGP)) {
          numMultBriks = meth[methIndex+1];

          /* note: this looks like it should be NV-1   4 Mar 2008 [rickr] */
          if (numMultBriks ==  0) numMultBriks = DSET_NVALS(old_dset)-1;
          /* new flag for NVALS [rickr] */
          if (numMultBriks == -1) numMultBriks = DSET_NVALS(old_dset);

          for (ii = 1; ii <= numMultBriks; ii++) {
            char tmpstr[25];
            if (meth[methIndex] == METH_AUTOREGP) {
              sprintf(tmpstr,"%s[%d](%d)",meth_names[meth[methIndex]],
                      numMultBriks,ii);
            } else {
              sprintf(tmpstr,"%s(%d)",meth_names[meth[methIndex]],ii);
            }
            EDIT_BRICK_LABEL(new_dset, (brikIndex + ii - 1), tmpstr) ;
          }
          methIndex++;
          brikIndex += numMultBriks - 1;
        } else {
          EDIT_BRICK_LABEL(new_dset, brikIndex, meth_names[meth[methIndex]]) ;
        }
      }

      if( tsout ) /* then change output to a time series */
         EDIT_dset_items( new_dset ,
                        ADN_ntt    , brikIndex ,
                        ADN_ttorg  , DSET_TIMEORIGIN(old_dset) ,
                        ADN_ttdel  , DSET_TIMESTEP(old_dset) ,
                        ADN_tunits , DSET_TIMEUNITS(old_dset) ,
                      NULL ) ;

      DSET_write( new_dset ) ;
      WROTE_DSET( new_dset ) ;
   } else {
      ERROR_exit("Unable to compute output dataset!\n") ;
   }

   exit(0) ;
}
Пример #21
0
int main( int argc , char *argv[] )
{
   int nopt , nbad=0 ; char *vlist, *expr , *mess ;
   int showgood=1;  /* 21 Mar 2016 [rickr] */

   /*-------------------------------------------------------------------------*/
   if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){
     printf("\n"
"The function of program GLTsymtest is to test a set of '-gltsym'\n"
"strings -- for use with 3dDeconvolve or 3dREMLfit -- for validity.\n"
"\n"
"Usage:  GLTsymtest [options] varlist expr [expr ...]\n"
"\n"
"   options (only 1 so far):\n"
"\n"
"      -badonly : output only BAD messages, rather than all\n"
"\n"
"* 'varlist' is a list of allowed variable names in the expression.\n"
"  These names can be separated by commans, semicolons, and/or\n"
"  spaces (varlist would have to be in quotes if it contains spaces).\n"
"\n"
"* Each 'expr' is a GLT symbolic expression, which should be in quotes\n"
"  since different components are separated by blanks.\n"
"\n"
"EXAMPLES\n"
"-------\n"
"  GLTsymtest -badonly 'Vrel Arel' 'Vrel -Arel' 'Verl + +aud'\n"
"\n"
"  GLTsymtest 'Vrel Arel' 'Vrel -Arel' 'Verl + +aud'\n"
"\n"
"  The first expression is good, but the second has both variable names\n"
"  mis-typed; the output from this program would include these messages:\n"
"\n"
"    ***** Scanned GLT messages *****\n"
"    ++ -gltsym is: 'Vrel -Arel'\n"
"    ++ INFO: Allowed variable list is 'Vrel Arel'\n"
"    ++ INFO: This gltsym appears to be OKAY :-)\n"
"\n"
"    ***** Scanned GLT messages *****\n"
"    ++ -gltsym is: 'Verl + +aud'\n"
"    ++ INFO: Allowed variable list is 'Vrel Arel'\n"
"    ++ INFO: -gltsym: isolated '+' is being ignored\n"
"    ** ERROR: -gltsym: can't match symbolic name 'Verl'\n"
"    ** ERROR: -gltsym: can't match symbolic name 'aud'\n"
"    ** SORRY: This gltsym appears to be BAD :-(\n"
"\n"
"NOTES\n"
"-----\n"
"* GLTsymtest does not check subscripts on variable names against the legal\n"
"  range for the name, since the information about the dimensionality of\n"
"  the beta vector associated with each name is not available here.\n"
"\n"
"* The exit status for this program is the number of expressions that had\n"
"  at least one ERROR message.  In the example above, this status would be 1.\n"
"\n"
"* The text output goes to stdout.\n"
"\n"
"\n"
"* Authored by RWCox on May Day 2015 to aid Rick Reynolds in detecting such\n"
"  problems, induced for example when his boss does someting stupid during\n"
"  an AFNI bootcamp in South Africa (a purely hypothetical case, I assure you).\n"
"\n"
     ) ;
     exit(0) ;
   }
   /*-------------------------------------------------------------------------*/

   mainENTRY("GLTsymtest"); machdep();

   /* 21 Mar 2016 */
   for( nopt=1; nopt < argc; nopt++ ) {
      if( ! strcmp(argv[nopt], "-badonly" ) ) showgood = 0;
      else break;
   }

   if( argc-nopt < 2 )
     ERROR_exit("GLTsymtest: missing labels or GLTs (too few args)") ;

   vlist = argv[nopt] ;
   for( nopt++ ; nopt < argc ; nopt++ ){
     expr = argv[nopt] ;
     mess = SYM_test_gltsym(vlist,expr) ;
     if( mess != NULL ){
       if( strstr(mess,"** ERROR:") != NULL ) {
          nbad++ ;
          puts(mess) ;
       } else if ( showgood )
          puts(mess) ;
       free(mess) ;
     }
   }

   exit(nbad) ;
}
int main( int argc , char *argv[] )
{
    char *prefix = "Deghost" ;
    int iarg ;
    int fe=1 , pe=2 , se=3 , nvals ;
    THD_3dim_dataset *inset=NULL , *outset , *filset=NULL ;

    if( argc < 2 || strcmp(argv[1],"-help") == 0 ) {
        printf(
            "Usage: 3dDeghost [options] dataset\n"
            "\n"
            "* This program tries do remove N/2 (AKA Nyquist) ghosts from an EPI\n"
            "  magnitude time series dataset.\n"
            "* If you apply it to some other kind of dataset (e.g., spiral), weird\n"
            "  things will probably transpire.\n"
            "* The input EPI dataset should NOT be filtered, masked, cropped,\n"
            "  registered, or pre-processed in any way!\n"
            "* This program will not work well if the input EPI dataset is heavily\n"
            "  'shaded' -- that is, its intensity varies dramatically inside the brain.\n"
            "* The output dataset is always stored in float format.\n"
            "* Only the Amitabha Buddha knows if this program is actually useful.\n"
            "\n"
            "========\n"
            "OPTIONS:\n"
            "========\n"
            "  -input dataset = Another way to specify the input dataset\n"
            "  -prefix pp     = Use 'pp' for prefix of output dataset\n"
            "  -FPS abc       = Define the Frequency, Phase, and Slice\n"
            "                   directions in the dataset based on the\n"
            "                   axis orientations inside the dataset header\n"
            "                   (e.g., see the output of 3dinfo).  The 'abc'\n"
            "                   code is a permutaton of the digits '123'.\n"
            "                 *  The first digit 'a' specifies which dataset\n"
            "                    axis/index is the Frequency encoding direction.\n"
            "                 *  The second digit 'b' specifies which dataset\n"
            "                    direction is the Phase encoding direction.\n"
            "                 *  The third digit 'c' specifies which dataset\n"
            "                    direction is the Slice encoding direction.\n"
            "             -->>** The default value for 'abc' is '123'; that is,\n"
            "                    the dataset is ordered so that the first index\n"
            "                    (x-axis) is frequency, the second index is phase,\n"
            "                    and the third index is slice.  In most cases,\n"
            "                    this is how the reconstruction software will\n"
            "                    store the images.  Only in unusual cases should\n"
            "                    you need the '-FPS' option!\n"
            "  -filt N        = Length of time series filter to apply when\n"
            "                    estimating ghosting parameters.  Set N to 0 or 1\n"
            "                    to turn this feature off; otherwise, N should be an\n"
            "                    odd positive integer from 3 to 19 [default N=%d].\n"
            "                 * Longer filter lengths ARE allowed, but will be slow\n"
            "                    (cases with N <= 19 are hand coded for speed).\n"
            "                 * Datasets with fewer than 4 time points will not\n"
            "                    be filtered.  For longer datasets, if the filter\n"
            "                    length is too big, it will be shortened ruthlessly.\n"
            "=======\n"
            "METHOD:\n"
            "=======\n"
            "Would you believe me if I said magic? Would you accept secret algorithms\n"
            "known only to the Olmecs? How about something so ad hoc that it cannot\n"
            "be described without embarrasment and shame?\n"
            "\n"
            "-- Feb 2014 - Zhark the Phantasmal\n"
            , orfilt_len
        ) ;
        PRINT_COMPILE_DATE ;
        exit(0) ;
    }

    mainENTRY("3dDeghost main");
    machdep();
    AFNI_logger("3dDeghost",argc,argv);
    PRINT_VERSION("3dDeghost") ;

    /*-- scan command line --*/

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

        /*---*/

        if( strcasecmp(argv[iarg],"-quiet") == 0 ) {
            verb = 0 ;
            iarg++ ;
            continue ;
        }
        if( strcasecmp(argv[iarg],"-verb") == 0 ) {
            verb++ ;
            iarg++ ;
            continue ;
        }

        /*---*/

        if( strcasecmp(argv[iarg],"-filt") == 0 ) {
            if( ++iarg >= argc )
                ERROR_exit("Need argument after option '%s'",argv[iarg-1]) ;
            orfilt_len = (int)strtod(argv[iarg],NULL) ;
            if( orfilt_len > 1 && orfilt_len%2 == 0 ) {
                orfilt_len++ ;
                INFO_message("-filt %d has been adjusted to %d (must be odd)" ,
                             orfilt_len-1 , orfilt_len) ;
            }
            if( orfilt_len > 19 )
                WARNING_message("-filt %d is over the recommended limit of 19",orfilt_len) ;
            iarg++ ;
            continue ;
        }

        /*---*/

        if( strcasecmp(argv[iarg],"-prefix") == 0 ) {
            if( ++iarg >= argc )
                ERROR_exit("Need argument after option '%s'",argv[iarg-1]) ;
            prefix = argv[iarg] ;
            if( !THD_filename_ok(prefix) )
                ERROR_exit("Illegal value after -prefix!\n");
            iarg++ ;
            continue ;
        }

        /*---*/

        if( strcasecmp(argv[iarg],"-input") == 0 || strcasecmp(argv[iarg],"-inset") == 0 ) {
            if( ++iarg >= argc )
                ERROR_exit("Need argument after option '%s'",argv[iarg-1]) ;
            if( inset != NULL )
                ERROR_exit("You can't give the input dataset twice!") ;
            inset = THD_open_dataset( argv[iarg] ) ;
            CHECK_OPEN_ERROR(inset,argv[iarg]) ;
            DSET_load(inset) ;
            CHECK_LOAD_ERROR(inset) ;
            iarg++ ;
            continue ;
        }

        /*---*/

        if( strcasecmp(argv[iarg],"-FPS") == 0 ) { /* stolen from 3dAllineate.c */
            char *fps ;
            if( ++iarg >= argc )
                ERROR_exit("Need argument after option '%s'",argv[iarg-1]) ;
            fps = argv[iarg] ;
            if( strlen(fps) < 3 ) ERROR_exit("Code '%s' after '%s' is too short",
                                                 fps , argv[iarg-1] ) ;
            switch( fps[0] ) {
            default:
                ERROR_exit("Illegal '%s' F code '%c' :-(" , argv[iarg-1],fps[0] );
            case 'i':
            case 'I':
            case 'x':
            case 'X':
            case '1':
                fe = 1;
                break;
            case 'j':
            case 'J':
            case 'y':
            case 'Y':
            case '2':
                fe = 2;
                break;
            case 'k':
            case 'K':
            case 'z':
            case 'Z':
            case '3':
                fe = 3;
                break;
            }
            switch( fps[1] ) {
            default:
                ERROR_exit("Illegal '%s' P code '%c' :-(" , argv[iarg-1],fps[1] );
            case 'i':
            case 'I':
            case 'x':
            case 'X':
            case '1':
                pe = 1;
                break;
            case 'j':
            case 'J':
            case 'y':
            case 'Y':
            case '2':
                pe = 2;
                break;
            case 'k':
            case 'K':
            case 'z':
            case 'Z':
            case '3':
                pe = 3;
                break;
            }
            switch( fps[2] ) {
            default:
                ERROR_exit("Illegal '%s' S code '%c' :-(" , argv[iarg-1],fps[2] );
            case 'i':
            case 'I':
            case 'x':
            case 'X':
            case '1':
                se = 1;
                break;
            case 'j':
            case 'J':
            case 'y':
            case 'Y':
            case '2':
                se = 2;
                break;
            case 'k':
            case 'K':
            case 'z':
            case 'Z':
            case '3':
                se = 3;
                break;
            }
            if( fe+pe+se != 6 ) ERROR_exit("Code '%s' after '%s' is nonsensical",
                                               fps , argv[iarg-1] ) ;
            iarg++ ;
            continue ;
        }

        /*---*/

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

    if( inset == NULL && iarg >= argc )
        ERROR_exit("No dataset name on command line?\n");

    /*-- read input if needed --*/

    if( inset == NULL ) {
        inset = THD_open_dataset( argv[iarg] ) ;
        CHECK_OPEN_ERROR(inset,argv[iarg]) ;
        DSET_load( inset ) ;
        CHECK_LOAD_ERROR(inset) ;
    }

    /*-- filter input? --*/

    nvals = DSET_NVALS(inset) ;
    if( orfilt_len > nvals/2 ) {
        orfilt_len = nvals/2 ;
        if( orfilt_len%2 == 0 ) orfilt_len++ ;
    }

    if( orfilt_len > 1 && nvals > 1 ) {
        MRI_vectim *invect ;
        int ii ;
        if( verb )
            INFO_message("Filtering input dataset: filter length=%d",orfilt_len) ;
        invect = THD_dset_to_vectim(inset,NULL,0) ;
        THD_vectim_applyfunc( invect , orfilt_vector ) ;
        filset = EDIT_empty_copy( inset ) ;
        for( ii=0 ; ii < nvals ; ii++ )
            EDIT_substitute_brick( filset , ii , MRI_float , NULL ) ;
        THD_vectim_to_dset( invect , filset ) ;
        VECTIM_destroy(invect) ;
    } else {
        if( verb )
            INFO_message("Time series filtering is turned off") ;
    }

    /***** outsource the work *****/

    outset = THD_deghoster( inset , (filset!=NULL)?filset:inset , pe,fe,se ) ;
    if( outset == NULL ) ERROR_exit("THD_deghoster fails :-(((") ;
    if( filset != NULL ) DSET_delete(filset) ;

    EDIT_dset_items( outset , ADN_prefix,prefix , ADN_none ) ;
    tross_Copy_History( inset , outset ) ;
    tross_Make_History( "3dDeghost" , argc,argv , outset ) ;
    DSET_write(outset) ;
    WROTE_DSET(outset) ;
    exit(0) ;
}
Пример #23
0
int main(int argc, char **argv)
{
   char *ppp=NULL , *sin ;
   int ii, iarg=1 , do_sin=0 , do_printf=0 , do_mul=0 , do_length=1 ;
   int do_stimes=0, do_stimes_verb=0 ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf("Usage: dicom_hdr [options] fname [...]\n"
            "Prints information from the DICOM file 'fname' to stdout.\n"
            "Multiple files can be given on the command line.\n"
            "\n"
            "OPTIONS:\n"
            " -hex     = Include hexadecimal printout for integer values.\n"
            " -noname  = Don't include element names in the printout.\n"
            " -sexinfo = Dump Siemens EXtra INFO text (0029 1020), if present\n"
            "             (can be VERY lengthy).\n"
            " -mulfram = Dump multi-frame information, if present\n"
            "             (1 line per frame, plus an XML-style header/footer)\n"
            "             [-mulfram also implies -noname]\n"
            " -v n     = Dump n words of binary data also.\n"
#if 0
            " -printf  = Use 'printf' directly, instead of an intermediate string.\n"
#endif
            "\n"
            " -no_length        = Skip lengths and offsets (helps diffs).\n"
            " -slice_times      = Show slice times from Siemens mosaic images.\n"
            " -slice_times_verb = Same, but be more verbose about it.\n"
            "\n"
            "Based on program dcm_dump_file from the RSNA, developed at\n"
            "the Mallinckrodt Institute of Radiology.  See the source\n"
            "code file mri_dicom_hdr.c for their Copyright and license.\n"
            "\n"
            "SOME SAMPLE OUTPUT LINES:\n"
            "\n"
            "0028 0010      2 [1234   ] //              IMG Rows// 512\n"
            "0028 0011      2 [1244   ] //           IMG Columns// 512\n"
            "0028 0030     18 [1254   ] //     IMG Pixel Spacing//0.488281\\0.488281\n"
            "0028 0100      2 [1280   ] //    IMG Bits Allocated// 16\n"
            "0028 0101      2 [1290   ] //       IMG Bits Stored// 12\n"
            "0028 0102      2 [1300   ] //          IMG High Bit// 11\n"
            "\n"
            "* The first 2 numbers on each line are the DICOM group and element tags,\n"
            "   in hexadecimal.\n"
            "* The next number is the number of data bytes, in decimal.\n"
            "* The next number [in brackets] is the offset in the file of the data,\n"
            "   in decimal.  This is where the data bytes start, and does not include\n"
            "   the tag, Value Representation, etc.\n"
            "* If -noname is NOT given, then the string in the '// ... //' region is\n"
            "   the standard DICOM dictionary name for this data element.  If this string\n"
            "   is blank, then this element isn't in the dictionary (e.g., is a private\n"
            "   tag, or an addition to DICOM that the program doesn't know about, etc.).\n"
            "* The value after the last '//' is the value of the data in the element.\n"
            "* In the example above, we have a 512x512 image with 0.488281 mm pixels,\n"
            "   with 12 bits (stored in 16 bits) per pixel.\n"
            "* For vastly more detail on DICOM standard, you can start with the\n"
            "   documents at ftp://afni.nimh.nih.gov/dicom/ (1000+ pages of PDF)!\n"
            "* Also see program dicom_hinfo -- which will print out just a few user-chosen\n"
            "   values for each input file.  It can be used in a script to sort through\n"
            "   a lot of files at once.\n"
           );
     exit(0);
   }

   mainENTRY("dicom_hdr main") ; machdep() ;

   mri_dicom_nohex( 1 ) ;

   while( argv[iarg] && argv[iarg][0] == '-' ){

     if( strcmp(argv[iarg],"-sexinfo") == 0 ){  /* 23 Dec 2002 */
       do_sin++ ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-printf") == 0 ){  /* 02 May 2008 */
       do_printf++ ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-no_length") == 0 ){  /* 17 Oct 2012 [rickr] */
       do_length = 0 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-mulfram",4) == 0 ){  /* 05 May 2008 */
       mri_dicom_noname(1) ; do_mul++ ; iarg++ ; continue ;
     }

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

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

     if( strcmp(argv[iarg],"-slice_times") == 0 ){  /* 14 Apr 2010 [rickr] */
       do_stimes++ ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-slice_times_verb") == 0 ){ /* 15 Apr 2010 */
       do_stimes++ ;    /* redundant, but for complete output */
       do_stimes_verb++ ; iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-v") == 0 ){
       int vv = strtol( argv[++iarg] , NULL , 10 ) ;
       if( vv > 0 ) mri_dicom_setvm( vv ) ;
       else         fprintf(stderr,"*** Illegal value after -v!\n") ;
       iarg++ ; continue ;
     }

     fprintf(stderr,"*** Unknown option: %s\n",argv[iarg]) ; iarg++ ;
   }

   if( iarg == argc ) { fprintf(stderr,"** no input files?\n"); return 0; }

   mri_dicom_header_use_printf(do_printf) ;  /* 02 May 2008 */
   mri_dicom_header_show_size_offset(do_length) ; /* 17 Oct 2012 [rickr] */
   if( do_stimes_verb ) mri_sst_set_verb(1+do_stimes_verb); /* 02 May 2011 */

   for( ii=iarg ; ii < argc ; ii++ ){
     if( ii > iarg )
       printf("---------------------------------------------------------------\n");

     mri_dicom_seterr(-1) ;  /* make sure all errors are printed - 07 May 2003 */
STATUS("calling funct mri_dicom_header()") ;
     if( ppp != NULL ) free(ppp) ;
     ppp = mri_dicom_header( argv[ii] ) ;

     /* show slice times (in lieu of header)    14 Apr 2011 [rickr] */
     if( do_stimes ) { get_and_display_siemens_times(); continue; }

     if( !do_printf && ppp != NULL ){
       off_t poff ; unsigned int plen ;
       printf("%s",ppp) ;
       mri_dicom_pxlarr( &poff , &plen ) ;
       if( plen > 0 )
         printf("Pixel array offset = %u (bytes)\n"
                "Pixel array length = %u (bytes)\n" ,
                (unsigned int)poff , plen ) ;
       if( do_sin ){
         (void) mri_imcount_dicom( argv[ii] ) ;  /* only to get the sexinfo */
         sin = mri_dicom_sexinfo() ;
         if( sin ){
           printf("................... Siemens Extra Info [0029 1020] ...................\n"
                  "%s\n" , sin ) ;
         } else {
           printf("........... Siemens Extra Info [0029 1020] = NOT PRESENT .............\n");
         }
       }
       if( do_mul ){  /* 05 May 2008 */
         MultiFrame_info *mfi = AFD_scanfor_MultiFrame(ppp) ;
         if( mfi != NULL ){
           int nz = mfi->nframe , jj ;
           printf("........... DICOM MultiFrame Information          ...........\n");
           printf("........... time_index stack_index xpos ypos zpos ...........\n");
           printf("<DICOM_MultiFrame nframe='%d'>\n",nz) ;
           for( jj=0 ; jj < nz ; jj++ ){
             printf(" %4d %4d" , mfi->time_index[jj] , mfi->stack_index[jj] ) ;
             if( mfi->xpos != NULL )
               printf("  %.3f %.3f %.3f",mfi->xpos[jj],mfi->ypos[jj],mfi->zpos[jj]);
             printf("\n") ;
           }
           printf("</DICOM_MultiFrame>\n") ;
           KILL_MultiFrame(mfi) ;
         } else {
           printf("........... DICOM MultiFrame Information = ABSENT ...........\n");
         }
       }
     } else if( !do_printf ) {
       printf("***\n*** ERROR: can't open %s as a DICOM file!\n***\n",argv[ii]) ;
     }
   }
   exit(0) ;
}
Пример #24
0
int main( int argc , char * argv[] )
{
   int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ;
   float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ;
   MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ;
   THD_3dim_dataset **ortset=NULL ; int nortset=0 ;
   THD_3dim_dataset *inset=NULL , *outset=NULL;
   char *prefix="RSFC" ;
   byte *mask=NULL ;
   int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , 
		nx,ny,nz,nvox , nfft=0 , kk ;
   float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime  ;
   MRI_vectim *mrv ;
   float pvrad=0.0f ; int nosat=0 ;
   int do_despike=0 ;

	// @@ non-BP variables
	float fbotALL=0.0f, ftopALL=999999.9f; // do full range version
	int NumDen = 0; // switch for doing numerator or denom
	THD_3dim_dataset *outsetALL=NULL ; 	
	int m, mm;
	float delf; // harmonics
	int ind_low,ind_high,N_ny, ctr;
	float sqnt,nt_fac;
	gsl_fft_real_wavetable *real1, *real2; // GSL stuff
	gsl_fft_real_workspace *work;
	double *series1, *series2;	
	double *xx1,*xx2;
	float numer,denom,val;
	float *alff=NULL,*malff=NULL,*falff=NULL,
         *rsfa=NULL,*mrsfa=NULL,*frsfa=NULL; // values
	float meanALFF=0.0f,meanRSFA=0.0f; // will be for mean in brain region
	THD_3dim_dataset *outsetALFF=NULL;
	THD_3dim_dataset *outsetmALFF=NULL;
	THD_3dim_dataset *outsetfALFF=NULL;
	THD_3dim_dataset *outsetRSFA=NULL;
	THD_3dim_dataset *outsetmRSFA=NULL;
	THD_3dim_dataset *outsetfRSFA=NULL;
	char out_lff[300];
	char out_alff[300];
	char out_malff[300];
	char out_falff[300];
	char out_rsfa[300];
	char out_mrsfa[300];
	char out_frsfa[300];
	char out_unBP[300];
	int SERIES_OUT = 1;
	int UNBP_OUT = 0; 
	int DO_RSFA = 1;
	int BP_LAST = 0; // option for only doing filter to LFFs at very end of proc
	float de_rsfa=0.0f,nu_rsfa=0.0f;
	double pow1=0.0,pow2=0.0;

   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
		printf(
"\n  Program to calculate common resting state functional connectivity (RSFC)\n"
"  parameters (ALFF, mALFF, fALFF, RSFA, etc.) for resting state time\n"
"  series.  This program is **heavily** based on the existing\n"
"  3dBandPass by RW Cox, with the amendments to calculate RSFC\n"
"  parameters written by PA Taylor (July, 2012).\n"
"  This program is part of FATCAT (Taylor & Saad, 2013) in AFNI. Importantly,\n"
"  its functionality can be included in the `afni_proc.py' processing-script \n"
"  generator; see that program's help file for an example including RSFC\n"
"  and spectral parameter calculation via the `-regress_RSFC' option.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
"  All options of 3dBandPass may be used here (with a couple other\n"
"  parameter options, as well): essentially, the motivation of this\n"
"  program is to produce ALFF, etc. values of the actual RSFC time\n"
"  series that you calculate.  Therefore, all the 3dBandPass processing\n"
"  you normally do en route to making your final `resting state time\n"
"  series' is done here to generate your LFFs, from which the\n"
"  amplitudes in the LFF band are calculated at the end.  In order to\n"
"  calculate fALFF, the same initial time series are put through the\n"
"  same processing steps which you have chosen but *without* the\n"
"  bandpass part; the spectrum of this second time series is used to\n"
"  calculate the fALFF denominator.\n"
" \n"
"  For more information about each RSFC parameter, see, e.g.:   \n"
"  ALFF/mALFF -- Zang et al. (2007),\n"
"  fALFF --      Zou et al. (2008),\n"
"  RSFA --       Kannurpatti & Biswal (2008).\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
" + USAGE: 3dRSFC [options] fbot ftop dataset\n"
"\n"
"* One function of this program is to prepare datasets for input\n"
"   to 3dSetupGroupInCorr.  Other uses are left to your imagination.\n"
"\n"
"* 'dataset' is a 3D+time sequence of volumes\n"
"   ++ This must be a single imaging run -- that is, no discontinuities\n"
"       in time from 3dTcat-ing multiple datasets together.\n"
"\n"
"* fbot = lowest frequency in the passband, in Hz\n"
"   ++ fbot can be 0 if you want to do a lowpass filter only;\n"
"       HOWEVER, the mean and Nyquist freq are always removed.\n"
"\n"
"* ftop = highest frequency in the passband (must be > fbot)\n"
"   ++ if ftop > Nyquist freq, then it's a highpass filter only.\n"
"\n"
"* Set fbot=0 and ftop=99999 to do an 'allpass' filter.\n"
"  ++ Except for removal of the 0 and Nyquist frequencies, that is.\n"
"\n"
"* You cannot construct a 'notch' filter with this program!\n"
"  ++ You could use 3dRSFC followed by 3dcalc to get the same effect.\n"
"  ++ If you are understand what you are doing, that is.\n"
"  ++ Of course, that is the AFNI way -- if you don't want to\n"
"     understand what you are doing, use Some other PrograM, and\n"
"     you can still get Fine StatisticaL maps.\n"
"\n"
"* 3dRSFC will fail if fbot and ftop are too close for comfort.\n"
"  ++ Which means closer than one frequency grid step df,\n"
"     where df = 1 / (nfft * dt) [of course]\n"
"\n"
"* The actual FFT length used will be printed, and may be larger\n"
"   than the input time series length for the sake of efficiency.\n"
"  ++ The program will use a power-of-2, possibly multiplied by\n"
"     a power of 3 and/or 5 (up to and including the 3rd power of\n"
"     each of these: 3, 9, 27, and 5, 25, 125).\n"
"\n"
"* Note that the results of combining 3dDetrend and 3dRSFC will\n"
"   depend on the order in which you run these programs.  That's why\n"
"   3dRSFC has the '-ort' and '-dsort' options, so that the\n"
"   time series filtering can be done properly, in one place.\n"
"\n"
"* The output dataset is stored in float format.\n"
"\n"
"* The order of processing steps is the following (most are optional), and\n"
"  for the LFFs, the bandpass is done between the specified fbot and ftop,\n"
"  while for the `whole spectrum' (i.e., fALFF denominator) the bandpass is:\n"
"  done only to exclude the time series mean and the Nyquist frequency:\n"
" (0) Check time series for initial transients [does not alter data]\n"
" (1) Despiking of each time series\n"
" (2) Removal of a constant+linear+quadratic trend in each time series\n"
" (3) Bandpass of data time series\n"
" (4) Bandpass of -ort time series, then detrending of data\n"
"      with respect to the -ort time series\n"
" (5) Bandpass and de-orting of the -dsort dataset,\n"
"      then detrending of the data with respect to -dsort\n"
" (6) Blurring inside the mask [might be slow]\n"
" (7) Local PV calculation     [WILL be slow!]\n"
" (8) L2 normalization         [will be fast.]\n"
" (9) Calculate spectrum and amplitudes, for RSFC parameters.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"--------\n"
"OPTIONS:\n"
"--------\n"
" -despike        = Despike each time series before other processing.\n"
"                   ++ Hopefully, you don't actually need to do this,\n"
"                      which is why it is optional.\n"
" -ort f.1D       = Also orthogonalize input to columns in f.1D\n"
"                   ++ Multiple '-ort' options are allowed.\n"
" -dsort fset     = Orthogonalize each voxel to the corresponding\n"
"                    voxel time series in dataset 'fset', which must\n"
"                    have the same spatial and temporal grid structure\n"
"                    as the main input dataset.\n"
"                   ++ At present, only one '-dsort' option is allowed.\n"
" -nodetrend      = Skip the quadratic detrending of the input that\n"
"                    occurs before the FFT-based bandpassing.\n"
"                   ++ You would only want to do this if the dataset\n"
"                      had been detrended already in some other program.\n"
" -dt dd          = set time step to 'dd' sec [default=from dataset header]\n"
" -nfft N         = set the FFT length to 'N' [must be a legal value]\n"
" -norm           = Make all output time series have L2 norm = 1\n"
"                   ++ i.e., sum of squares = 1\n"
" -mask mset      = Mask dataset\n"
" -automask       = Create a mask from the input dataset\n"
" -blur fff       = Blur (inside the mask only) with a filter\n"
"                    width (FWHM) of 'fff' millimeters.\n"
" -localPV rrr    = Replace each vector by the local Principal Vector\n"
"                    (AKA first singular vector) from a neighborhood\n"
"                    of radius 'rrr' millimiters.\n"
"                   ++ Note that the PV time series is L2 normalized.\n"
"                   ++ This option is mostly for Bob Cox to have fun with.\n"
"\n"
" -input dataset  = Alternative way to specify input dataset.\n"
" -band fbot ftop = Alternative way to specify passband frequencies.\n"
"\n"
" -prefix ppp     = Set prefix name of output dataset. Name of filtered time\n"
"                   series would be, e.g., ppp_LFF+orig.*, and the parameter\n"
"                   outputs are named with obvious suffices.\n"
" -quiet          = Turn off the fun and informative messages. (Why?)\n"
" -no_rs_out      = Don't output processed time series-- just output\n"
"                   parameters (not recommended, since the point of\n"
"                   calculating RSFC params here is to have them be quite\n"
"                   related to the time series themselves which are used for\n"
"                   further analysis)."
" -un_bp_out      = Output the un-bandpassed series as well (default is not \n"
"                   to).  Name would be, e.g., ppp_unBP+orig.* .\n"
"                   with suffix `_unBP'.\n"
" -no_rsfa        = If you don't want RSFA output (default is to do so).\n"
" -bp_at_end      = A (probably unnecessary) switch to have bandpassing be \n"
"                   the very last processing step that is done in the\n"
"                   sequence of steps listed above; at Step 3 above, only \n"
"                   the time series mean and nyquist are BP'ed out, and then\n"
"                   the LFF series is created only after Step 9.  NB: this \n"
"                   probably makes only very small changes for most\n"
"                   processing sequences (but maybe not, depending usage).\n"
"\n"
" -notrans        = Don't check for initial positive transients in the data:\n"
"  *OR*             ++ The test is a little slow, so skipping it is OK,\n"
" -nosat               if you KNOW the data time series are transient-free.\n"
"                   ++ Or set AFNI_SKIP_SATCHECK to YES.\n"
"                   ++ Initial transients won't be handled well by the\n"
"                      bandpassing algorithm, and in addition may seriously\n"
"                      contaminate any further processing, such as inter-\n"
"                      voxel correlations via InstaCorr.\n"
"                   ++ No other tests are made [yet] for non-stationary \n"
"                      behavior in the time series data.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
"  If you use this program, please reference the introductory/description\n"
"  paper for the FATCAT toolbox:\n"
"        Taylor PA, Saad ZS (2013).  FATCAT: (An Efficient) Functional\n"
"        And Tractographic Connectivity Analysis Toolbox. Brain \n"
"        Connectivity 3(5):523-535.\n"
"____________________________________________________________________________\n"
);
		PRINT_AFNI_OMP_USAGE(
" 3dRSFC" ,
" * At present, the only part of 3dRSFC that is parallelized is the\n"
"   '-blur' option, which processes each sub-brick independently.\n"
									) ;
		PRINT_COMPILE_DATE ; exit(0) ;
   }
	
   /*-- startup --*/
	
   mainENTRY("3dRSFC"); machdep();
   AFNI_logger("3dRSFC",argc,argv);
   PRINT_VERSION("3dRSFC (from 3dBandpass by RW Cox): version THETA"); 
	AUTHOR("PA Taylor");
	
   nosat =  AFNI_yesenv("AFNI_SKIP_SATCHECK") ;
	
   nopt = 1 ;
   while( nopt < argc && argv[nopt][0] == '-' ){

		if( strcmp(argv[nopt],"-despike") == 0 ){  /* 08 Oct 2010 */
			do_despike++ ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-nfft") == 0 ){
			int nnup ;
			if( ++nopt >= argc ) ERROR_exit("need an argument after -nfft!") ;
			nfft = (int)strtod(argv[nopt],NULL) ;
			nnup = csfft_nextup_even(nfft) ;
			if( nfft < 16 || nfft != nnup )
				ERROR_exit("value %d after -nfft is illegal! Next legal value = %d",nfft,nnup) ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-blur") == 0 ){
			if( ++nopt >= argc ) ERROR_exit("need an argument after -blur!") ;
			blur = strtod(argv[nopt],NULL) ;
			if( blur <= 0.0f ) WARNING_message("non-positive blur?!") ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-localPV") == 0 ){
			if( ++nopt >= argc ) ERROR_exit("need an argument after -localpv!") ;
			pvrad = strtod(argv[nopt],NULL) ;
			if( pvrad <= 0.0f ) WARNING_message("non-positive -localpv?!") ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-prefix") == 0 ){
			if( ++nopt >= argc ) ERROR_exit("need an argument after -prefix!") ;
			prefix = strdup(argv[nopt]) ;
			if( !THD_filename_ok(prefix) ) ERROR_exit("bad -prefix option!") ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-automask") == 0 ){
			if( mask != NULL ) ERROR_exit("Can't use -mask AND -automask!") ;
			do_automask = 1 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-mask") == 0 ){
			THD_3dim_dataset *mset ;
			if( ++nopt >= argc ) ERROR_exit("Need argument after '-mask'") ;
			if( mask != NULL || do_automask ) ERROR_exit("Can't have two mask inputs") ;
			mset = THD_open_dataset( argv[nopt] ) ;
			CHECK_OPEN_ERROR(mset,argv[nopt]) ;
			DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ;
			mask_nx = DSET_NX(mset); mask_ny = DSET_NY(mset); mask_nz = DSET_NZ(mset);
			mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ;
			if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[nopt]) ;
			nmask = THD_countmask( mask_nx*mask_ny*mask_nz , mask ) ;
			if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ;
			if( nmask < 1 ) ERROR_exit("Mask is too small to process") ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-norm") == 0 ){
			do_norm = 1 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-quiet") == 0 ){
			verb = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-no_rs_out") == 0 ){ // @@
			SERIES_OUT = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-un_bp_out") == 0 ){ // @@
			UNBP_OUT = 1 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-no_rsfa") == 0 ){ // @@
			DO_RSFA = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-bp_at_end") == 0 ){ // @@
			BP_LAST = 1 ; nopt++ ; continue ;
		}




		if( strcmp(argv[nopt],"-notrans") == 0 || strcmp(argv[nopt],"-nosat") == 0 ){
			nosat = 1 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-ort") == 0 ){
			if( ++nopt >= argc ) ERROR_exit("need an argument after -ort!") ;
			if( ortar == NULL ) INIT_IMARR(ortar) ;
			ortim = mri_read_1D( argv[nopt] ) ;
			if( ortim == NULL ) ERROR_exit("can't read from -ort '%s'",argv[nopt]) ;
			mri_add_name(argv[nopt],ortim) ;
			ADDTO_IMARR(ortar,ortim) ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-dsort") == 0 ){
			THD_3dim_dataset *qset ;
			if( ++nopt >= argc ) ERROR_exit("need an argument after -dsort!") ;
			if( nortset > 0 ) ERROR_exit("only 1 -dsort option is allowed!") ;
			qset = THD_open_dataset(argv[nopt]) ;
			CHECK_OPEN_ERROR(qset,argv[nopt]) ;
			ortset = (THD_3dim_dataset **)realloc(ortset,
															  sizeof(THD_3dim_dataset *)*(nortset+1)) ;
			ortset[nortset++] = qset ;
			nopt++ ; continue ;
		}

		if( strncmp(argv[nopt],"-nodetrend",6) == 0 ){
			qdet = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-dt") == 0 ){
			if( ++nopt >= argc ) ERROR_exit("need an argument after -dt!") ;
			dt = (float)strtod(argv[nopt],NULL) ;
			if( dt <= 0.0f ) WARNING_message("value after -dt illegal!") ;
			nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-input") == 0 ){
			if( inset != NULL ) ERROR_exit("Can't have 2 -input options!") ;
			if( ++nopt >= argc ) ERROR_exit("need an argument after -input!") ;
			inset = THD_open_dataset(argv[nopt]) ;
			CHECK_OPEN_ERROR(inset,argv[nopt]) ; 

			nopt++ ; continue ;
		}

		if( strncmp(argv[nopt],"-band",5) == 0 ){
			if( ++nopt >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ;
			if( have_freq ) WARNING_message("second -band option replaces first one!") ;
			fbot = strtod(argv[nopt++],NULL) ;
			ftop = strtod(argv[nopt++],NULL) ;
			have_freq = 1 ; continue ;
		}

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

   /** check inputs for reasonablositiness **/

   if( !have_freq ){
		if( nopt+1 >= argc )
			ERROR_exit("Need frequencies on command line after options!") ;
		fbot = (float)strtod(argv[nopt++],NULL) ;
		ftop = (float)strtod(argv[nopt++],NULL) ;
   }

   if( inset == NULL ){
		if( nopt >= argc )
			ERROR_exit("Need input dataset name on command line after options!") ;
		inset = THD_open_dataset(argv[nopt]) ;
		CHECK_OPEN_ERROR(inset,argv[nopt]) ;	 

		nopt++ ;
   }
   DSET_UNMSEC(inset) ;

   if( fbot < 0.0f  ) ERROR_exit("fbot value can't be negative!") ;
   if( ftop <= fbot ) ERROR_exit("ftop value %g must be greater than fbot value %g!",ftop,fbot) ;

   ntime = DSET_NVALS(inset) ;
   if( ntime < 9 ) ERROR_exit("Input dataset is too short!") ;

   if( nfft <= 0 ){
		nfft = csfft_nextup_even(ntime) ;
		if( verb ) INFO_message("Data length = %d  FFT length = %d",ntime,nfft) ;
		(void)THD_bandpass_set_nfft(nfft) ;
   } else if( nfft < ntime ){
		ERROR_exit("-nfft %d is less than data length = %d",nfft,ntime) ;
   } else {
		kk = THD_bandpass_set_nfft(nfft) ;
		if( kk != nfft && verb )
			INFO_message("Data length = %d  FFT length = %d",ntime,kk) ;
   }

   if( dt <= 0.0f ){
		dt = DSET_TR(inset) ;
		if( dt <= 0.0f ){
			WARNING_message("Setting dt=1.0 since input dataset lacks a time axis!") ;
			dt = 1.0f ;
		}
   }
   ftopALL = 1./dt ;// Aug,2016: should solve problem of a too-large
                    // value for THD_bandpass_vectors(), while still
                    // being >f_{Nyquist}

   if( !THD_bandpass_OK(ntime,dt,fbot,ftop,1) ) ERROR_exit("Can't continue!") ;

   nx = DSET_NX(inset); ny = DSET_NY(inset); nz = DSET_NZ(inset); nvox = nx*ny*nz;

   /* check mask, or create it */

   if( verb ) INFO_message("Loading input dataset time series" ) ;
   DSET_load(inset) ;

   if( mask != NULL ){
		if( mask_nx != nx || mask_ny != ny || mask_nz != nz )
			ERROR_exit("-mask dataset grid doesn't match input dataset") ;

   } else if( do_automask ){
		mask = THD_automask( inset ) ;
		if( mask == NULL )
			ERROR_message("Can't create -automask from input dataset?") ;
		nmask = THD_countmask( DSET_NVOX(inset) , mask ) ;
		if( verb ) INFO_message("Number of voxels in automask = %d",nmask);
		if( nmask < 1 ) ERROR_exit("Automask is too small to process") ;

   } else {
		mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ;
		memset(mask,1,sizeof(byte)*nvox) ;
		// if( verb ) // @@ alert if aaaalllllll vox are going to be analyzed!
		INFO_message("No mask ==> processing all %d voxels",nvox);
   }

   /* A simple check of dataset quality [08 Feb 2010] */

   if( !nosat ){
		float val ;
		INFO_message(
						 "Checking dataset for initial transients [use '-notrans' to skip this test]") ;
		val = THD_saturation_check(inset,mask,0,0) ; kk = (int)(val+0.54321f) ;
		if( kk > 0 )
			ININFO_message(
								"Looks like there %s %d non-steady-state initial time point%s :-(" ,
								((kk==1) ? "is" : "are") , kk , ((kk==1) ? " " : "s") ) ;
		else if( val > 0.3210f )  /* don't ask where this threshold comes from! */
			ININFO_message(
								"MAYBE there's an initial positive transient of 1 point, but it's hard to tell\n") ;
		else
			ININFO_message("No widespread initial positive transient detected :-)") ;
   }

   /* check -dsort inputs for match to inset */

   for( kk=0 ; kk < nortset ; kk++ ){
		if( DSET_NX(ortset[kk])    != nx ||
			 DSET_NY(ortset[kk])    != ny ||
			 DSET_NZ(ortset[kk])    != nz ||
			 DSET_NVALS(ortset[kk]) != ntime )
			ERROR_exit("-dsort %s doesn't match input dataset grid" ,
						  DSET_BRIKNAME(ortset[kk]) ) ;
   }

   /* convert input dataset to a vectim, which is more fun */

	// @@ convert BP'ing ftop/bot into indices for the DFT (below)
	delf = 1.0/(ntime*dt); 
	ind_low = (int) rint(fbot/delf);
	ind_high = (int) rint(ftop/delf);
	if( ntime % 2 ) // nyquist number
		N_ny = (ntime-1)/2;
	else
		N_ny = ntime/2;
	sqnt = sqrt(ntime);
	nt_fac = sqrt(ntime*(ntime-1));

	// @@ if BP_LAST==0:
	// now we go through twice, doing LFF bandpass for NumDen==0 and
	// `full spectrum' processing for NumDen==1.
	// if BP_LAST==1:
	// now we go through once, doing only `full spectrum' processing
	for( NumDen=0 ; NumDen<2 ; NumDen++) {
		//if( NumDen==1 ){ // full spectrum
		//	fbot = fbotALL;
		//	ftop = ftopALL;
		//}
		
		// essentially, just doesn't BP here, and the perfect filtering at end
		// is used for both still; this makes the final output spectrum
		// contain only frequencies in range of 0.01-0.08
		if( BP_LAST==1 )
			INFO_message("Only doing filtering to LFFs at end!");
		
		
		mrv = THD_dset_to_vectim( inset , mask , 0 ) ;
		if( mrv == NULL ) ERROR_exit("Can't load time series data!?") ;
		if( NumDen==1 )
			DSET_unload(inset) ; // @@ only unload on 2nd pass

		/* similarly for the ort vectors */

		if( ortar != NULL ){
			for( kk=0 ; kk < IMARR_COUNT(ortar) ; kk++ ){
				ortim = IMARR_SUBIM(ortar,kk) ;
				if( ortim->nx < ntime )
					ERROR_exit("-ort file %s is shorter than input dataset time series",
								  ortim->name ) ;
				ort  = (float **)realloc( ort , sizeof(float *)*(nort+ortim->ny) ) ;
				for( vv=0 ; vv < ortim->ny ; vv++ )
					ort[nort++] = MRI_FLOAT_PTR(ortim) + ortim->nx * vv ;
			}
		}

		/* all the real work now */

		if( do_despike ){
			int_pair nsp ;
			if( verb ) INFO_message("Testing data time series for spikes") ;
			nsp = THD_vectim_despike9( mrv ) ;
			if( verb ) ININFO_message(" -- Squashed %d spikes from %d voxels",nsp.j,nsp.i) ;
		}

		if( verb ) INFO_message("Bandpassing data time series") ;

		if( (BP_LAST==0) && (NumDen==0) )
			(void)THD_bandpass_vectim( mrv , dt,fbot,ftop , qdet , nort,ort ) ;
		else
			(void)THD_bandpass_vectim( mrv , dt,fbotALL,ftopALL, qdet,nort,ort ) ;

		/* OK, maybe a little more work */

		if( nortset == 1 ){
			MRI_vectim *orv ;
			orv = THD_dset_to_vectim( ortset[0] , mask , 0 ) ;
			if( orv == NULL ){
				ERROR_message("Can't load -dsort %s",DSET_BRIKNAME(ortset[0])) ;
			} else {
				float *dp , *mvv , *ovv , ff ;
				if( verb ) INFO_message("Orthogonalizing to bandpassed -dsort") ;
				//(void)THD_bandpass_vectim( orv , dt,fbot,ftop , qdet , nort,ort ) ; //@@
				if( (BP_LAST==0) && (NumDen==0) )
					(void)THD_bandpass_vectim(orv,dt,fbot,ftop,qdet,nort,ort);
				else
					(void)THD_bandpass_vectim(orv,dt,fbotALL,ftopALL,qdet,nort,ort);

				THD_vectim_normalize( orv ) ;
				dp = malloc(sizeof(float)*mrv->nvec) ;
				THD_vectim_vectim_dot( mrv , orv , dp ) ;
				for( vv=0 ; vv < mrv->nvec ; vv++ ){
					ff = dp[vv] ;
					if( ff != 0.0f ){
						mvv = VECTIM_PTR(mrv,vv) ; ovv = VECTIM_PTR(orv,vv) ;
						for( kk=0 ; kk < ntime ; kk++ ) mvv[kk] -= ff*ovv[kk] ;
					}
				}
				VECTIM_destroy(orv) ; free(dp) ;
			}
		}

		if( blur > 0.0f ){
			if( verb )
				INFO_message("Blurring time series data spatially; FWHM=%.2f",blur) ;
			mri_blur3D_vectim( mrv , blur ) ;
		}
		if( pvrad > 0.0f ){
			if( verb )
				INFO_message("Local PV-ing time series data spatially; radius=%.2f",pvrad) ;
			THD_vectim_normalize( mrv ) ;
			THD_vectim_localpv( mrv , pvrad ) ;
		}
		if( do_norm && pvrad <= 0.0f ){
			if( verb ) INFO_message("L2 normalizing time series data") ;
			THD_vectim_normalize( mrv ) ;
		}

		/* create output dataset, populate it, write it, then quit */
		if( (NumDen==0) ) { // @@ BP'ed version;  will do filt if BP_LAST

			if(BP_LAST) // do bandpass here for BP_LAST
				(void)THD_bandpass_vectim(mrv,dt,fbot,ftop,qdet,0,NULL);

			if( verb ) INFO_message("Creating output dataset in memory, then writing it") ;
			outset = EDIT_empty_copy(inset) ;
			if(SERIES_OUT){
				sprintf(out_lff,"%s_LFF",prefix); 
				EDIT_dset_items( outset , ADN_prefix,out_lff , ADN_none ) ;
				tross_Copy_History( inset , outset ) ;
				tross_Make_History( "3dBandpass" , argc,argv , outset ) ;
			}
			for( vv=0 ; vv < ntime ; vv++ )
				EDIT_substitute_brick( outset , vv , MRI_float , NULL ) ;
		
#if 1
			THD_vectim_to_dset( mrv , outset ) ;
#else
			AFNI_OMP_START ;
#pragma omp parallel
			{ float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ;
#pragma omp for
				for( vv=0 ; vv < ntime ; vv++ ){
					far = DSET_BRICK_ARRAY(outset,vv) ; var = mrv->fvec + vv ;
					for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ;
				}
			}
			AFNI_OMP_END ;
#endif
			VECTIM_destroy(mrv) ;
			if(SERIES_OUT){ // @@
				DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ;
			}
		}
		else{ // @@ non-BP'ed version
			if( verb ) INFO_message("Creating output dataset 2 in memory") ;

			// do this here because LFF version was also BP'ed at end.
			if(BP_LAST) // do bandpass here for BP_LAST
				(void)THD_bandpass_vectim(mrv,dt,fbotALL,ftopALL,qdet,0,NULL);

			outsetALL = EDIT_empty_copy(inset) ;
			if(UNBP_OUT){ 
				sprintf(out_unBP,"%s_unBP",prefix); 
				EDIT_dset_items( outsetALL, ADN_prefix, out_unBP, ADN_none );
				tross_Copy_History( inset , outsetALL ) ;
				tross_Make_History( "3dRSFC" , argc,argv , outsetALL ) ;
			}
			for( vv=0 ; vv < ntime ; vv++ )
				EDIT_substitute_brick( outsetALL , vv , MRI_float , NULL ) ;
		
#if 1
			THD_vectim_to_dset( mrv , outsetALL ) ;
#else
			AFNI_OMP_START ;
#pragma omp parallel
			{ float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ;
#pragma omp for
				for( vv=0 ; vv < ntime ; vv++ ){
					far = DSET_BRICK_ARRAY(outsetALL,vv) ; var = mrv->fvec + vv ;
					for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ;
				}
			}
			AFNI_OMP_END ;
#endif
			VECTIM_destroy(mrv) ;
			if(UNBP_OUT){ 
				DSET_write(outsetALL) ; if( verb ) WROTE_DSET(outsetALL) ;
			}
		}
	}// end of NumDen loop


	// @@
	INFO_message("Starting the (f)ALaFFel calcs") ;

	// allocations
	series1 = (double *)calloc(ntime,sizeof(double)); 
	series2 = (double *)calloc(ntime,sizeof(double)); 
	xx1 = (double *)calloc(2*ntime,sizeof(double)); 
	xx2 = (double *)calloc(2*ntime,sizeof(double)); 
	alff = (float *)calloc(nvox,sizeof(float)); 
	malff = (float *)calloc(nvox,sizeof(float)); 
	falff = (float *)calloc(nvox,sizeof(float)); 

	if( (series1 == NULL) || (series2 == NULL) 
		 || (xx1 == NULL) || (xx2 == NULL) 
		 || (alff == NULL) || (malff == NULL) || (falff == NULL)) { 
		fprintf(stderr, "\n\n MemAlloc failure.\n\n");
		exit(122);
	}
	if(DO_RSFA) {
		rsfa = (float *)calloc(nvox,sizeof(float)); 
		mrsfa = (float *)calloc(nvox,sizeof(float)); 
		frsfa = (float *)calloc(nvox,sizeof(float)); 
		if( (rsfa == NULL) || (mrsfa == NULL) || (frsfa == NULL)) { 
			fprintf(stderr, "\n\n MemAlloc failure.\n\n");
			exit(123);
		}	
	}
	
	
	work = gsl_fft_real_workspace_alloc (ntime);
	real1 = gsl_fft_real_wavetable_alloc (ntime);
	real2 = gsl_fft_real_wavetable_alloc (ntime);
	gsl_complex_packed_array compl_freqs1 = xx1;
	gsl_complex_packed_array compl_freqs2 = xx2;




	// *********************************************************************
	// *********************************************************************
	// **************    Falafelling = ALFF/fALFF calcs    *****************
	// *********************************************************************
	// *********************************************************************

	// Be now have the BP'ed data set (outset) and the non-BP'ed one
	// (outsetALL).  now we'll FFT both, get amplitudes in appropriate
	// ranges, and calculate:  ALFF, mALFF, fALFF,

	ctr = 0;
	for( kk=0; kk<nvox ; kk++) {
		if(mask[kk]) {
			
			// BP one, and unBP one, either for BP_LAST or !BP_LAST
			for( m=0 ; m<ntime ; m++ ) {
				series1[m] = THD_get_voxel(outset,kk,m);
				series2[m] = THD_get_voxel(outsetALL,kk,m);
			}
			
			
			mm = gsl_fft_real_transform(series1, 1, ntime, real1, work);
			mm = gsl_fft_halfcomplex_unpack(series1, compl_freqs1, 1, ntime);
			mm = gsl_fft_real_transform(series2, 1, ntime, real2, work);
			mm = gsl_fft_halfcomplex_unpack(series2, compl_freqs2, 1, ntime);

			numer = 0.0f; 
			denom = 0.0f;
			de_rsfa = 0.0f;
			nu_rsfa = 0.0f;
			for( m=1 ; m<N_ny ; m++ ) {
				mm = 2*m;
				pow2 = compl_freqs2[mm]*compl_freqs2[mm] +
					compl_freqs2[mm+1]*compl_freqs2[mm+1]; // power
				//pow2*=2;// factor of 2 since ampls are even funcs
				denom+= (float) sqrt(pow2); // amplitude 
				de_rsfa+= (float) pow2;
				
				if( ( m>=ind_low ) && ( m<=ind_high ) ){
					pow1 = compl_freqs1[mm]*compl_freqs1[mm]+
						compl_freqs1[mm+1]*compl_freqs1[mm+1];
					//pow1*=2;
					numer+= (float) sqrt(pow1);
					nu_rsfa+= (float) pow1;
				}
			}

			if( denom>0.000001 )
			  falff[kk] = numer/denom;
			else
			  falff[kk] = 0.;
			alff[kk] = 2*numer/sqnt;// factor of 2 since ampl is even funct
			meanALFF+= alff[kk];

			if(DO_RSFA){
			  nu_rsfa = sqrt(2*nu_rsfa); // factor of 2 since ampls 
			  de_rsfa = sqrt(2*de_rsfa); // are even funcs
			  if( de_rsfa>0.000001 )
			    frsfa[kk] = nu_rsfa/de_rsfa;
			  else
			    frsfa[kk]=0.;
			  rsfa[kk] = nu_rsfa/nt_fac;
			  meanRSFA+= rsfa[kk];
			}
			
			ctr+=1;
		}
	}
	meanALFF/= ctr;
	meanRSFA/= ctr;

	gsl_fft_real_wavetable_free(real1);
	gsl_fft_real_wavetable_free(real2);
	gsl_fft_real_workspace_free(work);

	// ALFFs divided by mean of brain value
	for( kk=0 ; kk<nvox ; kk++ ) 
		if(mask[kk]){
			malff[kk] = alff[kk]/meanALFF;
			if(DO_RSFA)
				mrsfa[kk] = rsfa[kk]/meanRSFA;
		}
	// **************************************************************
	// **************************************************************
	//                 Store and output
	// **************************************************************
	// **************************************************************
	
	outsetALFF = EDIT_empty_copy( inset ) ; 
	sprintf(out_alff,"%s_ALFF",prefix); 
	EDIT_dset_items( outsetALFF,
                    ADN_nvals, 1,
						  ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_alff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetALFF));
	EDIT_substitute_brick(outsetALFF, 0, MRI_float, alff); 
	alff=NULL;
	THD_load_statistics(outsetALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetALFF, True);

	outsetfALFF = EDIT_empty_copy( inset ) ;
	sprintf(out_falff,"%s_fALFF",prefix); 
	EDIT_dset_items( outsetfALFF,
                    ADN_nvals, 1,
						  ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_falff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetfALFF));
	EDIT_substitute_brick(outsetfALFF, 0, MRI_float, falff); 
	falff=NULL;
	THD_load_statistics(outsetfALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetfALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetfALFF, True);



	outsetmALFF = EDIT_empty_copy( inset ) ;
	sprintf(out_malff,"%s_mALFF",prefix); 
	EDIT_dset_items( outsetmALFF,
                    ADN_nvals, 1,
                    ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_malff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetmALFF));
	EDIT_substitute_brick(outsetmALFF, 0, MRI_float, malff); 
	malff=NULL;
	THD_load_statistics(outsetmALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetmALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetmALFF, True);

	if(DO_RSFA){
     outsetRSFA = EDIT_empty_copy( inset ) ;
		sprintf(out_rsfa,"%s_RSFA",prefix); 
		EDIT_dset_items( outsetRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_rsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetRSFA));
		EDIT_substitute_brick(outsetRSFA, 0, MRI_float, rsfa); 
		rsfa=NULL;
		THD_load_statistics(outsetRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetRSFA, True);
		
      outsetfRSFA = EDIT_empty_copy( inset ) ;
		sprintf(out_frsfa,"%s_fRSFA",prefix); 
		EDIT_dset_items( outsetfRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_frsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetfRSFA));
		EDIT_substitute_brick(outsetfRSFA, 0, MRI_float, frsfa); 
		frsfa=NULL;
		THD_load_statistics(outsetfRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetfRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetfRSFA, True);
		
		outsetmRSFA = EDIT_empty_copy( inset ) ; 
		sprintf(out_mrsfa,"%s_mRSFA",prefix); 
		EDIT_dset_items( outsetmRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_mrsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetmRSFA));
		EDIT_substitute_brick(outsetmRSFA, 0, MRI_float, mrsfa); 
		mrsfa=NULL;
		THD_load_statistics(outsetmRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetmRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetmRSFA, True);
	}



	// ************************************************************
	// ************************************************************
	//                    Freeing
	// ************************************************************
	// ************************************************************

	DSET_delete(inset);
	DSET_delete(outsetALL);
	DSET_delete(outset);
	DSET_delete(outsetALFF);
	DSET_delete(outsetmALFF);
	DSET_delete(outsetfALFF);
	DSET_delete(outsetRSFA);
	DSET_delete(outsetmRSFA);
	DSET_delete(outsetfRSFA);

	free(inset);
	free(outsetALL);
	free(outset);
	free(outsetALFF);
	free(outsetmALFF);
	free(outsetfALFF);
	free(outsetRSFA);
	free(outsetmRSFA);
	free(outsetfRSFA);

	free(rsfa);
	free(mrsfa);
	free(frsfa);
	free(alff);
	free(malff);
	free(falff);
	free(mask);
	free(series1);
	free(series2);
	free(xx1);
	free(xx2);

	exit(0) ;
}
Пример #25
0
/*! Replace a voxel's value by the value's rank in the entire set of input datasets */
int main( int argc , char * argv[] )
{
   THD_3dim_dataset ** dsets_in = NULL, *dset=NULL; /*input and output datasets*/
   int nopt=0, nbriks=0, nsubbriks=0, ib=0, isb=0;
   byte *cmask=NULL;
   int *all_uniques=NULL, **uniques=NULL, *final_unq=NULL, *N_uniques=NULL;
   int N_final_unq=0, iun=0, total_unq=0;
   INT_HASH_DATUM *rmap=NULL, *hd=NULL;
   int imax=0, iunq=0, ii=0, id = 0;
   long int off=0;
   char *prefix=NULL;
   char stmp[THD_MAX_PREFIX+1]={""}; 
   FILE *fout=NULL;

   /*----- Read command line -----*/
   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      Rank_help ();
      exit(0) ;
   }

   mainENTRY("3dRank main"); machdep(); AFNI_logger("3dRank",argc,argv);
   nopt = 1 ;
   
   while( nopt < argc && argv[nopt][0] == '-' ){
      if( strcmp(argv[nopt],"-ver") == 0 ){
         PRINT_VERSION("3dRank"); AUTHOR("Ziad Saad");
         nopt++; continue;
      }

      if( strcmp(argv[nopt],"-help") == 0 ){
         Rank_help();
         exit(0) ;
      }

      if( strcmp(argv[nopt],"-prefix") == 0 ){
         ++nopt;
         if (nopt>=argc) {
            fprintf(stderr,"**ERROR: Need string after -prefix\n");
            exit(1);
         }
         prefix = argv[nopt] ;
         ++nopt; continue;
      }
      if( strcmp(argv[nopt],"-input") == 0 ){
         dsets_in = (THD_3dim_dataset**)
                        calloc(argc-nopt+1, sizeof(THD_3dim_dataset*));
         ++nopt; nbriks=0;
         while (nopt < argc ) {
            dsets_in[nbriks] = THD_open_dataset( argv[nopt] );
            if( !ISVALID_DSET(dsets_in[nbriks]) ){
              fprintf(stderr,"**ERROR: can't open dataset %s\n",argv[nopt]) ;
              exit(1);
            }
            ++nopt; ++nbriks; 
         }
         continue;
      }
      
      ERROR_exit( " Error - unknown option %s", argv[nopt]);
   } 
   if (nopt < argc) {
      ERROR_exit( " Error unexplained trailing option: %s\n", argv[nopt]);
   }
   if (!nbriks) {
      ERROR_exit( " Error no volumes entered on command line?");
   }
   
   /* some checks and inits*/
   nsubbriks = 0;
   for (ib = 0; ib<nbriks; ++ib) {
      if (!is_integral_dset(dsets_in[ib], 0)) {
         ERROR_exit("Dset %s is not of an integral data type.", 
                        DSET_PREFIX(dsets_in[ib]));
      }
      nsubbriks += DSET_NVALS(dsets_in[ib]);
   }
   
   /* Now get unique arrays */
   uniques = (int **)calloc(nsubbriks, sizeof(int*));
   N_uniques = (int *)calloc(nsubbriks, sizeof(int));
   total_unq = 0;
   iun = 0;
   for (ib = 0; ib<nbriks; ++ib) {
      DSET_mallocize(dsets_in[ib]); DSET_load(dsets_in[ib]);
      for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) {
         uniques[iun] = THD_unique_vals(dsets_in[ib], isb,
                                        &(N_uniques[iun]), cmask);
         total_unq += N_uniques[iun]; 
         ++iun;
      }
   }
   
   /* put all the arrays together and get the unique of the uniques */
   all_uniques = (int *)calloc(total_unq, sizeof(int));
   off=0;
   for (iun=0; iun<nsubbriks; ++iun) {
      memcpy(all_uniques+off, uniques[iun], N_uniques[iun]*sizeof(int));
      off += N_uniques[iun];
   }
   
   /* free intermediate unique arrays */
   for (iun=0; iun<nsubbriks; ++iun) {
      free(uniques[iun]);
   }
   free(uniques); uniques=NULL;
   free(N_uniques); N_uniques=NULL;
   
   /* get unique of catenated array */
   if (!(final_unq = UniqueInt (all_uniques, total_unq, &N_final_unq, 0 ))) {
      ERROR_exit( " Failed to get unique list (%d, %d, %d) ", 
                  total_unq, N_final_unq, nsubbriks);
   }
   free(all_uniques); all_uniques=NULL;
  
   if (prefix) {
      snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
               "%s.rankmap.1D", prefix);
   } else {
      if (nbriks == 1) {
        snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "%s.rankmap.1D", DSET_PREFIX(dsets_in[0]));
      } else { 
         snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "%s+.rankmap.1D", DSET_PREFIX(dsets_in[0]));
      }
   }
      
   if (stmp[0]) {
      if ((fout = fopen(stmp,"w"))) {
         fprintf(fout, "#Rank Map (%d unique values)\n", N_final_unq);
         fprintf(fout, "#Col. 0: Rank\n");
         fprintf(fout, "#Col. 1: Input Dset Value\n");
      }
   } 

   
   /* get the maximum integer in the unique array */
   imax = 0;
   for (iunq=0; iunq<N_final_unq; ++iunq) {
      if (final_unq[iunq] > imax) imax = final_unq[iunq]; 
      if (fout) fprintf(fout, "%d   %d\n", iunq, final_unq[iunq]);
      hd = (INT_HASH_DATUM*)calloc(1,sizeof(INT_HASH_DATUM));
      hd->id = final_unq[iunq];
      hd->index = iunq;
      HASH_ADD_INT(rmap, id, hd); 
   }
   
   fclose(fout); fout=NULL;

   /* now cycle over all dsets and replace their voxel values with rank */
   for (ib = 0; ib<nbriks; ++ib) {
      for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) {
         EDIT_BRICK_LABEL(  dsets_in[ib],isb, "rank" ) ;
         EDIT_BRICK_TO_NOSTAT(  dsets_in[ib],isb ) ;
         EDIT_BRICK_FACTOR( dsets_in[ib],isb, 0.0);/* no factors for rank*/
         switch (DSET_BRICK_TYPE(dsets_in[ib],isb) ){
            default:
               fprintf(stderr,
                        "** Bad dset type for unique operation.\n"
                        "Only Byte, Short, and float dsets are allowed.\n");
               break ; /* this should not happen here, 
                        so don't bother returning*/
            case MRI_short:{
               short *mar = (short *) DSET_ARRAY(dsets_in[ib],isb) ;
               if (imax >  MRI_TYPE_maxval[MRI_short]) {
                  WARNING_message("Maximum rank value of %d is\n"
                                  "than maximum value for dset datatype of %d\n",
                                  imax, MRI_TYPE_maxval[MRI_short]);
               }
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii];
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (short)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;
            case MRI_byte:{
               byte *mar ;
               if (imax >  MRI_TYPE_maxval[MRI_short]) {
                  WARNING_message("Maximum rank value of %d is\n"
                                  "than maximum value for dset datatype of %d\n",
                                  imax, MRI_TYPE_maxval[MRI_byte]);
               }
               mar = (byte *) DSET_ARRAY(dsets_in[ib],isb) ;
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii];
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (byte)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;
            case MRI_float:{
               float *mar = (float *) DSET_ARRAY(dsets_in[ib],isb) ;
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii]; /* Assuming float is integral valued */
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (float)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;

         }
      }

      /* update range, etc. */
      THD_load_statistics(dsets_in[ib]);
      
      /* Now write the bricks */
      if (prefix) {
         if (nbriks == 1) { 
            snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                     "%s", prefix);
         } else {
            snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                     "r%02d.%s", ib, prefix);
         }
      } else {
         snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "rank.%s", DSET_PREFIX(dsets_in[ib]));
      }
      EDIT_dset_items( dsets_in[ib] ,
                       ADN_prefix   , stmp ,
                       ADN_none ) ;
      
      /* change storage mode, this way prefix will determine
         format of output dset */
      dsets_in[ib]->dblk->diskptr->storage_mode = STORAGE_BY_BRICK;
      
      tross_Make_History( "3dRank" , argc, argv , dsets_in[ib] ) ;
      if (DSET_IS_MASTERED(dsets_in[ib])) {
         /*  THD_write_3dim_dataset won't write a mastered dude */
         dset = EDIT_full_copy(dsets_in[ib],stmp); 
      } else {
         dset = dsets_in[ib];
      }
      
      /* New ID */
      ZERO_IDCODE(dset->idcode);
      dset->idcode = MCW_new_idcode() ;
      
      if (!THD_write_3dim_dataset( NULL, stmp, dset,True )) {
         ERROR_message("Failed to write %s", stmp);
         exit(1);  
      } else {
         WROTE_DSET(dsets_in[ib]); 
         if (dset != dsets_in[ib]) DSET_deletepp(dset);
         DSET_deletepp(dsets_in[ib]);
         
      }
   }
   
   /* destroy hash */
   while (rmap) {
      hd = rmap;
      HASH_DEL(rmap,hd);
      free(hd);
   }

   free(final_unq);  final_unq=NULL;
   
   exit(0);
}
Пример #26
0
int main( int argc , char *argv[] )
{
   int vstep=0 , ii,nvox , ntin , ntout , do_one=0 , nup=-1 ;
   THD_3dim_dataset *inset=NULL , *outset ;
   char *prefix="Upsam", *dsetname=NULL ;
   int verb=0 , iarg=1, datum = MRI_float;
   float *ivec , *ovec , trin , trout, *fac=NULL, *ofac=NULL, 
         top=0.0, maxtop=0.0;

   /*------- help the pitifully ignorant user? -------*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 3dUpsample [options] n dataset\n"
      "\n"
      "* Upsamples a 3D+time dataset, in the time direction,\n"
      "   by a factor of 'n'.\n"
      "* The value of 'n' must be between 2 and 320 (inclusive).\n"
      "* The output dataset is in float format by default.\n"
      "\n"
      "Options:\n"
      "--------\n"
      " -1 or -one = Use linear interpolation. Otherwise,\n"
      " or -linear   7th order polynomial interpolation is used.\n"
      "\n"
      " -prefix pp = Define the prefix name of the output dataset.\n"
      "              [default prefix is 'Upsam']\n"
      "\n"
      " -verb      = Be eloquently and mellifluosly verbose.\n"
      "\n"
      " -n n       = An alternate way to specify n\n"
      " -input dataset = An alternate way to specify dataset\n"
      "\n"
      " -datum ddd = Use datatype ddd at output. Choose from\n"
      "              float (default), short, byte.\n"
      "Example:\n"
      "--------\n"
      " 3dUpsample -prefix LongFred 5 Fred+orig\n"
      "\n"
      "Nota Bene:\n"
      "----------\n"
      "* You should not use this for files that were 3dTcat-ed across\n"
      "   imaging run boundaries, since that will result in interpolating\n"
      "   between non-contiguous time samples!\n"
      "* If the input has M time points, the output will have n*M time\n"
      "   points.  The last n-1 of them will be past the end of the original\n"
      "   time series.\n"
      "* This program gobbles up memory and diskspace as a function of n.\n"
      "  You can reduce output file size with -datum option.\n"
      "\n"
      "--- RW Cox - April 2008\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   mainENTRY("3dUpsample"); machdep();
   PRINT_VERSION("3dUpsample"); AUTHOR("RWCox") ;
   AFNI_logger("3dUpsample",argc,argv);

   /*------- read command line args -------*/

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

     if( strncasecmp(argv[iarg],"-prefix",5) == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
       prefix = argv[iarg] ;
       if( !THD_filename_ok(prefix) )
         ERROR_exit("Illegal string after -prefix: '%s'",prefix) ;
       iarg++ ; continue ;
     }

     if( strncasecmp(argv[iarg],"-one",4) == 0 ||
         strcmp     (argv[iarg],"-1"    ) == 0 ||
         strncasecmp(argv[iarg],"-lin",4) == 0   ){
       do_one = 1 ; iarg++ ; continue ;
     }

     if( strncasecmp(argv[iarg],"-verb",3) == 0 ){
       verb = 1 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-n") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      nup = (int)strtod(argv[iarg],NULL) ;
      if( nup < 2 || nup > 320 )
        ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ;
      iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-input") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      dsetname = argv[iarg];
      iarg++ ; continue ;
     }
     
     if( strcasecmp(argv[iarg],"-datum") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      
         if( strcmp(argv[iarg],"short") == 0 ){
            datum = MRI_short ;
         } else if( strcmp(argv[iarg],"float") == 0 ){
            datum = MRI_float ;
         } else if( strcmp(argv[iarg],"byte") == 0 ){
            datum = MRI_byte ;
         } else {
            ERROR_message("-datum of type '%s' not supported in 3dUpsample!\n",
                    argv[iarg] ) ;
            exit(1) ;
         }
         
      iarg++ ; continue ;
     }
     
     ERROR_message("Unknown argument on command line: '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit (1);
   }

   /*------- check options for completeness and consistency -----*/
   
   if (nup == -1) {
      if( iarg+1 >= argc )
        ERROR_exit("need 'n' and 'dataset' on command line!") ;

      nup = (int)strtod(argv[iarg++],NULL) ;
      if( nup < 2 || nup > 320 )
        ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ;
   } 
   if (!dsetname) {
      if( iarg >= argc )
        ERROR_exit("need 'dataset' on command line!") ;
      dsetname = argv[iarg];
   }
   
   inset = THD_open_dataset(dsetname) ;
   if( !ISVALID_DSET(inset) )
     ERROR_exit("3dUpsample can't open dataset '%s'", dsetname) ;
   ntin = DSET_NVALS(inset) ; trin = DSET_TR(inset) ;
   if( ntin < 2 )
     ERROR_exit("dataset '%s' has only 1 value per voxel?!",dsetname) ;

   nvox = DSET_NVOX(inset) ;

   if( verb ) INFO_message("loading input dataset into memory") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;


   /*------ create output dataset ------*/

   ntout = ntin * nup ; trout = trin / nup ;

   /* scaling factor for output */
   fac = NULL; maxtop = 0.0;
   if (MRI_IS_INT_TYPE(datum)) {
      fac = (float *)calloc(DSET_NVALS(inset), sizeof(float));
      ofac = (float *)calloc(ntout, sizeof(float));
      for (ii=0; ii<DSET_NVALS(inset); ++ii) {
         top = MCW_vol_amax( DSET_NVOX(inset),1,1 , 
                             DSET_BRICK_TYPE(inset,ii), 
                             DSET_BRICK_ARRAY(inset,ii) ) ;
         if (DSET_BRICK_FACTOR(inset, ii)) 
            top = top * DSET_BRICK_FACTOR(inset,ii);
         fac[ii] = (top > MRI_TYPE_maxval[datum]) ? 
                        top/MRI_TYPE_maxval[datum] : 0.0 ;
         if (top > maxtop) maxtop = top;
      }
      if (storage_mode_from_filename(prefix) != STORAGE_BY_BRICK) {
         fac[0] = (maxtop > MRI_TYPE_maxval[datum]) ? 
                        maxtop/MRI_TYPE_maxval[datum] : 0.0 ;
         for (ii=0; ii<ntout; ++ii) 
            ofac[ii] = fac[0];
         if (verb) INFO_message("Forcing global scaling, Max = %f, fac = %f\n", 
                        maxtop, fac[0]);
      } else {
         if (verb) INFO_message("Reusing scaling factors of input dset\n");
         upsample_1( nup, DSET_NVALS(inset), fac, ofac);
      }
   }
   free(fac); fac = NULL;
   outset = EDIT_empty_copy(inset) ;
   EDIT_dset_items( outset ,
                        ADN_nvals     , ntout          ,
                        ADN_ntt       , DSET_NUM_TIMES(inset) > 1 ? ntout : 0 ,
                        ADN_datum_all , datum      ,
                        ADN_brick_fac , ofac           ,
                        ADN_prefix    , prefix         ,
                      ADN_none ) ;
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dUpsample" , argc,argv , outset ) ;
   free(ofac); ofac = NULL;
   
   if( outset->taxis != NULL ){
     outset->taxis->ttdel /= nup ;
     outset->taxis->ttdur /= nup ;
     if( outset->taxis->toff_sl != NULL ){
       for( ii=0 ; ii < outset->taxis->nsl ; ii++ )
         outset->taxis->toff_sl[ii] /= nup ;
     }
   }

   for( ii=0 ; ii < ntout ; ii++ ){ /* create empty bricks to be filled below */
     EDIT_substitute_brick( outset , ii , datum , NULL ) ;
   }

   /*------- loop over voxels and process them one at a time ---------*/

   if( verb )
     INFO_message("Upsampling time series from %d to %d: %s interpolation",
                  ntin , ntout , (do_one) ? "linear" : "heptic" ) ;

   if( verb && nvox > 499 ) vstep = nvox / 50 ;
   if( vstep > 0 ) fprintf(stderr,"++ voxel loop: ") ;

   ivec = (float *)malloc(sizeof(float)*ntin) ;
   ovec = (float *)malloc(sizeof(float)*ntout) ;

   for( ii=0 ; ii < nvox ; ii++ ){

     if( vstep > 0 && ii%vstep==vstep-1 ) vstep_print() ;

     THD_extract_array( ii , inset , 0 , ivec ) ;

     if( do_one ) upsample_1( nup , ntin , ivec , ovec ) ;
     else         upsample_7( nup , ntin , ivec , ovec ) ;

     THD_insert_series( ii , outset , ntout , MRI_float , ovec , 
                        datum==MRI_float ? 1:0 ) ;
   } /* end of loop over voxels */

   if( vstep > 0 ) fprintf(stderr," Done!\n") ;

   /*----- clean up and go away -----*/

   DSET_write(outset) ;
   if( verb ) WROTE_DSET(outset) ;
   if( verb ) INFO_message("Total CPU time = %.1f s",COX_cpu_time()) ;
   exit(0);
}
Пример #27
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset=NULL;
   int iarg , verbose = -1 ;
   char *outbuf, *stmp=NULL;
   char *labelName = NULL;
   char *sbdelim = {"|"};
   char *NAflag = {"NA"};
   char *atrdelim = {"\t"}, *form=NULL;
   INFO_FIELDS sing[512];
   int iis=0, N_sing = 0, isb=0, withhead = 0, itmp=0;
   int ip=0, needpair = 0, namelen=0, monog_pairs = 0;
   THD_3dim_dataset *tttdset=NULL, *dsetp=NULL;
   char *tempstr = NULL;
   int extinit = 0;
   float RL_AP_IS[6];

   mainENTRY("3dinfo main") ; machdep() ;

   if( argc < 2) { Syntax(TXT,1) ; RETURN(0); }

   iarg = 1 ;
   while (iarg < argc && argv[iarg][0] == '-') {
      CHECK_HELP(argv[iarg],Syntax);
           if( strncmp(argv[iarg],"-verb" ,5) == 0 ){
            verbose =  0; iarg++; continue; }
      else if( strncmp(argv[iarg],"-VERB" ,5) == 0 ){
            verbose =  1; iarg++; continue; }
      else if( strncmp(argv[iarg],"-short",5) == 0 ){
            verbose = -1; iarg++; continue; }
      else if( strcasecmp(argv[iarg],"-header_line") == 0 ||
               strcasecmp(argv[iarg],"-hdr") == 0 ){
            withhead = 1; iarg++; continue; }
      else if( strcasecmp(argv[iarg],"-monog_pairs") == 0 ){
            monog_pairs = 1; iarg++; continue; }
      else if ( strncmp(argv[iarg],"-label2",7) == 0 )
      {
        iarg++;
        if (iarg >= argc)
           ERROR_exit( "3dinfo needs an argument after -label2number\n");
        labelName = malloc(sizeof(char) * 2048);
        strcpy(labelName, argv[iarg]);
        iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-sb_delim") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -sb_delim\n");
         sbdelim = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-NA_flag") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -NA_flag\n");
         NAflag = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-atr_delim") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -atr_delim\n");
         atrdelim = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-space") == 0) {
         sing[N_sing++] = DSET_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-av_space") == 0) {
         sing[N_sing++] = AV_DSET_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-gen_space") == 0) {
         sing[N_sing++] = DSET_GEN_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_nifti") == 0) {
         sing[N_sing++] = IS_NIFTI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_atlas") == 0) {
         sing[N_sing++] = IS_ATLAS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-exists") == 0) {
         sing[N_sing++] = DSET_EXISTS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_oblique") == 0) {
         sing[N_sing++] = IS_OBLIQUE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-obliquity") == 0) {
         sing[N_sing++] = OBLIQUITY; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-handedness") == 0) {
         sing[N_sing++] = HANDEDNESS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-prefix") == 0) {
         sing[N_sing++] = PREFIX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-prefix_noext") == 0) {
         sing[N_sing++] = PREFIX_NOEXT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ni") == 0) {
         sing[N_sing++] = NI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nj") == 0) {
         sing[N_sing++] = NJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nk") == 0) {
         sing[N_sing++] = NK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-n4") == 0) {
         sing[N_sing++] = NI;
         sing[N_sing++] = NJ;
         sing[N_sing++] = NK;
         sing[N_sing++] = NV; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Rextent") == 0) {
         sing[N_sing++] = EXTENT_R; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Lextent") == 0) {
         sing[N_sing++] = EXTENT_L; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Aextent") == 0) {
         sing[N_sing++] = EXTENT_A; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Pextent") == 0) {
         sing[N_sing++] = EXTENT_P; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Iextent") == 0) {
         sing[N_sing++] = EXTENT_I; iarg++;
         continue;
      }  else if( strcasecmp(argv[iarg],"-Sextent") == 0) {
         sing[N_sing++] = EXTENT_S; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-extent") == 0) {
         sing[N_sing++] = EXTENT_R;
         sing[N_sing++] = EXTENT_L;
         sing[N_sing++] = EXTENT_A;
         sing[N_sing++] = EXTENT_P;
         sing[N_sing++] = EXTENT_I;
         sing[N_sing++] = EXTENT_S;
         iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-di") == 0) {
         sing[N_sing++] = DI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dj") == 0) {
         sing[N_sing++] = DJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dk") == 0) {
         sing[N_sing++] = DK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-d3") == 0) {
         sing[N_sing++] = DI;
         sing[N_sing++] = DJ;
         sing[N_sing++] = DK; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-adi") == 0) {
         sing[N_sing++] = ADI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-adj") == 0) {
         sing[N_sing++] = ADJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-adk") == 0) {
         sing[N_sing++] = ADK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ad3") == 0) {
         sing[N_sing++] = ADI;
         sing[N_sing++] = ADJ;
         sing[N_sing++] = ADK; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-voxvol") == 0) {
         sing[N_sing++] = VOXVOL; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-iname") == 0) {
         sing[N_sing++] = INAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-oi") == 0) {
         sing[N_sing++] = OI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-oj") == 0) {
         sing[N_sing++] = OJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ok") == 0) {
         sing[N_sing++] = OK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-o3") == 0) {
         sing[N_sing++] = OI;
         sing[N_sing++] = OJ;
         sing[N_sing++] = OK; iarg++;
         continue;
      }else if( strcasecmp(argv[iarg],"-nt") == 0) {
         sing[N_sing++] = NT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nti") == 0) {
         sing[N_sing++] = NTI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nv") == 0) {
         sing[N_sing++] = NV; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nvi") == 0) {
         sing[N_sing++] = NVI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ntimes") == 0) {
         sing[N_sing++] = NTIMES; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-max_node") == 0) {
         sing[N_sing++] = MAX_NODE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nijk") == 0) {
         sing[N_sing++] = NIJK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-labeltable") == 0) {
         sing[N_sing++] = LTABLE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-labeltable_as_atlas_points") == 0) {
         sing[N_sing++] = LTABLE_AS_ATLAS_POINT_LIST; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-atlas_points") == 0) {
         sing[N_sing++] = ATLAS_POINTS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-fac") == 0) {
         sing[N_sing++] = FAC; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-datum") == 0) {
         sing[N_sing++] = DATUM; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-label") == 0) {
         sing[N_sing++] = LABEL; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-min") == 0) {
         sing[N_sing++] = MIN; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-max") == 0) {
         sing[N_sing++] = MAX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-minus") == 0) {
         sing[N_sing++] = MINUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-maxus") == 0) {
         sing[N_sing++] = MAXUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmin") == 0) {
         sing[N_sing++] = DMIN; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmax") == 0) {
         sing[N_sing++] = DMAX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dminus") == 0) {
         sing[N_sing++] = DMINUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmaxus") == 0) {
         sing[N_sing++] = DMAXUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-TR") == 0) {
         sing[N_sing++] = TR; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-header_name") == 0) {
         sing[N_sing++] = HEADER_NAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-brick_name") == 0) {
         sing[N_sing++] = BRICK_NAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-history") == 0) {
         sing[N_sing++] = HISTORY; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-all_names") == 0) {
         sing[N_sing++] = ALL_NAMES; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-orient") == 0) {
         sing[N_sing++] = ORIENT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_grid") == 0) {
         sing[N_sing++] = SAME_GRID; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_dim") == 0) {
         sing[N_sing++] = SAME_DIM; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_delta") == 0) {
         sing[N_sing++] = SAME_DELTA; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_orient") == 0) {
         sing[N_sing++] = SAME_ORIENT; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_center") == 0) {
         sing[N_sing++] = SAME_CENTER; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_obl") == 0) {
         sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-slice_timing") == 0) {
         sing[N_sing++] = SLICE_TIMING; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-sval_diff") == 0) {
         sing[N_sing++] = SVAL_DIFF; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-val_diff") == 0) {
         sing[N_sing++] = VAL_DIFF; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_all_grid") == 0) {
         sing[N_sing++] = SAME_DIM;
         sing[N_sing++] = SAME_DELTA;
         sing[N_sing++] = SAME_ORIENT;
         sing[N_sing++] = SAME_CENTER;
         sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-id") == 0) {
         sing[N_sing++] = ID; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-smode") == 0) {
         sing[N_sing++] = SMODE; iarg++; continue;
      } else {
         ERROR_message("Option %s unknown", argv[iarg]);
         suggest_best_prog_option(argv[0], argv[iarg]);
         exit(1);
      }
   }

   if (N_sing == 0) {
      sing[N_sing++] = CLASSIC;
   }

   if (sing[iis] == CLASSIC) PRINT_VERSION("3dinfo") ;

   THD_allow_empty_dataset(1) ;  /* 21 Mar 2007 */

   if (iarg == argc) {
      ERROR_message("No dsets on command line? I have nothing to do.\n");
      exit(1);
   }

   if (needpair && monog_pairs) needpair = 2; /* pair each couple separately */

   if (needpair==2 && (argc-iarg) % 2) {
      ERROR_message("Using options requiring dset pairs but have odd number\n"
                    "of dsets (%d) on command line.\n", (argc-iarg));
      exit (1);
   } else if (needpair==1 && (argc-iarg) < 2) {
      ERROR_message("Using options requiring dset pairs but have less than\n"
                    "two dsets (%d) on command line.\n", (argc-iarg));
      exit (1);
   }

   ip = 0;
   for( ; iarg < argc ; iarg++ ){
      if (ip == 0) {
         int kkk, nml; char *etr;
         namelen = 0;
         for (kkk=iarg; kkk<argc; ++kkk) {
            if ((etr = THD_trailname(argv[kkk],0))) {
               nml=strlen(etr);
               if (nml < 48 && nml > namelen) namelen = nml;
            }
         }
         if (namelen < 6) namelen = 6;
         if (withhead) {
            int havenew=0;
            for (iis = 0; iis < N_sing; ++iis) {
               if (sing[iis] != CLASSIC) {
                  ++havenew;
                  form = PrintForm(sing[iis], namelen, 1);
                  /*fprintf(stderr,"ZSS: %d %s >%s<\n",
                           sing[iis], Field_Names[sing[iis]], form);*/

                  fprintf(stdout, form, Field_Names[sing[iis]]);
               }
               if (havenew) {
                  if (N_sing > 1 && iis < N_sing-1)
                           fprintf(stdout,"%s",atrdelim);
                  else fprintf(stdout,"\n");
               }
            }
         }
      }
     if( argv[iarg][0] == '\0' ) continue ;  /* bad filename */

     set_obliquity_report(0); /* silence obliquity */

     if (!needpair) {
      if (!(dset = load_3dinfo_dataset(argv[iarg]))) {
        /* exit(1); */
      }
     } else {
      if (needpair == 2) { /* Crazy idea of comparing each pair separately */
         if (ip % 2 == 0) {
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /* exit(1); */
            }
            if (iarg+1==argc || argv[iarg+1][0] == '\0') {
               ERROR_message("Bad dset pair for %s\n", argv[iarg]);
               exit(1);
            }
            if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) {
               /* exit(1); */
            }
         } else { /* swap the pair - this allows non pair requiring functions
                     to work as before.*/
            tttdset = dsetp;
            dsetp = dset;
            dset = tttdset; tttdset=NULL;
         }
      } else { /* always compare to very first dset */
         if (ip==0) {
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /*exit(1);*/
            }
            if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) {
               /*exit(1);*/
            }
         } else if (ip==1) { /* switch order of first two */
            tttdset = dsetp;
            dsetp = dset; /* now dsetp is the very first dset */
            dset = tttdset; tttdset=NULL;
         } else { /* pair with very first, which is dsetp */
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /*exit(1);*/
            }
         }
      }
     }
     ++ip;

     if (0 && !dset) { /* allow for DSET_EXISTS option */
         ERROR_exit("Should not get here");
     }

     /* we should re-capture this per dataset   5 Feb 2019 [rickr] */
     extinit = 0;

     for (iis = 0; iis < N_sing; ++iis) {
        if (!dset) {
         if (sing[iis] == CLASSIC) {
            if( dset == NULL ){  /* still not open? */
               ERROR_exit("Can't open dataset %s\n", argv[iarg]) ;
            }
         } else if (sing[iis] != DSET_EXISTS && sing[iis] != INAME) {
            fprintf(stdout, "NO-DSET");
            SPIT_DELIM(iis, N_sing, atrdelim);
            continue;
         }
        }
        switch (sing[iis]) {
         case CLASSIC:
            if (labelName == NULL )  /*** get and output info ***/
            {
             outbuf = THD_dataset_info( dset , verbose ) ;
             if( outbuf != NULL ){
               printf("\n") ;
               puts(outbuf) ;
               free(outbuf) ; outbuf = NULL ;
             } else {
               ERROR_exit("Can't get info for dataset %s",argv[iarg]) ;
             }
            }
            else   /*** get and output label ***/
            {
             int nval_per = dset->dblk->nvals;
             int foundLabel = 0;
             int ival=0;

             for (ival=0 ; ival < nval_per && !foundLabel; ival++ )
             {
               if (strcmp(DSET_BRICK_LAB(dset,ival), labelName) == 0)
               {
                 printf("%d\n", ival); foundLabel = 1;
               }
             } /* end of for (ival=0 ; ival < nval_per ; ival++ ) */
             if (!foundLabel) printf("\n");
            }

            THD_delete_3dim_dataset( dset , False ) ;
            free(labelName);
            break;
         case DSET_EXISTS:
            fprintf(stdout, "%d", dset ? 1:0);
            break;
         case DSET_SPACE:
            tempstr = THD_get_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "-----");
            else
                  fprintf(stdout, "%s", tempstr);
            break;
         case DSET_GEN_SPACE:
            tempstr = THD_get_generic_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "-----");
            else
                  fprintf(stdout, "%s", tempstr);
            break;
         case AV_DSET_SPACE:
            /* don't allow anything but the three AFNI views */
            tempstr = THD_get_view_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "+orig");
            else if (!strncasecmp(tempstr,"ORIG",4))
                  fprintf(stdout, "+orig");
            else if (!strncasecmp(tempstr,"ACPC",4))
                  fprintf(stdout, "+acpc");
            else if (!strncasecmp(tempstr,"TLRC",4))
                  fprintf(stdout, "+tlrc");
            else  /* shouldn't get here */
                  fprintf(stdout, "+orig");
            break;
         case IS_NIFTI:
            if (  dset->dblk->diskptr &&
                  dset->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI ) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case IS_ATLAS:
            if (  is_Dset_Atlasy(dset, NULL) ) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case IS_OBLIQUE:
            if (dset_obliquity(dset,NULL) > 0) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case HANDEDNESS:
            if (THD_handedness(dset) > 0) {
               fprintf(stdout,"R");
            } else {
               fprintf(stdout,"L");
            }
            break;
         case OBLIQUITY:
            fprintf(stdout,"%.3f",
                  THD_compute_oblique_angle(dset->daxes->ijk_to_dicom_real, 0));
            break;
         case PREFIX:
            form = PrintForm(sing[iis], namelen, 1);
            fprintf(stdout,form, DSET_PREFIX(dset));
            break;
         case PREFIX_NOEXT:
            {
               form = PrintForm(sing[iis], namelen, 1);
               stmp=DSET_prefix_noext(dset);
               fprintf(stdout,form, stmp);
               free(stmp); stmp=NULL;
            }
            break;
         case HEADER_NAME:
            fprintf(stdout,"%s", dset->dblk->diskptr->header_name);
            break;
         case BRICK_NAME:
            fprintf(stdout,"%s", dset->dblk->diskptr->brick_name);
            break;
         case ALL_NAMES:
            THD_show_dataset_names(dset, "FOR_3DINFO", stdout);
            break;
         case HISTORY:
            stmp = tross_Get_History(dset);
            fprintf(stdout,"%s", stmp ? stmp:NAflag);
            if (stmp) free(stmp); stmp=NULL;
            break;
         case NI:
            fprintf(stdout,"%d", DSET_NX(dset));
            break;
         case NJ:
            fprintf(stdout,"%d", DSET_NY(dset));
            break;
         case NK:
            fprintf(stdout,"%d", DSET_NZ(dset));
            break;
         case NIJK:
            fprintf(stdout,"%d", DSET_NVOX(dset));
            break;
         case NTIMES:
            fprintf(stdout,"%d", DSET_NUM_TIMES(dset));
            break;
         case MAX_NODE:
            DSET_MAX_NODE(dset,itmp);
            fprintf(stdout,"%d", itmp);
            break;
         case NT:
         case NV:
            fprintf(stdout,"%d", DSET_NVALS(dset));
            break;
         case NTI:
         case NVI:
            fprintf(stdout,"%d", DSET_NVALS(dset)-1);
            break;
         case DI:
            fprintf(stdout,"%f", DSET_DX(dset));
            break;
         case DJ:
            fprintf(stdout,"%f", DSET_DY(dset));
            break;
         case DK:
            fprintf(stdout,"%f", DSET_DZ(dset));
            break;
         case OI:
            fprintf(stdout,"%f", DSET_XORG(dset));
            break;
         case OJ:
            fprintf(stdout,"%f", DSET_YORG(dset));
            break;
         case OK:
            fprintf(stdout,"%f", DSET_ZORG(dset));
            break;
         case ADI:
            fprintf(stdout,"%f", fabs(DSET_DX(dset)));
            break;
         case EXTENT_R:
         case EXTENT_L:
         case EXTENT_A:
         case EXTENT_P:
         case EXTENT_I:
         case EXTENT_S:
            {
               if (!extinit) {
                  THD_dset_extent(dset, '-', RL_AP_IS);
                  extinit = 1;
               }
               fprintf(stdout,"%f", RL_AP_IS[sing[iis]-EXTENT_R]);
            }
            break;

         case ADJ:
            fprintf(stdout,"%f", fabs(DSET_DY(dset)));
            break;
         case ADK:
            fprintf(stdout,"%f", fabs(DSET_DZ(dset)));
            break;
         case VOXVOL:
            fprintf(stdout,"%f", fabs(DSET_DX(dset))*
                                 fabs(DSET_DY(dset))*fabs(DSET_DZ(dset)));
            break;
         case INAME:
            fprintf(stdout,"%s", argv[iarg]);
            break;
         case LTABLE:
            {
               char *str;
               if ((str = Dtable_to_nimlstring(DSET_Label_Dtable(dset),                                                          "VALUE_LABEL_DTABLE"))) {
                  fprintf(stdout,"%s", str);
                  free(str);
               } else {
                  fprintf(stdout,"NO_LABEL_TABLE");
               }
            }
            break;
         case LTABLE_AS_ATLAS_POINT_LIST:
            {
               ATLAS_POINT_LIST *apl=NULL;
               if ((apl =
                     label_table_to_atlas_point_list(DSET_Label_Dtable(dset)))) {
                  atlas_list_to_niml(apl,NULL);
                  free_atlas_point_list(apl);
               } else {
                  fprintf(stdout,"NO_LABEL_TABLE");
               }
            }
            break;
         case  ATLAS_POINTS:
            {
               ATR_string *atr =
                  THD_find_string_atr( dset->dblk, "ATLAS_LABEL_TABLE");
               if (atr) {
                  fprintf(stdout,"%s", atr->ch);
               }  else {
                  fprintf(stdout,"NO_APL");
               }
            }
            break;
         case FAC:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%f%s",
                        DSET_BRICK_FACTOR(dset,isb),
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case DATUM:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%s%s",
                        MRI_TYPE_name[DSET_BRICK_TYPE(dset,isb)],
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case LABEL:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%s%s",
               DSET_BRICK_LABEL(dset,isb) ? DSET_BRICK_LABEL(dset,isb):NAflag,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case MIN:
         case MINUS:
         case MAX:
         case MAXUS:
            {
               float vv=0.0, min, max;
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  if (!THD_subbrick_minmax(dset, isb,
                        (sing[iis] == MINUS || sing[iis] == MAXUS) ? 0:1,
                        &min, &max)) {
                     fprintf(stdout,"%s%s",
                        NAflag,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
                  } else {
                          if (sing[iis] == MINUS)
                        vv = min;
                     else if (sing[iis] == MAXUS)
                        vv = max;
                     else if (sing[iis] == MIN)
                        vv = min;
                     else if (sing[iis] == MAX)
                        vv = max;
                     fprintf(stdout,"%g%s",
                        vv,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
                  }
               }
               break;
            }
         case DMIN:
         case DMINUS:
         case DMAX:
         case DMAXUS:
            {
               float vv=0.0, min, max;
               if (!THD_dset_minmax(dset,
                     (sing[iis] == DMINUS || sing[iis] == DMAXUS) ? 0:1,
                     &min, &max)) {
                  fprintf(stdout,"%s%s",
                     NAflag,
                     (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               } else {
                       if (sing[iis] == DMINUS)
                     vv = min;
                  else if (sing[iis] == DMAXUS)
                     vv = max;
                  else if (sing[iis] == DMIN)
                     vv = min;
                  else if (sing[iis] == DMAX)
                     vv = max;
                  fprintf(stdout,"%g%s",
                     vv,
                     (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case TR:
#if 0
            fprintf(stdout,"%f", DSET_TR_SEC(dset));
#else
            fprintf(stdout,"%f", DSET_TR(dset));
#endif
            break;
         case ORIENT:
            {
               /* fprintf(stdout,"%c%c%c",
                *         ORIENT_typestr[dset->daxes->xxorient][0], ... ); */
               char ostr[4];    /* just to show        23 Jan 2013 [rickr] */
               THD_fill_orient_str_3(dset->daxes, ostr);
               fprintf(stdout,"%3s", ostr);
            }
            break;
         case SAME_GRID:
            fprintf(stdout,"%d",
               !THD_dataset_mismatch( dset , dsetp ));
            break;
         case SAME_DIM:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DIMEN));
            break;
         case SAME_DELTA:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DELTA));
            break;
         case SAME_ORIENT:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_ORIENT));
            break;
         case SAME_CENTER:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_CENTER));
            break;
         case SAME_OBL:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_OBLIQ));
            break;
         case SLICE_TIMING:     /* 6 May 2013 [rickr] */
            {
               if( DSET_HAS_SLICE_TIMING(dset) ) {
                  DSET_UNMSEC(dset); /* make sure times are in seconds */
                  for (isb=0; isb<dset->taxis->nsl; ++isb) {
                     fprintf(stdout,"%s%f",
                           (isb > 0) ? sbdelim : "",
                           dset->taxis->toff_sl[isb]);
                  }
               } else { /* all slices times are at t=0.0 */
                  for (isb=0; isb<DSET_NZ(dset); ++isb) {
                     fprintf(stdout,"%s%f", (isb > 0) ? sbdelim : "", 0.0);
                  }
               }
            }
            break;
         case SVAL_DIFF:
            fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 1));
            break;
         case VAL_DIFF:
            fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 0));
            break;
         case ID:
            fprintf(stdout,"%s", DSET_IDCODE_STR(dset));
            break;
         case SMODE:
            fprintf(stdout,"%s", DSET_STORAGE_MODE_STR(dset));
            break;
         default:
            ERROR_message("Info field not set properly (%d)\n", sing[iis]);
            exit(1);
        }
        if (sing[iis] != CLASSIC) {
         SPIT_DELIM(iis, N_sing, atrdelim);
        }
      }
   }

   exit(0) ;
}
Пример #28
0
int main( int argc , char *argv[] )
{
   int iarg , ii,jj,kk,mm , nvec , nx=0,ny , ff , vlen=4 ;
   MRI_IMAGE *tim , *vsim=NULL ;
   MRI_IMARR *tar ;
   char **vecnam , *tnam ;
   float *far , **tvec , *vsig=NULL , xsig,ysig ;
   float_quad qcor ; float_pair pci ; float corst, cor025, cor500, cor975 ;
   char fmt[256] ;
   int cormeth=0 ;    /* 0=Pearson, 1=Spearman, 2=Quadrant, 3=Kendall tau_b */
   float (*corfun)(int,float *,float *) ;

   /*-- start the AFNI machinery --*/

   mainENTRY("1dCorrelate main") ; machdep() ;

   /* check for options */

   iarg = 1 ; nvec = 0 ;
   while( iarg < argc && argv[iarg][0] == '-' ){
      /* I get by with a little help from my friends? */

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

     /*--- methods ---*/

     if( toupper(argv[iarg][1]) == 'P' ){ cormeth = 0 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'S' ){ cormeth = 1 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'Q' ){ cormeth = 2 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'K' ){ cormeth = 3 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'T' ){ cormeth = 4 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'U' ){ cormeth = 5 ; iarg++ ; continue ; }

     /*--- set nboot ---*/

     if( strcasecmp(argv[iarg],"-nboot") == 0 || strcasecmp(argv[iarg],"-num") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-nboot'") ;
       nboot = (int)strtod(argv[iarg],NULL) ;
       if( nboot < NBMIN ){
         WARNING_message("Replacing -nboot %d with %d",nboot,NBMIN) ;
         nboot = NBMIN ;
       }
       iarg++ ; continue ;
     }

     /*--- set alpha ---*/

     if( strcasecmp(argv[iarg],"-alpha") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-alpha'") ;
       alpha = (float)strtod(argv[iarg],NULL) ;
       if( alpha < 1.0f ){
         WARNING_message("Replacing -alpha %.1f with 1",alpha) ;
         alpha = 0.01f ;
       } else if( alpha > 20.0f ){
         WARNING_message("Replacing -alpha %.1f with 20",alpha) ;
         alpha = 0.20f ;
       } else {
         alpha *= 0.01f ;  /* convert from percent to fraction */
       }
       iarg++ ; continue ;
     }

     /*--- block resampling ---*/

     if( strcasecmp(argv[iarg],"-blk") == 0 || strcasecmp(argv[iarg],"-block") == 0 ){
       doblk = 1 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-vsig") == 0 ){
       if( vsim != NULL ) ERROR_exit("Can't use -vsig twice!") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after -vsig") ;
       vsim = mri_read_1D(argv[iarg]) ;
       if( vsim == NULL ) ERROR_exit("Can't read -vsig file '%s'",argv[iarg]) ;
       iarg++ ; continue ;
     }

     /*--- user should be flogged ---*/

     ERROR_message("Monstrously illegal option '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1);
   }

   /*--- user should be flogged twice ---*/

   if( argc < 2 ){
     usage_1dCorrelate(1) ; exit(0) ; 
   }

   if( iarg == argc )
     ERROR_exit("No 1D files on command line!?\n") ;

   /* the function to compute the correlation */

   corfun = cor_func[cormeth] ;

   /* check and assemble list of input 1D files */

   ff = iarg ;
   INIT_IMARR(tar) ;
   for( ; iarg < argc ; iarg++ ){
     tim = mri_read_1D( argv[iarg] ) ;
     if( tim == NULL ) ERROR_exit("Can't read 1D file '%s'",argv[iarg]) ;
     if( nx == 0 ){
       nx = tim->nx ;
       if( nx < 3 )
         ERROR_exit("1D file '%.77s' length=%d is less than 3",argv[iarg],nx) ;
       else if( nx < 7 )
         WARNING_message("1D file '%.77s' length=%d is less than 7",argv[iarg],nx) ;
     } else if( tim->nx != nx ){
       ERROR_exit("Length of 1D file '%.77s' [%d] doesn't match first file [%d]",
                   argv[iarg] , tim->nx , nx );
     }
     nvec += tim->ny ;
     ADDTO_IMARR(tar,tim) ;
   }

   /* user is really an idiot -- flogging's too good for him */

   if( nvec < 2 ) ERROR_exit("Must have at least 2 input columns!") ;

   if( nx < 20 && doblk ){
     doblk = 0 ;
     WARNING_message("Column length %d < 20 ==> cannot use block resampling",nx) ;
   }

   if( vsim != NULL ){
     if( vsim->nvox < nvec )
       ERROR_exit("-vsig file only has %d entries, but needs at least %d",vsim->nvox,nvec) ;
     vsig = MRI_FLOAT_PTR(vsim) ;
   }

   /* create vectors from 1D files */

   tvec = (float **)malloc( sizeof(float *)*nvec ) ;
   vecnam = (char **)malloc( sizeof(char *)*nvec ) ;
   for( jj=0 ; jj < nvec ; jj++ ){
     tvec[jj] = (float *)malloc( sizeof(float)*nx ) ;
     vecnam[jj] = (char *)malloc(sizeof(char)*THD_MAX_NAME) ;
   }

   /* copy data into new space, create output labels, check for stoopiditees */

   for( kk=mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     far = MRI_FLOAT_PTR(tim) ;
     tnam = tim->name ; if( tnam == NULL ) tnam = "File" ;
     for( jj=0 ; jj < tim->ny ; jj++,kk++ ){
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] = far[ii+jj*nx] ;
       sprintf(vecnam[kk],"%s[%d]",THD_trailname(tnam,0),jj) ; /* vector name */
       iarg = strlen(vecnam[kk]) ; vlen = MAX(vlen,iarg) ;
       if( THD_is_constant(nx,tvec[kk]) )
         ERROR_exit("Column %s is constant!",vecnam[kk]) ;
     }
   }
   DESTROY_IMARR(tar) ;

   /*--- Print a beeyootiful header ---*/

   printf("# %s correlation [n=%d #col=%d]\n",cor_name[cormeth],nx,nvec) ;
   sprintf(fmt,"# %%-%ds  %%-%ds",vlen,vlen) ;
   printf(fmt,"Name","Name") ;
   printf("   Value   BiasCorr  %5.2f%%   %5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   if( cormeth == 0 )  /* Pearson */
     printf("  N:%5.2f%% N:%5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   printf("\n") ;
   printf("# ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf("  ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf(" ") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   if( cormeth == 0 ){ printf(" --------") ; printf(" --------") ; }
   printf("\n") ;
   if( cormeth != 0 )  /* non-Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;
   else                /* Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;

   /*--- Do some actual work for a suprising change ---*/

   for( jj=0 ; jj < nvec ; jj++ ){       /* loops over column pairs */
     for( kk=jj+1 ; kk < nvec ; kk++ ){

       if( vsig != NULL ){ xsig = vsig[jj]; ysig = vsig[kk]; } else { xsig = ysig = 0.0f; }

       qcor = Corrboot( nx, tvec[jj], tvec[kk], xsig, ysig, corfun ) ;  /* outsourced */

       corst = qcor.a ; cor025 = qcor.b ; cor500 = qcor.c ; cor975 = qcor.d ;

       if( cormeth == 0 ){                      /* Pearson */
         pci = PCorrCI( nx , corst , alpha ) ;
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975, pci.a,pci.b ) ;
       } else {                                 /* all other methods */
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975 ) ;
       }

     }
   }

   /* Finished -- go back to watching Star Trek reruns -- Tribbles ahoy, Cap'n! */

   exit(0) ;
}
Пример #29
0
int main( int argc , char * argv[] )
{
   int iarg=1 , dcode=0 , maxgap=2 , nftot=0 ;
   char * prefix="zfillin" , * dstr=NULL;
   THD_3dim_dataset * inset , * outset ;
   MRI_IMAGE * brim ;
   int verb=0 ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: 3dZFillin [options] dataset\n"
             "Extracts 1D rows in the given direction from a 3D dataset,\n"
             "searches for zeros that are 'close' to nonzero values in the row,\n"
             "and replaces the zeros with the closest nonzero neighbor.\n"
             "\n"
             "OPTIONS:\n"
             " -maxstep N  = set the maximum distance to a neighbor\n"
             "                [default=2].\n"
             " -dir D     = set the direction of fill to 'D', which can\n"
             "                be one of the following:\n"
             "                  A-P, P-A, I-S, S-I, L-R, R-L, x, y, z\n"
             "                The first 6 are anatomical directions;\n"
             "                the last 3 are reference to the dataset\n"
             "                internal axes [no default value].\n"
             " -prefix P  = set the prefix to 'P' for the output dataset.\n"
             "\n"
             "N.B.: * If the input dataset has more than one sub-brick,\n"
             "        only the first one will be processed.\n"
             "      * At this time, 3dZFillin only works on byte-valued datasets\n"
             "\n"
             "This program's only purpose is to fill up the Talairach Daemon\n"
             "bricks obtained from the UT San Antonio database.\n"
             "\n"
            ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   mainENTRY("3dZFillin main") ; machdep() ; AFNI_logger("3dZfillin",argc,argv) ;
   PRINT_VERSION(3dZFillin") ;

   /*-- scan args --*/

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

      if( strncmp(argv[iarg],"-verb",5) == 0 ){
         verb++ ; iarg++ ; continue ;
      }

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

      if( strcmp(argv[iarg],"-maxstep") == 0 ){
         maxgap = strtol( argv[++iarg] , NULL , 10 ) ;
         if( maxgap < 1 ){
            fprintf(stderr,"*** Illegal value after -maxgap!\n"); exit(1);
         }
         iarg++ ; continue ;
      }

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

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

   if( dstr == NULL ){
      fprintf(stderr,"*** No -dir option on command line!\n"); exit(1);
   }
   if( iarg >= argc ){
      fprintf(stderr,"*** No input dataset on command line!\n"); exit(1);
   }

   inset = THD_open_dataset( argv[iarg] ) ;
   if( inset == NULL ){
      fprintf(stderr,"*** Can't open dataset %s\n",argv[iarg]); exit(1);
   }

   outset = EDIT_empty_copy( inset ) ;
   EDIT_dset_items( outset , ADN_prefix , prefix , ADN_none ) ;
   if( THD_deathcon() && THD_is_file( DSET_HEADNAME(outset) ) ){
      fprintf(stderr,"** Output file %s exists -- cannot overwrite!\n",
              DSET_HEADNAME(outset) ) ;
      exit(1) ;
   }

   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dZFillin" , argc,argv , outset ) ;

   if( DSET_NVALS(inset) > 1 ){
      fprintf(stderr,"++ WARNING: input dataset has more than one sub-brick!\n");
      EDIT_dset_items( outset ,
                         ADN_ntt   , 0 ,
                         ADN_nvals , 1 ,
                       ADN_none ) ;
   }

   if( DSET_BRICK_TYPE(outset,0) != MRI_byte ){
      fprintf(stderr,"*** This program only works on byte datasets!\n");
      exit(1) ;
   }

   switch( *dstr ){
      case 'x': dcode = 1 ; break ;
      case 'y': dcode = 2 ; break ;
      case 'z': dcode = 3 ; break ;

      default:
        if( *dstr == ORIENT_tinystr[outset->daxes->xxorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->xxorient][1]   ) dcode = 1 ;

        if( *dstr == ORIENT_tinystr[outset->daxes->yyorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->yyorient][1]   ) dcode = 2 ;

        if( *dstr == ORIENT_tinystr[outset->daxes->zzorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->zzorient][1]   ) dcode = 3 ;
      break ;
   }
   if( dcode == 0 ){
      fprintf(stderr,"*** Illegal -dir direction!\n") ; exit(1) ;
   }
   if( verb )
      fprintf(stderr,"++ Direction = axis %d in dataset\n",dcode) ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   brim = mri_copy( DSET_BRICK(inset,0) ) ;
   DSET_unload(inset) ;
   EDIT_substitute_brick( outset , 0 , brim->kind , mri_data_pointer(brim) ) ;
   nftot = THD_dataset_zfillin( outset , 0 , dcode , maxgap ) ;
   fprintf(stderr,"++ Number of voxels filled = %d\n",nftot) ;
   if (DSET_write(outset) != False) {
      fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ;
      exit(0) ;
   } else {
      fprintf(stderr,
         "** 3dZFillin: Failed to write output!\n" ) ;
      exit(1) ;
   }
   
}
Пример #30
0
int main( int argc , char *argv[] )
{
   MRI_IMAGE *imin, *imout , *imout_orig;
   THD_3dim_dataset *iset, *oset , *ooset;
   char *prefix = "SpatNorm", *bottom_cuts = NULL;
   int iarg , verb=0, OrigSpace = 0 , specie = HUMAN;
   float SpatNormDxyz= 0.0, iset_scaled=1.0;
   THD_ivec3 orixyz , nxyz ;
   THD_fvec3 dxyz , orgxyz, originRAIfv, fv2;


   mainENTRY("3dSpatNorm main") ; machdep() ; 
   if (argc == 1) { usage_3dSpatNorm(1); exit(0); }

   /*--- options ---*/

   iarg = 1 ;
   OrigSpace = 0;
   while( iarg < argc && argv[iarg][0] == '-' ){
      if (strcmp(argv[iarg],"-h") == 0 || strcmp(argv[iarg],"-help") == 0 ) { 
         usage_3dSpatNorm(strlen(argv[iarg]) > 3 ? 2:1);
         exit(0); 
      }
      
     /* -prefix */

     if( strcmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"**ERROR: -prefix requires another argument!\n") ;
         exit(1) ;
       }
       prefix = strdup(argv[iarg]) ;
       if( !THD_filename_ok(prefix) ){
         fprintf(stderr,"**ERROR: -prefix value contains forbidden characters!\n") ;
         exit(1) ;
       }
       iarg++ ; continue ;
     }

     if( strcmp(argv[iarg],"-dxyz") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"**ERROR: -dxyz requires another argument!\n") ;
         exit(1) ;
       }
       SpatNormDxyz = atof(argv[iarg]) ;
       
       iarg++ ; continue ;
     }
     if( strcmp(argv[iarg],"-bottom_cuts") == 0 ){
       if( ++iarg >= argc ){
         fprintf(stderr,"**ERROR: -bottom_cuts requires another argument!\n") ;
         exit(1) ;
       }
       bottom_cuts = argv[iarg] ;
       
       iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-verb",5) == 0 ){
       verb++ ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-human",5) == 0 ){
       specie = HUMAN ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-monkey",5) == 0 ){
       specie = MONKEY ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-marmoset",5) == 0 ){
       specie = MARMOSET ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-rat",5) == 0 ){
       specie = RAT ; iarg++ ; continue ;
     }
     if( strncmp(argv[iarg],"-orig_space",10) == 0 ){
       OrigSpace = 1 ; iarg++ ; continue ;
     }
     
     fprintf(stderr,"**ERROR: %s is unknown option!\n",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1) ;
   }

   if( iarg >= argc ){
     fprintf(stderr,"**ERROR: no input dataset name on command line?!\n") ;
     exit(1) ;
   }

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

   iset = THD_open_dataset( argv[iarg] ) ;
   if( !ISVALID_DSET(iset) ){
     fprintf(stderr,"**ERROR: can't open dataset %s\n",argv[iarg]) ;
     exit(1) ;
   }

   /*--- get median brick --*/

   if( verb ) fprintf(stderr,"++3dSpatNorm: loading dataset\n") ;

   if (specie == MARMOSET) {
      iset_scaled = 2.5;
      THD_volDXYZscale(iset->daxes, iset_scaled, 0);
      specie = MONKEY;
   }
   imin = THD_median_brick( iset ) ;
   if( imin == NULL ){
     fprintf(stderr,"**ERROR: can't load dataset %s\n",argv[iarg]) ;
     exit(1) ;
   }
   imin->dx = fabs(iset->daxes->xxdel) ;
   imin->dy = fabs(iset->daxes->yydel) ;
   imin->dz = fabs(iset->daxes->zzdel) ;
   
   
   mri_speciebusiness(specie);
   mri_brain_normalize_cuts(bottom_cuts);
   
   if (SpatNormDxyz) {
      if (verb) fprintf(stderr,"Overriding default resampling\n");
      mri_brainormalize_initialize(SpatNormDxyz, SpatNormDxyz, SpatNormDxyz);
   } else {
      float xxdel, yydel, zzdel, minres;
      if (specie == MONKEY) minres = 0.5;
      else if (specie == MARMOSET) minres = 0.2;
      else if (specie == RAT) minres = 0.1;
      else minres = 0.5;
      /* don't allow for too low a resolution, please */
      if (imin->dx < minres) xxdel = minres;
      else xxdel = imin->dx;
      if (imin->dy < minres) yydel = minres;
      else yydel = imin->dy;
      if (imin->dz < minres) zzdel = minres;
      else zzdel = imin->dz;
      if (verb) {
         fprintf(stderr,
                  "%s:\n"
                  " Original resolution %f, %f, %f\n"
                  " SpatNorm resolution %f, %f, %f\n",
                  "3dSpatnorm", imin->dx, imin->dy, imin->dz, 
                     xxdel, yydel, zzdel);
      }   
      mri_brainormalize_initialize(xxdel, yydel, zzdel);
   }
   
      /* To get around the #define for voxel counts and dimensions */
   mri_brainormalize_initialize(imin->dz, imin->dy, imin->dz); 
   
   /* me needs the origin of this dset in RAI world */
   LOAD_FVEC3( originRAIfv , 
               iset->daxes->xxorg , iset->daxes->yyorg , iset->daxes->zzorg) ;
   originRAIfv = THD_3dmm_to_dicomm( iset , originRAIfv ) ;

   LOAD_FVEC3(fv2, iset->daxes->xxorg + (iset->daxes->nxx-1)*iset->daxes->xxdel ,
                   iset->daxes->yyorg + (iset->daxes->nyy-1)*iset->daxes->yydel ,
                   iset->daxes->zzorg + (iset->daxes->nzz-1)*iset->daxes->zzdel);
   fv2 = THD_3dmm_to_dicomm( iset , fv2 ) ;

   if( originRAIfv.xyz[0] > fv2.xyz[0] ) { 
      float tf; tf = originRAIfv.xyz[0]; 
                originRAIfv.xyz[0] = fv2.xyz[0];  fv2.xyz[0] = tf; } 
   if( originRAIfv.xyz[1] > fv2.xyz[1] ) { 
      float tf; tf = originRAIfv.xyz[1]; 
                originRAIfv.xyz[1] = fv2.xyz[1]; fv2.xyz[1] = tf; }
   if( originRAIfv.xyz[2] > fv2.xyz[2] ) { 
      float tf; tf = originRAIfv.xyz[2]; 
                originRAIfv.xyz[2] = fv2.xyz[2]; fv2.xyz[2] = tf; }
   
   if (verb) {
      fprintf(stderr,"++3dSpatNorm (ZSS): RAI origin info: %f %f %f\n", 
                     originRAIfv.xyz[0], originRAIfv.xyz[1], originRAIfv.xyz[2]);
   }
   
   
   DSET_unload( iset ) ;  /* don't need this data no more */

   /*-- convert image to shorts, if appropriate --*/

   if( DSET_BRICK_TYPE(iset,0) == MRI_short ||
       DSET_BRICK_TYPE(iset,0) == MRI_byte    ){

     imout = mri_to_short(0.0,imin) ; /* ZSS Oct 2012: Let function set scaling*/
     mri_free(imin) ; imin = imout ;
   }

   /*--- normalize image spatially ---*/

   mri_brainormalize_verbose( verb ) ;
   if (OrigSpace) {
      imout = mri_brainormalize( imin , iset->daxes->xxorient,
                                     iset->daxes->yyorient,
                                     iset->daxes->zzorient , &imout_orig, NULL) ;
   } else {
      imout = mri_brainormalize( imin , iset->daxes->xxorient,
                                     iset->daxes->yyorient,
                                     iset->daxes->zzorient , NULL, NULL) ;
   }
   mri_free( imin ) ;

   if( imout == NULL ){
     fprintf(stderr,"**ERROR: normalization fails!?\n"); exit(1);
   }
   
   if (OrigSpace) {
      if( verb ) fprintf(stderr,"++3dSpatNorm: Output in Orignal space\n") ;
      mri_free( imout ) ;
      imout = imout_orig; 
      imout->xo = originRAIfv.xyz[0]; 
      imout->yo = originRAIfv.xyz[1]; 
      imout->zo = originRAIfv.xyz[2]; 
      imout_orig = NULL;
   } else {
      if( verb ) fprintf(stderr,"++3dSpatNorm: Output in SpatNorm space\n") ;
   }
   
#if 0
   if( AFNI_yesenv("WATERSHED") ){
     imin = mri_watershedize( imout , 0.10 ) ;
     if( imin != NULL ){ mri_free(imout); imout = imin; }
   }
#endif

   /*--- create output dataset ---*/
   if( verb )
     fprintf(stderr,"++3dSpatNorm: Creating output dset\n") ;

   oset = EDIT_empty_copy( NULL ) ;

   tross_Copy_History( iset , oset ) ;
   tross_Make_History( "3dSpatNorm" , argc,argv , oset ) ;

   LOAD_IVEC3( nxyz   , imout->nx    , imout->ny    , imout->nz    ) ;
   LOAD_FVEC3( dxyz   , imout->dx    , imout->dy    , imout->dz    ) ;
   LOAD_FVEC3( orgxyz , imout->xo    , imout->yo    , imout->zo    ) ;
   LOAD_IVEC3( orixyz , ORI_R2L_TYPE , ORI_A2P_TYPE , ORI_I2S_TYPE ) ;

   if( verb )
     fprintf(stderr,"++3dSpatNorm: EDIT_dset_items\n") ;
   EDIT_dset_items( oset ,
                      ADN_prefix      , prefix ,
                      ADN_datum_all   , imout->kind ,
                      ADN_nxyz        , nxyz ,
                      ADN_xyzdel      , dxyz ,
                      ADN_xyzorg      , orgxyz ,
                      ADN_xyzorient   , orixyz ,
                      ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
                      ADN_view_type   , VIEW_ORIGINAL_TYPE ,
                      ADN_type        , HEAD_ANAT_TYPE ,
                      ADN_func_type   , ANAT_BUCK_TYPE ,
                    ADN_none ) ;

   if( verb )
     fprintf(stderr,"++3dSpatNorm: EDIT_substitute_brick\n") ;
   EDIT_substitute_brick( oset , 0 , imout->kind , mri_data_pointer(imout) ) ;

   if (OrigSpace) {
      if( verb )
         fprintf(stderr,"++3dSpatNorm: Changing orientation from RAI\n") ;
      ooset = r_new_resam_dset ( oset, iset, 0, 0, 0, NULL, MRI_NN, NULL, 1, 0);
      if (!ooset) {
         fprintf(stderr,"**ERROR: Failed to reslice!?\n"); exit(1);
      }
      /* put prefix back, r_new_resam_dset puts dummy prefix */
      EDIT_dset_items( ooset ,
                       ADN_prefix      , prefix,
                       ADN_none ) ;

      DSET_delete(oset); oset = ooset; ooset = NULL;
   }

   if (iset_scaled != 1.0f) 
      THD_volDXYZscale(oset->daxes,
                      1/iset_scaled, 0);

   DSET_write(oset) ;
   if( verb )
     fprintf(stderr,"++3dSpatNorm: wrote dataset %s\n",DSET_BRIKNAME(oset)) ;
   
   exit(0) ;
}