Esempio n. 1
0
int main( int argc , char * argv[] )
{
   THD_3dim_dataset * dset ;
   THD_dataxes      * daxes ;
   FD_brick        ** brarr , * baxi , * bsag , * bcor ;

   int iarg , ii ;
   Boolean ok ;
   MRI_IMAGE * pim , * flim , * slim ;
   float * flar ;
   dset_range dr ;
   float val , fimfac ;
   int  ival,ityp , kk ;

   float xbot=BIGG,xtop=BIGG , ybot=BIGG,ytop=BIGG , zbot=BIGG,ztop=BIGG ;
   int   xgood=0 , ygood=0 , zgood=0 ,
         proj_code=PROJ_SUM , mirror_code=MIRR_NO , nsize=0 ;
   char  root[THD_MAX_NAME] = "proj." ;
   char  fname[THD_MAX_NAME] ;

   int ixbot=0,ixtop=0 , jybot=0,jytop=0 , kzbot=0,kztop=0 ;
   THD_fvec3 fv ;
   THD_ivec3 iv ;

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

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

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

DB("new arg:",argv[iarg]) ;

      /**** check for editing option ****/

      ii = EDIT_check_argv( argc , argv , iarg , &PRED_edopt ) ;
      if( ii > 0 ){
         iarg += ii ;
         continue ;
      }

      /**** -sum or -max ****/

      if( strncmp(argv[iarg],"-sum",6) == 0 ){
         proj_code = PROJ_SUM ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-max",6) == 0 ){
         proj_code = PROJ_MMAX ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-amax",6) == 0 ){
         proj_code = PROJ_AMAX ;
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-smax",6) == 0 ){
         proj_code = PROJ_SMAX ;
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-first") == 0 ){  /* 02 Nov 2000 */
         proj_code = PROJ_FIRST ;
         first_thresh = strtod( argv[++iarg] , NULL ) ;
         iarg++ ; continue ;
      }

      /**** -mirror ****/

      if( strncmp(argv[iarg],"-mirror",6) == 0 ){
         mirror_code = MIRR_YES ;
         iarg++ ; continue ;
      }

      /**** -nsize ****/

      if( strncmp(argv[iarg],"-nsize",6) == 0 ){
         nsize = 1 ;
         iarg++ ; continue ;
      }

      /**** -output root ****/

      if( strncmp(argv[iarg],"-output",6) == 0 ||
          strncmp(argv[iarg],"-root",6)   == 0   ){

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         MCW_strncpy( root , argv[++iarg] , THD_MAX_NAME-1 ) ;
         ii = strlen(root) ;
         if( ii == 0 ){
            fprintf(stderr,"\n*** illegal rootname!\n") ; exit(-1) ;
         }
         if( root[ii-1] != '.' ){ root[ii] = '.' ; root[ii+1] = '\0' ; }
         iarg++ ; continue ;
      }

      /**** -ALL ****/

      if( strncmp(argv[iarg],"-ALL",6) == 0 ||
          strncmp(argv[iarg],"-all",6) == 0   ){

         xgood = ygood = zgood = 1 ;
         xbot  = ybot  = zbot  = -BIGG ;
         xtop  = ytop  = ztop  =  BIGG ;
         iarg++ ; continue ;
      }

      /**** -RL {all | x1 x2} ****/

      if( strncmp(argv[iarg],"-RL",6) == 0 ||
          strncmp(argv[iarg],"-LR",6) == 0 ||
          strncmp(argv[iarg],"-rl",6) == 0 ||
          strncmp(argv[iarg],"-lr",6) == 0 ||
          strncmp(argv[iarg],"-sag",6)== 0  ){

         char * cerr ; float tf ;

         xgood = 1 ;  /* mark for x projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            xbot = -BIGG;
            xtop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         xbot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'R' && xbot > 0.0 ) xbot = -xbot ;

         xtop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'R' && xtop > 0.0 ) xtop = -xtop ;

         if( xbot > xtop ){ tf = xbot ; xbot = xtop ; xtop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** -AP {all | y1 y2} ****/

      if( strncmp(argv[iarg],"-AP",6) == 0 ||
          strncmp(argv[iarg],"-PA",6) == 0 ||
          strncmp(argv[iarg],"-ap",6) == 0 ||
          strncmp(argv[iarg],"-pa",6) == 0 ||
          strncmp(argv[iarg],"-cor",6)== 0  ){

         char * cerr ; float tf ;

         ygood = 1 ;  /* mark for y projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            ybot = -BIGG ;
            ytop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         ybot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'A' && ybot > 0.0 ) ybot = -ybot ;

         ytop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'A' && ytop > 0.0 ) ytop = -ytop ;

         if( ybot > ytop ){ tf = ybot ; ybot = ytop ; ytop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** -IS {all | z1 z2} ****/

      if( strncmp(argv[iarg],"-IS",6) == 0 ||
          strncmp(argv[iarg],"-SI",6) == 0 ||
          strncmp(argv[iarg],"-is",6) == 0 ||
          strncmp(argv[iarg],"-si",6) == 0 ||
          strncmp(argv[iarg],"-axi",6)== 0   ){

         char * cerr ; float tf ;

         zgood = 1 ;  /* mark for y projection */

         if( iarg+1 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         if( strncmp(argv[iarg+1],"all",6) == 0 ||
             strncmp(argv[iarg+1],"ALL",6) == 0   ){

            zbot = -BIGG ;
            ztop =  BIGG ;
            iarg += 2 ; continue ;
         }

         if( iarg+2 >= argc ){
            fprintf(stderr,"\n*** no argument after option %s\n",argv[iarg]) ;
            exit(-1) ;
         }

         zbot = strtod( argv[iarg+1] , &cerr ) ;
         if( cerr == argv[iarg+1] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+1] ) ; exit(-1) ;
         }
         if( *cerr == 'I' && zbot > 0.0 ) zbot = -zbot ;

         ztop = strtod( argv[iarg+2] , &cerr ) ;
         if( cerr == argv[iarg+2] ){
            fprintf(stderr,"\n*** illegal argument after %s: %s\n",
                    argv[iarg],argv[iarg+2] ) ; exit(-1) ;
         }
         if( *cerr == 'I' && ztop > 0.0 ) ztop = -ztop ;

         if( zbot > ztop ){ tf = zbot ; zbot = ztop ; ztop = tf ; }
         iarg +=3 ; continue ;
      }

      /**** unknown option ****/

      fprintf(stderr,"\n*** Unknown option: %s\n",argv[iarg]) ;
      exit(-1) ;
   }  /* end of loop over input options */

   if( ! xgood && ! ygood && ! zgood ){
      fprintf(stderr,"\n*** No projections ordered!?\n") ; exit(-1) ;
   }

   /*--- open dataset and set up to extract data slices ---*/

   dset = THD_open_dataset( argv[iarg] ) ;
   if( dset == NULL ){
      fprintf(stderr,"\n*** Can't open dataset file %s\n",argv[iarg]) ;
      exit(-1) ;
   }
   if( DSET_NUM_TIMES(dset) > 1 ){
      fprintf(stderr,"\n*** Can't project time-dependent dataset!\n") ;
      exit(1) ;
   }
   EDIT_one_dataset( dset, &PRED_edopt ) ;
   daxes = dset->daxes ;
   brarr = THD_setup_bricks( dset ) ;
   baxi  = brarr[0] ; bsag = brarr[1] ; bcor = brarr[2] ;

   /*--- determine index range for each direction ---*/

   dr = PR_get_range( dset ) ;

   if( xgood ){
      if( xbot < dr.xbot ) xbot = dr.xbot ;
      if( xtop > dr.xtop ) xtop = dr.xtop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xbot,0,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bsag , iv ) ; ixbot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(xtop,0,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bsag , iv ) ; ixtop = iv.ijk[2] ;

      if( ixbot > ixtop ) { ii = ixbot ; ixbot = ixtop ; ixtop = ii ; }

      if( ixbot <  0        ) ixbot = 0 ;
      if( ixtop >= bsag->n3 ) ixtop = bsag->n3 - 1 ;
   }

   if( ygood ){
      if( ybot < dr.ybot ) ybot = dr.ybot ;
      if( ytop > dr.ytop ) ytop = dr.ytop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ybot,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bcor , iv ) ; jybot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,ytop,0) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( bcor , iv ) ; jytop = iv.ijk[2] ;

      if( jybot > jytop ) { ii = jybot ; jybot = jytop ; jytop = ii ; }

      if( jybot <  0        ) jybot = 0 ;
      if( jytop >= bcor->n3 ) jytop = bcor->n3 - 1 ;
   }

   if( zgood ){
      if( zbot < dr.zbot ) zbot = dr.zbot ;
      if( ztop > dr.ztop ) ztop = dr.ztop ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,zbot) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( baxi , iv ) ; kzbot = iv.ijk[2] ;

      fv = THD_dicomm_to_3dmm( dset , TEMP_FVEC3(0,0,ztop) ) ;
      iv = THD_3dmm_to_3dind ( dset , fv ) ;
      iv = THD_3dind_to_fdind( baxi , iv ) ; kztop = iv.ijk[2] ;

      if( kzbot > kztop ) { ii = kzbot ; kzbot = kztop ; kztop = ii ; }

      if( kzbot <  0        ) kzbot = 0 ;
      if( kztop >= baxi->n3 ) kztop = baxi->n3 - 1 ;
   }

   ival   = DSET_PRINCIPAL_VALUE(dset) ;    /* index to project */
   ityp   = DSET_BRICK_TYPE(dset,ival) ;    /* type of this data */
   fimfac = DSET_BRICK_FACTOR(dset,ival) ;  /* scale factor of this data */

   /*--- project the x direction, if desired ---*/

   if( xgood ){
      int n1 = bsag->n1 , n2 = bsag->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=ixbot ; ss <= ixtop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , bsag ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Sagittal projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Sagittal projection min = %g  max = %g\n",fmin,fmax) ;

      strcpy(fname,root) ; strcat(fname,"sag") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   /*--- project the y direction, if desired ---*/

   if( ygood ){
      int n1 = bcor->n1 , n2 = bcor->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=jybot ; ss <= jytop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , bcor ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Coronal projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Coronal projection min = %g  max = %g\n",fmin,fmax) ;

      if( mirror_code == MIRR_YES ){
         slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ;
         mri_free(pim) ; pim = slim ;
      }
      strcpy(fname,root) ; strcat(fname,"cor") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   /*--- project the z direction, if desired ---*/

   if( zgood ){
      int n1 = baxi->n1 , n2 = baxi->n2 ;
      int ss , npix ;
      float fmax , fmin , scl ;

      /*-- set up --*/

      npix = n1*n2 ;
      flim = mri_new( n1 , n2 , MRI_float ) ;
      flar = mri_data_pointer( flim ) ;
      for( ii=0 ; ii < npix ; ii++ ) flar[ii] = 0.0 ;

      /*-- actually project --*/

      for( ss=kzbot ; ss <= kztop ; ss++ ){
         slim = FD_brick_to_mri( ss , ival , baxi ) ;
         if( slim->kind != MRI_float ){
            pim = mri_to_float( slim ) ;
            mri_free( slim ) ; slim = pim ;
         }
         PR_one_slice( proj_code , slim , flim ) ;
         mri_free( slim ) ;
      }

      /*-- form output --*/

      if( fimfac != 0.0 && fimfac != 1.0 ){
         slim = mri_scale_to_float( 1.0/fimfac , flim ) ;
         mri_free(flim) ; flim = slim ;
      }

      scl = PR_type_scale( ityp , flim ) ;
      pim = mri_to_mri_scl( ityp , scl , flim ) ; mri_free( flim ) ;
      if( nsize ){
         slim = mri_nsize( pim ) ;
         if( slim != NULL && slim != pim ) { mri_free(pim) ; pim = slim ; }
      }

      if( scl != 1.0 )
         printf("Axial projection pixels scaled by %g to avoid overflow!\n",
                scl ) ;

      fmax = mri_max(pim) ; fmin = mri_min(pim) ;
      printf("Axial projection min = %g  max = %g\n",fmin,fmax) ;

      if( mirror_code == MIRR_YES ){
         slim = mri_flippo( MRI_ROT_0 , TRUE , pim ) ;
         mri_free(pim) ; pim = slim ;
      }
      strcpy(fname,root) ; strcat(fname,"axi") ;
      mri_write( fname, pim ) ;
      mri_free(pim) ;
   }

   exit(0) ;
}
Esempio n. 2
0
char * POWER_main( PLUGIN_interface * plint )
{
   MCW_idcode * idc ;                          /* input dataset idcode */
   THD_3dim_dataset * old_dset , * new_dsetD3 , * new_dsetA3, * new_dsetavgD3 ; /* input and output datasets */
   char * new_prefix , * str , * namestr, * filename;                 /* strings from user */
   int   new_datum , ignore , nfft , ninp ,    /* control parameters */
         old_datum , nuse , ntaper , ktbot,
         image_type, scale,OutputFlag ,numT,flip;
  float avFac;

   byte   ** bptr  = NULL ;  /* one of these will be the array of */
   short  ** sptr  = NULL ;  /* pointers to input dataset sub-bricks */
   float  ** fptr  = NULL ;  /* (depending on input datum type) */



   float   * this  = NULL ;  /* array loaded from input dataset */


   float  ** foutD3  = NULL ;  /* will be array of output floats */
   float  ** foutA3  = NULL ;  /* will be array of output floats */
   float  ** foutavgD3  = NULL ;  /* will be array of output floats */

   float   * tarD3   = NULL ;  /* will be array of taper coefficients */
   float   * tarA3   = NULL ;  /* will be array of taper coefficients */
   float   * taravgD3   = NULL ;  /* will be array of taper coefficients */


   /*float   * flip;*/
   float   * numAv;
   float dfreq , pfact , phi , xr,xi , yr,yi ;
   float x0,x1 , y0,y1 , d0fac,d1fac ;
   int   nfreq , nvox , perc , new_units ;
   int   istr , ii,iip , ibot,itop , kk , icx ;       /* temp variables */

   new_prefix = (char *)calloc(100, sizeof(char));
   filename = (char *)calloc(100, sizeof(char));
   str = (char *)calloc(100, sizeof(char));
   namestr = (char *)calloc(100, sizeof(char));
   OutputFlag=0;
   /*--------------------------------------------------------------------*/
   /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/

   /*--------- go to first input line ---------*/

   PLUTO_next_option(plint) ;

   idc      = PLUTO_get_idcode(plint) ;   /* get dataset item */
   old_dset = PLUTO_find_dset(idc) ;      /* get ptr to dataset */
   namestr  = DSET_PREFIX(old_dset) ;


   if( old_dset == NULL )
      return "*************************\n"
             "Cannot find Input Dataset\n"
             "*************************"  ;

   /*--------- go to second input line ---------*/

   PLUTO_next_option(plint) ;

  filename = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */

  sprintf(new_prefix,"%s%s",filename,"_D3");

  if (strcmp(new_prefix,"_D3")==0){
     OutputFlag=1;
     sprintf(new_prefix,"%s%s",namestr,"_D3");
  }


   if (! PLUTO_prefix_ok(new_prefix) ){
     PLUTO_popup_transient(plint,new_prefix);
     return "*************************\n"
             "Output filename already exists\n"
             "*************************"  ;
     }


   PLUTO_popup_transient(plint,"Output file tags set automatically");


   str  = PLUTO_get_string(plint) ;              /* get string item (the datum type) */
   istr = PLUTO_string_index( str ,              /* find it in the list it came from */
                              NUM_TYPE_STRINGS ,
                              type_strings ) ;
   switch( istr ){
      default:
      case 0:
         new_datum = MRI_float ; break ;
	 break ;

      case 1: new_datum = MRI_byte  ; break ;  /* assign type of user's choice */
      case 2: new_datum = MRI_short ; break ;
      case 3: new_datum = DSET_BRICK_TYPE( old_dset , 0 ) ;  /* use old dataset type */
   }

  /*--------- go to next input lines ---------*/

   PLUTO_next_option(plint) ;                 /* skip to next line */
   ignore = PLUTO_get_number(plint) ;         /* get number item (ignore) */




   ninp = DSET_NUM_TIMES(old_dset) ;   /* number of values in input */
   nuse = ninp;              /* number of values to actually use */
   nfreq=nuse;
   nfft=nuse;


   str  = PLUTO_get_string(plint) ;              /* get string item (the datum type) */
   istr = PLUTO_string_index( str ,              /* find it in the list it came from */
                              NUM_TYPE_STRINGSX ,
                              type_stringsx ) ;
   switch( istr ){
      default:
      case 0: image_type = 0; break;
           }

  PLUTO_next_option(plint) ;                 /* skip to next line */
  scale = PLUTO_get_number(plint) ;         /* get number item (scale) */


   /*------------------------------------------------------*/
   /*---------- At this point, the inputs are OK ----------*/

   PLUTO_popup_meter( plint ) ;  /* popup a progress meter */

   /*--------- set up pointers to each sub-brick in the input dataset ---------*/

   DSET_load( old_dset ) ;  /* must be in memory before we get pointers to it */

   old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum type */

   switch( old_datum ){  /* pointer type depends on input datum type */

      default:
         return "******************************\n"
                "Illegal datum in Input Dataset\n"
                "******************************"  ;

      /** create array of pointers into old dataset sub-bricks **/
      /** Note that we skip the first 'ignore' sub-bricks here **/

      /*--------- input is bytes ----------*/
      /* voxel #i at time #k is bptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_byte:
         bptr = (byte **) malloc( sizeof(byte *) * nuse ) ;
         if( bptr == NULL ) return "Malloc\nFailure!\n [bptr]" ;
         for( kk=0 ; kk < nuse ; kk++ )
            bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk) ;
      break ;

      /*--------- input is shorts ---------*/
      /* voxel #i at time #k is sptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_short:
         sptr = (short **) malloc( sizeof(short *) * nuse ) ;
         if( sptr == NULL ) return "Malloc\nFailure!\n [sptr]" ;
         for( kk=0 ; kk < nuse ; kk++ )
            sptr[kk] = (short *) DSET_ARRAY(old_dset,kk) ;
      break ;

      /*--------- input is floats ---------*/
      /* voxel #i at time #k is fptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_float:
         fptr = (float **) malloc( sizeof(float *) * nuse ) ;
         if( fptr == NULL ) return "Malloc\nFailure!\n [fptr]" ;
         for( kk=0 ; kk < nuse ; kk++ )
            fptr[kk] = (float *) DSET_ARRAY(old_dset,kk) ;
      break ;

   } /* end of switch on input type */

   /*---- allocate space for 2 voxel timeseries and 1 FFT ----*/



   this = (float *)   malloc( sizeof(float) * nuse ) ;   /* input */
   tarD3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ;
   tarA3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ;
   taravgD3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ;
   /*flip = (float *)malloc( sizeof(float) * 1);*/
   numAv = (float *)malloc( sizeof(float) * 1);


  numT=nuse-ignore;

  if (OutputFlag==1)
  sprintf(new_prefix,"%s%s",namestr,"_D3");
  else
  sprintf(new_prefix,"%s%s",filename,"_D3");

  new_dsetD3 = EDIT_empty_copy( old_dset );

  { char * his = PLUTO_commandstring(plint) ;
  tross_Copy_History( old_dset , new_dsetD3 ) ;
  tross_Append_History( new_dsetD3 , his ) ; free(his) ;
  }

   	/*-- edit some of its internal parameters --*/

  ii = EDIT_dset_items(
       new_dsetD3 ,
         ADN_prefix      , new_prefix ,           /* filename prefix */
         ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */
         ADN_datum_all   , new_datum ,            /* atomic datum */
	 ADN_nvals	      , numT ,
	 ADN_ntt	,numT,
         ADN_none ) ;



  if (OutputFlag==1)
  sprintf(new_prefix,"%s%s",namestr,"_A3");
  else
  sprintf(new_prefix,"%s%s",filename,"_A3");

  numT=nuse-ignore;
  new_dsetA3 = EDIT_empty_copy( old_dset );

  { char * his = PLUTO_commandstring(plint) ;
  tross_Copy_History( old_dset , new_dsetA3 ) ;
  tross_Append_History( new_dsetA3 , his ) ; free(his) ;
  }

   	/*-- edit some of its internal parameters --*/

  ii = EDIT_dset_items(
       new_dsetA3 ,
         ADN_prefix      , new_prefix ,           /* filename prefix */
         ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */
         ADN_datum_all   , new_datum ,            /* atomic datum */
	 ADN_nvals	      , numT,
	 ADN_ntt	,numT,
         ADN_none ) ;



  if (OutputFlag==1)
  sprintf(new_prefix,"%s%s",namestr,"_avgD3");
  else
  sprintf(new_prefix,"%s%s",filename,"_avgD3");

  new_dsetavgD3 = EDIT_empty_copy( old_dset );

  { char * his = PLUTO_commandstring(plint) ;
  tross_Copy_History( old_dset , new_dsetavgD3 ) ;
  tross_Append_History( new_dsetavgD3 , his ) ; free(his) ;
  }

   	/*-- edit some of its internal parameters --*/

  ii = EDIT_dset_items(
        new_dsetavgD3 ,
          ADN_prefix      , new_prefix ,           /* filename prefix */
          ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */
          ADN_datum_all   , new_datum ,            /* atomic datum */
	  ADN_nvals	      , 1,
	  ADN_ntt	,1,
          ADN_none ) ;





   /*---------------------- make a new dataset ----------------------*/

/*-------------------making a new dataset------------------------------------*/





   /*------ make floating point output sub-bricks
            (only at the end will scale to byte or shorts)

            Output #ii at freq #kk will go into fout[kk][ii],
            for kk=0..nfreq-1, and for ii=0..nvox-1.          ------*/

   nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ;

   foutD3 = (float **) malloc( sizeof(float *) * nuse ) ;  /* ptrs to sub-bricks */
   foutA3 = (float **) malloc( sizeof(float *) * nuse ) ;  /* ptrs to sub-bricks */
   foutavgD3 = (float **) malloc( sizeof(float *) * 1 ) ;  /* ptrs to sub-bricks */


   if( foutD3 == NULL | foutA3 == NULL | foutavgD3 == NULL){
      THD_delete_3dim_dataset( new_dsetD3 , False ) ;
      THD_delete_3dim_dataset( new_dsetA3 , False ) ;
      THD_delete_3dim_dataset( new_dsetavgD3 , False ) ;
      FREE_WORKSPACE ;
      return "Malloc\nFailure!\n [fout]" ;
   }

   for( kk=0 ; kk < nfreq ; kk++ ){
      foutD3[kk] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */
      foutA3[kk] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */
      foutavgD3[0] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */
      if( foutD3[kk] == NULL ) break ;
      if( foutA3[kk] == NULL ) break ;
      if( foutavgD3[0] == NULL ) break ;
   }

   if( kk < nfreq ){
      for( ; kk >= 0 ; kk-- ){
       FREEUP(foutD3[kk]) ;
       FREEUP(foutA3[kk]) ;
       FREEUP(foutavgD3[0]) ;
       }/* free all we did get */
      THD_delete_3dim_dataset( new_dsetD3 , False ) ;
      THD_delete_3dim_dataset( new_dsetA3 , False ) ;
      THD_delete_3dim_dataset( new_dsetavgD3 , False ) ;
      FREE_WORKSPACE ;
      return "Malloc\nFailure!\n [arrays]" ;
   }

   { char buf[128] ;
     ii = (nfreq * nvox * sizeof(float)) / (1024*1024) ;
     sprintf( buf , "  \n"
                    "*** 3D+time ASL a3/d3:\n"
                    "*** Using %d MBytes of workspace,\n "
                    "*** with # time points = %d\n" , ii,numT ) ;
     PLUTO_popup_transient( plint , buf ) ;
   }

   /*----------------------------------------------------*/
   /*----- Setup has ended.  Now do some real work. -----*/

   /***** loop over voxels *****/

/* *(flip)=scale; */

*(numAv)= nuse-ignore;

   for( ii=0 ; ii < nvox ; ii ++ ){  /* time series */

      switch( old_datum ){

	case MRI_byte:
            for( kk=0 ; kk < nuse ; kk++ ){
            	this[kk] =  bptr[kk][ii] ;
             }

         break ;

         case MRI_short:
            for( kk=0 ; kk < nuse ; kk++ ){
             this[kk] =  sptr[kk][ii] ;

            }
         break ;

         case MRI_float:
            for( kk=0 ; kk < nuse ; kk++ ){
             this[kk] =  fptr[kk][ii] ;

            }

         break ;
      }

      flip=scale*pow(-1,ignore+1);

      for( kk=0 ; kk < nuse-ignore ; kk++ ){

      		if (kk==nuse-1-ignore){
        		*(*(foutD3+kk)+ii)=
			flip*( *(this+kk+ignore-1)-*(this+kk+ignore) );

			*(*(foutA3+kk)+ii)=
			2*(*(this+kk+ignore-1)+*(this+kk+ignore));


			}
		else if (kk==0){
						/*D3 tag - control*/
        		*(*(foutD3+kk)+ii)=
			flip*( *(this+kk+ignore)-*(this+kk+ignore+1) );

			*(*(foutA3+kk)+ii)=
			2*(*(this+kk+ignore)+*(this+kk+ignore+1));

			}

		else{
			*(*(foutD3+kk)+ii)=
			flip*( 1*(*(this+kk+ignore-1))+-2*(*(this+kk+ignore))+1*(*(this+kk+ignore+1)) );

			*(*(foutA3+kk)+ii)=
			((*(this+kk+ignore-1))+2*(*(this+kk+ignore))+(*(this+kk+ignore+1)));

			flip=-1*flip;


			}


	}



      for( kk=0 ; kk < nuse-ignore ; kk++ )
     *(*(foutavgD3)+ii)= *(*(foutavgD3)+ii)+(*(*(foutD3+kk)+ii));

     *(*(foutavgD3)+ii)=*(*(foutavgD3)+ii) / (*(numAv));


      }

   DSET_unload( old_dset ) ;  /* don't need this no more */

   switch( new_datum ){

      /*** output is floats is the simplest:
           we just have to attach the fout bricks to the dataset ***/

      case MRI_float:
         for( kk=0 ; kk < nuse-ignore ; kk++ )
            EDIT_substitute_brick( new_dsetD3 , kk , MRI_float , foutD3[kk] ) ;
      break ;

      /*** output is shorts:
           we have to create a scaled sub-brick from fout ***/

      case MRI_short:{
         short * boutD3 ;
         float facD3 ;

         for( kk=0 ; kk < nuse-ignore ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/

            boutD3 = (short *) malloc( sizeof(short) * nvox ) ;
            if( boutD3 == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            /*-- find scaling and then scale --*/

            facD3  = MCW_vol_amax( nvox,1,1 , MRI_float , foutD3[kk] ) ;
            if( facD3  > 0.0 ){
               facD3  = 32767.0 / facD3  ;
               EDIT_coerce_scale_type( nvox,facD3  ,
                                       MRI_float,foutD3[kk] , MRI_short,boutD3  ) ;
               facD3  = 1.0 / facD3  ;
            }

            free( foutD3[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/

            EDIT_substitute_brick( new_dsetD3 , kk , MRI_short , boutD3  ) ;
            tarD3 [kk] = facD3  ;


         }

         /*-- save scale factor array into dataset --*/

         EDIT_dset_items( new_dsetD3 , ADN_brick_fac , tarD3  , ADN_none ) ;

      }
      break ;

      /*** output is bytes (byte = unsigned char)
           we have to create a scaled sub-brick from fout ***/

      case MRI_byte:{
         byte * boutD3  ;
         float facD3  ;

         for( kk=0 ; kk < nuse-ignore ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/

            boutD3  = (byte *) malloc( sizeof(byte) * nvox ) ;
            if( boutD3  == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            /*-- find scaling and then scale --*/

            facD3  = MCW_vol_amax( nvox,1,1 , MRI_float , foutD3[kk] ) ;
            if( facD3  > 0.0 ){
               facD3  = 255.0 / facD3  ;
               EDIT_coerce_scale_type( nvox,facD3  ,
                                       MRI_float,foutD3[kk] , MRI_byte,boutD3 ) ;
               facD3 = 1.0 / facD3  ;
            }

            free( foutD3[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/

            EDIT_substitute_brick( new_dsetD3 , kk , MRI_byte , boutD3  ) ;
            tarD3 [kk] = facD3  ;


         }

         /*-- save scale factor array into dataset --*/

         EDIT_dset_items( new_dsetD3 , ADN_brick_fac , tarD3  , ADN_none ) ;
      }
      break ;

   } /* end of switch on output data type */


   switch( new_datum ){

      /*** output is floats is the simplest:
           we just have to attach the fout bricks to the dataset ***/

      case MRI_float:
         for( kk=0 ; kk < nuse-ignore ; kk++ )
            EDIT_substitute_brick( new_dsetA3 , kk , MRI_float , foutA3[kk] ) ;
      break ;

      /*** output is shorts:
           we have to create a scaled sub-brick from fout ***/

      case MRI_short:{
         short * boutA3 ;
         float facA3 ;

         for( kk=0 ; kk < nuse-ignore ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/

            boutA3 = (short *) malloc( sizeof(short) * nvox ) ;
            if( boutA3 == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            /*-- find scaling and then scale --*/

            facA3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutA3[kk] ) ;
            if( facA3 > 0.0 ){
               facA3 = 32767.0 / facA3 ;
               EDIT_coerce_scale_type( nvox,facA3 ,
                                       MRI_float,foutA3[kk] , MRI_short,boutA3 ) ;
               facA3 = 1.0 / facA3 ;
            }

            free( foutA3[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/

            EDIT_substitute_brick( new_dsetA3 , kk , MRI_short , boutA3 ) ;
            tarA3[kk] = facA3 ;


         }

         /*-- save scale factor array into dataset --*/

         EDIT_dset_items( new_dsetA3 , ADN_brick_fac , tarA3 , ADN_none ) ;

      }
      break ;

      /*** output is bytes (byte = unsigned char)
           we have to create a scaled sub-brick from fout ***/

      case MRI_byte:{
         byte * boutA3 ;
         float facA3 ;

         for( kk=0 ; kk < nuse-ignore ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/

            boutA3 = (byte *) malloc( sizeof(byte) * nvox ) ;
            if( boutA3 == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            /*-- find scaling and then scale --*/

            facA3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutA3[kk] ) ;
            if( facA3 > 0.0 ){
               facA3 = 255.0 / facA3 ;
               EDIT_coerce_scale_type( nvox,facA3 ,
                                       MRI_float,foutA3[kk] , MRI_byte,boutA3 ) ;
               facA3 = 1.0 / facA3 ;
            }

            free( foutA3[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/

            EDIT_substitute_brick( new_dsetA3 , kk , MRI_byte , boutA3 ) ;
            tarA3[kk]= facA3 ;


         }

         /*-- save scale factor array into dataset --*/

         EDIT_dset_items( new_dsetA3 , ADN_brick_fac , tarA3 , ADN_none ) ;
      }
      break ;

   } /* end of switch on output data type */


     switch( new_datum ){

      case MRI_float:{

            EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_float , foutavgD3[0] ) ;


    }
      break ;

      case MRI_short:{
         short * boutavgD3 ;
         float facavgD3 ;

            boutavgD3 = (short *) malloc( sizeof(short) * nvox ) ;
            if( boutavgD3 == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            facavgD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutavgD3[0] ) ;
            if( facavgD3 > 0.0 ){
               facavgD3 = 32767.0 / facavgD3 ;
               EDIT_coerce_scale_type( nvox,facavgD3 ,
                                       MRI_float,foutavgD3[0] , MRI_short,boutavgD3 ) ;
               facavgD3 = 1.0 / facavgD3 ;
            }



            EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_short , boutavgD3 ) ;
            taravgD3[0] = facavgD3 ;

             EDIT_dset_items( new_dsetavgD3 , ADN_brick_fac , taravgD3 , ADN_none ) ;



      }
      break ;

      case MRI_byte:{
         byte * boutavgD3 ;
         float facavgD3 ;


            boutavgD3 = (byte *) malloc( sizeof(byte) * nvox ) ;
            if( boutavgD3 == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ;
               EXIT(1) ;
            }

            facavgD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutavgD3[0] ) ;
            if( facavgD3 > 0.0 ){
               facavgD3 = 255.0 / facavgD3 ;
               EDIT_coerce_scale_type( nvox,facavgD3 ,
                                       MRI_float,foutavgD3[0] , MRI_byte,boutavgD3 ) ;
               facavgD3 = 1.0 / facavgD3 ;
            }



            EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_byte , boutavgD3 ) ;
            taravgD3[0]= facavgD3 ;

            EDIT_dset_items( new_dsetavgD3 , ADN_brick_fac , taravgD3 , ADN_none ) ;




      }
      break ;

   } /* endasda of switch on output data type */




   /*-------------- Cleanup and go home ----------------*/



   PLUTO_add_dset( plint , new_dsetD3 , DSET_ACTION_NONE ) ;
  PLUTO_add_dset( plint , new_dsetA3 , DSET_ACTION_NONE ) ;
  PLUTO_add_dset( plint , new_dsetavgD3 , DSET_ACTION_NONE ) ;



   FREE_WORKSPACE ;
   free(numAv);


   return NULL ;  /* null string returned means all was OK */
}
char * THD_dataset_info( THD_3dim_dataset *dset , int verbose )
{
   THD_dataxes      *daxes ;
   THD_fvec3 fv1 , fv2 , fv3 ;
   int ival , ntimes , nval_per , n1,n2,n3 , kv,npar ;
   float tf, angle=0.0;
   long long tb ;

   static char *RR="[R]" , *LL="[L]" ,
               *PP="[P]" , *AA="[A]" ,
               *SS="[S]" , *II="[I]" , *ZZ="   " ;
   char *xlbot , *xltop , *ylbot , *yltop , *zlbot , *zltop , *cpt ;
   char str[1024], soblq[1024] ;
   int nstr , obliquity;

   char *outbuf = NULL ;  /* output buffer */

ENTRY("THD_dataset_info") ;

   if( ! ISVALID_3DIM_DATASET(dset) ) RETURN(NULL) ;

   daxes = dset->daxes ;

   if( DSET_IS_BRIK(dset) )
     outbuf = THD_zzprintf(outbuf,"Dataset File:    %s\n" , DSET_FILECODE(dset) ) ;
   else
     outbuf = THD_zzprintf(outbuf,"Dataset File:    %s\n" , DSET_BRIKNAME(dset) ) ;

   outbuf = THD_zzprintf(outbuf,"Identifier Code: %s  Creation Date: %s\n" ,
             dset->idcode.str , dset->idcode.date ) ;
   outbuf = THD_zzprintf(outbuf,   "Template Space:  %s\n", dset->atlas_space);

   if( ISANAT(dset) ){
      outbuf = THD_zzprintf(outbuf,"Dataset Type:    %s (-%s)\n",
                ANAT_typestr[dset->func_type] , ANAT_prefixstr[dset->func_type] ) ;
   } else {
      outbuf = THD_zzprintf(outbuf,"Dataset Type:    %s (-%s)\n",
                FUNC_typestr[dset->func_type] , FUNC_prefixstr[dset->func_type] ) ;
   }

   /* 25 April 1998: do byte order stuff */

   switch( DSET_BYTEORDER(dset) ){
      case LSB_FIRST:
         outbuf = THD_zzprintf(outbuf,"Byte Order:      %s" , LSB_FIRST_STRING) ;
      break ;
      case MSB_FIRST:
         outbuf = THD_zzprintf(outbuf,"Byte Order:      %s" , MSB_FIRST_STRING) ;
      break ;
   }

   if( THD_find_string_atr(dset->dblk,ATRNAME_BYTEORDER) == NULL ) /* 19 Sep 1999 */
      outbuf = THD_zzprintf(outbuf," {assumed}") ;

   kv = mri_short_order() ;
   switch( kv ){
      case LSB_FIRST:
         outbuf = THD_zzprintf(outbuf," [this CPU native = %s]\n" , LSB_FIRST_STRING) ;
      break ;
      case MSB_FIRST:
         outbuf = THD_zzprintf(outbuf," [this CPU native = %s]\n" , MSB_FIRST_STRING) ;
      break ;
   }

   /*-- 21 Jun 2002: print storage mode --*/
   if( dset->dblk->diskptr != NULL ){
      outbuf = THD_zzprintf(outbuf,"Storage Mode:    %s\n",
                        storage_mode_str(dset->dblk->diskptr->storage_mode));
   }

   tb = dset->dblk->total_bytes ;
   if( tb > 0 )
     outbuf = THD_zzprintf(outbuf,"Storage Space:   %s (%s) bytes\n",
                           commaized_integer_string(dset->dblk->total_bytes) ,
                           approximate_number_string(dset->dblk->total_bytes) ) ;

   /*-- keywords --*/

   if( verbose >= 0 ){
     cpt = DSET_KEYWORDS(dset) ;
     if( cpt != NULL && cpt[0] != '\0' ){
       int j = strlen(cpt) ;
       if( j < 99 ){
         outbuf = THD_zzprintf(outbuf,"Keywords:        %s\n" , cpt ) ;
       } else {
        int k ;
        outbuf = THD_zzprintf(outbuf,"\n----- KEYWORDS -----\n") ;
        for( k=0 ; k < j ; k += ZMAX )
          outbuf = THD_zzprintf(outbuf,SZMAX,cpt+k) ;
         outbuf = THD_zzprintf(outbuf,"\n") ;
       }
     }
   }

   /*-- idcodes --*/

  if( verbose >= 0 ){
   if( ! ISZERO_IDCODE(dset->anat_parent_idcode) )
      outbuf = THD_zzprintf(outbuf,"Anatomy Parent:  %s [%s]\n" ,
                dset->anat_parent_name , dset->anat_parent_idcode.str ) ;
   else if( strlen(dset->anat_parent_name) > 0 )
      outbuf = THD_zzprintf(outbuf,"Anatomy Parent:  %s\n" , dset->anat_parent_name ) ;

   if( ! ISZERO_IDCODE(dset->warp_parent_idcode) )
      outbuf = THD_zzprintf(outbuf,"Warp Parent:     %s [%s]\n" ,
                 dset->warp_parent_name , dset->warp_parent_idcode.str) ;
   else if( strlen(dset->warp_parent_name) > 0 )
      outbuf = THD_zzprintf(outbuf,"Warp Parent:     %s\n" , dset->warp_parent_name ) ;
  }

   /*-- tagset --*/
   if( verbose > 0 && dset->tagset != NULL && dset->tagset->num > 0 ){
      int ii , ns=0 ;
      for( ii=0 ; ii < dset->tagset->num ; ii++ )
         if( dset->tagset->tag[ii].set ) ns++ ;

      outbuf = THD_zzprintf(outbuf,"Tagset:          %d set [out of %d total]\n",
                            ns , dset->tagset->num ) ;
   }

   /* are we oblique ? */
   if((obliquity = dset_obliquity(dset, &angle)) >= 0) {
      if(angle>0.0) {
         sprintf (soblq,
            "Data Axes Tilt:  Oblique (%.3f deg. from plumb)\n"
            "Data Axes Approximate Orientation:",
            angle);
      } else {
         sprintf (soblq,
            "Data Axes Tilt:  Plumb\n"
            "Data Axes Orientation:");
      }
      { char *gstr = EDIT_get_geometry_string(dset) ;
        if( gstr != NULL && *gstr != '\0' )
          outbuf = THD_zzprintf(outbuf,"Geometry String: \"%s\"\n",gstr) ;
      }
   } else {
      sprintf (soblq,
            "Data Axes Tilt:  Unspecified, assumed plumb\n"
            "Data Axes Orientation:");
   }

   outbuf = THD_zzprintf(outbuf,
      "%s\n"
      "  first  (x) = %s\n"
      "  second (y) = %s\n"
      "  third  (z) = %s   [-orient %c%c%c]\n" ,
    soblq,
    ORIENT_typestr[daxes->xxorient] ,
      ORIENT_typestr[daxes->yyorient] ,
      ORIENT_typestr[daxes->zzorient] ,
    ORIENT_typestr[daxes->xxorient][0] ,
      ORIENT_typestr[daxes->yyorient][0] ,
      ORIENT_typestr[daxes->zzorient][0]  ) ;

   LOAD_FVEC3(fv1 , daxes->xxorg , daxes->yyorg , daxes->zzorg) ;
   fv1 = THD_3dmm_to_dicomm( dset , fv1 ) ;

   LOAD_FVEC3(fv2 , daxes->xxorg + (daxes->nxx-1)*daxes->xxdel ,
                    daxes->yyorg + (daxes->nyy-1)*daxes->yydel ,
                    daxes->zzorg + (daxes->nzz-1)*daxes->zzdel  ) ;
   fv2 = THD_3dmm_to_dicomm( dset , fv2 ) ;

   if( fv1.xyz[0] > fv2.xyz[0] ) FSWAP( fv1.xyz[0] , fv2.xyz[0] ) ;
   if( fv1.xyz[1] > fv2.xyz[1] ) FSWAP( fv1.xyz[1] , fv2.xyz[1] ) ;
   if( fv1.xyz[2] > fv2.xyz[2] ) FSWAP( fv1.xyz[2] , fv2.xyz[2] ) ;

   LOAD_FVEC3(fv3 , daxes->xxdel , daxes->yydel , daxes->zzdel) ;
   fv3 = THD_3dmm_to_dicomm( dset , fv3 ) ;

   XLAB(xlbot,fv1.xyz[0]) ; YLAB(ylbot,fv1.xyz[1]) ; ZLAB(zlbot,fv1.xyz[2]) ;
   XLAB(xltop,fv2.xyz[0]) ; YLAB(yltop,fv2.xyz[1]) ; ZLAB(zltop,fv2.xyz[2]) ;

   n1 = DAXES_NUM(daxes,ORI_R2L_TYPE) ;
   n2 = DAXES_NUM(daxes,ORI_A2P_TYPE) ;
   n3 = DAXES_NUM(daxes,ORI_I2S_TYPE) ;

   outbuf = THD_zzprintf(outbuf,
      "R-to-L extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n"
      "A-to-P extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n"
      "I-to-S extent: %9.3f %s -to- %9.3f %s -step- %9.3f mm [%3d voxels]\n" ,
    fv1.xyz[0],xlbot , fv2.xyz[0],xltop , fabs(fv3.xyz[0]) , n1 ,
    fv1.xyz[1],ylbot , fv2.xyz[1],yltop , fabs(fv3.xyz[1]) , n2 ,
    fv1.xyz[2],zlbot , fv2.xyz[2],zltop , fabs(fv3.xyz[2]) , n3  ) ;

   /*-- 01 Feb 2001: print the center of the dataset as well --*/

   if( verbose > 0 ){
    fv1.xyz[0] = 0.5*(fv1.xyz[0]+fv2.xyz[0]) ; XLAB(xlbot,fv1.xyz[0]) ;
    fv1.xyz[1] = 0.5*(fv1.xyz[1]+fv2.xyz[1]) ; YLAB(ylbot,fv1.xyz[1]) ;
    fv1.xyz[2] = 0.5*(fv1.xyz[2]+fv2.xyz[2]) ; ZLAB(zlbot,fv1.xyz[2]) ;

    outbuf = THD_zzprintf(outbuf,
                            "R-to-L center: %9.3f %s\n"
                            "A-to-P center: %9.3f %s\n"
                            "I-to-S center: %9.3f %s\n" ,
                          fv1.xyz[0],xlbot ,
                          fv1.xyz[1],ylbot ,
                          fv1.xyz[2],zlbot  ) ;
   }

   ntimes   = DSET_NUM_TIMES(dset) ;
   nval_per = DSET_NVALS_PER_TIME(dset) ;
   if( ntimes > 1 ){

      outbuf = THD_zzprintf(outbuf,
         "Number of time steps = %d" , ntimes ) ;

      STATUS("timestep") ;

      outbuf = THD_zzprintf(outbuf, "  Time step = %.5f%s  Origin = %.5f%s" ,
                 dset->taxis->ttdel ,
                 UNITS_TYPE_LABEL(dset->taxis->units_type) ,
                 dset->taxis->ttorg ,
                 UNITS_TYPE_LABEL(dset->taxis->units_type)  ) ;
      if( dset->taxis->nsl > 0 )
        outbuf = THD_zzprintf(outbuf,"  Number time-offset slices = %d  Thickness = %.3f",
                  dset->taxis->nsl , fabs(dset->taxis->dz_sl) ) ;
      outbuf = THD_zzprintf(outbuf,"\n") ;

      STATUS("nsl done") ;

      if( verbose > 0 && dset->taxis->nsl > 0 && dset->taxis->toff_sl != NULL ){
         outbuf = THD_zzprintf(outbuf,"Time-offsets per slice:") ;
         for( ival=0 ; ival < dset->taxis->nsl ; ival++ )
           outbuf = THD_zzprintf(outbuf, " %.3f" , dset->taxis->toff_sl[ival] ) ;
         outbuf = THD_zzprintf(outbuf,"\n") ;
      }
   } else {
      outbuf = THD_zzprintf(outbuf,
           "Number of values stored at each pixel = %d\n" , nval_per ) ;
   }

#if 0
   if( verbose > 0 && ntimes > 1 ) nval_per = dset->dblk->nvals ;
   else                            nval_per = 1 ;                 /* 12 Feb 2002 */
#else
   nval_per = dset->dblk->nvals ;
   if( verbose < 0 && nval_per > 5 ) nval_per = 3 ;
#endif

   /* print out stuff for each sub-brick */

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

     STATUS("ival a") ;

      sprintf( str ,
               "  -- At sub-brick #%d '%s' datum type is %s" ,
               ival , DSET_BRICK_LAB(dset,ival) ,
               MRI_TYPE_name[DSET_BRICK_TYPE(dset,ival)] ) ;
      nstr = strlen(str) ;

      tf = DSET_BRICK_FACTOR(dset,ival) ;

      if( ISVALID_STATISTIC(dset->stats) ){

         if( tf != 0.0 ){
            sprintf( str+nstr ,
                                ":%13.6g to %13.6g [internal]\n"
                    "%*s[*%13.6g] %13.6g to %13.6g [scaled]\n" ,
                    dset->stats->bstat[ival].min/tf ,
                    dset->stats->bstat[ival].max/tf ,
                    nstr-16," " , tf ,
                    dset->stats->bstat[ival].min , dset->stats->bstat[ival].max ) ;
          } else {
            sprintf( str+nstr , ":%13.6g to %13.6g\n" ,
                    dset->stats->bstat[ival].min , dset->stats->bstat[ival].max ) ;
          }
      } else if( tf != 0.0 ){
         sprintf( str+nstr , " [*%g]\n",tf) ;
      } else {
         sprintf( str+nstr , "\n") ;
      }
     STATUS("ival b") ;
      outbuf = THD_zzprintf(outbuf,"%s",str) ;

      /** 30 Nov 1997: print sub-brick stat params **/

      kv = DSET_BRICK_STATCODE(dset,ival) ;
      if( FUNC_IS_STAT(kv) ){
     STATUS("ival c") ;
         outbuf = THD_zzprintf(outbuf,"     statcode = %s",FUNC_prefixstr[kv] ) ;
         npar = FUNC_need_stat_aux[kv] ;
         if( npar > 0 ){
            outbuf = THD_zzprintf(outbuf,";  statpar =") ;
            for( kv=0 ; kv < npar ; kv++ )
               outbuf = THD_zzprintf(outbuf," %g",DSET_BRICK_STATPAR(dset,ival,kv)) ;
         }
         outbuf = THD_zzprintf(outbuf,"\n") ;
     STATUS("ival d") ;
      }

      cpt = DSET_BRICK_KEYWORDS(dset,ival) ;
      if( cpt != NULL && cpt[0] != '\0' ){
        outbuf = THD_zzprintf(outbuf,"     keywords = %.66s\n",cpt) ;
      }

     STATUS("ival z") ;
   }
   if( verbose < 0 && nval_per < dset->dblk->nvals )  /* 21 Sep 2007 */
     outbuf = THD_zzprintf(outbuf,
                "** For info on all %d sub-bricks, use '3dinfo -verb' **\n",
                dset->dblk->nvals) ;

   /** print out dataset global statistical parameters **/

   if( ISFUNC(dset) && FUNC_need_stat_aux[dset->func_type] > 0 ){
      outbuf = THD_zzprintf(outbuf,"Auxiliary functional statistical parameters:\n %s\n",
             FUNC_label_stat_aux[dset->func_type] ) ;
      for( ival=0 ; ival < FUNC_need_stat_aux[dset->func_type] ; ival++ )
         outbuf = THD_zzprintf(outbuf," %g",dset->stat_aux[ival]) ;
      outbuf = THD_zzprintf(outbuf,"\n") ;
   }

   /** If present, print out History **/

   { char *chn ; int j,k ;
     chn = tross_Get_History(dset) ;
     if( chn != NULL ){
       j = strlen(chn) ;
       outbuf = THD_zzprintf(outbuf,"\n----- HISTORY -----\n") ;
       for( k=0 ; k < j ; k += ZMAX )
         outbuf = THD_zzprintf(outbuf,SZMAX,chn+k) ;
       free(chn) ;
       outbuf = THD_zzprintf(outbuf,"\n") ;
     }
   }

   /** If present, print out Notes **/

   if( verbose >= 0 ){
     ATR_int *notecount;
     int num_notes, i, j, mmm ;
     char *chn , *chd ;

     notecount = THD_find_int_atr(dset->dblk, "NOTES_COUNT");
     if( notecount != NULL ){
        num_notes = notecount->in[0] ;
        if( verbose == 0 && num_notes > 5 ) num_notes = 5 ;
        mmm = (verbose > 0) ? ZMAX : 1200 ;   /* 400 it was!
                                                 Come on Bob, have a heart! -ZSS */
        for (i=1; i<= num_notes; i++) {
           chn = tross_Get_Note( dset , i ) ;
           if( chn != NULL ){
              j = strlen(chn) ; if( j > mmm ) chn[mmm] = '\0' ;
              chd = tross_Get_Notedate(dset,i) ;
              if( chd == NULL ){ chd = AFMALL(char,16) ; strcpy(chd,"no date") ; }
              outbuf = THD_zzprintf(outbuf,"\n----- NOTE %d [%s] -----\n%s\n",i,chd,chn) ;
              free(chn) ; free(chd) ;
           }
Esempio n. 4
0
int main( int argc , char *argv[] )
{
   int vstep=0 , ii,nvox , ntin , ntout , do_one=0 , nup=-1 ;
   THD_3dim_dataset *inset=NULL , *outset ;
   char *prefix="Upsam", *dsetname=NULL ;
   int verb=0 , iarg=1, datum = MRI_float;
   float *ivec , *ovec , trin , trout, *fac=NULL, *ofac=NULL, 
         top=0.0, maxtop=0.0;

   /*------- help the pitifully ignorant user? -------*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 3dUpsample [options] n dataset\n"
      "\n"
      "* Upsamples a 3D+time dataset, in the time direction,\n"
      "   by a factor of 'n'.\n"
      "* The value of 'n' must be between 2 and 320 (inclusive).\n"
      "* The output dataset is in float format by default.\n"
      "\n"
      "Options:\n"
      "--------\n"
      " -1 or -one = Use linear interpolation. Otherwise,\n"
      " or -linear   7th order polynomial interpolation is used.\n"
      "\n"
      " -prefix pp = Define the prefix name of the output dataset.\n"
      "              [default prefix is 'Upsam']\n"
      "\n"
      " -verb      = Be eloquently and mellifluosly verbose.\n"
      "\n"
      " -n n       = An alternate way to specify n\n"
      " -input dataset = An alternate way to specify dataset\n"
      "\n"
      " -datum ddd = Use datatype ddd at output. Choose from\n"
      "              float (default), short, byte.\n"
      "Example:\n"
      "--------\n"
      " 3dUpsample -prefix LongFred 5 Fred+orig\n"
      "\n"
      "Nota Bene:\n"
      "----------\n"
      "* You should not use this for files that were 3dTcat-ed across\n"
      "   imaging run boundaries, since that will result in interpolating\n"
      "   between non-contiguous time samples!\n"
      "* If the input has M time points, the output will have n*M time\n"
      "   points.  The last n-1 of them will be past the end of the original\n"
      "   time series.\n"
      "* This program gobbles up memory and diskspace as a function of n.\n"
      "  You can reduce output file size with -datum option.\n"
      "\n"
      "--- RW Cox - April 2008\n"
     ) ;
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   mainENTRY("3dUpsample"); machdep();
   PRINT_VERSION("3dUpsample"); AUTHOR("RWCox") ;
   AFNI_logger("3dUpsample",argc,argv);

   /*------- read command line args -------*/

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

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

     if( strncasecmp(argv[iarg],"-one",4) == 0 ||
         strcmp     (argv[iarg],"-1"    ) == 0 ||
         strncasecmp(argv[iarg],"-lin",4) == 0   ){
       do_one = 1 ; iarg++ ; continue ;
     }

     if( strncasecmp(argv[iarg],"-verb",3) == 0 ){
       verb = 1 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-n") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      nup = (int)strtod(argv[iarg],NULL) ;
      if( nup < 2 || nup > 320 )
        ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ;
      iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-input") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      dsetname = argv[iarg];
      iarg++ ; continue ;
     }
     
     if( strcasecmp(argv[iarg],"-datum") == 0 ){
      if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]);
      
         if( strcmp(argv[iarg],"short") == 0 ){
            datum = MRI_short ;
         } else if( strcmp(argv[iarg],"float") == 0 ){
            datum = MRI_float ;
         } else if( strcmp(argv[iarg],"byte") == 0 ){
            datum = MRI_byte ;
         } else {
            ERROR_message("-datum of type '%s' not supported in 3dUpsample!\n",
                    argv[iarg] ) ;
            exit(1) ;
         }
         
      iarg++ ; continue ;
     }
     
     ERROR_message("Unknown argument on command line: '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit (1);
   }

   /*------- check options for completeness and consistency -----*/
   
   if (nup == -1) {
      if( iarg+1 >= argc )
        ERROR_exit("need 'n' and 'dataset' on command line!") ;

      nup = (int)strtod(argv[iarg++],NULL) ;
      if( nup < 2 || nup > 320 )
        ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ;
   } 
   if (!dsetname) {
      if( iarg >= argc )
        ERROR_exit("need 'dataset' on command line!") ;
      dsetname = argv[iarg];
   }
   
   inset = THD_open_dataset(dsetname) ;
   if( !ISVALID_DSET(inset) )
     ERROR_exit("3dUpsample can't open dataset '%s'", dsetname) ;
   ntin = DSET_NVALS(inset) ; trin = DSET_TR(inset) ;
   if( ntin < 2 )
     ERROR_exit("dataset '%s' has only 1 value per voxel?!",dsetname) ;

   nvox = DSET_NVOX(inset) ;

   if( verb ) INFO_message("loading input dataset into memory") ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;


   /*------ create output dataset ------*/

   ntout = ntin * nup ; trout = trin / nup ;

   /* scaling factor for output */
   fac = NULL; maxtop = 0.0;
   if (MRI_IS_INT_TYPE(datum)) {
      fac = (float *)calloc(DSET_NVALS(inset), sizeof(float));
      ofac = (float *)calloc(ntout, sizeof(float));
      for (ii=0; ii<DSET_NVALS(inset); ++ii) {
         top = MCW_vol_amax( DSET_NVOX(inset),1,1 , 
                             DSET_BRICK_TYPE(inset,ii), 
                             DSET_BRICK_ARRAY(inset,ii) ) ;
         if (DSET_BRICK_FACTOR(inset, ii)) 
            top = top * DSET_BRICK_FACTOR(inset,ii);
         fac[ii] = (top > MRI_TYPE_maxval[datum]) ? 
                        top/MRI_TYPE_maxval[datum] : 0.0 ;
         if (top > maxtop) maxtop = top;
      }
      if (storage_mode_from_filename(prefix) != STORAGE_BY_BRICK) {
         fac[0] = (maxtop > MRI_TYPE_maxval[datum]) ? 
                        maxtop/MRI_TYPE_maxval[datum] : 0.0 ;
         for (ii=0; ii<ntout; ++ii) 
            ofac[ii] = fac[0];
         if (verb) INFO_message("Forcing global scaling, Max = %f, fac = %f\n", 
                        maxtop, fac[0]);
      } else {
         if (verb) INFO_message("Reusing scaling factors of input dset\n");
         upsample_1( nup, DSET_NVALS(inset), fac, ofac);
      }
   }
   free(fac); fac = NULL;
   outset = EDIT_empty_copy(inset) ;
   EDIT_dset_items( outset ,
                        ADN_nvals     , ntout          ,
                        ADN_ntt       , DSET_NUM_TIMES(inset) > 1 ? ntout : 0 ,
                        ADN_datum_all , datum      ,
                        ADN_brick_fac , ofac           ,
                        ADN_prefix    , prefix         ,
                      ADN_none ) ;
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dUpsample" , argc,argv , outset ) ;
   free(ofac); ofac = NULL;
   
   if( outset->taxis != NULL ){
     outset->taxis->ttdel /= nup ;
     outset->taxis->ttdur /= nup ;
     if( outset->taxis->toff_sl != NULL ){
       for( ii=0 ; ii < outset->taxis->nsl ; ii++ )
         outset->taxis->toff_sl[ii] /= nup ;
     }
   }

   for( ii=0 ; ii < ntout ; ii++ ){ /* create empty bricks to be filled below */
     EDIT_substitute_brick( outset , ii , datum , NULL ) ;
   }

   /*------- loop over voxels and process them one at a time ---------*/

   if( verb )
     INFO_message("Upsampling time series from %d to %d: %s interpolation",
                  ntin , ntout , (do_one) ? "linear" : "heptic" ) ;

   if( verb && nvox > 499 ) vstep = nvox / 50 ;
   if( vstep > 0 ) fprintf(stderr,"++ voxel loop: ") ;

   ivec = (float *)malloc(sizeof(float)*ntin) ;
   ovec = (float *)malloc(sizeof(float)*ntout) ;

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

     if( vstep > 0 && ii%vstep==vstep-1 ) vstep_print() ;

     THD_extract_array( ii , inset , 0 , ivec ) ;

     if( do_one ) upsample_1( nup , ntin , ivec , ovec ) ;
     else         upsample_7( nup , ntin , ivec , ovec ) ;

     THD_insert_series( ii , outset , ntout , MRI_float , ovec , 
                        datum==MRI_float ? 1:0 ) ;
   } /* end of loop over voxels */

   if( vstep > 0 ) fprintf(stderr," Done!\n") ;

   /*----- clean up and go away -----*/

   DSET_write(outset) ;
   if( verb ) WROTE_DSET(outset) ;
   if( verb ) INFO_message("Total CPU time = %.1f s",COX_cpu_time()) ;
   exit(0);
}
Esempio n. 5
0
static int * PLUTO_4D_to_nothing (THD_3dim_dataset * old_dset , int ignore , int detrend ,
                         generic_func * user_func, void * user_data )
{

   byte    ** bptr = NULL ;  /* one of these will be the array of */
   short   ** sptr = NULL ;  /* pointers to input dataset sub-bricks */
   float   ** fptr = NULL ;  /* (depending on input datum type) */
   complex ** cptr = NULL ;

   float * fxar = NULL ;  /* array loaded from input dataset */
   float * fac  = NULL ;  /* array of brick scaling factors */
   float * dtr  = NULL ;  /* will be array of detrending coeff */

   float val , d0fac , d1fac , x0,x1;
   double tzero=0.0 , tdelta , ts_mean , ts_slope ;
   int   ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox ;
   static int retval;
	register int kk ;

   /*----------------------------------------------------------*/
   /*----- Check inputs to see if they are reasonable-ish -----*/

   if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ;

   if( user_func == NULL ) return NULL ;

   if( ignore < 0 ) ignore = 0 ;

   /*--------- set up pointers to each sub-brick in the input dataset ---------*/

   old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ;   /* get old dataset datum */
   nuse      = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */
   if( nuse < 2 ) return NULL ;

   DSET_load( old_dset ) ;  /* must be in memory before we get pointers to it */

   kk = THD_count_databricks( old_dset->dblk ) ;  /* check if it was */
   if( kk < DSET_NVALS(old_dset) ){               /* loaded correctly */
      DSET_unload( old_dset ) ;
      return NULL ;
   }

   switch( old_datum ){  /* pointer type depends on input datum type */

      default:                      /** don't know what to do **/
         DSET_unload( old_dset ) ;
         return NULL ;

      /** create array of pointers into old dataset sub-bricks **/

      /*--------- input is bytes ----------*/
      /* voxel #i at time #k is bptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_byte:
         bptr = (byte **) malloc( sizeof(byte *) * nuse ) ;
         if( bptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is shorts ---------*/
      /* voxel #i at time #k is sptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_short:
         sptr = (short **) malloc( sizeof(short *) * nuse ) ;
         if( sptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is floats ---------*/
      /* voxel #i at time #k is fptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_float:
         fptr = (float **) malloc( sizeof(float *) * nuse ) ;
         if( fptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is complex ---------*/
      /* voxel #i at time #k is cptr[k][i]  */
      /* for i=0..nvox-1 and k=0..nuse-1.   */

      case MRI_complex:
         cptr = (complex **) malloc( sizeof(complex *) * nuse ) ;
         if( cptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

   } /* end of switch on input type */

	nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ;

   
   /*---- allocate space for 1 voxel timeseries ----*/

   fxar = (float *) malloc( sizeof(float) * nuse ) ;   /* voxel timeseries */
   if( fxar == NULL ){ ZFREE_WORKSPACE ; return NULL ; }

   /*--- get scaling factors for sub-bricks ---*/

   fac = (float *) malloc( sizeof(float) * nuse ) ;   /* factors */
   if( fac == NULL ){ ZFREE_WORKSPACE ; return NULL ; }

   use_fac = 0 ;
   for( kk=0 ; kk < nuse ; kk++ ){
      fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ;
      if( fac[kk] != 0.0 ) use_fac++ ;
      else                 fac[kk] = 1.0 ;
   }
   if( !use_fac ) ZFREEUP(fac) ;

   /*--- setup for detrending ---*/

   dtr = (float *) malloc( sizeof(float) * nuse ) ;
   if( dtr == NULL ){ ZFREE_WORKSPACE ; return NULL ; }

   d0fac = 1.0 / nuse ;
   d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ;
   for( kk=0 ; kk < nuse ; kk++ )
      dtr[kk] = kk - 0.5 * (nuse-1) ;  /* linear trend, orthogonal to 1 */


   /*----- set up to find time at each voxel -----*/

   tdelta = old_dset->taxis->ttdel ;
   if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ;
   if( tdelta == 0.0 ) tdelta = 1.0 ;

   izold  = -666 ;
   nxy    = old_dset->daxes->nxx * old_dset->daxes->nyy ;

   /*----------------------------------------------------*/
   /*----- Setup has ended.  Now do some real work. -----*/

   /* start notification */
#if 0
   user_func(  0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data ) ;
#else
   { void (*uf)(double,double,int,float *,double,double,void *) =
     (void (*)(double,double,int,float *,double,double,void *))(user_func) ;
     uf( 0.0l,0.0l , nvox , NULL , 0.0l,0.0l , user_data ) ;
   }
#endif

   /***** loop over voxels *****/   
   for( ii=0 ; ii < nvox ; ii++  ){  /* 1 time series at a time */
		
      /*** load data from input dataset, depending on type ***/

      switch( old_datum ){

         /*** input = bytes ***/

         case MRI_byte:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ;
         break ;

         /*** input = shorts ***/

         case MRI_short:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ;
         break ;

         /*** input = floats ***/

         case MRI_float:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ;
         break ;

         /*** input = complex (note we use absolute value) ***/

         case MRI_complex:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ;
         break ;

      } /* end of switch over input type */

      /*** scale? ***/
     if( use_fac )
         for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ;

      /** compute mean and slope **/

      x0 = x1 = 0.0 ;
      for( kk=0 ; kk < nuse ; kk++ ){
         x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ;
      }

      x0 *= d0fac ; x1 *= d1fac ;  /* factors to remove mean and trend */

      ts_mean  = x0 ;
      ts_slope = x1 / tdelta ;
 
      /** detrend? **/

      if( detrend )
         for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ;

      /** compute start time of this timeseries **/
		/* The info computed here is not being used in this version*/
      iz = ii / nxy ;    /* which slice am I in? */

      if( iz != izold ){          /* in a new slice? */
         tzero = THD_timeof( ignore ,
                             old_dset->daxes->zzorg
                           + iz*old_dset->daxes->zzdel , old_dset->taxis ) ;
         izold = iz ;

         if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ;
      }

      /*** Send data to user function ***/
#if 0
      user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ;
#else
     { void (*uf)(double,double,int,float *,double,double,void *) =
       (void (*)(double,double,int,float *,double,double,void *))(user_func) ;
       uf( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data) ;
     }
#endif

      

   } /* end of outer loop over 1 voxels at a time */

   DSET_unload( old_dset ) ;  

   /* end notification */
#if 0
   user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data ) ;
#else
   { void (*uf)(double,double,int,float *,double,double,void *) =
     (void (*)(double,double,int,float *,double,double,void *))(user_func) ;
     uf( 0.0l,0.0l, 0 , NULL,0.0l,0.0l, user_data ) ;
   }
#endif

   
   /*-------------- Cleanup and go home ----------------*/
   
   ZFREE_WORKSPACE ;
	retval = 0;
	return &retval; /* this value is not used for now .... */

}
Esempio n. 6
0
static char *Fourier_Filter_Driver(PLUGIN_interface *plint, THD_3dim_dataset *input, float low_fc, float high_fc, int ignore, int autocorr, int retrend, char *output_prefix)  {
#else
static char *Fourier_Filter_Driver(THD_3dim_dataset *input, float low_fc, float high_fc, int ignore, int autocorr, int retrend, char *output_prefix)  {
#endif
	int i, j;
	int ntimes, nvox;
	float **out_data, *out_temp, *scale, *input_data_f, period;
	byte *input_data_b;
	short *input_data_s;
	THD_3dim_dataset *output=NULL;
	char *err;

	/* should be a valid 3d+time input */	
	DSET_load(input);
	
	ntimes = DSET_NUM_TIMES(input);
	nvox = DSET_NVOX(input);
	
	/* Create a float array for the output */
	out_data = (float **)My_Malloc(ntimes * sizeof(float *));
	for (i=0; i<ntimes; out_data[i++] = (float *)My_Malloc(nvox * sizeof(float)));
	
	/* Create the tempory float array */
	out_temp = (float *)My_Malloc(ntimes*sizeof(float));
	
	/* Get the scale factors for later */
	scale = (float *)My_Malloc(ntimes*sizeof(float));
	for (i=0; i<ntimes; i++) {
		if (!DSET_BRICK_FACTOR(input,i))
			scale[i] = 1.0;
		else
			scale[i] = DSET_BRICK_FACTOR(input,i);
	}
	
	/* get the sampling period */
	period = DSET_TIMESTEP(input);
	switch (DSET_TIMEUNITS(input)) {
		case UNITS_MSEC_TYPE: {period/=1000; break; }
		case UNITS_SEC_TYPE:   break;
		case UNITS_HZ_TYPE:   return ("FIlter_Driver Error:\nHmm, you would think I could handle a 3d+time that is already\nfrequency, but Im lame");
		default: return("Filter_Driver Error:\nI dont understand the units of the 3d+time");
	}

#ifdef IN_FOURIER_PLUGIN
	PLUTO_popup_meter(plint);		
#endif			
			
	/* Loop over voxels, pull out the time series and filter */
	for (i=0; i< nvox; i++) {
		for (j=0; j<ntimes; j++) {
			switch(DSET_BRICK_TYPE(input,j)) {
				case MRI_byte: {
					input_data_b = (byte *)DSET_ARRAY(input,j);
					out_temp[j] = scale[j] * (float)input_data_b[i];
					break;
				}

				case MRI_short: {
					input_data_s = (short *)DSET_ARRAY(input,j);
					out_temp[j] = scale[j] * (float)input_data_s[i];
					break;
				}

				case MRI_float: {
					input_data_f = (float *)DSET_ARRAY(input,j);
					out_temp[j] = scale[j] * input_data_f[i];
					break;
				}
				
				default : {
					return("FIlter_Driver Error:\nInvalid data type for one of the sub-bricks");
				}
			}
		}
					
		err = filter(out_temp, low_fc, high_fc, ntimes, period, ignore, retrend, FALSE);
		if (err != NULL)
			return err;
		
		for(j=0; j<ntimes; j++)
			out_data[j][i] = out_temp[j];
#ifdef IN_FOURIER_PLUGIN		
		PLUTO_set_meter(plint, (int)(100.0*((float)i/(float)nvox)));
#endif
			
	}
	
	/* create new dataset and convert, etc. */
	output = EDIT_empty_copy(input);

        tross_Copy_History(output,input) ;  /* Jul 2010 */
#if defined(ARGC) && defined(ARGV)
        tross_Make_History( "3dFourier" , ARGC,ARGV , output ) ;
#endif
	
	j=EDIT_dset_items(output,
		ADN_prefix, output_prefix,
		ADN_none);
	
	for (j=0; j<ntimes; j++) {
		switch(DSET_BRICK_TYPE(input,j)) {
			case MRI_byte: {
				input_data_b = (byte *)My_Malloc(nvox*sizeof(byte));
				for (i=0; i<nvox; i++) 
					input_data_b[i] = (byte)(out_data[j][i] / scale[j]);
				EDIT_substitute_brick(output, j, MRI_byte, (byte *)input_data_b); 
				break;
			} 	
			case MRI_short: {
				input_data_s = (short *)My_Malloc(nvox*sizeof(short));
				for (i=0; i<nvox; i++) 
					input_data_s[i] = (short)(out_data[j][i] / scale[j]);
				EDIT_substitute_brick(output, j, MRI_short, (short *)input_data_s); 
				break;
			} 	
			case MRI_float: {
				input_data_f = (float *)My_Malloc(nvox*sizeof(float));
				for (i=0; i<nvox; i++) 
					input_data_f[i] = (float)(out_data[j][i] / scale[j]);
				EDIT_substitute_brick(output, j, MRI_float, (float *)input_data_f); 
				break;
			} 	
		}
#ifdef IN_FOURIER_PLUGIN		
		PLUTO_set_meter(plint, (int)(100.0*((float)j/(float)ntimes)));
#endif
}
	
	/* Write out the new brick at let the memory be free */
#ifdef IN_FOURIER_PLUGIN
	PLUTO_add_dset(plint, output, DSET_ACTION_MAKE_CURRENT);
#else
	DSET_write(output);
#endif
	DSET_unload(input);
	DSET_unload(output);
	for (i=0; i<ntimes; free(out_data[i++]));
	free (out_data);
	free (scale);
	free (out_temp);
#ifdef IN_FOURIER_PLUGIN
	PLUTO_popdown_meter(plint);		
#endif			

	return NULL;
}
Esempio n. 7
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset=NULL;
   int iarg , verbose = -1 ;
   char *outbuf, *stmp=NULL;
   char *labelName = NULL;
   char *sbdelim = {"|"};
   char *NAflag = {"NA"};
   char *atrdelim = {"\t"}, *form=NULL;
   INFO_FIELDS sing[512];
   int iis=0, N_sing = 0, isb=0, withhead = 0, itmp=0;
   int ip=0, needpair = 0, namelen=0, monog_pairs = 0;
   THD_3dim_dataset *tttdset=NULL, *dsetp=NULL;
   char *tempstr = NULL;
   int extinit = 0;
   float RL_AP_IS[6];

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

   if( argc < 2) { Syntax(TXT,1) ; RETURN(0); }

   iarg = 1 ;
   while (iarg < argc && argv[iarg][0] == '-') {
      CHECK_HELP(argv[iarg],Syntax);
           if( strncmp(argv[iarg],"-verb" ,5) == 0 ){
            verbose =  0; iarg++; continue; }
      else if( strncmp(argv[iarg],"-VERB" ,5) == 0 ){
            verbose =  1; iarg++; continue; }
      else if( strncmp(argv[iarg],"-short",5) == 0 ){
            verbose = -1; iarg++; continue; }
      else if( strcasecmp(argv[iarg],"-header_line") == 0 ||
               strcasecmp(argv[iarg],"-hdr") == 0 ){
            withhead = 1; iarg++; continue; }
      else if( strcasecmp(argv[iarg],"-monog_pairs") == 0 ){
            monog_pairs = 1; iarg++; continue; }
      else if ( strncmp(argv[iarg],"-label2",7) == 0 )
      {
        iarg++;
        if (iarg >= argc)
           ERROR_exit( "3dinfo needs an argument after -label2number\n");
        labelName = malloc(sizeof(char) * 2048);
        strcpy(labelName, argv[iarg]);
        iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-sb_delim") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -sb_delim\n");
         sbdelim = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-NA_flag") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -NA_flag\n");
         NAflag = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-atr_delim") == 0) {
         iarg++;
         if (iarg >= argc)
           ERROR_exit( "3dinfo needs a string after -atr_delim\n");
         atrdelim = argv[iarg];
         iarg++; continue;
      }
      else if( strcasecmp(argv[iarg],"-space") == 0) {
         sing[N_sing++] = DSET_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-av_space") == 0) {
         sing[N_sing++] = AV_DSET_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-gen_space") == 0) {
         sing[N_sing++] = DSET_GEN_SPACE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_nifti") == 0) {
         sing[N_sing++] = IS_NIFTI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_atlas") == 0) {
         sing[N_sing++] = IS_ATLAS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-exists") == 0) {
         sing[N_sing++] = DSET_EXISTS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-is_oblique") == 0) {
         sing[N_sing++] = IS_OBLIQUE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-obliquity") == 0) {
         sing[N_sing++] = OBLIQUITY; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-handedness") == 0) {
         sing[N_sing++] = HANDEDNESS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-prefix") == 0) {
         sing[N_sing++] = PREFIX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-prefix_noext") == 0) {
         sing[N_sing++] = PREFIX_NOEXT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ni") == 0) {
         sing[N_sing++] = NI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nj") == 0) {
         sing[N_sing++] = NJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nk") == 0) {
         sing[N_sing++] = NK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-n4") == 0) {
         sing[N_sing++] = NI;
         sing[N_sing++] = NJ;
         sing[N_sing++] = NK;
         sing[N_sing++] = NV; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Rextent") == 0) {
         sing[N_sing++] = EXTENT_R; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Lextent") == 0) {
         sing[N_sing++] = EXTENT_L; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Aextent") == 0) {
         sing[N_sing++] = EXTENT_A; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Pextent") == 0) {
         sing[N_sing++] = EXTENT_P; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-Iextent") == 0) {
         sing[N_sing++] = EXTENT_I; iarg++;
         continue;
      }  else if( strcasecmp(argv[iarg],"-Sextent") == 0) {
         sing[N_sing++] = EXTENT_S; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-extent") == 0) {
         sing[N_sing++] = EXTENT_R;
         sing[N_sing++] = EXTENT_L;
         sing[N_sing++] = EXTENT_A;
         sing[N_sing++] = EXTENT_P;
         sing[N_sing++] = EXTENT_I;
         sing[N_sing++] = EXTENT_S;
         iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-di") == 0) {
         sing[N_sing++] = DI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dj") == 0) {
         sing[N_sing++] = DJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dk") == 0) {
         sing[N_sing++] = DK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-d3") == 0) {
         sing[N_sing++] = DI;
         sing[N_sing++] = DJ;
         sing[N_sing++] = DK; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-adi") == 0) {
         sing[N_sing++] = ADI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-adj") == 0) {
         sing[N_sing++] = ADJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-adk") == 0) {
         sing[N_sing++] = ADK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ad3") == 0) {
         sing[N_sing++] = ADI;
         sing[N_sing++] = ADJ;
         sing[N_sing++] = ADK; iarg++;
         continue;
      } else if( strcasecmp(argv[iarg],"-voxvol") == 0) {
         sing[N_sing++] = VOXVOL; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-iname") == 0) {
         sing[N_sing++] = INAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-oi") == 0) {
         sing[N_sing++] = OI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-oj") == 0) {
         sing[N_sing++] = OJ; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ok") == 0) {
         sing[N_sing++] = OK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-o3") == 0) {
         sing[N_sing++] = OI;
         sing[N_sing++] = OJ;
         sing[N_sing++] = OK; iarg++;
         continue;
      }else if( strcasecmp(argv[iarg],"-nt") == 0) {
         sing[N_sing++] = NT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nti") == 0) {
         sing[N_sing++] = NTI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nv") == 0) {
         sing[N_sing++] = NV; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nvi") == 0) {
         sing[N_sing++] = NVI; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-ntimes") == 0) {
         sing[N_sing++] = NTIMES; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-max_node") == 0) {
         sing[N_sing++] = MAX_NODE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-nijk") == 0) {
         sing[N_sing++] = NIJK; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-labeltable") == 0) {
         sing[N_sing++] = LTABLE; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-labeltable_as_atlas_points") == 0) {
         sing[N_sing++] = LTABLE_AS_ATLAS_POINT_LIST; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-atlas_points") == 0) {
         sing[N_sing++] = ATLAS_POINTS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-fac") == 0) {
         sing[N_sing++] = FAC; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-datum") == 0) {
         sing[N_sing++] = DATUM; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-label") == 0) {
         sing[N_sing++] = LABEL; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-min") == 0) {
         sing[N_sing++] = MIN; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-max") == 0) {
         sing[N_sing++] = MAX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-minus") == 0) {
         sing[N_sing++] = MINUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-maxus") == 0) {
         sing[N_sing++] = MAXUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmin") == 0) {
         sing[N_sing++] = DMIN; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmax") == 0) {
         sing[N_sing++] = DMAX; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dminus") == 0) {
         sing[N_sing++] = DMINUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-dmaxus") == 0) {
         sing[N_sing++] = DMAXUS; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-TR") == 0) {
         sing[N_sing++] = TR; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-header_name") == 0) {
         sing[N_sing++] = HEADER_NAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-brick_name") == 0) {
         sing[N_sing++] = BRICK_NAME; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-history") == 0) {
         sing[N_sing++] = HISTORY; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-all_names") == 0) {
         sing[N_sing++] = ALL_NAMES; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-orient") == 0) {
         sing[N_sing++] = ORIENT; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_grid") == 0) {
         sing[N_sing++] = SAME_GRID; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_dim") == 0) {
         sing[N_sing++] = SAME_DIM; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_delta") == 0) {
         sing[N_sing++] = SAME_DELTA; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_orient") == 0) {
         sing[N_sing++] = SAME_ORIENT; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_center") == 0) {
         sing[N_sing++] = SAME_CENTER; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_obl") == 0) {
         sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-slice_timing") == 0) {
         sing[N_sing++] = SLICE_TIMING; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-sval_diff") == 0) {
         sing[N_sing++] = SVAL_DIFF; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-val_diff") == 0) {
         sing[N_sing++] = VAL_DIFF; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-same_all_grid") == 0) {
         sing[N_sing++] = SAME_DIM;
         sing[N_sing++] = SAME_DELTA;
         sing[N_sing++] = SAME_ORIENT;
         sing[N_sing++] = SAME_CENTER;
         sing[N_sing++] = SAME_OBL; needpair = 1; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-id") == 0) {
         sing[N_sing++] = ID; iarg++; continue;
      } else if( strcasecmp(argv[iarg],"-smode") == 0) {
         sing[N_sing++] = SMODE; iarg++; continue;
      } else {
         ERROR_message("Option %s unknown", argv[iarg]);
         suggest_best_prog_option(argv[0], argv[iarg]);
         exit(1);
      }
   }

   if (N_sing == 0) {
      sing[N_sing++] = CLASSIC;
   }

   if (sing[iis] == CLASSIC) PRINT_VERSION("3dinfo") ;

   THD_allow_empty_dataset(1) ;  /* 21 Mar 2007 */

   if (iarg == argc) {
      ERROR_message("No dsets on command line? I have nothing to do.\n");
      exit(1);
   }

   if (needpair && monog_pairs) needpair = 2; /* pair each couple separately */

   if (needpair==2 && (argc-iarg) % 2) {
      ERROR_message("Using options requiring dset pairs but have odd number\n"
                    "of dsets (%d) on command line.\n", (argc-iarg));
      exit (1);
   } else if (needpair==1 && (argc-iarg) < 2) {
      ERROR_message("Using options requiring dset pairs but have less than\n"
                    "two dsets (%d) on command line.\n", (argc-iarg));
      exit (1);
   }

   ip = 0;
   for( ; iarg < argc ; iarg++ ){
      if (ip == 0) {
         int kkk, nml; char *etr;
         namelen = 0;
         for (kkk=iarg; kkk<argc; ++kkk) {
            if ((etr = THD_trailname(argv[kkk],0))) {
               nml=strlen(etr);
               if (nml < 48 && nml > namelen) namelen = nml;
            }
         }
         if (namelen < 6) namelen = 6;
         if (withhead) {
            int havenew=0;
            for (iis = 0; iis < N_sing; ++iis) {
               if (sing[iis] != CLASSIC) {
                  ++havenew;
                  form = PrintForm(sing[iis], namelen, 1);
                  /*fprintf(stderr,"ZSS: %d %s >%s<\n",
                           sing[iis], Field_Names[sing[iis]], form);*/

                  fprintf(stdout, form, Field_Names[sing[iis]]);
               }
               if (havenew) {
                  if (N_sing > 1 && iis < N_sing-1)
                           fprintf(stdout,"%s",atrdelim);
                  else fprintf(stdout,"\n");
               }
            }
         }
      }
     if( argv[iarg][0] == '\0' ) continue ;  /* bad filename */

     set_obliquity_report(0); /* silence obliquity */

     if (!needpair) {
      if (!(dset = load_3dinfo_dataset(argv[iarg]))) {
        /* exit(1); */
      }
     } else {
      if (needpair == 2) { /* Crazy idea of comparing each pair separately */
         if (ip % 2 == 0) {
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /* exit(1); */
            }
            if (iarg+1==argc || argv[iarg+1][0] == '\0') {
               ERROR_message("Bad dset pair for %s\n", argv[iarg]);
               exit(1);
            }
            if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) {
               /* exit(1); */
            }
         } else { /* swap the pair - this allows non pair requiring functions
                     to work as before.*/
            tttdset = dsetp;
            dsetp = dset;
            dset = tttdset; tttdset=NULL;
         }
      } else { /* always compare to very first dset */
         if (ip==0) {
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /*exit(1);*/
            }
            if (!(dsetp = load_3dinfo_dataset(argv[iarg+1] ))) {
               /*exit(1);*/
            }
         } else if (ip==1) { /* switch order of first two */
            tttdset = dsetp;
            dsetp = dset; /* now dsetp is the very first dset */
            dset = tttdset; tttdset=NULL;
         } else { /* pair with very first, which is dsetp */
            if (!(dset = load_3dinfo_dataset(argv[iarg] ))) {
               /*exit(1);*/
            }
         }
      }
     }
     ++ip;

     if (0 && !dset) { /* allow for DSET_EXISTS option */
         ERROR_exit("Should not get here");
     }

     /* we should re-capture this per dataset   5 Feb 2019 [rickr] */
     extinit = 0;

     for (iis = 0; iis < N_sing; ++iis) {
        if (!dset) {
         if (sing[iis] == CLASSIC) {
            if( dset == NULL ){  /* still not open? */
               ERROR_exit("Can't open dataset %s\n", argv[iarg]) ;
            }
         } else if (sing[iis] != DSET_EXISTS && sing[iis] != INAME) {
            fprintf(stdout, "NO-DSET");
            SPIT_DELIM(iis, N_sing, atrdelim);
            continue;
         }
        }
        switch (sing[iis]) {
         case CLASSIC:
            if (labelName == NULL )  /*** get and output info ***/
            {
             outbuf = THD_dataset_info( dset , verbose ) ;
             if( outbuf != NULL ){
               printf("\n") ;
               puts(outbuf) ;
               free(outbuf) ; outbuf = NULL ;
             } else {
               ERROR_exit("Can't get info for dataset %s",argv[iarg]) ;
             }
            }
            else   /*** get and output label ***/
            {
             int nval_per = dset->dblk->nvals;
             int foundLabel = 0;
             int ival=0;

             for (ival=0 ; ival < nval_per && !foundLabel; ival++ )
             {
               if (strcmp(DSET_BRICK_LAB(dset,ival), labelName) == 0)
               {
                 printf("%d\n", ival); foundLabel = 1;
               }
             } /* end of for (ival=0 ; ival < nval_per ; ival++ ) */
             if (!foundLabel) printf("\n");
            }

            THD_delete_3dim_dataset( dset , False ) ;
            free(labelName);
            break;
         case DSET_EXISTS:
            fprintf(stdout, "%d", dset ? 1:0);
            break;
         case DSET_SPACE:
            tempstr = THD_get_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "-----");
            else
                  fprintf(stdout, "%s", tempstr);
            break;
         case DSET_GEN_SPACE:
            tempstr = THD_get_generic_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "-----");
            else
                  fprintf(stdout, "%s", tempstr);
            break;
         case AV_DSET_SPACE:
            /* don't allow anything but the three AFNI views */
            tempstr = THD_get_view_space(dset);
            if(tempstr==NULL)
                  fprintf(stdout, "+orig");
            else if (!strncasecmp(tempstr,"ORIG",4))
                  fprintf(stdout, "+orig");
            else if (!strncasecmp(tempstr,"ACPC",4))
                  fprintf(stdout, "+acpc");
            else if (!strncasecmp(tempstr,"TLRC",4))
                  fprintf(stdout, "+tlrc");
            else  /* shouldn't get here */
                  fprintf(stdout, "+orig");
            break;
         case IS_NIFTI:
            if (  dset->dblk->diskptr &&
                  dset->dblk->diskptr->storage_mode == STORAGE_BY_NIFTI ) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case IS_ATLAS:
            if (  is_Dset_Atlasy(dset, NULL) ) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case IS_OBLIQUE:
            if (dset_obliquity(dset,NULL) > 0) {
               fprintf(stdout,"1");
            } else {
               fprintf(stdout,"0");
            }
            break;
         case HANDEDNESS:
            if (THD_handedness(dset) > 0) {
               fprintf(stdout,"R");
            } else {
               fprintf(stdout,"L");
            }
            break;
         case OBLIQUITY:
            fprintf(stdout,"%.3f",
                  THD_compute_oblique_angle(dset->daxes->ijk_to_dicom_real, 0));
            break;
         case PREFIX:
            form = PrintForm(sing[iis], namelen, 1);
            fprintf(stdout,form, DSET_PREFIX(dset));
            break;
         case PREFIX_NOEXT:
            {
               form = PrintForm(sing[iis], namelen, 1);
               stmp=DSET_prefix_noext(dset);
               fprintf(stdout,form, stmp);
               free(stmp); stmp=NULL;
            }
            break;
         case HEADER_NAME:
            fprintf(stdout,"%s", dset->dblk->diskptr->header_name);
            break;
         case BRICK_NAME:
            fprintf(stdout,"%s", dset->dblk->diskptr->brick_name);
            break;
         case ALL_NAMES:
            THD_show_dataset_names(dset, "FOR_3DINFO", stdout);
            break;
         case HISTORY:
            stmp = tross_Get_History(dset);
            fprintf(stdout,"%s", stmp ? stmp:NAflag);
            if (stmp) free(stmp); stmp=NULL;
            break;
         case NI:
            fprintf(stdout,"%d", DSET_NX(dset));
            break;
         case NJ:
            fprintf(stdout,"%d", DSET_NY(dset));
            break;
         case NK:
            fprintf(stdout,"%d", DSET_NZ(dset));
            break;
         case NIJK:
            fprintf(stdout,"%d", DSET_NVOX(dset));
            break;
         case NTIMES:
            fprintf(stdout,"%d", DSET_NUM_TIMES(dset));
            break;
         case MAX_NODE:
            DSET_MAX_NODE(dset,itmp);
            fprintf(stdout,"%d", itmp);
            break;
         case NT:
         case NV:
            fprintf(stdout,"%d", DSET_NVALS(dset));
            break;
         case NTI:
         case NVI:
            fprintf(stdout,"%d", DSET_NVALS(dset)-1);
            break;
         case DI:
            fprintf(stdout,"%f", DSET_DX(dset));
            break;
         case DJ:
            fprintf(stdout,"%f", DSET_DY(dset));
            break;
         case DK:
            fprintf(stdout,"%f", DSET_DZ(dset));
            break;
         case OI:
            fprintf(stdout,"%f", DSET_XORG(dset));
            break;
         case OJ:
            fprintf(stdout,"%f", DSET_YORG(dset));
            break;
         case OK:
            fprintf(stdout,"%f", DSET_ZORG(dset));
            break;
         case ADI:
            fprintf(stdout,"%f", fabs(DSET_DX(dset)));
            break;
         case EXTENT_R:
         case EXTENT_L:
         case EXTENT_A:
         case EXTENT_P:
         case EXTENT_I:
         case EXTENT_S:
            {
               if (!extinit) {
                  THD_dset_extent(dset, '-', RL_AP_IS);
                  extinit = 1;
               }
               fprintf(stdout,"%f", RL_AP_IS[sing[iis]-EXTENT_R]);
            }
            break;

         case ADJ:
            fprintf(stdout,"%f", fabs(DSET_DY(dset)));
            break;
         case ADK:
            fprintf(stdout,"%f", fabs(DSET_DZ(dset)));
            break;
         case VOXVOL:
            fprintf(stdout,"%f", fabs(DSET_DX(dset))*
                                 fabs(DSET_DY(dset))*fabs(DSET_DZ(dset)));
            break;
         case INAME:
            fprintf(stdout,"%s", argv[iarg]);
            break;
         case LTABLE:
            {
               char *str;
               if ((str = Dtable_to_nimlstring(DSET_Label_Dtable(dset),                                                          "VALUE_LABEL_DTABLE"))) {
                  fprintf(stdout,"%s", str);
                  free(str);
               } else {
                  fprintf(stdout,"NO_LABEL_TABLE");
               }
            }
            break;
         case LTABLE_AS_ATLAS_POINT_LIST:
            {
               ATLAS_POINT_LIST *apl=NULL;
               if ((apl =
                     label_table_to_atlas_point_list(DSET_Label_Dtable(dset)))) {
                  atlas_list_to_niml(apl,NULL);
                  free_atlas_point_list(apl);
               } else {
                  fprintf(stdout,"NO_LABEL_TABLE");
               }
            }
            break;
         case  ATLAS_POINTS:
            {
               ATR_string *atr =
                  THD_find_string_atr( dset->dblk, "ATLAS_LABEL_TABLE");
               if (atr) {
                  fprintf(stdout,"%s", atr->ch);
               }  else {
                  fprintf(stdout,"NO_APL");
               }
            }
            break;
         case FAC:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%f%s",
                        DSET_BRICK_FACTOR(dset,isb),
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case DATUM:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%s%s",
                        MRI_TYPE_name[DSET_BRICK_TYPE(dset,isb)],
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case LABEL:
            {
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  fprintf(stdout,"%s%s",
               DSET_BRICK_LABEL(dset,isb) ? DSET_BRICK_LABEL(dset,isb):NAflag,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case MIN:
         case MINUS:
         case MAX:
         case MAXUS:
            {
               float vv=0.0, min, max;
               for (isb=0; isb<DSET_NVALS(dset); ++isb) {
                  if (!THD_subbrick_minmax(dset, isb,
                        (sing[iis] == MINUS || sing[iis] == MAXUS) ? 0:1,
                        &min, &max)) {
                     fprintf(stdout,"%s%s",
                        NAflag,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
                  } else {
                          if (sing[iis] == MINUS)
                        vv = min;
                     else if (sing[iis] == MAXUS)
                        vv = max;
                     else if (sing[iis] == MIN)
                        vv = min;
                     else if (sing[iis] == MAX)
                        vv = max;
                     fprintf(stdout,"%g%s",
                        vv,
                        (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
                  }
               }
               break;
            }
         case DMIN:
         case DMINUS:
         case DMAX:
         case DMAXUS:
            {
               float vv=0.0, min, max;
               if (!THD_dset_minmax(dset,
                     (sing[iis] == DMINUS || sing[iis] == DMAXUS) ? 0:1,
                     &min, &max)) {
                  fprintf(stdout,"%s%s",
                     NAflag,
                     (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               } else {
                       if (sing[iis] == DMINUS)
                     vv = min;
                  else if (sing[iis] == DMAXUS)
                     vv = max;
                  else if (sing[iis] == DMIN)
                     vv = min;
                  else if (sing[iis] == DMAX)
                     vv = max;
                  fprintf(stdout,"%g%s",
                     vv,
                     (isb == (DSET_NVALS(dset)-1)) ? "" : sbdelim);
               }
               break;
            }
         case TR:
#if 0
            fprintf(stdout,"%f", DSET_TR_SEC(dset));
#else
            fprintf(stdout,"%f", DSET_TR(dset));
#endif
            break;
         case ORIENT:
            {
               /* fprintf(stdout,"%c%c%c",
                *         ORIENT_typestr[dset->daxes->xxorient][0], ... ); */
               char ostr[4];    /* just to show        23 Jan 2013 [rickr] */
               THD_fill_orient_str_3(dset->daxes, ostr);
               fprintf(stdout,"%3s", ostr);
            }
            break;
         case SAME_GRID:
            fprintf(stdout,"%d",
               !THD_dataset_mismatch( dset , dsetp ));
            break;
         case SAME_DIM:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DIMEN));
            break;
         case SAME_DELTA:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_DELTA));
            break;
         case SAME_ORIENT:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_ORIENT));
            break;
         case SAME_CENTER:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_CENTER));
            break;
         case SAME_OBL:
            fprintf(stdout,"%d",
               !(THD_dataset_mismatch( dset , dsetp ) & MISMATCH_OBLIQ));
            break;
         case SLICE_TIMING:     /* 6 May 2013 [rickr] */
            {
               if( DSET_HAS_SLICE_TIMING(dset) ) {
                  DSET_UNMSEC(dset); /* make sure times are in seconds */
                  for (isb=0; isb<dset->taxis->nsl; ++isb) {
                     fprintf(stdout,"%s%f",
                           (isb > 0) ? sbdelim : "",
                           dset->taxis->toff_sl[isb]);
                  }
               } else { /* all slices times are at t=0.0 */
                  for (isb=0; isb<DSET_NZ(dset); ++isb) {
                     fprintf(stdout,"%s%f", (isb > 0) ? sbdelim : "", 0.0);
                  }
               }
            }
            break;
         case SVAL_DIFF:
            fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 1));
            break;
         case VAL_DIFF:
            fprintf(stdout,"%f",THD_diff_vol_vals(dset, dsetp, 0));
            break;
         case ID:
            fprintf(stdout,"%s", DSET_IDCODE_STR(dset));
            break;
         case SMODE:
            fprintf(stdout,"%s", DSET_STORAGE_MODE_STR(dset));
            break;
         default:
            ERROR_message("Info field not set properly (%d)\n", sing[iis]);
            exit(1);
        }
        if (sing[iis] != CLASSIC) {
         SPIT_DELIM(iis, N_sing, atrdelim);
        }
      }
   }

   exit(0) ;
}
Esempio n. 8
0
THD_3dim_dataset * MAKER_4D_to_typed_fim( THD_3dim_dataset * old_dset ,
                                          char * new_prefix , int new_datum ,
                                          int ignore , int detrend ,
                                          generic_func * user_func ,
                                          void * user_data )
{
   THD_3dim_dataset * new_dset ;  /* output dataset */

   byte    ** bptr = NULL ;  /* one of these will be the array of */
   short   ** sptr = NULL ;  /* pointers to input dataset sub-bricks */
   float   ** fptr = NULL ;  /* (depending on input datum type) */
   complex ** cptr = NULL ;

   float * fxar = NULL ;  /* array loaded from input dataset */
   float * fac  = NULL ;  /* array of brick scaling factors */
   float * fout = NULL ;  /* will be array of output floats */
   float * dtr  = NULL ;  /* will be array of detrending coeff */

   float val , d0fac , d1fac , x0,x1;
   double tzero=0 , tdelta , ts_mean , ts_slope ;
   int   ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , nbad ;
   register int kk ;

   void (*ufunc)(double,double,int,float *,double,double,void *,float *)
     = (void (*)(double,double,int,float *,double,double,void *,float *)) user_func ;

   /*----------------------------------------------------------*/
   /*----- Check inputs to see if they are reasonable-ish -----*/

   if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ;

   if( new_datum >= 0         &&
       new_datum != MRI_byte  &&
       new_datum != MRI_short &&
       new_datum != MRI_float   ) return NULL ;

   if( user_func == NULL ) return NULL ;

   if( ignore < 0 ) ignore = 0 ;

   /*--------- set up pointers to each sub-brick in the input dataset ---------*/

   old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ;   /* get old dataset datum */
   nuse      = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */
   if( nuse < 2 ) return NULL ;

   if( new_datum < 0 ) new_datum = old_datum ;   /* output datum = input */
   if( new_datum == MRI_complex ) return NULL ;  /* but complex = bad news */

   DSET_load( old_dset ) ;  /* must be in memory before we get pointers to it */

   kk = THD_count_databricks( old_dset->dblk ) ;  /* check if it was */
   if( kk < DSET_NVALS(old_dset) ){               /* loaded correctly */
      DSET_unload( old_dset ) ;
      return NULL ;
   }

   switch( old_datum ){  /* pointer type depends on input datum type */

      default:                      /** don't know what to do **/
         DSET_unload( old_dset ) ;
         return NULL ;

      /** create array of pointers into old dataset sub-bricks **/

      /*--------- input is bytes ----------*/
      /* voxel #i at time #k is bptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_byte:
         bptr = (byte **) malloc( sizeof(byte *) * nuse ) ;
         if( bptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is shorts ---------*/
      /* voxel #i at time #k is sptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_short:
         sptr = (short **) malloc( sizeof(short *) * nuse ) ;
         if( sptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is floats ---------*/
      /* voxel #i at time #k is fptr[k][i] */
      /* for i=0..nvox-1 and k=0..nuse-1.  */

      case MRI_float:
         fptr = (float **) malloc( sizeof(float *) * nuse ) ;
         if( fptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

      /*--------- input is complex ---------*/
      /* voxel #i at time #k is cptr[k][i]  */
      /* for i=0..nvox-1 and k=0..nuse-1.   */

      case MRI_complex:
         cptr = (complex **) malloc( sizeof(complex *) * nuse ) ;
         if( cptr == NULL ) return NULL ;
         for( kk=0 ; kk < nuse ; kk++ )
            cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ;
      break ;

   } /* end of switch on input type */

   /*---- allocate space for 1 voxel timeseries ----*/

   fxar = (float *) malloc( sizeof(float) * nuse ) ;   /* voxel timeseries */
   if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; }

   /*--- get scaling factors for sub-bricks ---*/

   fac = (float *) malloc( sizeof(float) * nuse ) ;   /* factors */
   if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; }

   use_fac = 0 ;
   for( kk=0 ; kk < nuse ; kk++ ){
      fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ;
      if( fac[kk] != 0.0 ) use_fac++ ;
      else                 fac[kk] = 1.0 ;
   }
   if( !use_fac ) FREEUP(fac) ;

   /*--- setup for detrending ---*/

   dtr = (float *) malloc( sizeof(float) * nuse ) ;
   if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; }

   d0fac = 1.0 / nuse ;
   d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ;
   for( kk=0 ; kk < nuse ; kk++ )
      dtr[kk] = kk - 0.5 * (nuse-1) ;  /* linear trend, orthogonal to 1 */

   /*---------------------- make a new dataset ----------------------*/

   new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */

   /*-- edit some of its internal parameters --*/

   ii = EDIT_dset_items(
           new_dset ,
              ADN_prefix      , new_prefix ,           /* filename prefix */
              ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */
              ADN_datum_all   , new_datum ,            /* atomic datum */
              ADN_nvals       , 1 ,                    /* # sub-bricks */
              ADN_ntt         , 0 ,                    /* # time points */
              ADN_type        , ISHEAD(old_dset)       /* dataset type */
                                 ? HEAD_FUNC_TYPE
                                 : GEN_FUNC_TYPE ,
              ADN_func_type   , FUNC_FIM_TYPE ,        /* function type */
           ADN_none ) ;

   if( ii != 0 ){
      ERROR_message("Error creating dataset '%s'",new_prefix) ;
      THD_delete_3dim_dataset( new_dset , False ) ;  /* some error above */
      FREE_WORKSPACE ; return NULL ;
   }

   /*------ make floating point output brick
            (only at the end will scale to byte or shorts) ------*/

   nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ;

   fout = (float *) malloc( sizeof(float) * nvox ) ;  /* ptr to brick */

   if( fout == NULL ){
      THD_delete_3dim_dataset( new_dset , False ) ;
      FREE_WORKSPACE ; return NULL ;
   }

   /*----- set up to find time at each voxel -----*/

   tdelta = old_dset->taxis->ttdel ;
   if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ;
   if( tdelta == 0.0 ) tdelta = 1.0 ;

   izold  = -666 ;
   nxy    = old_dset->daxes->nxx * old_dset->daxes->nyy ;

   /*----------------------------------------------------*/
   /*----- Setup has ended.  Now do some real work. -----*/

   /* start notification */

#if 0
   user_func(  0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ;
#else
   ufunc(  0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ;
#endif

   /***** loop over voxels *****/

   for( ii=0 ; ii < nvox ; ii++  ){  /* 1 time series at a time */

      /*** load data from input dataset, depending on type ***/

      switch( old_datum ){

         /*** input = bytes ***/

         case MRI_byte:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ;
         break ;

         /*** input = shorts ***/

         case MRI_short:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ;
         break ;

         /*** input = floats ***/

         case MRI_float:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ;
         break ;

         /*** input = complex (note we use absolute value) ***/

         case MRI_complex:
            for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ;
         break ;

      } /* end of switch over input type */

      /*** scale? ***/

      if( use_fac )
         for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ;

      /** compute mean and slope **/

      x0 = x1 = 0.0 ;
      for( kk=0 ; kk < nuse ; kk++ ){
         x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ;
      }

      x0 *= d0fac ; x1 *= d1fac ;  /* factors to remove mean and trend */

      ts_mean  = x0 ;
      ts_slope = x1 / tdelta ;

      /** detrend? **/

      if( detrend )
         for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ;

      /** compute start time of this timeseries **/

      iz = ii / nxy ;    /* which slice am I in? */

      if( iz != izold ){          /* in a new slice? */
         tzero = THD_timeof( ignore ,
                             old_dset->daxes->zzorg
                           + iz*old_dset->daxes->zzdel , old_dset->taxis ) ;
         izold = iz ;

         if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ;
      }

      /*** compute output ***/

#if 0
      user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ;
#else
      ufunc( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ;
#endif

   } /* end of outer loop over 1 voxels at a time */

   DSET_unload( old_dset ) ;  /* don't need this no more */

   /* end notification */

#if 0
   user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ;
#else
   ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ;
#endif

   nbad = thd_floatscan( nvox , fout ) ;  /* 08 Aug 2000 */
   if( nbad > 0 )
      fprintf(stderr,
              "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fim\n\a",
              nbad ) ;

   /*------------------------------------------------------------*/
   /*------- The output is now in fout[ii], ii=0..nvox-1.
             We must now put this into the output dataset -------*/

   switch( new_datum ){

      /*** output is floats is the simplest:
           we just have to attach the fout brick to the dataset ***/

      case MRI_float:
         EDIT_substitute_brick( new_dset , 0 , MRI_float , fout ) ;
         fout = NULL ;  /* so it won't be freed later */
      break ;

      /*** output is shorts:
           we have to create a scaled sub-brick from fout ***/

      case MRI_short:{
         short * bout ;
         float sfac ;

         /*-- get output sub-brick --*/

         bout = (short *) malloc( sizeof(short) * nvox ) ;
         if( bout == NULL ){
            fprintf(stderr,
             "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a");
            EXIT(1) ;
         }

         /*-- find scaling and then scale --*/

         sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ;
         if( sfac > 0.0 ){
            sfac = 32767.0 / sfac ;
            EDIT_coerce_scale_type( nvox,sfac ,
                                    MRI_float,fout , MRI_short,bout ) ;
            sfac = 1.0 / sfac ;
         }

         /*-- put output brick into dataset, and store scale factor --*/

         EDIT_substitute_brick( new_dset , 0 , MRI_short , bout ) ;
         EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ;
      }
      break ;

      /*** output is bytes (byte = unsigned char)
           we have to create a scaled sub-brick from fout ***/

      case MRI_byte:{
         byte * bout ;
         float sfac ;

         /*-- get output sub-brick --*/

         bout = (byte *) malloc( sizeof(byte) * nvox ) ;
         if( bout == NULL ){
            fprintf(stderr,
             "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a");
            EXIT(1) ;
         }

         /*-- find scaling and then scale --*/

         sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ;
         if( sfac > 0.0 ){
            sfac = 255.0 / sfac ;
            EDIT_coerce_scale_type( nvox,sfac ,
                                    MRI_float,fout , MRI_byte,bout ) ;
            sfac = 1.0 / sfac ;
         }

         /*-- put output brick into dataset, and store scale factor --*/

         EDIT_substitute_brick( new_dset , 0 , MRI_byte , bout ) ;
         EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ;
      }
      break ;

   } /* end of switch on output data type */

   /*-------------- Cleanup and go home ----------------*/

   FREE_WORKSPACE ;
   return new_dset ;
}
Esempio n. 9
0
/*!
   Put some help like for function thd_polyfit
*/
int thd_Acluster (  THD_3dim_dataset *in_set,
                  byte *mask, int nmask,
                  THD_3dim_dataset **clust_set,
                  THD_3dim_dataset **dist_set,
                  OPT_KMEANS oc )
{
   int ii, nl, nc;
   double **D=NULL, **distmatrix=NULL;  /* this double business is a waste of
                                           memory, at least for D..*/
   int ncol = -1;
   float *dvec=NULL;
   int* clusterid = NULL;
   short *sc = NULL;
   
   ENTRY("thd_Acluster");
   
   if (!clust_set || *clust_set) {
      fprintf(stderr,
               "ERROR: output volume pointer pointers must point to NULL\n");
      RETURN(0);
   }
   if (!mask) nmask = DSET_NVOX(in_set);
   ncol = DSET_NVALS(in_set); 
   if (ncol < DSET_NUM_TIMES(in_set)) ncol = DSET_NUM_TIMES(in_set);
   
   if (oc.verb) {
      ININFO_message("Have %d/%d voxels to process "
                     "with %d dimensions per voxel.\n",
                     nmask, DSET_NVOX(in_set), ncol);
   }
   
   /* Create data matrix */
   D = (double **)calloc(sizeof(double*), nmask);
   for (ii=0;ii<(nmask);++ii) {
      if (!(D[ii] = (double *)calloc(sizeof(double), ncol))) {
         fprintf(stderr,"ERROR: Failed while allocating %dx%d double matrix\n", 
                        nmask, ncol);
         RETURN(0);
      }
   }

   dvec = (float * )malloc(sizeof(float)*ncol) ;  /* array to hold series */
   if (oc.verb) {
      ININFO_message("Filling D(%dx%d) (mask=%p).\n", nmask, ncol, mask);
   }
   ii = 0;
   for (nl=0; nl<DSET_NVOX(in_set); ++nl) {
      if (!mask || mask[nl]) {
         THD_extract_array( nl , in_set , 0 , dvec ) ; 
         for (nc=0; nc<ncol; ++nc) D[ii][nc] = dvec[nc]; 
         ++ii;                              
      }
   }

   /* allocate for answer arrays */
   if (!(clusterid = (int *)calloc(sizeof(int), nmask))) {
      fprintf(stderr,"ERROR: Failed to allocate for clusterid\n");
      RETURN(0);
   }

   /* now do the clustering 
     (ANDREJ: I do not know why the counting skipped 1st row and 1st col....) */
   if (oc.k > 0) {
      if (oc.verb) {
         ININFO_message("Going to cluster: k=%d, r=%d\n"
                        "distmetric %c, jobname %s\n",
                        oc.k, oc.r, oc.distmetric, oc.jobname);
      }
      example_kmeans(   nmask, ncol, D, 
                        oc.k, oc.r, oc.distmetric, 
                        oc.jobname, clusterid);
   } else if (oc.kh > 0) {
      if (oc.verb) {
         ININFO_message("Going to h cluster: kh=%d\n"
                        "jobname %s\n",
                        oc.kh, oc.jobname);
      }
      if ((distmatrix = example_distance_gene(nmask, ncol, D))) {
         example_hierarchical(   nmask, ncol, D, 
                                 oc.jobname, oc.kh, 
                                 distmatrix, 
                                 clusterid);
         /* YOU SHOULD FREE distmatrix here ...*/
      } else {
         ERROR_message("Failed to create distmatrix");
         RETURN(0);
      }
   } else {
      ERROR_message("Bad option selection");
      RETURN(0);
   }
   
   /* create output datasets, if required*/
   *clust_set = EDIT_empty_copy(in_set) ;
   EDIT_dset_items(  *clust_set ,
                     ADN_nvals     , 1           ,
                     ADN_ntt       , 1          ,
                     ADN_datum_all , MRI_short      ,
                     ADN_brick_fac , NULL           ,
                     ADN_prefix    , "OML!"   ,
                     ADN_none ) ;
   /* MRI_float */
   if (oc.verb) {
      ININFO_message("loading results into %s\n",
                     DSET_PREFIX(*clust_set));
   }
   
   /* transfer ints in clusterid to shorts array */
   sc = (short *)calloc(sizeof(short),DSET_NVOX(in_set));
   ii = 0;
   for (nl=0; nl<DSET_NVOX(in_set); ++nl) {
      if (!mask || mask[nl]) {
         sc[nl] = (short)clusterid[ii]+1;
         ++ii;
      }
   }
   free(clusterid); clusterid = NULL;
   EDIT_substitute_brick( *clust_set , 0 , MRI_short , sc ) ;
   sc = NULL; /* array now in brick */
   
   if (oc.verb) {
      ININFO_message("Freedom");
   }
   
   if (dvec) free(dvec); dvec=NULL;
   // To free D 
   for (ii=0;ii<nmask;++ii) {
    if (D[ii]) free(D[ii]);
   }
   free(D); D = NULL;
   
   RETURN(1);
}
Esempio n. 10
0
File: 3dTfilter.c Progetto: nno/afni
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *old_dset=NULL , *new_dset=NULL ;
   char *prefix = "Filtered" ;
   int hh=0 ;
   int nvals , nopt ;

   if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){
     printf(
      "\n"
      "3dTfilter takes as input a dataset, filters the time series in\n"
      "each voxel as ordered by the user, and outputs a new dataset.\n"
      "The data in each voxel is processed separately.\n"
      "\n"
      "The user (you?) specifies the filter functions to apply.\n"
      "They are applied in the order given on the command line:\n"
      "  -filter rank -filter adaptive:7\n"
      "means to do the following operations\n"
      "  (1) turn the data into ranks\n"
      "  (2) apply the adaptive mean filter to the ranks\n"
      "\n"
      "Notes:\n"
      "------\n"
      "** This program is a work in progress, and more capabilities\n"
      "   will be added as time allows, as the need arises, and as\n"
      "   the author's whims bubble to the surface of his febrile brain.\n"
      "\n"
      "** This program is for people who have Sisu.\n"
      "\n"
      "Options:\n"
      "--------\n"
      "\n"
      " -input inputdataset\n"
      "\n"
      " -prefix outputdataset\n"
      "\n"
      " -filter FunctionName\n"
      "     At least one '-filter' option is required!\n"
      "     The FunctionName values that you can give are:\n"
      "\n"
      "        rank       = smallest value is replaced by 0,\n"
      "                     next smallest value by 1, and so forth.\n"
      "                     ** This filter is pretty useless.\n"
      "\n"
      "        adaptive:H = adaptive mean filter with half-width of\n"
      "                     'H' time points (H > 0).\n"
      "                     ** At most one 'adaptive' filter can be used!\n"
      "                     ** The filter 'footprint' is 2*H+1 points.\n"
      "                     ** This filter does local smoothing over the\n"
      "                        'footprint', with values far away from\n"
      "                        the local median being weighted less.\n"
      "\n"
      "        detrend:P  = (least squares) detrend with polynomials of up\n"
      "                     order 'P' for P=0, 1, 2, ....\n"
      "                     ** At most one 'detrend' filter can be used!\n"
      "\n"
      "        despike    = apply the 'NEW25' despiking algorithm, as in\n"
      "                     program 3dDespike.\n"
      "\n"
      "Example:\n"
      "--------\n"
      " 3dTfilter -input fred.nii -prefix fred.af.nii -filter adaptive:7\n"
      "\n"
      "-------\n"
      "Author: The Programmer with No Name\n"
      "-------\n"
      "\n"
     ) ;
     exit(0) ;
   }

   /* bureaucracy */

   mainENTRY("3dTfilter main"); machdep(); AFNI_logger("3dTfilter",argc,argv);
   PRINT_VERSION("3dTfilter"); AUTHOR("Thorby Baslim");


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

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

      /*-- prefix --*/

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

     if( strcasecmp(argv[nopt],"-input") == 0 ||
         strcasecmp(argv[nopt],"-inset") == 0   ){
       if( ++nopt >= argc ) ERROR_exit("%s needs an argument!",argv[nopt-1]);
       if( old_dset != NULL ) ERROR_exit("you can't have 2 input datasets!") ;
       old_dset = THD_open_dataset(argv[nopt]) ;
       CHECK_OPEN_ERROR(old_dset,argv[nopt]) ;
       nopt++ ; continue ;
     }

     if( strcasecmp(argv[nopt],"-filter") == 0 ){
       if( ++nopt >= argc ) ERROR_exit("%s needs an argument!",argv[nopt-1]);

       if( strcasecmp(argv[nopt],"rank") == 0 ){
         ADD_FILTER(rank_order_float) ;
         INFO_message("Filter #%d = rank",nffunc) ;

       } else if( strncasecmp(argv[nopt],"adaptive:",9) == 0 ){
         char *cpt=argv[nopt]+9 ;
         if( hh > 0 )
           ERROR_exit("You can't use more than one 'adaptive' filter :(") ;
         if( !isdigit(*cpt) )
           ERROR_exit("'%s' is not a valid 'adaptive' filter name",argv[nopt]) ;
         hh = (int)strtod(cpt,NULL) ;
         if( hh > 29 )
           WARNING_message("Very long filter '%s' will be very slow",argv[nopt]) ;
         else if( hh <= 0 )
           ERROR_exit("'%s' is not a legal 'adaptive' filter name",argv[nopt]) ;
         ADD_FILTER(adaptive_filter) ;
         INFO_message("Filter #%d = adaptive:%d",nffunc,hh) ;

       } else if( strncasecmp(argv[nopt],"detrend:",8) == 0 ){
         char *cpt=argv[nopt]+8 ;
         if( polort > 0 )
           ERROR_exit("You can't use more than one 'detrend' filter :(") ;
         if( !isdigit(*cpt) )
           ERROR_exit("'%s' is not a valid 'detrend' filter name",argv[nopt]) ;
         polort = (int)strtod(cpt,NULL) ;
         if( polort < 0 )
           ERROR_exit("'%s' is not a legal 'detrend' filter name",argv[nopt]) ;
         ADD_FILTER(polort_filter) ;
         INFO_message("Filter #%d = detrend:%d",nffunc,polort) ;

       } else if( strcasecmp(argv[nopt],"despike") == 0 ){
         ADD_FILTER(DES_despike25) ;
         INFO_message("Filter #%d = despike",nffunc) ;

       } else {
         ERROR_exit("Unkown filter type '%s'",argv[nopt]) ;
       }
       nopt++ ; continue ;
     }

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

   if( nffunc == 0 ) ERROR_exit("No -filter options given !? :(") ;

   if( old_dset == NULL ){
     if( nopt >= argc ) ERROR_exit("no input dataset?") ;
     old_dset = THD_open_dataset(argv[nopt]) ;
     CHECK_OPEN_ERROR(old_dset,argv[nopt]) ;
   }

   nvals = DSET_NVALS(old_dset) ;
   if( nvals < 2 ) ERROR_exit("Input dataset too short to filter!") ;

   if( hh > 0 ) setup_adaptive_filter( hh , nvals ) ;

   INFO_message("Load input dataset") ;

   DSET_load(old_dset) ; CHECK_LOAD_ERROR(old_dset) ;

   /** do the work **/

   INFO_message("Start processing") ;

   new_dset = MAKER_4D_to_typed_fbuc(
                    old_dset ,             /* input dataset */
                    prefix ,               /* output prefix */
                    MRI_float ,            /* output datum  */
                    0 ,                    /* ignore count  */
                    0 ,                    /* don't detrend */
                    nvals ,                /* number of briks */
                    FILTER_tsfunc ,        /* timeseries processor */
                    NULL,                  /* data for tsfunc */
                    NULL,                  /* mask */
                    0                      /* Allow auto scaling of output */
                 ) ;

   DSET_unload(old_dset) ;

   if( new_dset != NULL ){
     tross_Copy_History( old_dset , new_dset ) ;
     tross_Make_History( "3dTfilter" , argc,argv , new_dset ) ;
     if( DSET_NUM_TIMES(old_dset) > 1 )
       EDIT_dset_items( new_dset ,
                         ADN_ntt    , DSET_NVALS(old_dset) ,
                         ADN_ttorg  , DSET_TIMEORIGIN(old_dset) ,
                         ADN_ttdel  , DSET_TR(old_dset) ,
                         ADN_tunits , UNITS_SEC_TYPE ,
                       NULL ) ;
     DSET_write( new_dset ) ; WROTE_DSET( new_dset ) ;
   } else {
     ERROR_exit("Unable to compute output dataset!\n") ;
   }

   exit(0) ;
}
Esempio n. 11
0
THD_3dim_dataset * fim3d_fimmer_compute ( THD_3dim_dataset * dset_time ,
   time_series_array * ref_ts , time_series_array * ort_ts , 
   int itbot, char * new_prefix, 
   float max_percent        /* 19 May 1997 */ ) 
{
   THD_3dim_dataset * new_dset ;
   int ifim , it,iv , nvox=0 , ngood_ref , ntime , it1 , dtyp , nxyz;
   float * vval , * tsar , * aval , * rbest , * abest ;
   int   * indx=NULL ;
   short * bar ;
   void  * ptr ;
   float stataux[MAX_STAT_AUX];
   float fthr , topval ;
   int nx_ref , ny_ref , ivec , nnow ;
   PCOR_references ** pc_ref ;
   PCOR_voxel_corr ** pc_vc ;
   int save_resam ;

   int fim_nref , nx_ort , ny_ort=0 , internal_ort ;    /* 10 Dec 1996 */
   static float * ref_vec = NULL ;
   static int    nref_vec = -666 ;

   float * ref_ts_min = NULL, 
         * ref_ts_max = NULL, 
         * baseline   = NULL;      /* 19 May 1997 */

   int i;
   
   int nupdt      = 0 ,  /* number of updates done yet */
       min_updt   = 5 ;  /* min number needed for display */


   /*--- check for legal inputs ---*/      /* 14 Jan 1998 */

   if (!DSET_GRAPHABLE(dset_time)) 
     {
       fprintf (stderr, "Error:  Invalid 3d+time input data file \n");
       RETURN (NULL);
     }
   
   if (ref_ts == NULL)
     {
       fprintf (stderr, "Error:  No ideal time series \n");
       RETURN (NULL);
     }

   for (i = 0;  i < ref_ts->num;  i++)
     if (ref_ts->tsarr[i]->len < DSET_NUM_TIMES(dset_time))
       { 
	 fprintf (stderr,
	   "Error:  ideal time series is too short: ntime=%d num_ts=%d \n",
		  DSET_NUM_TIMES(dset_time), 
		  ref_ts->tsarr[i]->len);
	 RETURN (NULL) ;
       }


   /** 10 Dec 1996: allow for orts **/

   if( ort_ts->num > 0 )      /** 05 Sept 1997 **/
     {
       internal_ort = 0;
       ny_ort = ort_ts->num;
       for (i = 0;  i < ny_ort;  i++)
	 {
	   nx_ort = ort_ts->tsarr[i]->len ;
	   if (nx_ort < DSET_NUM_TIMES(dset_time))   /* 14 Jan 1998 */
	     { 
	       fprintf (stderr,
		 "Error:  ort time series is too short: ntime=%d ort_ts=%d \n",
			DSET_NUM_TIMES(dset_time), 
			ort_ts->tsarr[i]->len);
	       RETURN (NULL) ;
	     }	   
	 }
     } 
   else 
     {
       internal_ort = 1 ;
     }
   fim_nref = (internal_ort) ? 3 : (ny_ort+3) ;

   if( nref_vec < fim_nref )
     {
       ref_vec = (float *) malloc (sizeof(float)*fim_nref) ;
       nref_vec = fim_nref;
     }


   /* arrays to store maximum change in the ideal time series */
   if (max_percent > 0.0)    /* 19 May 1997 */
     {
       ref_ts_max = (float *) malloc (sizeof(float) * (ref_ts->num));
       ref_ts_min = (float *) malloc (sizeof(float) * (ref_ts->num));
     }


   nx_ref    = ref_ts->tsarr[0]->len;
   ny_ref    = ref_ts->num;
   ntime     = DSET_NUM_TIMES(dset_time) ;
   ngood_ref = 0 ;
   it1      = -1 ;
   for( ivec=0 ; ivec < ny_ref ; ivec++ ){
      tsar = ref_ts->tsarr[ivec]->ts;
      ifim = 0 ;

      if (max_percent > 0.0)       /* 19 May 1997 */
	{
	  ref_ts_min[ivec] = (float) SO_BIG;              
	  ref_ts_max[ivec] = - (float) SO_BIG;
	}

      for( it=itbot ; it < ntime ; it++ )
	{
         if( tsar[it] < SO_BIG )
	   { 
	     ifim++ ; 
	     if( it1 < 0 ) it1 = it ;

	     if (max_percent > 0.0)      /* 19 May 1997 */
	       {
		 if (tsar[it] > ref_ts_max[ivec])  ref_ts_max[ivec] = tsar[it];
		 if (tsar[it] < ref_ts_min[ivec])  ref_ts_min[ivec] = tsar[it];
	       }
	   }
	}

      if( ifim < min_updt ){
	 STATUS("ref_ts has too few good entries!") ;
         RETURN(NULL) ;
      }

      ngood_ref = MAX( ifim , ngood_ref ) ;
   }

   /** at this point, ngood_ref = max number of good reference points,
       and                  it1 = index of first point used in first reference **/
   
   dtyp = DSET_BRICK_TYPE(dset_time,it1) ;
   if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){
      STATUS("illegal input data type!") ;
      RETURN(NULL) ;
   }


#ifdef AFNI_DEBUG
{ char str[256] ;
  sprintf(str,"new prefix = %s",new_prefix) ; STATUS(str) ; }
#endif

   /*--- FIM: find values above threshold to fim ---*/

   DSET_load(dset_time); CHECK_LOAD_ERROR(dset_time);

   nxyz =  dset_time->dblk->diskptr->dimsizes[0]
         * dset_time->dblk->diskptr->dimsizes[1]
         * dset_time->dblk->diskptr->dimsizes[2] ;

   /** find the mean of the first array,
       compute the threshold (fthr) from it,
       make indx[i] be the 3D index of the i-th voxel above threshold **/

   switch( dtyp ){

      case MRI_short:{
         short * dar = (short *) DSET_ARRAY(dset_time,it1) ;
         for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ;
         fthr = FIM_THR * fthr / nxyz ;
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( abs(dar[iv]) > fthr ) nvox++ ;
         indx = (int *) malloc( sizeof(int) * nvox ) ;
         if( indx == NULL ){
            fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
            RETURN(NULL) ;
         }
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ;
      }
      break ;

      case MRI_float:{
         float * dar = (float *) DSET_ARRAY(dset_time,it1) ;
         for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ;
         fthr = FIM_THR * fthr / nxyz ;
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( fabs(dar[iv]) > fthr ) nvox++ ;
         indx = (int *) malloc( sizeof(int) * nvox ) ;
         if( indx == NULL ){
            fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
            RETURN(NULL) ;
         }
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ;
      }
      break ;

      case MRI_byte:{
         byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ;
         for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ;
         fthr = FIM_THR * fthr / nxyz ;
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( dar[iv] > fthr ) nvox++ ;
         indx = (int *) malloc( sizeof(int) * nvox ) ;
         if( indx == NULL ){
            fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
            RETURN(NULL) ;
         }
         for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
            if( dar[iv] > fthr ) indx[nvox++] = iv ;
      }
      break ;
   }

   /** allocate space for voxel values **/

   vval = (float *) malloc( sizeof(float) * nvox) ;
   if( vval == NULL ){
      fprintf(stderr,"\n*** vval malloc failure in fim3d_fimmer_compute\n") ;
      free(indx) ; RETURN(NULL) ;
   }

  
   /*----- allocate space for baseline values -----*/
   if (max_percent > 0.0)    /* 19 May 1997 */
     {
       baseline = (float *) malloc (sizeof(float) * nvox);
       if (baseline == NULL)
	 {
	   fprintf(stderr,
		   "\n*** baseline malloc failure in fim3d_fimmer_compute\n") ;
	   free(indx) ; free(vval); RETURN(NULL) ;
	 }
       else  /* initialize baseline values to zero */
	 for (iv = 0;  iv < nvox;  iv++)
	   baseline[iv] = 0.0;
     } 


   /** allocate extra space for comparing results from multiple ref vectors **/

   if( ny_ref > 1 ){
      aval  = (float *) malloc( sizeof(float) * nvox) ;
      rbest = (float *) malloc( sizeof(float) * nvox) ;
      abest = (float *) malloc( sizeof(float) * nvox) ;
      if( aval==NULL || rbest==NULL || abest==NULL ){
         fprintf(stderr,"\n*** abest malloc failure in fim3d_fimmer_compute\n") ;
         free(vval) ; free(indx) ;
         if( aval  != NULL ) free(aval) ;
         if( rbest != NULL ) free(rbest) ;
         if( abest != NULL ) free(abest) ;
         RETURN(NULL) ;
      }
   } else {
      aval = rbest = abest = NULL ;
   }

#ifdef AFNI_DEBUG
{ char str[256] ;
  sprintf(str,"nxyz = %d  nvox = %d",nxyz,nvox) ; STATUS(str) ; }
#endif

   /*--- FIM: initialize recursive updates ---*/

   pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ;
   pc_vc  = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ;

   if( pc_ref == NULL || pc_vc == NULL ){
      free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
      if( aval  != NULL ) free(aval) ;
      if( rbest != NULL ) free(rbest) ;
      if( abest != NULL ) free(abest) ;
      fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ;
      RETURN(NULL) ;
   }

   ifim = 0 ;
   for( ivec=0 ; ivec < ny_ref ; ivec++ ){
      pc_ref[ivec] = new_PCOR_references( fim_nref ) ;
      pc_vc[ivec]  = new_PCOR_voxel_corr( nvox , fim_nref ) ;
      if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ) ifim++ ;
   }

   if( ifim > 0 ){
      for( ivec=0 ; ivec < ny_ref ; ivec++ ){
         free_PCOR_references(pc_ref[ivec]) ;
         free_PCOR_voxel_corr(pc_vc[ivec]) ;
      }
      free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
      if( aval  != NULL ) free(aval) ;
      if( rbest != NULL ) free(rbest) ;
      if( abest != NULL ) free(abest) ;
      fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ;
      RETURN(NULL) ;
   }

   /*--- Make a new dataset to hold the output ---*/

   new_dset = EDIT_empty_copy( dset_time ) ;

   it = EDIT_dset_items( new_dset ,
                            ADN_prefix      , new_prefix ,
                            ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
                            ADN_type        , ISHEAD(dset_time)
                                              ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
                            ADN_func_type   , FUNC_COR_TYPE ,
                            ADN_nvals       , FUNC_nvals[FUNC_COR_TYPE] ,
                            ADN_datum_all   , MRI_short ,
                            ADN_ntt         , 0 ,
                         ADN_none ) ;

   if( it > 0 ){
      fprintf(stderr,
              "\n*** EDIT_dset_items error %d in fim3d_fimmer_compute\n",it) ;
      THD_delete_3dim_dataset( new_dset , False ) ;
      for( ivec=0 ; ivec < ny_ref ; ivec++ ){
         free_PCOR_references(pc_ref[ivec]) ;
         free_PCOR_voxel_corr(pc_vc[ivec]) ;
      }
      free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
      if( aval  != NULL ) free(aval) ;
      if( rbest != NULL ) free(rbest) ;
      if( abest != NULL ) free(abest) ;
      RETURN(NULL) ;
   }

   for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){
      ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ;
      mri_fix_data_pointer( ptr ,  DSET_BRICK(new_dset,iv) ) ;
   }

   if( THD_count_databricks(new_dset->dblk) < new_dset->dblk->nvals ){
      fprintf(stderr,
              "\n*** failure to malloc new bricks in fim3d_fimmer_compute\n") ;
      THD_delete_3dim_dataset( new_dset , False ) ;
      for( ivec=0 ; ivec < ny_ref ; ivec++ ){
         free_PCOR_references(pc_ref[ivec]) ;
         free_PCOR_voxel_corr(pc_vc[ivec]) ;
      }
      free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
      if( aval  != NULL ) free(aval) ;
      if( rbest != NULL ) free(rbest) ;
      if( abest != NULL ) free(abest) ;
      RETURN(NULL) ;
   }


   /*--- FIM: do recursive updates ---*/

   for( it=itbot ; it < ntime ; it++ ){

      nnow = 0 ;
      for( ivec=0 ; ivec < ny_ref ; ivec++ ){
         tsar = ref_ts->tsarr[ivec]->ts ;
         if( tsar[it] >= SO_BIG ) continue ;  /* skip this */

         ref_vec[0] = 1.0 ;         /* we always supply orts */
         ref_vec[1] = (float) it ;  /* for mean and linear trend */

         if (internal_ort)          /* 10 Dec 1996 */
	   {
	     ref_vec[2] = tsar[it] ;
	   } 
	 else 
	   {
	     for( iv=0 ; iv < ny_ort ; iv++ )
               ref_vec[iv+2] = ort_ts->tsarr[iv]->ts[it];
	     ref_vec[ny_ort+2] = tsar[it] ;
	   }


#ifdef AFNI_DEBUG
{ char str[256] ;
  sprintf(str,"time index=%d  ideal[%d]=%f" , it,ivec,tsar[it] ) ;
  if (ivec == 0) STATUS(str) ; }
#endif


         update_PCOR_references( ref_vec , pc_ref[ivec] ) ;

         switch( dtyp ){
            case MRI_short:{
               short * dar = (short *) DSET_ARRAY(dset_time,it) ;
               for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
            }
            break ;

            case MRI_float:{
               float * dar = (float *) DSET_ARRAY(dset_time,it) ;
               for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
            }
            break ;

            case MRI_byte:{
               byte * dar = (byte *) DSET_ARRAY(dset_time,it) ;
               for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
            }
            break ;
         }

         PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ;
         nnow++ ;

	 /*----- update baseline value calculation -----*/
	 if (max_percent > 0.0)    /* 19 May 1997 */
	   if (ivec == 0)
	     for (iv = 0;  iv < nvox;  iv++)
	       baseline[iv] += vval[iv] / ngood_ref;
 
      }
      if( nnow > 0 ) nupdt++ ;


      /*--- Load results into the dataset and redisplay it ---*/

      if( nupdt == ngood_ref ) 
      {
         /*--- set the statistical parameters ---*/

         stataux[0] = nupdt ;               /* number of points used */
         stataux[1] = (ny_ref==1) ? 1 : 2 ; /* number of references  */
         stataux[2] = fim_nref - 1 ;     /* number of orts */  /* 12 Dec 96 */
         for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ;

STATUS("setting statistical parameters") ;

         (void) EDIT_dset_items( new_dset ,
                                    ADN_stat_aux , stataux ,
                                 ADN_none ) ;

         /*** Compute brick arrays for new dataset ***/

         if( ny_ref == 1 ){

         /*** Just 1 ref vector --> load values directly into dataset ***/

            /*--- get alpha (coef) into vval,
                  find max value, scale into brick array ---*/

STATUS("getting 1 ref alpha") ;

            PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ;

	    /*--- replace alpha with percentage change, if so requested ---*/
	    if (max_percent > 0.0)    /* 19 May 1997 */
	      {
		for (iv = 0;  iv < nvox;  iv++)
		  {
		    vval[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]);
		    if (fabs(vval[iv]) < max_percent * fabs(baseline[iv]))
		      vval[iv] = fabs( vval[iv] / baseline[iv] );
		    else
		      vval[iv] = max_percent;
		  }
		topval = max_percent;
	      }
	    else 
	      {
		topval = 0.0 ;
		for( iv=0 ; iv < nvox ; iv++ )
		  if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
	      }

            bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
            memset( bar , 0 , sizeof(short)*nxyz ) ;

            if( topval > 0.0 ){
               topval = MRI_TYPE_maxval[MRI_short] / topval ;
               for( iv=0 ; iv < nvox ; iv++ )
                  bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;

               stataux[0] = 1.0/topval ;
            } else {
               stataux[0] = 0.0 ;
            }

            /*--- get correlation coefficient (pcor) into vval,
                  scale into brick array (with fixed scaling factor) ---*/

STATUS("getting 1 ref pcor") ;

            PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ;

            bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
            memset( bar , 0 , sizeof(short)*nxyz ) ;

            for( iv=0 ; iv < nvox ; iv++ )
               bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ;

            stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;

         } else {

         /*** Multiple references --> find best correlation at each voxel ***/

            /*--- get first ref results into abest and rbest (best so far) ---*/

            PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ;

	    /*--- modify alpha for percentage change calculation ---*/
	    if (max_percent > 0.0)    /* 19 May 1997 */
	      for (iv = 0;  iv < nvox;  iv++)
		abest[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]);	       
	      
            PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ;

            /*--- for each succeeding ref vector,
                  get results into aval and vval,
                  if |vval| > |rbest|, then use that result instead ---*/

            for( ivec=1 ; ivec < ny_ref ; ivec++ ){

               PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ;

               PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ;

               for( iv=0 ; iv < nvox ; iv++ ){
                  if( fabs(vval[iv]) > fabs(rbest[iv]) ){
                     rbest[iv] = vval[iv] ;
                     abest[iv] = aval[iv] ;

		     /*--- modify alpha for percentage change calculation ---*/
		     if (max_percent > 0.0)    /* 19 May 1997 */
		       abest[iv] *= 100.0 *
			 (ref_ts_max[ivec] - ref_ts_min[ivec]);

                  }
               }

            }

            /*--- at this point, abest and rbest are the best
                  results, so scale them into the dataset bricks ---*/

	    /*--- finish percentage change calculation, if so requested ---*/
	    if (max_percent > 0.0)    /* 19 May 1997 */
	      {
		for (iv = 0;  iv < nvox;  iv++)
		  {
		    if (fabs(abest[iv]) < max_percent * fabs(baseline[iv]))
		      abest[iv] = fabs( abest[iv] / baseline[iv] );
		    else
		      abest[iv] = max_percent;
		  }
		topval = max_percent;
	      }
	    else
	      {
		topval = 0.0 ;
		for( iv=0 ; iv < nvox ; iv++ )
		  if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ;
	      }

            bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
            memset( bar , 0 , sizeof(short)*nxyz ) ;

            if( topval > 0.0 ){
               topval = MRI_TYPE_maxval[MRI_short] / topval ;
               for( iv=0 ; iv < nvox ; iv++ )
                  bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ;

               stataux[0] = 1.0/topval ;
            } else {
               stataux[0] = 0.0 ;
            }

            bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
            memset( bar , 0 , sizeof(short)*nxyz ) ;

            for( iv=0 ; iv < nvox ; iv++ )
               bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ;

            stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;

         }

STATUS("setting brick_fac") ;

         (void) EDIT_dset_items( new_dset ,
                                    ADN_brick_fac , stataux ,
                                 ADN_none ) ;

      }
   }

 
   /*--- End of recursive updates; now free temporary workspaces ---*/

   for( ivec=0 ; ivec < ny_ref ; ivec++ ){
      free_PCOR_references(pc_ref[ivec]) ;
      free_PCOR_voxel_corr(pc_vc[ivec]) ;
   }
   free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
   if( aval  != NULL ) free(aval) ;
   if( rbest != NULL ) free(rbest) ;
   if( abest != NULL ) free(abest) ;

   if (ref_ts_min != NULL)  free (ref_ts_min);    /* 19 May 1997 */
   if (ref_ts_max != NULL)  free (ref_ts_max);
   if (baseline != NULL)    free (baseline);


   /* --- load the statistics --- */
   THD_load_statistics (new_dset);
   
   /*--- Return new dataset ---*/

   RETURN(new_dset) ;
}
Esempio n. 12
0
int main(int argc, char * argv[])
{
   char cphase1d[256] = "\0", rphase1d[256] = "\0";
   char new_prefix[THD_MAX_PREFIX] = TRIC_O_DEF_NEWPREFIX;
   MCW_idcode * idc ;
   THD_3dim_dataset * dset , * new_dset;
   double * avg = NULL;
   double * ca , * cb, * ra, * rb;
   MRI_IMAGE * card = NULL, * resp = NULL;
   MRI_IMAGE * cardphase = NULL, * respphase = NULL;
   float threshold = TRIC_C_DEF_THRESHOLD;
   int ignore = TRIC_I_DEF_IGNORE;
   int M = TRIC_M_DEF_ORDER;
   int winsize = TRIC_R_DEF_WINSIZE;
   float tr;
   int ival, nvals;
   FILE * fp;
   float * cpdata, * rpdata;
   int argi = 1;

   /*-------------------------------------------------------------*/
   /*----- Check arguments to see if they are reasonable-ish -----*/

   if (argc < 2 || strcmp(argv[1], "-help") == 0) {
       TRIC_printhelp();
       exit(-1);
   }

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

   /* Iterate over commandline args */
   while (argi < argc && argv[argi][0] == '-') {

       /*-- ignore --*/

       if (strcmp(argv[argi], "-ignore") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -ignore needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   ignore = atoi(argv[argi]);
	   if (ignore < 0) {
	       fprintf(stderr, "*** %i is not a valid number to ignore!\n",
		       ignore);
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- prefix --*/

       if (strcmp(argv[argi], "-prefix") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -prefix needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   MCW_strncpy(new_prefix, argv[argi], THD_MAX_PREFIX);
	   if (! THD_filename_ok(new_prefix)) {
	       fprintf(stderr, "*** %s is not a valid prefix!\n", new_prefix);
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- card --*/

       if (strcmp(argv[argi], "-card") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -card needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   card = mri_read_1D(argv[argi]);
	   if (card == NULL) {
	       fprintf(stderr, "*** Can't read -card %s\n", argv[argi]);
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- cardphase --*/

       if (strcmp(argv[argi], "-cardphase") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -cardphase needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   MCW_strncpy(cphase1d, argv[argi], 256);
	   if (! THD_filename_ok(cphase1d)) {
	       fprintf(stderr, "*** Bad name argument for -cardphase\n");
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- threshold --*/

       if (strcmp(argv[argi], "-threshold") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -threshold needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   threshold = atof(argv[argi]);
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- resp --*/

       if (strcmp(argv[argi], "-resp") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -resp needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   resp = mri_read_1D(argv[argi]);
	   if (resp == NULL) {
	       fprintf(stderr, "*** Can't read -resp %s\n", argv[argi]);
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- respphase --*/

       if (strcmp(argv[argi], "-respphase") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -respphase needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   MCW_strncpy(rphase1d, argv[argi], 256);
	   if (! THD_filename_ok(rphase1d)) {
	       fprintf(stderr, "*** Bad name argument for -respphase\n");
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }

       /*-- window --*/

       /*-- removed winsize ui --*/
#if 0
       if (strcmp(argv[argi], "-window") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -window needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   winsize = atoi(argv[argi]);
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }
#endif
       /*-- removed winsize ui --*/

       /*-- order --*/

       if (strcmp(argv[argi], "-order") == 0) {
	   if (argi + 1 >= argc) {
	       fprintf(stderr, "*** -order needs an argument!\n");
	       exit(1);
	   }
	   argi += 1;
	   M = atoi(argv[argi]);
	   if (M < 1) {
	       fprintf(stderr, "*** %i is not a valid order number\n", M);
	       exit(1);
	   }
	   argi += 1;
	   continue;  /* Skip the rest of the loop and go to the next arg */
       }
   } /* End iterating over commandline args */

   /* Check that at least one of Cardiac and Resp were selected */
   if (card == NULL && resp == NULL) {
       fprintf(stderr, "*** Need at least one correction (-card, -resp)\n");
       exit(1);
   }

   /*-- Open and check input dataset --*/

   if (argi >= argc) {
       fprintf(stderr, "*** No input dataset!?\n");
       exit(1);
   } else if (argi < argc - 1) {
       fprintf(stderr, "*** Too many input datasets?!\n");
       exit(1);
   }

   dset = THD_open_dataset(argv[argi]);
   if (! ISVALID_3DIM_DATASET(dset)) {
       fprintf(stderr, "*** Can't open dataset %s\n", argv[argi]);
       exit(1);
   }
   if (DSET_NUM_TIMES(dset) < 2) {
       fprintf(stderr, "*** Input dataset is not 3D+time!\n");
       exit(1);
   }

   /*----------------------------------------------------------*/
   /*---------- At this point, the inputs are OK-ish ----------*/

   /*-- copy the image data for editing in place --*/

   new_dset = EDIT_full_copy( dset , new_prefix );
   if( new_dset == NULL ) {
       fprintf(stderr, "*** Error copying dataset\n");
       exit(1);
   }
   tross_Copy_History(dset, new_dset); /* Copy and add to new_dset history */
   tross_Make_History("3dretroicor", argc, argv, new_dset);
   DSET_unload( dset ) ;  /* We won't need the old dataset anymore */

   /*-- calculate cardiac correction coefficients if requested --*/

   if (card != NULL) {
       /*-- convert cardiac waveform to phase --*/
       cardphase = RIC_ToCardiacPhase(card, threshold) ;
       if (cardphase == NULL) {
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   fprintf(stderr, "*** Error transforming cardiac data\n");
	   exit(2);
       }

       /*-- calculate dataset voxel means --*/
       avg = RIC_CalcVoxelMeans(new_dset, ignore);
       if (avg == NULL) {
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   mri_free(cardphase);
	   fprintf(stderr, "*** Error calculating dataset voxel means\n");
	   exit(2);
       }

       /*-- calculate coefficients for each voxel --*/
       if (RIC_CalcCoeffAB(new_dset, cardphase, avg, &ca, &cb, M, ignore)
	   != 0) {

	   THD_delete_3dim_dataset( new_dset , False ) ;
	   mri_free(cardphase);
	   fprintf(stderr, "*** Error calculating cardiac a b coefficients\n");
	   exit(2);
       }
   }

   /*-- calculate respiratory correction coefficients if requested --*/

   if (resp != NULL) {
       /*-- Set winsize to 1/2 sampling rate of resp in Hz --*/
       tr = new_dset->taxis->ttdel;
       switch (new_dset->taxis->units_type) {
       case UNITS_MSEC_TYPE: tr /= 1000; break;
       case UNITS_SEC_TYPE:  break;
       case UNITS_HZ_TYPE:   tr = 1 / tr; break;
       default:
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   fprintf(stderr, "*** Bad time units type in dataset\n");
	   exit(2);
       }
       winsize = ceil(resp->nx / (tr * DSET_NVALS(new_dset)) / 2.0);

       /*-- convert respiratory waveform to phase --*/
       respphase = RIC_ToRespPhase(resp, winsize) ;
       if (respphase == NULL) {
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   fprintf(stderr, "*** Error transforming resp data\n");
	   exit(2);
       }

       /*-- calculate dataset voxel means if not already done --*/
       if (avg == NULL) {
	   avg = RIC_CalcVoxelMeans(new_dset, ignore);
	   if (avg == NULL) {
	       THD_delete_3dim_dataset( new_dset , False ) ;
	       mri_free(respphase);
	       fprintf(stderr, "*** Error calculating dataset voxel means2\n");
	       exit(2);
	   }
       }

       /*-- calculate coefficients for each voxel --*/
       if (RIC_CalcCoeffAB(new_dset, respphase, avg, &ra, &rb, M, ignore)
	   != 0) {

	   THD_delete_3dim_dataset( new_dset , False ) ;
	   mri_free(respphase);
	   fprintf(stderr, "*** Error calculating resp a, b coefficients\n");
	   exit(2);
       }
   }

   /*-- do cardiac correction if requested --*/

   if (card != NULL) {
       /*-- correct the image data --*/
       if (RIC_CorrectDataset(new_dset, cardphase, ca, cb, M, ignore) != 0) {
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   mri_free(cardphase);
	   free(ca); free(cb);
	   fprintf(stderr, "*** Error applying cardiac correction\n");
	   exit(3);
       }

       /*-- if requested, write phase data to file and pass to AFNI --*/
       if ( THD_filename_ok(cphase1d) ) {
	   /* Write the file */
	   fp = fopen(cphase1d, "w");
	   nvals = cardphase->nx;
	   cpdata = MRI_FLOAT_PTR(cardphase);
	   for (ival = 0; ival < nvals; ival += 1) {
	       fprintf(fp, "%f\n", cpdata[ival]);
	   }
	   fclose(fp);
       }

       mri_free(cardphase);
       free(ca); free(cb); free(avg); avg = NULL;
   }

   /*-- do resp correction if requested --*/

   if (resp != NULL) {
       /*-- correct the image data --*/
       if (RIC_CorrectDataset(new_dset, respphase, ra, rb, M, ignore) != 0) {
	   THD_delete_3dim_dataset( new_dset , False ) ;
	   mri_free(respphase);
	   free(ra); free(rb);
	   fprintf(stderr, "*** Error applying resp correction\n");
	   exit(3);
       }

       /*-- if requested, write phase data to file and pass to AFNI --*/
       if ( THD_filename_ok(rphase1d) ) {
	   /* Write the file */
	   fp = fopen(rphase1d, "w");
	   nvals = respphase->nx;
	   rpdata = MRI_FLOAT_PTR(respphase);
	   for (ival = 0; ival < nvals; ival += 1) {
	       fprintf(fp, "%f\n", rpdata[ival]);
	   }
	   fclose(fp);
       }

       mri_free(respphase);
       free(ra); free(rb); if (avg != NULL) free(avg);
   }

   /*-- write out new dataset --*/

   if (DSET_write(new_dset) != False) {
      fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(new_dset)) ;
      exit(0) ;
   } else {
      fprintf(stderr,
         "** 3dretroicor: Failed to write output!\n" ) ;
      exit(1) ;
   }

   /*-- done successfully!!! --*/

   exit(0);
}
Esempio n. 13
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() ) ;
}
Esempio n. 14
0
static char * DELAY_main( PLUGIN_interface * plint )
{
   hilbert_data_V2 uda,*ud;
   MRI_IMAGE * tsim;
   MCW_idcode * idc ;         /* input dataset idcode */
   THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
   char *tmpstr , * str , *nprfxstr;                 /* strings from user */
   int   ntime, nvec ,nprfx, i;
	float * vec , fs , T ;
		
	/* Allocate as much character space as Bob specifies in afni.h + a bit more */
	
	tmpstr = (char *) calloc (PLUGIN_MAX_STRING_RANGE+10,sizeof(char));
	nprfxstr = (char *) calloc (PLUGIN_MAX_STRING_RANGE+10,sizeof(char));
	
	if (tmpstr == NULL || nprfxstr == NULL) 
									  return "********************\n"
												"Could not Allocate\n"
												"a teeni weeni bit of\n"
												"Memory ! \n"
												"********************\n";
														
	ud = &uda;		/* ud now points to an allocated space */
	ud->errcode = 0;	/*reset error flag */
	
   /*--------------------------------------------------------------------*/
   /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/

   /*--------- go to first input line ---------*/
		
   PLUTO_next_option(plint) ;

   idc      = PLUTO_get_idcode(plint) ;   /* get dataset item */
   old_dset = PLUTO_find_dset(idc) ;      /* get ptr to dataset */
   if( old_dset == NULL )
      return "*************************\n"
             "Cannot find Input Dataset\n"
             "*************************"  ;
   
   ud->dsetname = DSET_FILECODE (old_dset);
	ud->nsamp = DSET_NUM_TIMES (old_dset);
	ud->Navg = 1 ;    /* Navg does not play a role for the p value, averaging increases sensitivity */
	ud->Nort = PLUTO_get_number(plint) ; /* Should be two by default, for mean and linear trend */
	ud->Nfit = 2 ;  /* Always 2 for phase and amplitude for this plugin */
	/*--------- go to 2nd input line, input time series ---------*/
		
	PLUTO_next_option(plint) ;
	
	tsim = PLUTO_get_timeseries(plint);
	if (tsim == NULL) return "No Timeseries Input";
	
	ud->ln = (int)tsim -> nx;									/* number of points in each vector */
	nvec 	= tsim -> ny;									/* number of vectors */
	ud->rvec   = (float *) MRI_FLOAT_PTR(tsim);	/* vec[i+j*nx] = ith point of jth vector */
																/* for i=0 .. ntime-1 and j=0 .. nvec-1 */
	
	if (is_vect_null (ud->rvec,ud->ln) == 1) 	/* check if ref vect is all zeroes */
		{
			return "Reference vector is all zeros";	
		}
		
	ud->refname = tsim->name;
	ud->ignore = PLUTO_get_number(plint) ;    /* get number item */
	
	str = PLUTO_get_string(plint) ;
   ud->Dsamp = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
   
   /*--------- go to 3rd input line, sampling frequency, and stimulus period ---------*/
   	
   PLUTO_next_option(plint) ;
   
   ud->fs = PLUTO_get_number(plint) ;    /* get number item */
   ud->T = PLUTO_get_number(plint) ;    /* get number item */
   
   ud->co = PLUTO_get_number(plint) ;    /* get number item */
   str = PLUTO_get_string(plint) ;
   ud->biasrem = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
   
   /*--------- go to 4th input line, delay units and wrp option---------*/
		
   PLUTO_next_option(plint) ;

   ud->Nseg = (int)PLUTO_get_number(plint) ;    /* get number item */
   ud->Pover = (int)PLUTO_get_number(plint) ;    /* get number item */
   
   str = PLUTO_get_string(plint) ;      						/* get string item (the method) */
   ud->unt = (int)PLUTO_string_index( str ,      				/* find it in list it is from */
             	 NUM_METHOD_STRINGS ,
             	 method_strings ) ;
	
	str = PLUTO_get_string(plint) ;  
	ud->wrp = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings ) ;
	
   /*--------- go to 5th input line Output prefix ---------*/
		
   PLUTO_next_option(plint) ;
		
   ud->new_prefix = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */
	
	/* check to see if the field is empty */
	if (ud->new_prefix == NULL)
			nprfx = 0;
		else
			nprfx = 1;
	/* check if the size is larger than 0. I did not want to check for this unless it's allocated */
	if (nprfx == 1 && (int)strlen (ud->new_prefix) == 0)
		nprfx = 0;
		
	if (nprfx == 0)		/* now create the new name and make new_prefix point to it */
		{
			sprintf (nprfxstr,"%s.DEL",DSET_PREFIX (old_dset));
			ud->new_prefix = nprfxstr;
			/*printf ("New prefix is set to be : %s\n\a",ud->new_prefix);*/
		}
	
   if( ! PLUTO_prefix_ok(ud->new_prefix) )      /* check if it is OK */
      return "************************\n"
             "Output Prefix is illegal\n"
             "************************"  ;
	
	str = PLUTO_get_string(plint) ; 				/* write delays to file ? */
	ud->out = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings );
	
	ud->strout = PLUTO_get_string(plint) ; 				/* strout is for the outiflename, which will be used after the debugging section */
	if (ud->strout == NULL)						/* if no output name is given, use the new_prefix */
		{ud->strout = ud->new_prefix;}
		else 
			{	
				if((int)strlen (ud->strout) == 0) ud->strout = ud->new_prefix;
			}
			
	str = PLUTO_get_string(plint) ; 
	ud->outts = (int)PLUTO_string_index( str , NUM_YN_STRINGS , yn_strings );
	
	/* ------------------Done with user parameters ---------------------------- */
	
	ud->nxx = (int)old_dset->daxes->nxx;				/* get data set dimensions */
	ud->nyy = (int)old_dset->daxes->nyy;
	ud->nzz = (int)old_dset->daxes->nzz;
	
	/* No need for users to set these options ...*/
	
	ud->dtrnd = 0;
	
	if (ud->ln != (ud->nsamp - ud->ignore))
		{
			ud->errcode = ERROR_BADLENGTH;
			return "***************************\n"
					 "Bad time series length \n"
					 "Check reference time series\n"
					 " or the ignore parameter   \n"
					 "***************************\n";
		}
	
	if ((ud->unt < 0) || (ud->unt > 2))										/* unt error Check */
	  	{
         ud->errcode = ERROR_WRONGUNIT;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "unt values out of bound\n"
					 "***********************\n";			/*unt must be between 0 and 2 */
	  	}
	  
	  if ((ud->wrp < 0) || (ud->wrp > 1))										/* wrp error Check */
	  	{
         ud->errcode = ERROR_WARPVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "wrp values out of bound\n"
					 "***********************\n";			/* wrp must be between 0 and 1*/
	  	}
	  
	  if (ud->fs < 0.0) {       /* fs error Check */
         ud->errcode = ERROR_FSVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "fs value is negative !\n"
					 "***********************\n";			/* fs must be >= 0*/
        }
	  
	  if (ud->T < 0.0) {        /* T error Check */
         ud->errcode = ERROR_TVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "T value is negative !\n"
					 "***********************\n";					/*T must be >= 0  */
        }
        
           	
     if ((ud->T == 0.0) && (ud->unt > 0))                /* unt error Check */
   	{
         ud->errcode = ERROR_TaUNITVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "T and unt val. mismatch\n"
					 "***********************\n";			/*T must be specified, and > 0 in order to use polar units*/
   	}

    
    if ((ud->wrp == 1) && (ud->T == 0.0))                  /* wrp error Check */
        {
         ud->errcode = ERROR_TaWRAPVALUES;
         return "***********************\n"
         		 " internal error: (ziad)\n"
					 "wrp and T val. mismatch\n"
					 "***********************\n"; 			/*T must be specified, and > 0 in order to use polar warp*/
        }
	 if ((ud->out == NOPE) && (ud->outts == YUP))
	 		{
	 		 ud->errcode = ERROR_OUTCONFLICT;
	 		 return"***********************\n"
         		 "error: \n"
					 "Write flag must be on\n"
					 "to use Write ts\n"
					 "***********************\n";	
	 		
	 		}
	

	/* Open the logfile, regardless of the ascii output files */
	sprintf ( tmpstr , "%s.log" , ud->strout);
	ud->outlogfile = fopen (tmpstr,"w");


	if (ud->out == YUP)									/* open outfile */
				{					
					ud->outwrite = fopen (ud->strout,"w");
					
					if (ud->outts == YUP)
						{
							sprintf ( tmpstr , "%s.ts" , ud->strout);
							ud->outwritets = fopen (tmpstr,"w");
							
						}
					
					if ((ud->outwrite == NULL) || (ud->outlogfile == NULL) ||\
					    (ud->outwritets == NULL && ud->outts == YUP) )
						{
							ud->errcode = ERROR_FILEOPEN; 
							
							return "***********************\n"
									 "Could Not Write Outfile\n"
									 "***********************\n";
						}
	
				}
	
	/* Write out user variables to Logfile */
	write_ud (ud);			/* writes user data to a file */
	
	/*show_ud (ud,0);	*/			/* For some debugging */

   
   /*------------- ready to compute new dataset -----------*/

   new_dset = MAKER_4D_to_typed_fbuc ( old_dset ,             /* input dataset */
          ud->new_prefix ,           /* output prefix */
          -1,	/* negative value indicating data type is like original brick */
          ud->ignore ,               /* ignore count */
          1 ,   /* detrend = ON Let BOB do it*/
          NBUCKETS,					/*Number of values at each voxel*/
			 DELAY_tsfuncV2 ,         /* timeseries processor (bucket version)*/
			 (void *)ud,          /* data for tsfunc */
			 NULL, 0							) ; 
										 
   /* Setup the label, keywords and types of subbricks */
	i = 0;
	while (i < NBUCKETS)
		{
			switch (i)
				{
					case DELINDX:					/* delay value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Delay");
						EDIT_BRICK_ADDKEY (new_dset,i,"D");
						++i;
						break;
					case COVINDX:					/* covariance value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Covariance");
						EDIT_BRICK_ADDKEY (new_dset,i,"I");
						++i;
						break;
					case COFINDX:					/* cross correlation coefficient value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Corr. Coef.");
						EDIT_BRICK_ADDKEY (new_dset,i,"r");
						/* Here you must modify either ud->Nfit or ud->Nort or most likely ud->nsamp based on ud->Navg */
						EDIT_BRICK_TO_FICO (new_dset,i,ud->nsamp - ud->ignore,ud->Nfit,ud->Nort);
						++i;
						break;
					case VARINDX:					/* FMRI time course variance value in results vector */
						EDIT_BRICK_LABEL (new_dset,i,"Variance");
						EDIT_BRICK_ADDKEY (new_dset,i,"S2");
						++i;
						break;
					default :
						return "*********************\n"
								 "Internal Error (ziad)\n"
								 " Bad i value \n"
								 "*********************\n";
						break;
				}
				
		}
	
   
   if (!AFNI_noenv("AFNI_AUTOMATIC_FDR")) {
      THD_create_all_fdrcurves( new_dset );
   }
	PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;
	
	

   if (ud->out == YUP)									/* close outfile and outlogfile*/
				{
					fclose (ud->outlogfile);
					fclose (ud->outwrite);
					if (ud->outts  == YUP) fclose (ud->outwritets);
				}
				else
				{
					if (ud->outlogfile != NULL)	fclose (ud->outlogfile);		/* close outlogfile */
				}
	
	free (tmpstr);		
	free (nprfxstr);
   return NULL ;  /* null string returned means all was OK */
}
Esempio n. 15
0
char * STAVG_main( PLUGIN_interface * plint )
{
   MCW_idcode * idc ;                          /* input dataset idcode */
   THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
   char * new_prefix , * str , * str2;         /* strings from user */
   int   meth;                                 /* chosen computation method */
   int   new_datum ,                           /* control parameters */
         old_datum , ntime ;

   int   te, ne, tinc, kim, nia;
   int   numepochs, minlength, maxlength, lastindex, navgpts;
   int   nvox , perc , new_units, old_units ;
   int   ii, ibot,itop , kk, jj; 
   int   no1, user_maxlength, delta;
   int   *pEpochLength, *pTimeIndex;
   int   nx, ny, nz, npix;
   float *pNumAvg;
   float old_dtime;

   MRI_IMAGE * stimim;
   
   MRI_IMARR *avgimar;

   byte   ** bptr  = NULL ;  /* one of these will be the array of */
   short  ** sptr  = NULL ;  /* pointers to input dataset sub-bricks */
   float  ** fptr  = NULL ;  /* (depending on input datum type) */

   float   * fxar  = NULL ;  /* array loaded from input dataset */
   float   * stimar = NULL ;
   float  ** fout  = NULL ;  /* will be array of output floats */

   float   * tar   = NULL ;  /* will be array of taper coefficients */

   float   * nstimar;

   /*--------------------------------------------------------------------*/
   /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/

   /*--------- go to first input line ---------*/

   PLUTO_next_option(plint) ;

   idc      = PLUTO_get_idcode(plint) ;   /* get dataset item */
   old_dset = PLUTO_find_dset(idc) ;      /* get ptr to dataset */
   if( old_dset == NULL )
      return "*************************\n"
             "Cannot find Input Dataset\n"
             "*************************"  ;

   ntime = DSET_NUM_TIMES(old_dset) ;
   if( ntime < 2 )
      return "*****************************\n"
             "Dataset has only 1 time point\n"
             "*****************************"  ;

   ii = DSET_NVALS_PER_TIME(old_dset) ;
   if( ii > 1 )
      return "************************************\n"
             "Dataset has > 1 value per time point\n"
             "************************************"  ;
   
   old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum type */
   new_datum = old_datum;
   old_dtime = DSET_TIMESTEP(old_dset);
   old_units = DSET_TIMEUNITS(old_dset);
   
   nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz;
   npix = old_dset->daxes->nxx * old_dset->daxes->nyy;
   nx = old_dset->daxes->nxx;


   new_prefix = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */
   if( ! PLUTO_prefix_ok(new_prefix) )      /* check if it is OK */
      return "************************\n"
             "Output Prefix is illegal\n"
             "************************"  ;

   /*--------- go to next input line ---------*/

   PLUTO_next_option(plint);

   stimim = PLUTO_get_timeseries(plint);
   if( stimim == NULL ) return "Please specify stimulus timing";

   if( stimim->nx < ntime ){
      return "**************************************\n"
             "Not enough pts in stimulus time-series\n"
             "**************************************";
   }

   stimar = MRI_FLOAT_PTR(stimim);


   delta = PLUTO_get_number(plint);

   if( abs(delta) > ntime ){
      return "************************\n"
             "Delta shift is too large\n"
             "************************";
   }
  
   /*initialize variables if not user specified */
   user_maxlength = ntime;
   no1 = 0;

   /*--------- go to next input line ---------*/

   PLUTO_next_option(plint);

   str  = PLUTO_get_string(plint) ;      /* get string item (the method) */
   meth = PLUTO_string_index( str ,      /* find it in list it is from */
                              _STAVG_NUM_METHODS ,
                              method_strings ) ;

   /*--------- see if the 4th option line is present --------*/

   str = PLUTO_get_optiontag( plint ) ;
   if( str != NULL ){
      user_maxlength = (int) PLUTO_get_number(plint) ;
      str2  = PLUTO_get_string(plint) ;      /* get string item (the method) */
      no1   = PLUTO_string_index( str2 ,      /* find it in list it is from */
                                 2 ,
                                 yes_no_strings) ;
   }
   

   /*------------------------------------------------------*/
   /*---------- At this point, the inputs are OK ----------*/

   PLUTO_popup_meter( plint ) ;  /* popup a progress meter */

   /*________________[ Main Code ]_________________________*/
  
   fout = avg_epochs( old_dset, stimar, user_maxlength, 1, meth, plint );
   if( fout == NULL ) return " \nError in avg_epochs() function!\n " ;
   
   if( RMB_DEBUG ) fprintf(stderr, "Done with avg_epochs\n");
   maxlength = M_maxlength;
   
   
   /*______________________________________________________*/

   
   new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */

   { char * his = PLUTO_commandstring(plint) ;
     tross_Copy_History( old_dset , new_dset ) ;
     tross_Append_History( new_dset , his ) ; free( his ) ;
   }
   
   /*-- edit some of its internal parameters --*/
   ii = EDIT_dset_items(
           new_dset ,
              ADN_prefix      , new_prefix ,           /* filename prefix */
              ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */
              ADN_datum_all   , new_datum ,            /* atomic datum */
              ADN_nvals       , maxlength ,            /* # sub-bricks */
              ADN_ntt         , maxlength ,            /* # time points */
           /*   ADN_ttorg       , old_dtime ,  */              /* time origin */
           /*   ADN_ttdel       , old_dtime ,  */            /* time step */
           /*   ADN_ttdur       , old_dtime ,  */            /* time duration */
           /*   ADN_nsl         , 0 ,          */        /* z-axis time slicing */
           /*   ADN_tunits      , old_units ,  */        /* time units */
           ADN_none ) ;

   if( ii != 0 ){
      THD_delete_3dim_dataset( new_dset , False ) ;
      FREE_WORKSPACE ;
      return "***********************************\n"
             "Error while creating output dataset\n"
             "***********************************"  ;
   }


   /*------------------------------------------------------------*/
   /*------- The output is now in fout[kk][ii],
             for kk=0..maxlength-1 , ii=0..nvox-1.
             We must now put this into the output dataset -------*/

   switch( new_datum ){

      /*** output is floats is the simplest:
           we just have to attach the fout bricks to the dataset ***/

      case MRI_float:
         for( kk=0 ; kk < maxlength ; kk++ )
            EDIT_substitute_brick( new_dset , kk , MRI_float , fout[kk] ) ;
      break ;

      /*** output is shorts:
           we have to create a scaled sub-brick from fout ***/

      case MRI_short:{
         short * bout ;
         float fac ; 

         for( kk=0 ; kk < maxlength ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/
            bout = (short *) malloc( sizeof(short) * nvox ) ;
            if( bout == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_stavg!\n\a") ;
               return("Final malloc error in plug_stavg!"); ;
               /*  exit(1) ;*/
            }

            /*-- find scaling and then scale --*/
            /*fac = MCW_vol_amax( nvox,1,1 , MRI_float , fout[kk] ) ;*/
            fac = 1.0;
            EDIT_coerce_scale_type( nvox,fac ,
                                    MRI_float,fout[kk] , MRI_short,bout ) ;
            free( fout[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/
            EDIT_substitute_brick( new_dset , kk , MRI_short , bout ) ;
         }
      }
      break ;

      /*** output is bytes (byte = unsigned char)
           we have to create a scaled sub-brick from fout ***/

      case MRI_byte:{
         byte * bout ;
         float fac ;

         for( kk=0 ; kk < maxlength ; kk++ ){  /* loop over sub-bricks */

            /*-- get output sub-brick --*/

            bout = (byte *) malloc( sizeof(byte) * nvox ) ;
            if( bout == NULL ){
               fprintf(stderr,"\nFinal malloc error in plug_stavg!\n\a") ;
               return("Final malloc error in plug_stavg!"); ;
	       /*               exit(1) ;*/
            }

            /*-- find scaling and then scale --*/

            fac = 1.0;
            EDIT_coerce_scale_type( nvox,fac ,
                                    MRI_float,fout[kk] , MRI_byte,bout ) ;

            free( fout[kk] ) ;  /* don't need this anymore */

            /*-- put output brick into dataset, and store scale factor --*/

            EDIT_substitute_brick( new_dset , kk , MRI_byte , bout ) ;
         }

      }
      break ;

   } /* end of switch on output data type */

   /*-------------- Cleanup and go home ----------------*/

   PLUTO_set_meter( plint , 100 ) ;  /* set progress meter to 100% */

   PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;

   FREE_WORKSPACE ;
   return NULL ;  /* null string returned means all was OK */
}
Esempio n. 16
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *old_dset , *new_dset ;  /* input and output datasets */
   THD_3dim_dataset *mask_dset=NULL  ;
   float mask_bot=666.0 , mask_top=-666.0 ;
   byte *cmask=NULL ; int ncmask=0 ;
   byte *mmm   = NULL ;
   int mcount=0, verb=0;
   int nopt, nbriks, ii ;
   int addBriks = 0 ;   /* n-1 sub-bricks out */
   int fullBriks = 0 ;  /* n   sub-bricks out */
   int tsout = 0 ;      /* flag to output a time series (not a stat bucket) */
   int numMultBriks,methIndex,brikIndex;

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      /*-- prefix --*/

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

      /*-- tdiff --*/

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

      /*-- nscale --*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   if( DSET_NUM_TIMES(old_dset) < 2 ){
     WARNING_message("Input dataset is not 3D+time; assuming TR=1.0") ;
     EDIT_dset_items( old_dset ,
                        ADN_ntt    , DSET_NVALS(old_dset) ,
                        ADN_ttorg  , 0.0 ,
                        ADN_ttdel  , 1.0 ,
                        ADN_tunits , UNITS_SEC_TYPE ,
                      NULL ) ;
   }

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

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

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

   /*------------- ready to compute new dataset -----------*/

   new_dset = MAKER_4D_to_typed_fbuc(
                 old_dset ,             /* input dataset */
                 prefix ,               /* output prefix */
                 datum ,                /* output datum  */
                 0 ,                    /* ignore count  */
                 0 ,              /* can't detrend in maker function  KRH 12/02*/
                 nbriks ,               /* number of briks */
                 STATS_tsfunc ,         /* timeseries processor */
                 NULL,                  /* data for tsfunc */
                 mmm,
                 nscale
              ) ;

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

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

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

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

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

   exit(0) ;
}
Esempio n. 17
0
/*-------------------------------------------------------*/
MRI_IMARR * dset_to_mri(THD_3dim_dataset * dset)
/*--------------------------------------------------------*/
{

   int ii, kk, ntime, datum;
   int nvox, nx, ny, nz;
   int use_fac;
   
   MRI_IMARR * ims_in;
   MRI_IMAGE * im, *temp_im;
   

   byte   ** bptr  = NULL ;  /* one of these will be the array of */
   short  ** sptr  = NULL ;  /* pointers to input dataset sub-bricks */
   float  ** fptr  = NULL ;  /* (depending on input datum type) */
   
   float * fac  = NULL ;  /* array of brick scaling factors */
   
   float * fout;
   

   ntime = DSET_NUM_TIMES(dset) ;
   nx = dset->daxes->nxx;
   ny = dset->daxes->nyy;
   nz = dset->daxes->nzz;
   nvox = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz ;
   datum = DSET_BRICK_TYPE( dset , 0 ) ; /* get dataset datum type */

   switch( datum ){  /* pointer type depends on input datum type */

      default:
         return NULL  ;

      /** create array of pointers into old dataset sub-bricks **/

      /*--------- input is bytes ----------*/
      /* voxel #i at time #k is bptr[k][i] */
      /* for i=0..nvox-1 and k=0..ntime-1.  */

      case MRI_byte:
         bptr = (byte **) malloc( sizeof(byte *) * ntime ) ;
         if( bptr == NULL ) return NULL ;
         for( kk=0 ; kk < ntime ; kk++ )
            bptr[kk] = (byte *) DSET_ARRAY(dset,kk) ;
      break ;

      /*--------- input is shorts ---------*/
      /* voxel #i at time #k is sptr[k][i] */
      /* for i=0..nvox-1 and k=0..ntime-1.  */

      case MRI_short:
         sptr = (short **) malloc( sizeof(short *) * ntime ) ;
         if( sptr == NULL ) return NULL ;
         for( kk=0 ; kk < ntime; kk++ )
            sptr[kk] = (short *) DSET_ARRAY(dset,kk) ;
      break ;

      /*--------- input is floats ---------*/
      /* voxel #i at time #k is fptr[k][i] */
      /* for i=0..nvox-1 and k=0..ntime-1.  */

      case MRI_float:
         fptr = (float **) malloc( sizeof(float *) * ntime) ;
         if( fptr == NULL ) return NULL ;
         for( kk=0 ; kk < ntime; kk++ )
            fptr[kk] = (float *) DSET_ARRAY(dset,kk) ;
      break ;

   } /* end of switch on input type */
   
   INIT_IMARR(ims_in) ;
   for( kk=0 ; kk < ntime ; kk++ ){
      im = mri_new_vol_empty( nx , ny , nz , datum ) ;
      ADDTO_IMARR(ims_in,im) ;
   }
   
   for( kk=0 ; kk < ntime ; kk++ ){
      im = IMARR_SUBIMAGE(ims_in,kk) ;
      
      switch( datum ){
         case MRI_byte:  mri_fix_data_pointer( bptr[kk], im ) ; break ;
         case MRI_short: mri_fix_data_pointer( sptr[kk], im ) ; break ;
         case MRI_float: mri_fix_data_pointer( fptr[kk], im ) ; break ;
      }
   }


   
   return(ims_in);
}
Esempio n. 18
0
char * IMREG_main( PLUGIN_interface * plint )
{
    MCW_idcode * idc ;                          /* input dataset idcode */
    THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
    char * new_prefix , * str ;                 /* strings from user */
    int base , ntime , datum , nx,ny,nz , ii,kk , npix ;
    float                      dx,dy,dz ;
    MRI_IMARR * ims_in , * ims_out ;
    MRI_IMAGE * im , * imbase ;

    byte   ** bptr = NULL , ** bout = NULL ;
    short  ** sptr = NULL , ** sout = NULL ;
    float  ** fptr = NULL , ** fout = NULL ;

    float * dxar = NULL , * dyar = NULL , * phiar = NULL ;

    /*--------------------------------------------------------------------*/
    /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/

    /*--------- go to first input line ---------*/

    PLUTO_next_option(plint) ;

    idc      = PLUTO_get_idcode(plint) ;   /* get dataset item */
    old_dset = PLUTO_find_dset(idc) ;      /* get ptr to dataset */
    if( old_dset == NULL )
        return "*************************\n"
               "Cannot find Input Dataset\n"
               "*************************"  ;

    ntime = DSET_NUM_TIMES(old_dset) ;
    if( ntime < 2 )
        return "*****************************\n"
               "Dataset has only 1 time point\n"
               "*****************************"  ;

    ii = DSET_NVALS_PER_TIME(old_dset) ;
    if( ii > 1 )
        return "************************************\n"
               "Dataset has > 1 value per time point\n"
               "************************************"  ;

    nx = old_dset->daxes->nxx ;
    dx = old_dset->daxes->xxdel ;
    ny = old_dset->daxes->nyy ;
    dy = old_dset->daxes->yydel ;
    npix = nx*ny ;
    nz = old_dset->daxes->nzz ;
    dz = old_dset->daxes->zzdel ;

    if( nx != ny || fabs(dx) != fabs(dy) ) {

#ifdef IMREG_DEBUG
        fprintf(stderr,"\nIMREG: nx=%d ny=%d nz=%d  dx=%f dy=%f dz=%f\n",
                nx,ny,nz,dx,dy,dz ) ;
#endif

        return "***********************************\n"
               "Dataset does not have square slices\n"
               "***********************************"  ;
    }

    new_prefix = PLUTO_get_string(plint) ;   /* get string item (the output prefix) */
    if( ! PLUTO_prefix_ok(new_prefix) )      /* check if it is OK */
        return "************************\n"
               "Output Prefix is illegal\n"
               "************************"  ;

    /*--------- go to next input line ---------*/

    PLUTO_next_option(plint) ;

    base = PLUTO_get_number(plint) ;
    if( base >= ntime )
        return "********************\n"
               "Base value too large\n"
               "********************"  ;

    /*--------- see if the 3rd option line is present --------*/

    str = PLUTO_get_optiontag( plint ) ;
    if( str != NULL ) {
        float fsig , fdxy , fdph ;
        fsig = PLUTO_get_number(plint) * 0.42466090 ;
        fdxy = PLUTO_get_number(plint) ;
        fdph = PLUTO_get_number(plint) ;
        mri_align_params( 0 , 0.0,0.0,0.0 , fsig,fdxy,fdph ) ;
        /* fprintf(stderr,"Set fine params = %f %f %f\n",fsig,fdxy,fdph) ; */
    }

    /*------------- ready to compute new dataset -----------*/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: loading dataset\n") ;
#endif

    DSET_load( old_dset ) ;

    /*** 1) Copy the dataset in toto ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: Copying dataset\n") ;
#endif

    new_dset = PLUTO_copy_dset( old_dset , new_prefix ) ;
    if( new_dset == NULL )
        return "****************************\n"
               "Failed to copy input dataset\n"
               "****************************"  ;

    /*** 2) Make an array of empty images ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: making empty images\n") ;
#endif

    datum = DSET_BRICK_TYPE(new_dset,0) ;

    INIT_IMARR(ims_in) ;
    for( ii=0 ; ii < ntime ; ii++ ) {
        im = mri_new_vol_empty( nx , ny , 1 , datum ) ;
        ADDTO_IMARR(ims_in,im) ;
    }

    imbase = mri_new_vol_empty( nx , ny , 1 , datum ) ;

    dxar  = (float *) malloc( sizeof(float) * ntime ) ;
    dyar  = (float *) malloc( sizeof(float) * ntime ) ;
    phiar = (float *) malloc( sizeof(float) * ntime ) ;

    /*** 3) Get pointers to sub-bricks in old and new datasets ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: getting input brick pointers\n") ;
#endif

    switch( datum ) { /* pointer type depends on input datum type */
    case MRI_byte:
        bptr = (byte **) malloc( sizeof(byte *) * ntime ) ;
        bout = (byte **) malloc( sizeof(byte *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            bptr[ii] = (byte *) DSET_ARRAY(old_dset,ii) ;
            bout[ii] = (byte *) DSET_ARRAY(new_dset,ii) ;
        }
        break ;

    case MRI_short:
        sptr = (short **) malloc( sizeof(short *) * ntime ) ;
        sout = (short **) malloc( sizeof(short *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            sptr[ii] = (short *) DSET_ARRAY(old_dset,ii) ;
            sout[ii] = (short *) DSET_ARRAY(new_dset,ii) ;
        }

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: sptr[0] = %p  sout[0] = %p\n",sptr[0],sout[0]) ;
#endif

        break ;

    case MRI_float:
        fptr = (float **) malloc( sizeof(float *) * ntime ) ;
        fout = (float **) malloc( sizeof(float *) * ntime ) ;
        for( ii=0 ; ii < ntime ; ii++ ) {
            fptr[ii] = (float *) DSET_ARRAY(old_dset,ii) ;
            fout[ii] = (float *) DSET_ARRAY(new_dset,ii) ;
        }
        break ;
    }

    /*** 4) Loop over slices ***/

    PLUTO_popup_meter(plint) ;

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

        /*** 4a) Setup ims_in images to point to input slices ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- setup input images\n",kk) ;
#endif

        for( ii=0 ; ii < ntime ; ii++ ) {
            im = IMARR_SUBIMAGE(ims_in,ii) ;
            switch( datum ) {
            case MRI_byte:
                mri_fix_data_pointer( bptr[ii] + kk*npix, im ) ;
                break ;
            case MRI_short:
                mri_fix_data_pointer( sptr[ii] + kk*npix, im ) ;
                break ;
            case MRI_float:
                mri_fix_data_pointer( fptr[ii] + kk*npix, im ) ;
                break ;
            }
        }

        /*** 4b) Setup im to point to base image ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- setup base image\n",kk) ;
#endif

        switch( datum ) {
        case MRI_byte:
            mri_fix_data_pointer( bptr[base] + kk*npix, imbase ) ;
            break ;
        case MRI_short:
            mri_fix_data_pointer( sptr[base] + kk*npix, imbase ) ;
            break ;
        case MRI_float:
            mri_fix_data_pointer( fptr[base] + kk*npix, imbase ) ;
            break ;
        }

        /*** 4c) Register this slice at all times ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- register\n",kk) ;
#endif

        ims_out = mri_align_dfspace( imbase , NULL , ims_in ,
                                     ALIGN_REGISTER_CODE , dxar,dyar,phiar ) ;

        if( ims_out == NULL )
            fprintf(stderr,"IMREG: mri_align_dfspace return NULL\n") ;

        /*** 4d) Put the output back in on top of the input;
                 note that the output is always in MRI_float format ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: slice %d -- put output back into dataset\n",kk) ;
#endif

        for( ii=0 ; ii < ntime ; ii++ ) {
            switch( datum ) {
            case MRI_byte:
                im = mri_to_mri( MRI_byte , IMARR_SUBIMAGE(ims_out,ii) ) ;
                memcpy( bout[ii] + kk*npix , MRI_BYTE_PTR(im) , sizeof(byte)*npix ) ;
                mri_free(im) ;
                break ;

            case MRI_short:
#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: conversion to short at ii=%d\n",ii) ;
#endif

                im = mri_to_mri( MRI_short , IMARR_SUBIMAGE(ims_out,ii) ) ;

#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: copying to %p from %p\n",sout[ii] + kk*npix,MRI_SHORT_PTR(im)) ;
#endif

                memcpy( sout[ii] + kk*npix , MRI_SHORT_PTR(im) , sizeof(short)*npix ) ;

#ifdef IMREG_DEBUG
                if( ii==0 )fprintf(stderr,"IMREG: freeing\n") ;
#endif

                mri_free(im) ;
                break ;

            case MRI_float:
                im = IMARR_SUBIMAGE(ims_out,ii) ;
                memcpy( fout[ii] + kk*npix , MRI_FLOAT_PTR(im) , sizeof(float)*npix ) ;
                break ;
            }
        }

        PLUTO_set_meter(plint, (100*(kk+1))/nz ) ;

        /*** 4e) Destroy the output images ***/

#ifdef IMREG_DEBUG
        fprintf(stderr,"IMREG: destroying aligned output\n") ;
#endif

        DESTROY_IMARR( ims_out ) ;
    }

    /*** 5) Destroy the empty images and other workspaces ***/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: destroy workspaces\n") ;
#endif

    mri_clear_data_pointer(imbase) ;
    mri_free(imbase) ;
    for( ii=0 ; ii < ntime ; ii++ ) {
        im = IMARR_SUBIMAGE(ims_in,ii) ;
        mri_clear_data_pointer(im) ;
    }
    DESTROY_IMARR(ims_in) ;
    FREE_WORKSPACE ;

    /*------------- let AFNI know about the new dataset ------------*/

#ifdef IMREG_DEBUG
    fprintf(stderr,"IMREG: send result to AFNI\n") ;
#endif

    PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;

    return NULL ;  /* null string returned means all was OK */
}