示例#1
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) ;
   }
   
}
示例#2
0
void initialize_program (int argc, char * argv[])
{
  int iv;                  /* index number of sub-brick */
  void * vfim = NULL;      /* sub-brick data pointer */
  float * ffim = NULL;     /* sub-brick data in floating point format */
  int ixyz;                /* voxel index */
  int nx, ny, nz, nxyz;    /* numbers of voxels in input dataset */
  int mx=0, my=0, mz=0, mxyz;    /* numbers of voxels in mask dataset */
  int nthr=0;                /* number of voxels above mask threshold */
  char message[80];        /* error message */
  int ibin;                /* p-value bin index */


  /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/
  machdep() ; 
  { int new_argc ; char ** new_argv ;
  addto_args( argc , argv , &new_argc , &new_argv ) ;
  if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
  }
  

  /*----- Save command line for history notes -----*/
  commandline = tross_commandline( PROGRAM_NAME , argc,argv ) ;


  /*----- Does user request help menu? -----*/
  if( argc < 2 || strcmp(argv[1],"-help") == 0 ) FDR_Syntax() ;

  
  /*----- Add to program log -----*/
  AFNI_logger (PROGRAM_NAME,argc,argv); 


  /*----- Read input options -----*/
  read_options( argc , argv ) ;


  /*----- Open the mask dataset -----*/
  if (FDR_mask_filename != NULL)
    {
      if (!FDR_quiet) 
        printf ("Reading mask dataset: %s \n", FDR_mask_filename);
      DOPEN (FDR_dset, FDR_mask_filename);

      if (FDR_dset == NULL)
      {
        sprintf (message, "Cannot open mask dataset %s", FDR_mask_filename); 
        FDR_error (message);
      }

      if (DSET_NVALS(FDR_dset) != 1)
        WARNING_message("Mask dataset: using sub-brick #0") ;


      /*----- Get dimensions of mask dataset -----*/
      mx   = DSET_NX(FDR_dset);   
      my   = DSET_NY(FDR_dset);   
      mz   = DSET_NZ(FDR_dset);
      mxyz = mx*my*mz;


      /*----- Allocate memory for float data -----*/
      ffim = (float *) malloc (sizeof(float) * mxyz);   MTEST (ffim);


      /*----- Convert mask dataset sub-brick to floats (in ffim) -----*/
      iv = 0 ;
      SUB_POINTER (FDR_dset, iv, 0, vfim);
      EDIT_coerce_scale_type (mxyz, DSET_BRICK_FACTOR(FDR_dset,iv),
			      DSET_BRICK_TYPE(FDR_dset,iv), vfim,  /* input  */
			      MRI_float                   , ffim); /* output */
  
      
      /*----- Allocate memory for mask volume -----*/
      FDR_mask = (byte *) malloc (sizeof(byte) * mxyz);
      MTEST (FDR_mask);
      
      
      /*----- Create mask of voxels above mask threshold -----*/
      nthr = 0;
      for (ixyz = 0;  ixyz < mxyz;  ixyz++){
        if (fabs(ffim[ixyz]) >= FDR_mask_thr){ FDR_mask[ixyz] = 1; nthr++; }
        else                                   FDR_mask[ixyz] = 0;
      }

      if (!FDR_quiet)  
        printf ("Number of voxels above mask threshold = %d \n", nthr);
      if (nthr < 1)  
        FDR_error ("No voxels above mask threshold.  Cannot continue.");


      /*----- Delete floating point sub-brick -----*/
      if (ffim != NULL) { free (ffim);   ffim = NULL; }

      /*----- Delete mask dataset -----*/
      THD_delete_3dim_dataset (FDR_dset, False);  FDR_dset = NULL ;

    }


  /*----- Get the input data -----*/

  if (FDR_input1D_filename != NULL)
    {
      /*----- Read the input .1D file -----*/
      if (!FDR_quiet)  printf ("Reading input data: %s \n", 
			       FDR_input1D_filename);
      FDR_input1D_data = read_time_series (FDR_input1D_filename, &nxyz);

      if (FDR_input1D_data == NULL)  
	{ 
	  sprintf (message,  "Unable to read input .1D data file: %s", 
		   FDR_input1D_filename);
	  FDR_error (message);
	}
      
      if (nxyz < 1)  
	{ 
	  sprintf (message,  "No p-values in input .1D data file: %s", 
		   FDR_input1D_filename);
	  FDR_error (message);
	}

      FDR_nxyz = nxyz;
      FDR_nthr = nxyz;
    }
  
  else
    {
      /*----- Open the input 3D dataset -----*/
      if (!FDR_quiet)  printf ("Reading input dataset: %s \n", 
			       FDR_input_filename);
      FDR_dset = THD_open_dataset(FDR_input_filename);
      CHECK_OPEN_ERROR(FDR_dset,FDR_input_filename);
      
      /*----- Get dimensions of input dataset -----*/
      nx   = DSET_NX(FDR_dset);   
      ny   = DSET_NY(FDR_dset);   
      nz   = DSET_NZ(FDR_dset);
      nxyz = nx*ny*nz;
      
      
      /*----- Check for compatible dimensions -----*/
      if (FDR_mask != NULL)
	{
	  if ((nx != mx) || (ny != my) || (nz != mz))
	    FDR_error ("Mask and input dataset have incompatible dimensions");
	  FDR_nxyz = nxyz;
	  FDR_nthr = nthr;
	}
      else
	{
	  FDR_nxyz = nxyz;
	  FDR_nthr = nxyz;
	}


      /*----- Check whether output dataset already exists -----*/
      if( THD_deathcon() ) check_one_output_file (FDR_dset, FDR_output_prefix);
    }


  /*----- Initialize constant c(N) -----*/
  if (FDR_cn < 0.0)
    {
      double cn;
      cn = 0.0;
      for (ixyz = 1;  ixyz <= FDR_nthr;  ixyz++)
	cn += 1.0 / ixyz;
      FDR_cn = cn;
      if (!FDR_quiet)
	printf ("c(N) = %f \n", FDR_cn);
    }
  
  /*----- Initialize voxel pointers -----*/
  for (ibin = 0;  ibin < FDR_MAX_LL;  ibin++)
    FDR_head_voxel[ibin] = NULL;

  return ;
}
示例#3
0
文件: 3dttest.c 项目: Gilles86/afni
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) ;
}
示例#4
0
int main( int argc , char * argv[] )
{
   THD_3dim_dataset *dset, *outset=NULL;
   int iarg=1, npad = 0, extent=0;
   char *prefix=NULL, *iname=NULL;

   char *oijkext = NULL;
   FILE *fout_ijkext=NULL;
   int extent_ijk=0;
   int extent_ijk_midslice=0;
   int imid=0, jmid=0, kmid=0;
   int extent_xyz_midslice=0;
   float xmid=0, ymid=0, zmid=0;


   /*-- startup bureaucracy --*/

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

   /*-- read command line options --*/

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

      if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
         help_autobox();
         exit(0) ;
      }

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

      if( strcmp(argv[iarg],"-input") == 0 ){
         iname = argv[++iarg] ;
         // This is a bad check, because it doesn't permit subbrick
         // selection!  Will do check later.
         /*if( !THD_filename_ok(iname) ){
            fprintf(stderr,"** 3dAutobox: Illegal string after -input!\n"); 
            exit(1) ;
            }*/
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-noclust") == 0 ){
         MRI_autobbox_clust(0) ;  /* turn of clustering and clipping */
         THD_autobbox_clip(0) ;
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-npad") == 0 ){
        npad = (int)strtod(argv[++iarg],NULL) ;
        iarg++ ; continue ;
      }

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

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

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

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

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

     /*- washappenin, dood? -*/

      ERROR_message("** 3dAutobox: %s makes no sense here.\n",
                 argv[iarg]) ;
      suggest_best_prog_option(argv[0], argv[iarg]);
      exit(1);
   }

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

   /* got input ? */

   if( iarg == argc-1 )
     iname = argv[iarg] ;
   else if (iarg != argc)
     ERROR_exit("** 3dAutobox: %s is nonsense on the line \n"
                "   I know you're John; stop pretending you have an accent!",
                argv[iarg]) ;

   if( !iname )
     ERROR_exit("** 3dAutobox: Where is my input?") ;

   /*-- read data --*/

   dset = THD_open_dataset(iname); 
   // Check here instead of after -input.
   if( dset == NULL )
      ERROR_exit("Can't open time series dataset '%s'.",iname);
   CHECK_OPEN_ERROR(dset,iname);

   if( DSET_BRICK_TYPE(dset,0) != MRI_short &&
       DSET_BRICK_TYPE(dset,0) != MRI_byte  &&
       DSET_BRICK_TYPE(dset,0) != MRI_float   )
       ERROR_exit("** ILLEGAL dataset type: %s :-(",
                  MRI_type_name[DSET_BRICK_TYPE(dset,0)]) ;

   DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;

   {
      int nx=DSET_NX(dset), ny=DSET_NY(dset), nz=DSET_NZ(dset), nxy=nx*ny ;
      int xm=-1,xp=-1,ym=-1,yp=-1,zm=-1,zp=-1;
      THD_autobbox( dset , &xm,&xp , &ym,&yp , &zm,&zp, NULL ) ;

      xm -= npad; ym -= npad; zm -= npad;  /* for LRF */
      xp += npad; yp += npad; zp += npad;

      INFO_message("Auto bbox: x=%d..%d  y=%d..%d  z=%d..%d\n",
                   xm,xp,ym,yp,zm,zp ) ;

      // [PT: Oct 18, 2018] New output text file, if desired
      if( oijkext ) {
         if( (fout_ijkext = fopen(oijkext, "w")) == NULL ) {
            fprintf(stderr, "\n\nError opening file %s.\n", oijkext);
            exit(1);
         }
         fprintf( fout_ijkext, "%8d %8d %8d %8d %8d %8d\n",
                  xm, xp, ym, yp, zm, zp );
         fclose(fout_ijkext);
         INFO_message("Wrote ijk extents file: %s", oijkext);
      }

      if( extent_ijk ) 
         printf( "%8d %8d %8d %8d %8d %8d\n",
                 xm, xp, ym, yp, zm, zp );

      if( extent_ijk_midslice ) {
         imid = (xm + xp) / 2;  // integer division fine, b/c we need ints
         jmid = (ym + yp) / 2;
         kmid = (zm + zp) / 2;
         printf( "%8d %8d %8d\n", imid, jmid, kmid );
      }


      if ( (extent && !prefix) || (extent_xyz_midslice && !prefix) )
         prefix = "EXTENT_ONLY";

      if( prefix ){
         outset = THD_zeropad( dset ,
                            -xm, xp-nx+1,
                            -ym, yp-ny+1,
                            -zm, zp-nz+1,
                            prefix , ZPAD_IJK ) ;
         if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) )
            ERROR_exit("3dAutobox: output file %s already exists :-(",
                       DSET_HEADNAME(outset) ) ;

         if( outset == NULL )
            ERROR_exit("3dAutobox: Some error occurred in processing :-(") ;

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

         if (!strstr(prefix,"EXTENT_ONLY")) {
            DSET_write(outset) ;
            INFO_message("3dAutobox: output dataset = %s",
                         DSET_BRIKNAME(outset)) ;
         }
         if (extent) {
          float RL_AP_IS[6];
          THD_dset_extent(outset, '-', RL_AP_IS);
          printf("Extent auto bbox: R=%f L=%f  A=%f P=%f  I=%f S=%f\n",
                    RL_AP_IS[0],RL_AP_IS[1],
                    RL_AP_IS[2],RL_AP_IS[3],
                    RL_AP_IS[4],RL_AP_IS[5] ) ;
         }
         if( extent_xyz_midslice ) {
            INFO_message("aaa" );
            float RL_AP_IS2[6];
            THD_dset_extent(outset, '-', RL_AP_IS2);
            xmid = (RL_AP_IS2[0] + RL_AP_IS2[1]) / 2.;
            ymid = (RL_AP_IS2[2] + RL_AP_IS2[3]) / 2.;
            zmid = (RL_AP_IS2[4] + RL_AP_IS2[5]) / 2.;
            printf( "%10.5f %10.5f %10.5f\n", xmid, ymid, zmid );
         }
      }
   }

   exit(0) ;
}
示例#5
0
int main( int argc , char * argv[] )
{
   int ninp , ids , nv , iv,jv,kv , ivout , new_nvals , have_fdr = 0, nfdr = 0 ;
   THD_3dim_dataset * new_dset=NULL , * dset ;
   char buf[256] ;
   double angle;

   /*----- identify program -----*/
#if 0
   printf ("\n\nProgram %s \n", PROGRAM_NAME);
   printf ("Last revision: %s \n\n", LAST_MOD_DATE);
#endif

   /*** read input options ***/


   mainENTRY("3dbucket main"); machdep(); PRINT_VERSION("3dbucket") ;
   set_obliquity_report(0); /* silence obliquity */
   
   /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/

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

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

   BUCK_read_opts( argc , argv ) ;

   /*** create new dataset (empty) ***/
   ninp = BUCK_dsar->num ;
   if( ninp < 1 ){
      fprintf(stderr,"*** No input datasets?\n") ; exit(1) ;
   }

   new_nvals = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ;

   if( BUCK_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ;

   new_dset = EDIT_empty_copy( DSUB(0) ) ;

   /* 23 May 2005: check for axis consistency */
   /* 06 Feb 2008: and see if there are fdrcurves to perpetuate */

   if( DSUB(0)->dblk->brick_fdrcurve ) have_fdr = 1 ;
   for( iv=1 ; iv < ninp ; iv++ ){
     if( !EQUIV_DATAXES(new_dset->daxes,DSUB(iv)->daxes) )
       fprintf(stderr,"++ WARNING: %s grid mismatch with %s\n",
               DSET_BRIKNAME(DSUB(0)) , DSET_BRIKNAME(DSUB(iv)) ) ;
     if( DSUB(iv)->dblk->brick_fdrcurve ) have_fdr = 1 ;
     angle = dset_obliquity_angle_diff(new_dset, DSUB(iv), -1.0);
     if (angle > 0.0) {
       WARNING_message(
          "dataset %s has an obliquity difference of %f degress with %s\n",
          new_dset ,
          angle, DSUB(iv) );
     }
   }

   /*  if( ninp == 1 ) */   tross_Copy_History( DSUB(0) , new_dset ) ;
   tross_Make_History( "3dbucket" , argc,argv , new_dset ) ;

   EDIT_dset_items( new_dset ,
                      ADN_prefix        , BUCK_output_prefix ,
                      ADN_directory_name, BUCK_session ,
                      ADN_type          , BUCK_type ,
                      ADN_func_type     , ISANATTYPE(BUCK_type) ? ANAT_BUCK_TYPE
                                                                : FUNC_BUCK_TYPE,
                      ADN_ntt           , 0 ,
                      ADN_nvals         , new_nvals ,
                    ADN_none ) ;

   /* can't re-write existing dataset, unless glueing is used */

   if (! BUCK_glue){
     if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){
       fprintf(stderr,"*** Fatal error: file %s already exists!\n",
               DSET_HEADNAME(new_dset) ) ;
       exit(1) ;
     }
   } else {   /* if glueing is used, make the 'new'
                 dataset have the same idcode as the old one */

      new_dset->idcode = DSUB(0) -> idcode ;  /* copy the struct */
   }

   THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ;

   /* if there are fdr curves, allocate space    06 Feb 2008 [rickr] */
   if( have_fdr ){
      new_dset->dblk->brick_fdrcurve = (floatvec **)calloc(sizeof(floatvec *),
                                                           new_nvals) ;
      if( !new_dset->dblk->brick_fdrcurve ){
         fprintf(stderr,"** failed to alloc %d fdrcurves\n",new_nvals);
         exit(1);
      }
      if( BUCK_verb ) printf("-verb: adding fdrcurve list\n");

      new_dset->dblk->brick_mdfcurve = (floatvec **)calloc(sizeof(floatvec *),
                         /* 22 Oct 2008 */                 new_nvals) ;
   }

   /*** loop over input datasets ***/

   if( ninp > 1 ) myXtFree( new_dset->keywords ) ;

   ivout = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ){
      dset = DSUB(ids) ;
      nv   = NSUBV(ids) ;

      if( ! BUCK_dry ){
         DSET_load(dset) ;  CHECK_LOAD_ERROR(dset) ;
      }
      /** loop over sub-bricks to output **/

      for( iv=0 ; iv < nv ; iv++ ){
         jv = SUBV(ids,iv) ;                /* which sub-brick to use */

         if( ! BUCK_dry ){
            EDIT_substitute_brick( new_dset , ivout ,
                                   DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ;

            /*----- preserve label when one exists --- Modified March 2010 ZSS*/
            if (DSET_HAS_LABEL(dset, jv) ) 
              sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv));
            else
              sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ;
            EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ;

#if 0
            sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ;
            EDIT_dset_items(
              new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ;
#endif

            EDIT_dset_items(
              new_dset ,
                ADN_brick_fac_one            +ivout, DSET_BRICK_FACTOR(dset,jv),
#if 0
                ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) ,
#endif
              ADN_none ) ;

            /** possibly write statistical parameters for this sub-brick **/

            kv = DSET_BRICK_STATCODE(dset,jv) ;

            if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */

               int npar = FUNC_need_stat_aux[kv] , lv ;
               float * par = (float *) malloc( sizeof(float) * (npar+2) ) ;
               float * sax = DSET_BRICK_STATAUX(dset,jv) ;
               par[0] = kv ;
               par[1] = npar ;
               for( lv=0 ; lv < npar ; lv++ )
                  par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ;

               EDIT_dset_items(new_dset ,
                                ADN_brick_stataux_one+ivout , par ,
                               ADN_none ) ;
               free(par) ;

            /* 2: if the input dataset has statistical parameters */

            } else if( ISFUNC(dset)                        &&   /* dset has stat */
                       FUNC_IS_STAT(dset->func_type)       &&   /* params        */
                       jv == FUNC_ival_thr[dset->func_type]  ){ /* thr sub-brick */

               int npar , lv ;
               float * par , * sax ;
               kv  = dset->func_type ;
               npar = FUNC_need_stat_aux[kv] ;
               par  = (float *) malloc( sizeof(float) * (npar+2) ) ;
               sax  = dset->stat_aux ;
               par[0] = kv ;
               par[1] = npar ;
               for( lv=0 ; lv < npar ; lv++ )
                  par[lv+2] = (sax != NULL) ? sax[lv] : 0.0 ;

               EDIT_dset_items(new_dset ,
                                ADN_brick_stataux_one+ivout , par ,
                               ADN_none ) ;
               free(par) ;
            }

            /** append any fdrcurve **/
            if( have_fdr ){
               /* fixed iv->jv (ick!), noticed by dglen  16 Mar 2010 [rickr] */
               if(dset->dblk->brick_fdrcurve && dset->dblk->brick_fdrcurve[jv]){
                  COPY_floatvec(new_dset->dblk->brick_fdrcurve[ivout],
                                    dset->dblk->brick_fdrcurve[jv]) ;
                  nfdr++;
               }
               else new_dset->dblk->brick_fdrcurve[ivout] = NULL ;

               if(dset->dblk->brick_mdfcurve && dset->dblk->brick_mdfcurve[jv]){
                  COPY_floatvec(new_dset->dblk->brick_mdfcurve[ivout],
                                    dset->dblk->brick_mdfcurve[jv]) ;
               }
               else new_dset->dblk->brick_mdfcurve[ivout] = NULL ;
            }

            /** print a message? **/

            if( BUCK_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" ,
                                   DSET_FILECODE(dset) , jv ,
                                   DSET_FILECODE(new_dset) , ivout ) ;
         } else {
            printf("-dry: would copy %s[%d] into %s[%d]\n" ,
                    DSET_FILECODE(dset) , jv ,
                    DSET_FILECODE(new_dset) , ivout ) ;
         }

         ivout++ ;
      }

      /** loop over all bricks in input dataset and
          unload them if they aren't going into the output
          (not required, but is done to economize on memory) **/

      if( ! BUCK_dry && nv < DSET_NVALS(dset) ){

         for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){  /* all input sub-bricks */
            for( iv=0 ; iv < nv ; iv++ ){             /* all output sub-bricks */
               jv = SUBV(ids,iv) ;
               if( jv == kv ) break ;                 /* input matches output */
            }
            if( iv == nv ){
               mri_free( DSET_BRICK(dset,kv) ) ;
#if 0
               if( BUCK_verb ) printf("-verb: unloaded unused %s[%d]\n" ,
                                      DSET_FILECODE(dset) , kv ) ;
#endif
            }
         }
      }

   } /* end of loop over input datasets */

   if( ! BUCK_dry ){
      if( BUCK_verb ){
         if( have_fdr ) fprintf(stderr,"-verb: added %d of %d fdr curves\n",
                                nfdr, new_nvals);
         fprintf(stderr,"-verb: loading statistics\n") ;
      }
      THD_load_statistics( new_dset ) ;
      if( BUCK_glue ) putenv("AFNI_DECONFLICT=OVERWRITE") ;
      if( BUCK_glue && BUCK_ccode >= 0 )
        THD_set_write_compression(BUCK_ccode) ; /* 16 Mar 2010 */
      THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
      if( BUCK_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ;
   }

   exit(0) ;
}
示例#6
0
int main( int argc , char * argv[] )
{
   THD_dfvec3 *xx , *yy , dv ;
   int nvec=0 , ii,jj, iarg ;
   THD_dvecmat rt , rtinv ;
   THD_dmat33  pp,ppt , rr ;
   THD_dfvec3  tt ;

   THD_3dim_dataset *mset=NULL , *dset=NULL ;
   double *ww=NULL ;
   int     nww=0 ;
   int keeptags=1 , wtval=0 , verb=0 , dummy=0 ;
   char * prefix = "tagalign" , *mfile=NULL ;

   float *fvol , cbot,ctop , dsum ;
   int nval , nvox , clipit , ival, RMETH=MRI_CUBIC;

   float matar[12] ;

   int use_3dWarp=1 , matrix_type=ROTATION ;

   mainENTRY("3dTagalign main");
   
   /*--- help? ---*/

   /*- scan args -*/
   iarg = 1 ; RMETH=MRI_CUBIC;
   while( iarg < argc && argv[iarg][0] == '-' ){

      /*-----*/

      if( strcmp(argv[iarg],"-h") == 0 ||
          strcmp(argv[iarg],"-help") == 0){   /* 22 Apr 2003 */
        usage_3dTagalign(strlen(argv[iarg]) > 3 ? 2:1);
        exit(0);
      }
      
     /*-----*/

     if( strcmp(argv[iarg],"-NN")     == 0 ){
       RMETH = MRI_NN ; iarg++ ; continue ;
     }
     if( strcmp(argv[iarg],"-linear") == 0 ){
       RMETH = MRI_LINEAR ; iarg++ ; continue ;
     }
     if( strcmp(argv[iarg],"-cubic")  == 0 ){
       RMETH = MRI_CUBIC ; iarg++ ; continue ;
     }
     if( strcmp(argv[iarg],"-quintic") == 0 ){
       RMETH = MRI_QUINTIC ; iarg++ ; continue ;  
     }

      /*-----*/

      if( strcmp(argv[iarg],"-rotate") == 0 ){   /* 22 Apr 2003 */
        matrix_type = ROTATION ; use_3dWarp = 1 ;
        iarg++ ; continue ;
      }

      /*-----*/

      if( strcmp(argv[iarg],"-affine") == 0 ){   /* 21 Apr 2003 */
        matrix_type = AFFINE ; use_3dWarp = 1 ;
        iarg++ ; continue ;
      }

      /*-----*/

      if( strcmp(argv[iarg],"-rotscl") == 0 ){   /* 22 Apr 2003 */
        matrix_type = ROTSCL ; use_3dWarp = 1 ;
        iarg++ ; continue ;
      }

#if 0
      /*-----*/

      if( strcmp(argv[iarg],"-3dWarp") == 0 ){   /* 21 Apr 2003 */
        use_3dWarp = 1 ;
        iarg++ ; continue ;
      }
#endif

      /*-----*/

      if( strcmp(argv[iarg],"-master") == 0 ){
         if( mset != NULL )                    ERREX("Can only have one -master option") ;
         if( ++iarg >= argc )                  ERREX("Need an argument after -master") ;

         mset = THD_open_dataset( argv[iarg] ) ;

         if( mset == NULL )                    ERREX("Can't open -master dataset") ;
         if( mset->tagset == NULL )            ERREX("No tags in -master dataset") ;
         if( TAGLIST_COUNT(mset->tagset) < 3 ) ERREX("Not enough tags in -master dataset") ;

         for( nvec=ii=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ )
            if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ) nvec++ ;

         if( nvec < 3 )                        ERREX("Not enough tags set in -master dataset") ;

         if( nvec < TAGLIST_COUNT(mset->tagset) )
            fprintf(stderr,"++ WARNING: not all tags are set in -master dataset\n") ;

         if( verb ) fprintf(stderr,"++ Found %d tags in -master dataset\n",nvec) ;

         iarg++ ; continue ;
      }

#if 0
      /*-----*/

      if( strcmp(argv[iarg],"-wtval") == 0 ){
         if( ww != NULL )                      ERREX("Can't have -wtval after -wt1D") ;
         wtval++ ;
         iarg++ ; continue ;
      }

      /*-----*/

      if( strcmp(argv[iarg],"-wt1D") == 0 ){
         MRI_IMAGE * wtim ; float * wtar ;

         if( wtval )                           ERREX("Can't have -wt1D after -wtval") ;
         if( ww != NULL )                      ERREX("Can't have two -wt1D options!") ;
         if( ++iarg >= argc )                  ERREX("Need an argument after -wt1D") ;

         wtim = mri_read_1D( argv[iarg] ) ;

         if( wtim == NULL )                    ERREX("Can't read -wtim file") ;
         if( wtim->ny > 1 )                    ERREX("-wtim file has more than one columm") ;

         wtar = MRI_FLOAT_PTR(wtim) ;
         ww   = (double *) malloc(sizeof(double)*wtim->nx) ; nww = wtim->nx ;
         for( ii=0 ; ii < nww ; ii++ ){
            ww[ii] = (double) wtar[ii] ;
            if( ww[ii] < 0.0 )                 ERREX("Negative value found in -wt1D file") ;
         }

         mri_free(wtim) ;
         iarg++ ; continue ;
      }
#endif

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

      if( strcmp(argv[iarg],"-prefix") == 0 ){
         if( ++iarg >= argc )                  ERREX("Need an argument after -prefix") ;
         prefix = argv[iarg] ;
         if( !THD_filename_ok(prefix) )        ERREX("-prefix string is illegal") ;
         iarg++ ; continue ;
      }

      /*-----*/

      if( strcmp(argv[iarg],"-matvec") == 0 ){
         if( ++iarg >= argc )                  ERREX("Need an argument after -matvec") ;
         mfile = argv[iarg] ;
         if( !THD_filename_ok(mfile) )         ERREX("-matvec string is illegal") ;
         iarg++ ; continue ;
      }


      /*-----*/

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

   } /* end of scanning command line for options */

   if( argc < 2 ){
      ERROR_message("Too few options");
      usage_3dTagalign(0);
      exit(1) ;
   }


   if( mset == NULL )                    ERREX("No -master option found on command line") ;

#if 0
   if( ww != NULL && nww < nvec )        ERREX("Not enough weights found in -wt1D file") ;

   /*-- if -wtval, setup weights from master tag values --*/

   if( wtval ){
      ww = (double *) malloc(sizeof(double)*nvec) ; nww = nvec ;
      for( ii=jj=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ ){
         if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ){
            ww[jj] = (double) TAG_VAL(TAGLIST_SUBTAG(mset->tagset,ii)) ;

            if( ww[jj] < 0.0 )           ERREX("Negative value found in -master tag values") ;
            jj++ ;
         }
      }
   }
#endif

   /*-- read input dataset (to match to master dataset) --*/

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

   dset = THD_open_dataset( argv[iarg] ) ;

   if( dset == NULL )                    ERREX("Can't open input dataset") ;
   if( dset->tagset == NULL )            ERREX("No tags in input dataset") ;
   if( TAGLIST_COUNT(dset->tagset) !=
       TAGLIST_COUNT(mset->tagset)   )   ERREX("Tag counts don't match in -master and input") ;

   /* check if set tags match exactly */

   for( ii=0 ; ii < TAGLIST_COUNT(mset->tagset) ; ii++ ){
      if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) !=
          TAG_SET(TAGLIST_SUBTAG(dset->tagset,ii))    )
                                         ERREX("Set tags don't match in -master and input") ;
   }

   /*-- load vector lists: xx=master, yy=input --*/

   xx = (THD_dfvec3 *) malloc( sizeof(THD_dfvec3) * nvec ) ;
   yy = (THD_dfvec3 *) malloc( sizeof(THD_dfvec3) * nvec ) ;
   dsum = 0.0 ;
   for( ii=jj=0 ; ii < nvec ; ii++ ){
      if( TAG_SET(TAGLIST_SUBTAG(mset->tagset,ii)) ){

         LOAD_DFVEC3( xx[jj] ,                                      /* N.B.:     */
                     TAG_X( TAGLIST_SUBTAG(mset->tagset,ii) ) ,     /* these are */
                     TAG_Y( TAGLIST_SUBTAG(mset->tagset,ii) ) ,     /* in Dicom  */
                     TAG_Z( TAGLIST_SUBTAG(mset->tagset,ii) )  ) ;  /* order now */

         LOAD_DFVEC3( yy[jj] ,
                     TAG_X( TAGLIST_SUBTAG(dset->tagset,ii) ) ,
                     TAG_Y( TAGLIST_SUBTAG(dset->tagset,ii) ) ,
                     TAG_Z( TAGLIST_SUBTAG(dset->tagset,ii) )  ) ;

         dv    = SUB_DFVEC3( xx[jj] , yy[jj] ) ;
         dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1] + dv.xyz[2]*dv.xyz[2] ;

         jj++ ;
      }
   }

   dsum = sqrt(dsum/nvec) ;
   fprintf(stderr,"++ RMS distance between tags before = %.2f mm\n" , dsum ) ;

   /*-- compute best transformation from mset to dset coords --*/

   switch( matrix_type ){
     default:
     case ROTATION:
       rt = DLSQ_rot_trans( nvec , yy , xx , ww ) ;  /* in thd_rot3d.c */
     break ;

     case AFFINE:
       rt = DLSQ_affine   ( nvec , yy , xx ) ;       /* 21 Apr 2003 */
     break ;

     case ROTSCL:
       rt = DLSQ_rotscl   ( nvec , yy , xx , (DSET_NZ(dset)==1) ? 2 : 3 ) ;
     break ;
   }
   rtinv = INV_DVECMAT(rt) ;

   /*-- check for floating point legality --*/

   nval = 0 ;
   for( ii=0 ; ii < 3 ; ii++ ){
      dsum = rt.vv.xyz[ii] ; nval += thd_floatscan(1,&dsum) ;
      for( jj=0 ; jj < 3 ; jj++ ){
         dsum = rt.mm.mat[ii][jj] ; nval += thd_floatscan(1,&dsum) ;
      }
   }
   if( nval > 0 ){
      fprintf(stderr,"** Floating point errors during calculation\n"
                     "** of transform matrix and translation vector\n" ) ;
      exit(1) ;
   }

   /*-- check for rotation matrix legality --*/

   dsum = DMAT_DET(rt.mm) ;

   if( dsum == 0.0 || (matrix_type == ROTATION && fabs(dsum-1.0) > 0.01) ){
     fprintf(stderr,"** Invalid transform matrix computed: tags dependent?\n"
                    "** computed [matrix] and [vector] follow:\n" ) ;

     for( ii=0 ; ii < 3 ; ii++ )
       fprintf(stderr,"  [ %10.5f %10.5f %10.5f ]   [ %10.5f ] \n",
               rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] );

     exit(1) ;
   }

   /*-- print summary --*/

   if( verb ){
     fprintf(stderr,"++ Matrix & Vector [Dicom: x=R-L; y=A-P; z=I-S]\n") ;
     for( ii=0 ; ii < 3 ; ii++ )
       fprintf(stderr,"    %10.5f %10.5f %10.5f   %10.5f\n",
               rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] );
   }

   if( matrix_type == ROTATION || matrix_type == ROTSCL ){
     double theta, costheta , dist , fac=1.0 ;

     if( matrix_type == ROTSCL ){
       fac = DMAT_DET(rt.mm); fac = fabs(fac);
       if( DSET_NZ(dset) == 1 ) fac = sqrt(fac) ;
       else                     fac = cbrt(fac) ;
     }

     costheta = 0.5 * sqrt(1.0 + DMAT_TRACE(rt.mm)/fac ) ;
     theta    = 2.0 * acos(costheta) * 180/3.14159265 ;
     dist     = SIZE_DFVEC3(rt.vv) ;

     fprintf(stderr,"++ Total rotation=%.2f degrees; translation=%.2f mm; scaling=%.2f\n",
             theta,dist,fac) ;
   }

   if( mfile ){
      FILE * mp ;

      if( THD_is_file(mfile) )
         fprintf(stderr,"++ Warning: -matvec will overwrite file %s\n",mfile) ;

      mp = fopen(mfile,"w") ;
      if( mp == NULL ){
         fprintf(stderr,"** Can't write to -matvec %s\n",mfile) ;
      } else {
        for( ii=0 ; ii < 3 ; ii++ )
          fprintf(mp,"    %10.5f %10.5f %10.5f   %10.5f\n",
                  rt.mm.mat[ii][0],rt.mm.mat[ii][1],rt.mm.mat[ii][2],rt.vv.xyz[ii] );
        fclose(mp) ;
        if( verb ) fprintf(stderr,"++ Wrote matrix+vector to %s\n",mfile) ;
      }
   }

   if( dummy ){
      fprintf(stderr,"++ This was a -dummy run: no output dataset\n") ; exit(0) ;
   }

   /*-- 21 Apr 2003: transformation can be done the old way (a la 3drotate),
                     or the new way (a la 3dWarp).                          --*/

#if 0
   if( !use_3dWarp ){          /**** the old way ****/

     /*-- now must scramble the rotation matrix and translation
          vector from Dicom coordinate order to dataset brick order --*/

     pp  = DBLE_mat_to_dicomm( dset ) ;
     ppt = TRANSPOSE_DMAT(pp) ;
     rr  = DMAT_MUL(ppt,rt.mm) ; rr = DMAT_MUL(rr,pp) ; tt = DMATVEC(ppt,rt.vv) ;

     /*-- now create the output dataset by screwing with the input dataset
          (this code is adapted from 3drotate.c)                           --*/

     DSET_mallocize(dset) ;
     DSET_load( dset ) ;  CHECK_LOAD_ERROR(dset) ;
     dset->idcode = MCW_new_idcode() ;
     dset->dblk->diskptr->storage_mode = STORAGE_BY_BRICK ; /* 14 Jan 2004 */
     EDIT_dset_items( dset ,
                         ADN_prefix , prefix ,
                         ADN_label1 , prefix ,
                      ADN_none ) ;

     if( !THD_ok_overwrite() && 
         (THD_deathcon() && THD_is_file(dset->dblk->diskptr->header_name) )){
        fprintf(stderr,
                "** Output file %s already exists -- cannot continue!\n",
                dset->dblk->diskptr->header_name ) ;
        exit(1) ;
     }

     tross_Make_History( "3dTagalign" , argc,argv , dset ) ;

     /*-- if desired, keep old tagset --*/

     if( keeptags ){
        THD_dfvec3 rv ;

        dsum = 0.0 ;
        for( jj=ii=0 ; ii < TAGLIST_COUNT(dset->tagset) ; ii++ ){
           if( TAG_SET(TAGLIST_SUBTAG(dset->tagset,ii)) ){
              rv = DMATVEC( rt.mm , yy[jj] ) ;                     /* operating on */
              rv = ADD_DFVEC3( rt.vv , rv ) ;                      /* Dicom order  */

              dv    = SUB_DFVEC3( xx[jj] , rv ) ;
              dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1]
                                          + dv.xyz[2]*dv.xyz[2] ;

              UNLOAD_DFVEC3( rv , TAG_X( TAGLIST_SUBTAG(dset->tagset,ii) ) ,
                                  TAG_Y( TAGLIST_SUBTAG(dset->tagset,ii) ) ,
                                  TAG_Z( TAGLIST_SUBTAG(dset->tagset,ii) )  ) ;

              jj++ ;
           }
        }
        dsum = sqrt(dsum/nvec) ;
        fprintf(stderr,"++ RMS distance between tags after  = %.2f mm\n" , dsum ) ;

     } else {
        myXtFree(dset->tagset) ;  /* send it to the dustbin */
     }

     /*-- rotate sub-bricks --*/

     if( verb ) fprintf(stderr,"++ computing output BRIK") ;

     nvox = DSET_NVOX(dset) ;
     nval = DSET_NVALS(dset) ;
     fvol = (float *) malloc( sizeof(float) * nvox ) ;

     THD_rota_method( MRI_HEPTIC ) ;
     clipit = 1 ;

     for( ival=0 ; ival < nval ; ival++ ){

        /*- get sub-brick out of dataset -*/

        EDIT_coerce_type( nvox ,
                          DSET_BRICK_TYPE(dset,ival),DSET_ARRAY(dset,ival) ,
                          MRI_float,fvol ) ;

        if( clipit ){
           register int ii ; register float bb,tt ;
           bb = tt = fvol[0] ;
           for( ii=1 ; ii < nvox ; ii++ ){
                   if( fvol[ii] < bb ) bb = fvol[ii] ;
              else if( fvol[ii] > tt ) tt = fvol[ii] ;
           }
           cbot = bb ; ctop = tt ;
        }

        if( verb && nval < 5 ) fprintf(stderr,".") ;

        /*- rotate it -*/

        THD_rota_vol_matvec( DSET_NX(dset) , DSET_NY(dset) , DSET_NZ(dset) ,
                             fabs(DSET_DX(dset)) , fabs(DSET_DY(dset)) ,
                                                   fabs(DSET_DZ(dset)) ,
                             fvol , rr , tt ) ;

        if( verb ) fprintf(stderr,".") ;

        if( clipit ){
           register int ii ; register float bb,tt ;
           bb = cbot ; tt = ctop ;
           for( ii=0 ; ii < nvox ; ii++ ){
                   if( fvol[ii] < bb ) fvol[ii] = bb ;
              else if( fvol[ii] > tt ) fvol[ii] = tt ;
           }
        }

        if( verb && nval < 5 ) fprintf(stderr,".") ;

        /*- put it back into dataset -*/

        EDIT_coerce_type( nvox, MRI_float,fvol ,
                                DSET_BRICK_TYPE(dset,ival),DSET_ARRAY(dset,ival) );

     } /* end of loop over sub-brick index */

     if( verb ) fprintf(stderr,":") ;

     /* save matrix+vector into dataset, too */

     UNLOAD_DMAT(rt.mm,matar[0],matar[1],matar[2],
                       matar[4],matar[5],matar[6],
                       matar[8],matar[9],matar[10] ) ;
     UNLOAD_DFVEC3(rt.vv,matar[3],matar[7],matar[11]) ;
     THD_set_atr( dset->dblk, "TAGALIGN_MATVEC", ATR_FLOAT_TYPE, 12, matar ) ;

     /* write dataset to disk */

     dset->dblk->master_nvals = 0 ;  /* in case this was a mastered dataset */
     DSET_write(dset) ;

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

   } else
#endif
   {   /**** the new way: use 3dWarp type transformation ****/

     THD_3dim_dataset *oset ;
     THD_vecmat tran ;

#if 0
     DFVEC3_TO_FVEC3( rt.vv , tran.vv ) ;
     DMAT_TO_MAT    ( rt.mm , tran.mm ) ;
#else
     DFVEC3_TO_FVEC3( rtinv.vv , tran.vv ) ;
     DMAT_TO_MAT    ( rtinv.mm , tran.mm ) ;
#endif

     mri_warp3D_method( RMETH ) ;
     oset = THD_warp3D_affine( dset, tran, mset, prefix, 0, WARP3D_NEWDSET ) ;
     if( oset == NULL ){
       fprintf(stderr,"** ERROR: THD_warp3D() fails!\n"); exit(1);
     }

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

     UNLOAD_DMAT(rt.mm,matar[0],matar[1],matar[2],
                       matar[4],matar[5],matar[6],
                       matar[8],matar[9],matar[10] ) ;
     UNLOAD_DFVEC3(rt.vv,matar[3],matar[7],matar[11]) ;
     THD_set_atr( oset->dblk, "TAGALIGN_MATVEC", ATR_FLOAT_TYPE, 12, matar ) ;

     /*-- if desired, keep old tagset --*/

     if( keeptags ){
        THD_dfvec3 rv ;

        oset->tagset = myXtNew(THD_usertaglist) ;
        *(oset->tagset) = *(dset->tagset) ;

        dsum = 0.0 ;
        for( jj=ii=0 ; ii < TAGLIST_COUNT(oset->tagset) ; ii++ ){
          if( TAG_SET(TAGLIST_SUBTAG(oset->tagset,ii)) ){
            rv = DMATVEC( rt.mm , yy[jj] ) ;
            rv = ADD_DFVEC3( rt.vv , rv ) ;

            dv    = SUB_DFVEC3( xx[jj] , rv ) ;
            dsum += dv.xyz[0]*dv.xyz[0] + dv.xyz[1]*dv.xyz[1]
                                        + dv.xyz[2]*dv.xyz[2] ;

            UNLOAD_DFVEC3( rv , TAG_X( TAGLIST_SUBTAG(oset->tagset,ii) ) ,
                                TAG_Y( TAGLIST_SUBTAG(oset->tagset,ii) ) ,
                                TAG_Z( TAGLIST_SUBTAG(oset->tagset,ii) )  ) ;

            jj++ ;
          }
        }
        dsum = sqrt(dsum/nvec) ;
        fprintf(stderr,"++ RMS distance between tags after  = %.2f mm\n" , dsum ) ;
     }

     DSET_write(oset) ;

   } /* end of 3dWarp-like work */

   exit(0) ;
}
示例#7
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset , *oset=NULL , *tset=NULL ;
   int nvals , iv , nxyz , ii,jj,kk , iarg , kz,kzold ;
   float cut1=2.5,cut2=4.0 , sq2p,sfac , fq ;
   MRI_IMAGE *flim ;
   char *prefix="despike" , *tprefix=NULL ;

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

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

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

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

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

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

   /** AFNI package setup and logging **/

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

   /** parse options **/

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

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

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

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

      /** -localedit **/

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

      /** don't use masking **/

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

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

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

      /** output dataset prefix **/

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

      /** ratio dataset prefix **/

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

      /** trigonometric polynomial order **/

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

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

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

      /** thresholds for s ratio **/

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

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

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

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

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

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

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

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

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

   /*-- create automask --*/

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

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

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

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

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

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

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

   /* copy the ignored bricks */

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

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

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

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

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

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

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

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

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

   /* make ref functions */

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

   /* r(t) = 1 */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        /* find spikiness for each point in time */

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

        /* save spikiness in -ssave datset */

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

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

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

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

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

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

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

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

 } /* end OpenMP */
 AFNI_OMP_END ;

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

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

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

   if( do_NEW ) mri_free(NEW_psinv) ;

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

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

   /* write results */

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

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

   exit( THD_get_write_error_count() ) ;
}
示例#8
0
int main( int argc , char * argv[] )
{
   int iv,nvals , nvec , ii,jj,kk , nvox ;
   THD_3dim_dataset * new_dset=NULL ;
   double * choleski ;
   float ** refvec , * fv , * fc , * fit ;
   MRI_IMAGE * flim ;

   /*** read input options ***/

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

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

   mainENTRY("3dDetrend main"); machdep() ; PRINT_VERSION("3dDetrend");
   AFNI_logger("3dDetrend",argc,argv) ;
   { int new_argc ; char ** new_argv ;
     addto_args( argc , argv , &new_argc , &new_argv ) ;
     if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
   }

   DT_read_opts( argc , argv ) ;

   /*** create new dataset (empty) ***/

   new_dset = EDIT_empty_copy( DT_dset ) ; /* make a copy of its header */

   /* modify its header */

   tross_Copy_History( DT_dset , new_dset ) ;
   tross_Make_History( "3dDetrend" , argc,argv , new_dset ) ;

   EDIT_dset_items( new_dset ,
                      ADN_prefix        , DT_output_prefix ,
                      ADN_directory_name, DT_session ,
                    ADN_none ) ;

   /* can't re-write existing dataset */

   if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) )
     ERROR_exit("File %s already exists!\n",DSET_HEADNAME(new_dset) ) ;

   /* read input in, and attach its bricks to the output dataset */
   /* (not good in a plugin, but OK in a standalone program!)    */

   if( DT_verb ) INFO_message("Loading input dataset bricks\n") ;

   DSET_mallocize( new_dset ) ;
   DSET_mallocize( DT_dset ) ;
   DSET_load( DT_dset ) ; CHECK_LOAD_ERROR(DT_dset) ;

   nvals = DSET_NVALS(new_dset) ;
   for( iv=0 ; iv < nvals ; iv++ )
     EDIT_substitute_brick( new_dset , iv ,
                            DSET_BRICK_TYPE(DT_dset,iv) ,
                            DSET_ARRAY(DT_dset,iv)       ) ;

   if( DT_norm && DSET_BRICK_TYPE(new_dset,0) != MRI_float ){
     INFO_message("Turning -normalize option off (input not in float format)");
     DT_norm = 0 ;
   }

   /* load reference (detrending) vectors;
      setup to do least squares fitting of each voxel */

   nvec = 0 ;
   for( ii=0 ; ii < IMARR_COUNT(DT_imar) ; ii++ )  /* number of detrending vectors */
      nvec += IMARR_SUBIMAGE(DT_imar,ii)->ny ;

   refvec = (float **) malloc( sizeof(float *)*nvec ) ;
   for( kk=ii=0 ; ii < IMARR_COUNT(DT_imar) ; ii++ ){
     fv = MRI_FLOAT_PTR( IMARR_SUBIMAGE(DT_imar,ii) ) ;
     for( jj=0 ; jj < IMARR_SUBIMAGE(DT_imar,ii)->ny ; jj++ )         /* compute ptr */
       refvec[kk++] = fv + ( jj * IMARR_SUBIMAGE(DT_imar,ii)->nx ) ;  /* to vectors  */
   }

   fit = (float *) malloc( sizeof(float) * nvals ) ;  /* will get fit to voxel data */

   /*--- do the all-voxels-together case ---*/

   if( !DT_byslice ){
      choleski = startup_lsqfit( nvals , NULL , nvec , refvec ) ;
      if( choleski == NULL )
        ERROR_exit("Choleski factorization fails: linearly dependent vectors!\n") ;

      /* loop over voxels, fitting and detrending (or replacing) */

      nvox = DSET_NVOX(new_dset) ;

      if( DT_verb ) INFO_message("Computing voxel fits\n") ;

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

         flim = THD_extract_series( kk , new_dset , 0 ) ;              /* data */
         fv   = MRI_FLOAT_PTR(flim) ;
         fc   = delayed_lsqfit( nvals, fv, nvec, refvec, choleski ) ;  /* coef */

         for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = 0.0 ;

         for( jj=0 ; jj < nvec ; jj++ )
            for( ii=0 ; ii < nvals ; ii++ )
               fit[ii] += fc[jj] * refvec[jj][ii] ;                    /* fit */

         if( !DT_replace )                                             /* remove */
            for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = fv[ii] - fit[ii] ;

         if( DT_norm ) THD_normalize( nvals , fit ) ;  /* 23 Nov 1999 */

         THD_insert_series( kk, new_dset, nvals, MRI_float, fit, 0 ) ;

         free(fc) ; mri_free(flim) ;
      }

      free(choleski) ;

      /*- end of all-voxels-together case -*/

   }
#ifdef ALLOW_BYSLICE
     else {                                 /*- start of slice case [08 Dec 1999] -*/
      int ksl , nslice , tt , nx,ny , nxy , kxy ;
      MRI_IMAGE * vim ;

      /* make separate space for the slice-wise detrending vectors */

      for( kk=ii=0 ; ii < DT_nvector ; ii++ ){
         for( jj=0 ; jj < IMARR_SUBIMAGE(DT_imar,ii)->ny ; jj++ )       /* replace ptrs */
            refvec[kk++] = (float *) malloc( sizeof(float) * nvals ) ;  /* to vectors   */
      }

      nslice = DSET_NZ(new_dset) ;
      nxy    = DSET_NX(new_dset) * DSET_NY(new_dset) ;

      /* loop over slices */

      for( ksl=0 ; ksl < nslice ; ksl++ ){

         if( DT_verb ) INFO_message("Computing voxel fits for slice %d\n",ksl) ;

         /* extract slice vectors from input interlaced vectors */

         for( kk=ii=0 ; ii < DT_nvector ; ii++ ){        /* loop over vectors */
            vim = IMARR_SUBIMAGE(DT_imar,ii) ;           /* ii-th vector image */
            nx = vim->nx ; ny = vim->ny ;                /* dimensions */
            for( jj=0 ; jj < ny ; jj++ ){                /* loop over columns */
               fv = MRI_FLOAT_PTR(vim) + (jj*nx) ;       /* ptr to column */
               for( tt=0 ; tt < nvals ; tt++ )           /* loop over time */
                  refvec[kk][tt] = fv[ksl+tt*nslice] ;   /* data point */
            }
         }

         /* initialize fitting for this slice */

         choleski = startup_lsqfit( nvals , NULL , nvec , refvec ) ;
         if( choleski == NULL )
           ERROR_exit("Choleski fails: linearly dependent vectors at slice %d\n",ksl) ;

         /* loop over voxels in this slice */

         for( kxy=0 ; kxy < nxy ; kxy++ ){

            kk   = kxy + ksl*nxy ;                                        /* 3D index */
            flim = THD_extract_series( kk , new_dset , 0 ) ;              /* data */
            fv   = MRI_FLOAT_PTR(flim) ;
            fc   = delayed_lsqfit( nvals, fv, nvec, refvec, choleski ) ;  /* coef */

            for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = 0.0 ;

            for( jj=0 ; jj < nvec ; jj++ )
               for( ii=0 ; ii < nvals ; ii++ )
                  fit[ii] += fc[jj] * refvec[jj][ii] ;                    /* fit */

            if( !DT_replace )                                             /* remove */
               for( ii=0 ; ii < nvals ; ii++ ) fit[ii] = fv[ii] - fit[ii] ;

            if( DT_norm ) THD_normalize( nvals , fit ) ;  /* 23 Nov 1999 */

            THD_insert_series( kk, new_dset, nvals, MRI_float, fit, 0 ) ;

            free(fc) ; mri_free(flim) ;
         }

         free(choleski) ;

      } /* end of loop over slices */

   } /*- end of -byslice case -*/
#endif

   /*-- done done done done --*/

   DSET_write(new_dset) ;
   if( DT_verb ) WROTE_DSET(new_dset) ;
   exit(0) ;
}
示例#9
0
文件: 3dZeropad.c 项目: Gilles86/afni
int main( int argc , char * argv[] )
{
   int iarg ;
   THD_3dim_dataset *inset , *outset ;
   int add_I=0 , add_S=0 , add_A=0 , add_P=0 , add_L=0 , add_R=0 ;
   int RLsiz=0, APsiz=0, ISsiz=0 ; /* 23 Mar 2004 */
   char * prefix="zeropad" ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      /*- -mm -*/

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

      /*- -prefix -*/

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

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

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

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

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

      /*- what the hell? -*/

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

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

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

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

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

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

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

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

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

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

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

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

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

     /* check if datasets are oriented the same */

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

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

     /* check if datasets have same voxel dimensions */

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

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

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

     if( nerr ) exit(1) ;

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

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

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

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

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

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

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

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

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

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

     DSET_delete(mset) ;
   }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   if (DSET_write(outset) != False) {
      fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ;
      exit(0) ;
   } else {
      fprintf(stderr,
              "** 3dZeropad: Failed to write output!\n" ) ;
      exit(1) ;
   }
   
}
示例#10
0
文件: 3dbuc2fim.c 项目: Gilles86/afni
int main( int argc , char * argv[] )
{
   int ninp , ids , nv , iv,jv,kv , ivout , new_nvals ;
   THD_3dim_dataset * new_dset=NULL , * dset ;
   char buf[256] ;

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


   /*** read input options ***/

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

   mainENTRY("3dbuc2fim main"); machdep(); AFNI_logger(PROGRAM_NAME,argc,argv);
   PRINT_VERSION("3dbuc2fim") ; AUTHOR(PROGRAM_AUTHOR);

   B2F_read_opts( argc , argv ) ;

   /*** create new dataset (empty) ***/
   ninp = B2F_dsar->num ;
   if( ninp < 1 ){
      fprintf(stderr,"*** No input datasets?\n") ; exit(1) ;
   }

   new_nvals = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ) new_nvals += NSUBV(ids) ;

   /*----- Check for acceptable number of sub-bricks -----*/
   if (new_nvals < 1)
     { fprintf(stderr,"*** Less than 1 sub-brick specified\n") ; exit(1) ; }
   if (new_nvals > 2)
     { fprintf(stderr,"*** More than 2 sub-bricks specified\n") ; exit(1) ; }


   if( B2F_verb ) printf("-verb: output will have %d sub-bricks\n",new_nvals) ;

   new_dset = EDIT_empty_copy( DSUB(0) ) ;

   if( ninp == 1 ) tross_Copy_History( DSUB(0) , new_dset ) ;
   tross_Make_History( "3dbuc2fim" , argc,argv , new_dset ) ;

   /*-----  Set default value for function type. This will be changed later,
            if the second sub-brick has a statistic type.  -----*/
   if (new_nvals == 1)
     B2F_func_type = FUNC_FIM_TYPE;
   else
     B2F_func_type = FUNC_THR_TYPE;


   EDIT_dset_items (new_dset ,
		    ADN_prefix        , B2F_output_prefix ,
		    ADN_directory_name, B2F_session ,
		    ADN_type          , HEAD_FUNC_TYPE,
		    ADN_func_type     , B2F_func_type,
		    ADN_ntt           , 0 ,
		    ADN_nvals         , new_nvals ,
                    ADN_none ) ;


   if( THD_deathcon() && THD_is_file(DSET_HEADNAME(new_dset)) ){
     fprintf(stderr,"*** Fatal error: file %s already exists!\n",
	     DSET_HEADNAME(new_dset) ) ;
     exit(1) ;
   }

   THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ;

   /*** loop over input datasets ***/

   if( ninp > 1 ) myXtFree( new_dset->keywords ) ;

   ivout = 0 ;
   for( ids=0 ; ids < ninp ; ids++ ){
      dset = DSUB(ids) ;
      nv   = NSUBV(ids) ;

      DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;


      /** loop over sub-bricks to output **/

      for( iv=0 ; iv < nv ; iv++ ){
         jv = SUBV(ids,iv) ;                /* which sub-brick to use */

	 EDIT_substitute_brick( new_dset , ivout ,
				DSET_BRICK_TYPE(dset,jv) , DSET_ARRAY(dset,jv) ) ;
	
	 /*----- If this sub-brick is from a bucket dataset,
	   preserve the label for this sub-brick -----*/
	 if (dset->func_type == FUNC_BUCK_TYPE)
	   sprintf (buf, "%s", DSET_BRICK_LABEL(dset,jv));
	 else
	   sprintf(buf,"%.12s[%d]",DSET_PREFIX(dset),jv) ;
	 EDIT_dset_items( new_dset , ADN_brick_label_one+ivout, buf , ADN_none ) ;

#if 0	
	 sprintf(buf,"%s[%d]",DSET_FILECODE(dset),jv) ;
	 EDIT_dset_items(
			 new_dset, ADN_brick_keywords_replace_one+ivout, buf, ADN_none ) ;
#endif
	
	 EDIT_dset_items(
			 new_dset ,
			 ADN_brick_fac_one            +ivout, DSET_BRICK_FACTOR(dset,jv),
#if 0
			 ADN_brick_keywords_append_one+ivout, DSET_BRICK_KEYWORDS(dset,jv) ,
#endif
			 ADN_none ) ;
	
	 /** possibly write statistical parameters for this sub-brick **/
	
	 kv = DSET_BRICK_STATCODE(dset,jv) ;
	
	 if( FUNC_IS_STAT(kv) ){ /* input sub-brick has stat params */
	
	   int npar = MAX_STAT_AUX , lv ;
	   float * par = (float *) malloc( sizeof(float) * (npar) ) ;
	   float * sax = DSET_BRICK_STATAUX(dset,jv) ;
	   for( lv=0 ; lv < npar ; lv++ )
	     par[lv] = (sax != NULL && lv < FUNC_need_stat_aux[kv]) ? sax[lv] : 0.0;
	
	   if (ivout == 1)
	     {
	       EDIT_dset_items(new_dset ,
			       ADN_func_type     , kv,		
			       ADN_stat_aux, par ,
			       ADN_none ) ;
	     }
	
	   free(par) ;
	
	     /* 2: if the input dataset has statistical parameters */

	 } else if( ISFUNC(dset)                        &&   /* dset has stat */
		    FUNC_IS_STAT(dset->func_type)       &&   /* params        */
		    jv == FUNC_ival_thr[dset->func_type]  ){ /* thr sub-brick */
	
	   int npar , lv ;
	   float * par , * sax ;
	   kv  = dset->func_type ;
	   npar = MAX_STAT_AUX ;
	   par  = (float *) malloc( sizeof(float) * (npar+2) ) ;
	   sax  = dset->stat_aux ;
	   for( lv=0 ; lv < npar ; lv++ )
	     par[lv] = (sax != NULL) ? sax[lv] : 0.0 ;
	

	   if (ivout == 1)
	     {
	       for( lv=0 ; lv < npar+2 ; lv++ )
		 printf ("par[%d] = %f \n", lv, par[lv]);
	       EDIT_dset_items(new_dset ,
			       ADN_func_type     , kv,		
			       ADN_stat_aux, par ,
			       ADN_none ) ;
	     }
	
	   free(par) ;
	 }
	
	 /** print a message? **/
	
	 if( B2F_verb ) printf("-verb: copied %s[%d] into %s[%d]\n" ,
			       DSET_FILECODE(dset) , jv ,
			       DSET_FILECODE(new_dset) , ivout ) ;
	 ivout++ ;
      }

      /** loop over all bricks in input dataset and
	unload them if they aren't going into the output
	(not required, but is done to economize on memory) **/

      if( nv < DSET_NVALS(dset) ){
	
	for( kv=0 ; kv < DSET_NVALS(dset) ; kv++ ){  /* all input sub-bricks */
	  for( iv=0 ; iv < nv ; iv++ ){             /* all output sub-bricks */
	    jv = SUBV(ids,iv) ;
	    if( jv == kv ) break ;                 /* input matches output */
	  }
	  if( iv == nv ){
	    mri_free( DSET_BRICK(dset,kv) ) ;
#if 0
	    if( B2F_verb ) printf("-verb: unloaded unused %s[%d]\n" ,
				  DSET_FILECODE(dset) , kv ) ;
#endif
	  }
	}
      }

   } /* end of loop over input datasets */


   if( B2F_verb ) fprintf(stderr,"-verb: loading statistics\n") ;
   THD_load_statistics( new_dset ) ;
   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
   if( B2F_verb ) fprintf(stderr,"-verb: wrote output: %s\n",DSET_BRIKNAME(new_dset)) ;


   exit(0) ;
}