Ejemplo n.º 1
0
int SUMA_ShortizeDset(THD_3dim_dataset **dsetp, float thisfac) {
   static char FuncName[]={"SUMA_ShortizeDset"};
   char sprefix[THD_MAX_PREFIX+10];
   int i, j;
   byte *bb=NULL;
   short *sb=NULL;
   float bbf=0.0;
   
   THD_3dim_dataset *cpset=NULL, *dset=*dsetp;
   
   SUMA_ENTRY;
   
   if (!dset) {
      SUMA_S_Err("NULL *dsetp at input!");
      SUMA_RETURN(0);
   }
   
   sprintf(sprefix, "%s.s", dset->dblk->diskptr->prefix);
   NEW_SHORTY(dset, DSET_NVALS(dset), "ss.cp", cpset);      
   for (i=0; i<DSET_NVALS(dset); ++i) {
      if (DSET_BRICK_TYPE(dset,i) == MRI_byte) {
         bb = (byte *)DSET_ARRAY(dset,i);
         sb = (short *)DSET_ARRAY(cpset,i);
         if (thisfac <= 0.0) {
            for (j=0; j<DSET_NVOX(dset); ++j) {
               sb[j] = (short)bb[j];
            }
            thisfac = DSET_BRICK_FACTOR(dset,i);
         } else {
            bbf = DSET_BRICK_FACTOR(dset,i); if (bbf == 0.0f) bbf = 1.0;
            bbf = bbf/thisfac;
            for (j=0; j<DSET_NVOX(dset); ++j) {
               sb[j] = SHORTIZE((((float)bb[j])*bbf));
            }
         }
         EDIT_BRICK_FACTOR( cpset,i,thisfac ) ;
      } else {
         EDIT_substscale_brick(cpset, i, DSET_BRICK_TYPE(dset,i), 
                            DSET_ARRAY(dset,i), MRI_short, thisfac);
         if (DSET_BRICK_TYPE(dset,i) != MRI_short) {
            DSET_FREE_ARRAY(dset, i);
         } else {
            DSET_NULL_ARRAY(dset, i);
         }
      }
   }
   /* preserve tables, if any */
   THD_copy_labeltable_atr( cpset->dblk,  dset->dblk); 
   DSET_delete(dset); dset = NULL; 
   *dsetp=cpset;

   SUMA_RETURN(1);
}
Ejemplo n.º 2
0
float THD_get_float_value( int ind , int ival , THD_3dim_dataset *dset )
{
   MRI_TYPE typ ; float val=0.0f ;

   if( ind < 0 || ival < 0 || !ISVALID_DSET(dset) ||
       ival >= DSET_NVALS(dset) || ind >= DSET_NVOX(dset) ) return val ;

   typ = DSET_BRICK_TYPE(dset,ival) ;  /* raw data type */

   switch( typ ){

      default:           /* don't know what to do --> return nada */
         return(-1);
      break ;

      case MRI_byte:{
         byte *bar ;
         bar = (byte *) DSET_ARRAY(dset,ival) ;
         if( bar != NULL ) val = (float)bar[ind] ;
      }
      break ;

      case MRI_short:{
         short *bar ;
         bar = (short *) DSET_ARRAY(dset,ival) ;
         if( bar != NULL ) val = (float)bar[ind] ;
      }
      break ;

      case MRI_float:{
         float *bar ;
         bar = (float *) DSET_ARRAY(dset,ival) ;
         if( bar != NULL ) val = bar[ind] ;
      }
      break ;

      case MRI_complex:{
         complex *bar ;
         bar = (complex *) DSET_ARRAY(dset,ival) ;
         if( bar != NULL ) val = CABS(bar[ind]) ;
      }
      break ;

   }

   if( DSET_BRICK_FACTOR(dset,ival) > 0.0f )
     val *= DSET_BRICK_FACTOR(dset,ival) ;

   return val ;
}
Ejemplo n.º 3
0
/*----------------------------------------------------------------------
**
**  Subtract hemispheres.
**
**  Check if we need to create or change the factor.
**
**----------------------------------------------------------------------
*/
static char *
process_data( THD_3dim_dataset * dset, hemi_s * hs )
{
    int     count, nx, ny, nz, cx, cx2;
    int     type, diff, floats = ( DSET_BRICK_FACTOR( dset, 0 ) != 0.0 );
    short * data, * sp, * sp2;

    nx = dset->daxes->nxx;
    ny = dset->daxes->nyy;
    nz = dset->daxes->nzz;

    type = hs->thresh_type;

    data = (short *)DSET_ARRAY( dset, 0 );
    for ( count = 0; ! floats && count < ny*nz; count++ )
    {
	sp  = data;
	sp2 = data + nx - 1;

	for ( cx = 0; cx < (nx+1)/2; cx++ )
	{
	    if ( type == 1 )            /* positives only */
	    {
		if ( *sp < 0 )
		    *sp = 0;
		if ( *sp2 < 0 )
		    *sp2 = 0;
	    }
	    else if ( type == 2 )       /* negatives only */
	    {
		if ( *sp > 0 )
		    *sp = 0;
		if ( *sp2 > 0 )
		    *sp2 = 0;
	    }

	    diff = *sp - *sp2;
						  /* if out of short range */
	    if ( ( diff > 32767 ) || ( diff < -32768 ) )
		floats = 1;
	    else
	    {
		*sp  = diff;
		*sp2 = -diff;
	    }

	    sp++;
	    sp2--;
	}

	data += nx;
    }

    if ( floats )
	return process_as_floats( dset, hs );

    return NULL;        /* success */
}
Ejemplo n.º 4
0
int is_integral_sub_brick ( THD_3dim_dataset *dset, int isb, int check_values)
{
   float mfac = 0.0;
   void *vv=NULL;

   if(   !ISVALID_DSET(dset)    ||
            isb < 0                     ||
            isb >= DSET_NVALS(dset)  ) {

      fprintf(stderr,"** Bad dset or sub-brick index.\n");
      return (0) ;

   }
   if( !DSET_LOADED(dset) ) DSET_load(dset);

   switch( DSET_BRICK_TYPE(dset,isb) ){
      case MRI_short:
      case MRI_byte:
         if (check_values) {
            mfac = DSET_BRICK_FACTOR(dset,isb) ;
            if (mfac != 0.0f && mfac != 1.0f) return(0);
         }
         break;
      case MRI_double:
      case MRI_complex:
      case MRI_float:
         vv = (void *)DSET_ARRAY(dset,isb);
         mfac = DSET_BRICK_FACTOR(dset,isb) ;
         if (mfac != 0.0f && mfac != 1.0f) return(0);
         if (!vv) {
            fprintf(stderr,"** NULL array!\n");
            return(0);
         }
         return(is_integral_data(DSET_NVOX(dset),
                                 DSET_BRICK_TYPE(dset,isb),
                                 DSET_ARRAY(dset,isb) ) );
         break;
      default:
         return(0);
   }

   return(1);
}
Ejemplo n.º 5
0
void THD_load_tcat( THD_datablock *dblk )
{
   int ivout , dd , iv ;
   THD_3dim_dataset *dset_in , *dset_out ;
   NI_str_array *sar ;

ENTRY("THD_load_tcat") ;

   if( !ISVALID_DBLK(dblk) ) EXRETURN ;
   dset_out = (THD_3dim_dataset *)dblk->parent ;
   if( !ISVALID_DSET(dset_out) ) EXRETURN ;
   sar = NI_decode_string_list( dset_out->tcat_list , "~" ) ;
   if( sar == NULL ) EXRETURN ;
   if( sar->num != dset_out->tcat_num ){ NI_delete_str_array(sar); EXRETURN; }

   ivout = 0 ;
   for( dd=0 ; dd < sar->num ; dd++ ){
     dset_in = THD_open_dataset( sar->str[dd] ) ;
     if( dset_in == NULL ){
       NI_delete_str_array(sar) ; DSET_unload(dset_out) ;
       EXRETURN ;
     }
     DSET_mallocize(dset_in) ; DSET_load(dset_in) ;
     if( !DSET_LOADED(dset_in) ){
       NI_delete_str_array(sar) ; DSET_unload(dset_out) ; DSET_delete(dset_in) ;
       EXRETURN ;
     }

     for( iv=0 ; iv < DSET_NVALS(dset_in) ; iv++ ){
       EDIT_substitute_brick( dset_out , ivout ,
                              DSET_BRICK_TYPE(dset_in,iv), DSET_ARRAY(dset_in,iv) );
       mri_fix_data_pointer( NULL , DSET_BRICK(dset_in,iv) ) ;
       EDIT_BRICK_FACTOR( dset_out , ivout , DSET_BRICK_FACTOR(dset_in,iv) ) ;
       EDIT_BRICK_LABEL(dset_out, ivout, 
                        DSET_BRICK_LABEL(dset_in, iv)); /* ZSS Aug. 27 2012 */
       ivout++ ;
     }
     DSET_delete(dset_in) ;
   }

   NI_delete_str_array(sar) ; EXRETURN ;
}
Ejemplo n.º 6
0
MRI_IMAGE * FD_brick_to_series( int ixyz , FD_brick *br )
{
   MRI_IMAGE *im ;  /* output */
   int nv , ival ;
   char *iar ;      /* brick in the input */
   MRI_TYPE typ ;
   int ix,jy,kz , ind ;
   THD_ivec3 ind_fd , ind_ds ;

   if( ixyz < 0 || ixyz >= br->n1 * br->n2 * br->n3 ) return NULL ;

   /** otherwise, get ready for a real image **/

   ix  = ixyz % br->n1 ;
   jy  = ( ixyz % (br->n1 * br->n2) ) / br->n1 ;
   kz  = ixyz / (br->n1 * br->n2) ;
   LOAD_IVEC3( ind_fd , ix,jy,kz ) ; ind_ds = THD_fdind_to_3dind( br , ind_fd ) ;
   ix  = ind_ds.ijk[0] ;
   jy  = ind_ds.ijk[1] ;
   kz  = ind_ds.ijk[2] ;
   ind = (kz * br->dset->daxes->nyy + jy) * br->dset->daxes->nxx + ix ;

   nv = br->dset->dblk->nvals ;

   iar = DSET_ARRAY(br->dset,0) ;
   if( iar == NULL ){  /* if data needs to be loaded from disk */
      (void) THD_load_datablock( br->dset->dblk ) ;
      iar = DSET_ARRAY(br->dset,0) ;
      if( iar == NULL ) return NULL ;
   }

   /* 15 Sep 2004: allow for nonconstant datum */

   if( !DSET_datum_constant(br->dset) ){  /* only for stupid users */
     float *ar ;
     im = mri_new( nv , 1 , MRI_float ) ; ar = MRI_FLOAT_PTR(im) ;
     for( ival = 0 ; ival < nv ; ival++ )
       ar[ival] = THD_get_voxel( br->dset , ind , ival ) ;
     goto image_done ;
   }

   /* the older (more efficient) way */

   typ = DSET_BRICK_TYPE(br->dset,0) ;
   im  = mri_new( nv , 1 , typ ) ;
#if 0
   mri_zero_image(im) ;             /* 18 Oct 2001 */
#endif

   switch( typ ){

      default:             /* don't know what to do --> return nada */
         mri_free( im ) ;
         return NULL ;

      case MRI_byte:{
         byte *ar  = MRI_BYTE_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (byte *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_short:{
         short *ar  = MRI_SHORT_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (short *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_float:{
         float *ar  = MRI_FLOAT_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (float *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_int:{
         int *ar  = MRI_INT_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (int *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_double:{
         double *ar  = MRI_DOUBLE_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (double *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_complex:{
         complex *ar  = MRI_COMPLEX_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (complex *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      /* 15 Apr 2002: RGB types */

      case MRI_rgb:{
         rgbyte *ar  = (rgbyte *) MRI_RGB_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (rgbyte *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

      case MRI_rgba:{
         rgba *ar  = (rgba *) MRI_RGBA_PTR(im) , *bar ;
         for( ival=0 ; ival < nv ; ival++ ){
            bar = (rgba *) DSET_ARRAY(br->dset,ival) ;
            if( bar != NULL ) ar[ival] = bar[ind] ;
         }
      }
      break ;

   }

   if( THD_need_brick_factor(br->dset) ){
      MRI_IMAGE *qim ;
      qim = mri_mult_to_float( br->dset->dblk->brick_fac , im ) ;
      mri_free(im) ; im = qim ;
   }

   /* at this point, the image is ready to ship out;
      but first, maybe attach a time origin and spacing */

image_done:
   if( br->dset->taxis != NULL ){  /* 21 Oct 1996 */
      float zz , tt ;

      zz = br->dset->daxes->zzorg + kz * br->dset->daxes->zzdel ;
      tt = THD_timeof( 0 , zz , br->dset->taxis ) ;

      im->xo = tt ; im->dx = br->dset->taxis->ttdel ;   /* origin and delta */

      if( br->dset->taxis->units_type == UNITS_MSEC_TYPE ){ /* convert to sec */
         im->xo *= 0.001 ; im->dx *= 0.001 ;
      }
   } else {
      im->xo = 0.0 ; im->dx = 1.0 ;  /* 08 Nov 1996 */
   }

   return im ;
}
Ejemplo n.º 7
0
/*!
  contains code shamelessly stolen from Rick who stole it from Bob. 
*/
SUMA_Boolean SUMA_Get_isosurface_datasets (
                     SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt)
{
   static char FuncName[]={"SUMA_Get_isosurface_datasets"};
   int i;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;
   
   if (!Opt->in_vol && !Opt->in_name) {
      SUMA_S_Err("NULL input");
      SUMA_RETURN(NOPE);
   } 
   if (!Opt->in_vol) { /* open it */
     Opt->in_vol = THD_open_dataset( Opt->in_name );
   }
   if (!Opt->in_vol) {
      SUMA_S_Err("No volume could be had");
      SUMA_RETURN(NOPE);
   } 
   
   if (!ISVALID_DSET(Opt->in_vol)) {
      if (!Opt->in_name) {
         SUMA_SL_Err("NULL input volume.");
         SUMA_RETURN(NOPE);
      } else {
         SUMA_SL_Err("invalid volume.");
         SUMA_RETURN(NOPE);
      }
   } else if ( DSET_BRICK_TYPE(Opt->in_vol, 0) == MRI_complex) {
      SUMA_SL_Err("Can't do complex data.");
      SUMA_RETURN(NOPE);
   }
   
   Opt->nvox = DSET_NVOX( Opt->in_vol );
   if (DSET_NVALS( Opt->in_vol) != 1) {
      SUMA_SL_Err("Input volume can only have one sub-brick in it.\n"
                  "Use [.] selectors to choose sub-brick needed.");
      SUMA_RETURN(NOPE);
   }
   
   
   Opt->mcdatav = (double *)SUMA_malloc(sizeof(double)*Opt->nvox);
   if (!Opt->mcdatav) {
      SUMA_SL_Crit("Failed to allocate for maskv");
      SUMA_RETURN(NOPE);
   }
   if (Opt->xform == SUMA_ISO_XFORM_MASK) {
      SUMA_LH("SUMA_ISO_XFORM_MASK");
      switch (Opt->MaskMode) {
         case SUMA_ISO_CMASK:
            SUMA_LH("SUMA_ISO_CMASK");
            if (Opt->cmask) {
               /* here's the second order grand theft */
               int    clen = strlen( Opt->cmask );
	            char * cmd;
               byte *bmask;

	            cmd = (char *)malloc((clen + 1) * sizeof(char));
	            strcpy( cmd,  Opt->cmask);

	            bmask = EDT_calcmask( cmd, &Opt->ninmask, 0 );
               SUMA_LHv("Have %d\n", Opt->ninmask);
	            free( cmd );			   /* free EDT_calcmask() string */

	            if ( bmask == NULL ) {
	               SUMA_SL_Err("Failed to compute mask from -cmask option");
	               SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
                  SUMA_RETURN(NOPE);
	            } 
	            if ( Opt->ninmask != Opt->nvox ) {
	               SUMA_SL_Err("Input and cmask datasets do not have "
		                        "the same dimensions\n" );
	               SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
	               SUMA_RETURN(NOPE);
	            }
	            Opt->ninmask = THD_countmask( Opt->ninmask, bmask );
               SUMA_LHv("Have %d\n", Opt->ninmask);
               for (i=0; i<Opt->nvox; ++i) 
                  if (bmask[i]) Opt->mcdatav[i] = (double)bmask[i]; 
                  else Opt->mcdatav[i] = -1;
               free(bmask);bmask=NULL;
            } else {
               SUMA_SL_Err("NULL cmask"); SUMA_RETURN(NOPE);
            }
            break;
         case SUMA_ISO_VAL:
         case SUMA_ISO_RANGE:
            SUMA_LH("SUMA_ISO_VAL, SUMA_ISO_RANGE");
            /* load the dset */
            DSET_load(Opt->in_vol);
            Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
            if (!Opt->dvec) {
               SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
               SUMA_RETURN(NOPE);
            }
            EDIT_coerce_scale_type( 
               Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
               DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , 
               MRI_double               , Opt->dvec  ) ;  
            /* no need for data in input volume anymore */
            PURGE_DSET(Opt->in_vol);

            Opt->ninmask = 0;
            if (Opt->MaskMode == SUMA_ISO_VAL) {
               for (i=0; i<Opt->nvox; ++i) {
                  if (Opt->dvec[i] == Opt->v0) { 
                     Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
                  }  else Opt->mcdatav[i] = -1;
               }
            } else if (Opt->MaskMode == SUMA_ISO_RANGE) {
               for (i=0; i<Opt->nvox; ++i) {
                  if (Opt->dvec[i] >= Opt->v0 && Opt->dvec[i] < Opt->v1) { 
                     Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
                  }  else Opt->mcdatav[i] = -1;
               }
            } else {
               SUMA_SL_Err("Bad Miracle.");
               SUMA_RETURN(NOPE);
            }
            SUMA_free(Opt->dvec); Opt->dvec = NULL; 
                  /* this vector is not even created in SUMA_ISO_CMASK mode ...*/
            break;
         default:
            SUMA_SL_Err("Unexpected value of MaskMode");
            SUMA_RETURN(NOPE);
            break;   
      }
   } else if (Opt->xform == SUMA_ISO_XFORM_SHIFT) {
      /* load the dset */
      DSET_load(Opt->in_vol);
      Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
      if (!Opt->dvec) {
         SUMA_SL_Crit("Failed to allocate for dvec.\nOh misery.");
         SUMA_RETURN(NOPE);
      }
      EDIT_coerce_scale_type( 
         Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
         DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) ,      
         MRI_double               , Opt->dvec  ) ;   
      /* no need for data in input volume anymore */
      PURGE_DSET(Opt->in_vol);
      Opt->ninmask = Opt->nvox;
      for (i=0; i<Opt->nvox; ++i) { 
         Opt->mcdatav[i] = Opt->dvec[i] - Opt->v0;
      }
      SUMA_free(Opt->dvec); Opt->dvec = NULL; 
   } else if (Opt->xform == SUMA_ISO_XFORM_NONE) {
      /* load the dset */
      DSET_load(Opt->in_vol);
      Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
      if (!Opt->dvec) {
         SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
         SUMA_RETURN(NOPE);
      }
      EDIT_coerce_scale_type( 
         Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
         DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , 
         MRI_double               , Opt->dvec  ) ;   
      /* no need for data in input volume anymore */
      PURGE_DSET(Opt->in_vol);
      Opt->ninmask = Opt->nvox;
      for (i=0; i<Opt->nvox; ++i) { 
         Opt->mcdatav[i] = Opt->dvec[i];
      }
      SUMA_free(Opt->dvec); Opt->dvec = NULL; 
   } else {
      SUMA_SL_Err("Bad Opt->xform.");
      SUMA_RETURN(NOPE);
   }
   
   if ( Opt->ninmask  <= 0 ) {
	   if (Opt->ninmask == 0) {
         SUMA_SL_Err("A negative value!\nNothing to do." );
      } else {
         SUMA_SL_Err("An empty mask!\n Nothing to do." );
	   }
      SUMA_RETURN(NOPE);
	}
   
   if (Opt->debug > 0) {
      fprintf( SUMA_STDERR, 
               "%s:\nInput dset %s has nvox = %d, nvals = %d",
		         FuncName, SUMA_CHECK_NULL_STR(Opt->in_name), 
               Opt->nvox, DSET_NVALS(Opt->in_vol) );
	   fprintf( SUMA_STDERR, " (%d voxels in mask)\n", Opt->ninmask );
   }
   
   SUMA_RETURN(YUP);
}
Ejemplo n.º 8
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *xset , *cset, *mset=NULL ;
   int nopt=1 , method=PEARSON , do_autoclip=0 ;
   int nvox , nvals , ii, jj, kout, kin, polort=1 ;
   int ix1,jy1,kz1, ix2, jy2, kz2 ;
   char *prefix = "degree_centrality" ;
   byte *mask=NULL;
   int   nmask , abuc=1 ;
   int   all_source=0;        /* output all source voxels  25 Jun 2010 [rickr] */
   char str[32] , *cpt ;
   int *imap = NULL ; MRI_vectim *xvectim ;
   float (*corfun)(int,float *,float*) = NULL ;
   /* djc - add 1d file output for similarity matrix */
   FILE *fout1D=NULL;

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

   int nb_ctr = 0;

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

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

   /*----*/

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

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

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

   /*-- option processing --*/

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

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

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

         do_autoclip = 1 ; nopt++ ; continue ;
      }

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

             if ( car <= thresh )
             {
                 continue ;
             }

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

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

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

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

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

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

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

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

    } /* end OpenMP */
    AFNI_OMP_END ;

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

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

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

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

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

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

   ININFO_message("creating output dataset in memory") ;

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

   sprintf(str,"Binary Degree Centrality") ;

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


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

   sprintf(str,"Weighted Degree Centrality") ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   INFO_message("Done..\n") ;

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

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

   PRINT_MEM_STATS( "vectim unload" );

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

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

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

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

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

   exit(0) ;
}
Ejemplo n.º 9
0
int main( int argc , char * argv[] )
{
   THD_dfvec3 *xx , *yy , dv ;
   int nvec=0 , ii,jj, iarg ;
   THD_dvecmat rt , rtinv ;
   THD_dmat33  pp,ppt , rr ;
   THD_dfvec3  tt ;

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

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

   float matar[12] ;

   int use_3dWarp=1 , matrix_type=ROTATION ;

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

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

      /*-----*/

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

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

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

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

      /*-----*/

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

         mset = THD_open_dataset( argv[iarg] ) ;

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

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

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

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

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

         iarg++ ; continue ;
      }

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

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

      /*-----*/

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

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

         wtim = mri_read_1D( argv[iarg] ) ;

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

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

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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


      /*-----*/

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

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

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


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

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

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

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

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

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

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

   dset = THD_open_dataset( argv[iarg] ) ;

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

   /* check if set tags match exactly */

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

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

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

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

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

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

         jj++ ;
      }
   }

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

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

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

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

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

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

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

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

   dsum = DMAT_DET(rt.mm) ;

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

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

     exit(1) ;
   }

   /*-- print summary --*/

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

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

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

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

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

   if( mfile ){
      FILE * mp ;

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

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

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

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

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

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

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

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

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

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

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

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

     if( keeptags ){
        THD_dfvec3 rv ;

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

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

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

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

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

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

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

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

     THD_rota_method( MRI_HEPTIC ) ;
     clipit = 1 ;

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

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

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

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

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

        /*- rotate it -*/

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

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

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

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

        /*- put it back into dataset -*/

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

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

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

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

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

     /* write dataset to disk */

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

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

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

     THD_3dim_dataset *oset ;
     THD_vecmat tran ;

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

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

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

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

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

     if( keeptags ){
        THD_dfvec3 rv ;

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

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

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

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

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

     DSET_write(oset) ;

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

   exit(0) ;
}
Ejemplo n.º 10
0
int SUMA_SegEngine(SEG_OPTS *Opt) 
{
   
   static char FuncName[]={"SUMA_SegEngine"};
   THD_3dim_dataset *pygcbo=NULL;
   int iter=0, kk, UseK[500];
   char sinf[256];
   char sreport[512]={"unset_report_name.txt"};
   SUMA_Boolean LocalHead = YUP;
   
   SUMA_ENTRY;
   
#ifdef USE_OMP
#pragma omp parallel
 {
  if( LocalHead && omp_get_thread_num() == 0 )
    INFO_message("OpenMP thread count = %d",omp_get_num_threads()) ;
}
#endif
   if (Opt->cset) {/* Hide Classes not for analysis */
      int mm;
      short *sc=NULL;
      sc= (short *)DSET_ARRAY (Opt->cset, 0);
      for (kk=0 ; kk<DSET_NVOX(Opt->cset); ++kk) {
         for (mm=0; mm<Opt->cs->N_label; ++mm) {
            if (sc[kk] == Opt->cs->keys[mm]) break;
         }
         if (mm >= Opt->cs->N_label) sc[kk] = 0;
      }
   } else {
      SUMA_S_Err("Need cset");
      SUMA_RETURN(0);
   }
   
   if (!Opt->priCgALL) {
      if ((Opt->priCgA || Opt->priCgL)) {
         if (!SUMA_MergeCpriors( Opt->cs, Opt->cmask, Opt->aset, 
                                 Opt->priCgA, Opt->wA, 
                                 Opt->priCgL, Opt->wL,
                                 &Opt->priCgALL, Opt)) {
            SUMA_S_Err("NULL Opt->priCgALL");
            SUMA_RETURN(0);
         }
      } else if ((Opt->priCgLname && !strcmp(Opt->priCgLname,"INIT_MIXFRAC")) ||
                 (Opt->priCgAname && !strcmp(Opt->priCgAname,"INIT_MIXFRAC")) ){
         SUMA_S_Note("Forcing spatial priors at initial mixing fraction");
         if (!SUMA_MergeCpriors( Opt->cs, Opt->cmask, Opt->aset, 
                                 NULL, 0.0, 
                                 NULL, 0.0,
                                 &Opt->priCgALL, Opt)) {
            SUMA_S_Err("NULL Opt->priCgALL");
            SUMA_RETURN(0);
         }
      }
      if (Opt->priCgALL && Opt->debug > 1) {
         SUMA_Seg_Write_Dset(Opt->proot,"priCgALLmerged", 
                             Opt->priCgALL, -1, Opt->hist);
      }
   }
   
   /* split the classes */
   if (Opt->Split) { 
      THD_3dim_dataset *Scset=NULL;
      int N_split=0;
      SUMA_CLASS_STAT *Scs=NULL;
      SUMA_S_Warn("Splitting classes");
      while (Opt->Split[N_split] > 0) ++N_split;
      if (N_split != Opt->cs->N_label) {
         SUMA_S_Errv("Split vector malformed.\n"
                     "Have %d values in Split, but %d classes\n",
                     N_split, Opt->cs->N_label);
         SUMA_RETURN(0);
      }
      if (!SUMA_Split_Classes(Opt->cs->label, Opt->cs->N_label, Opt->cs->keys,
                              Opt->Split, Opt->aset, Opt->cset, Opt->cmask,
                              &Scset, &Scs, Opt)) {
         SUMA_S_Err("Failed to split classes");
         SUMA_RETURN(0);
      }
      /* Save old class stats and replace by split classes */
      Opt->Gcs = Opt->cs; Opt->cs = Scs; Scs=NULL;
      DSET_delete(Opt->cset); Opt->cset = Scset; Scset=NULL;
   }
      
   /* get the initial parameters pstCgALL is still null here normally 
      and priCgALL will not be used when that is the case.
      So these estimates are from cset alone */
   if (!SUMA_Class_stats( Opt->aset, Opt->cset, Opt->cmask, Opt->cmask_count,
                          Opt->pstCgALL, Opt->priCgALL, Opt->gold, 
                          Opt->cs, Opt->mix_frac_floor)) {
      SUMA_S_Err("Failed in class stats");
      SUMA_RETURN(0);
   }
   if (Opt->debug) SUMA_show_Class_Stat(Opt->cs, "Class Stat At Input:\n", NULL);
   
   /* Make sure there are good estimates for all classes */
   if (SUMA_ZeroSamp_from_ClassStat(Opt->cs)) {
      if (!Opt->debug) 
         SUMA_show_Class_Stat(Opt->cs, "Class Stat At Input:\n", NULL);
      SUMA_S_Err("Have empty classes at initialization. Not cool\n");
      SUMA_RETURN(0);
   }

   if (!Opt->pstCgALL) { /* Compute initial posterior distribution */
      if (!(SUMA_pst_C_giv_ALL(Opt->aset, 
                   Opt->cmask, Opt->cmask_count,
                   Opt->cs, Opt->priCgALL, Opt->pCgN, 
                   Opt->B, Opt->T, 
                   (!Opt->mixopt || strcmp(Opt->mixopt,"IGNORE")) ? 1:0,
                               &Opt->pstCgALL))) {
         SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL");
         SUMA_RETURN(0);
      }
   }
     
   if (!SUMA_Class_stats( Opt->aset, Opt->cset, Opt->cmask, Opt->cmask_count,
                          Opt->pstCgALL, Opt->priCgALL, Opt->gold, 
                          Opt->cs, Opt->mix_frac_floor)) {
      SUMA_S_Err("Failed in class stats");
      SUMA_RETURN(0);
   }
   if (Opt->debug) 
      SUMA_show_Class_Stat(Opt->cs, 
                           "Posterior Weighted Class Stat At Input:\n", NULL);
   
   /* To begin iterations, we should have class stats and pstCgALL. 
      Also, need an initial cset if B > 0.0  */
   for (iter=0; iter<Opt->N_main; ++iter) {
      if (Opt->debug) {
         INFO_message("Iteration %d memory check:\n",iter);MCHECK;
      }
      /* improve parameters based on edge energy */
      if (Opt->edge) {
         double en;
         float vv=1.0;
         int *UseK, N_kok;
         THD_3dim_dataset *skelset=NULL, *l_Bset=NULL, *l_aset=NULL;
         NEW_SHORTY(Opt->aset, Opt->cs->N_label*(Opt->cs->N_label-1)/2, 
                     "skelly", skelset);
         UseK = (int *)SUMA_calloc(Opt->cs->N_label, sizeof(int));
         if ((N_kok = SUMA_Class_k_Selector(Opt->cs, "classes_string", 
                                          "CSF; GM; WM", UseK))<0) {
            SUMA_S_Err("Failed to find classes");
            SUMA_RETURN(0);
         }
         if (1) {
            /* It should be the case that edge energy should not be affected
            by the presence of bias field (METH2), for now, I will
            pass a constant field here for testing */
            NEW_SHORTY(Opt->aset, 1, "l_Bset", l_Bset);
            if (!SUMA_InitDset(l_Bset, &vv, 1, Opt->cmask, 1)) {
                     SUMA_S_Err("Failed to initialize l_Bset");
                     SUMA_RETURN(0);
            }
            if (iter == 0) l_aset = Opt->aset;
            else l_aset = Opt->xset; 
         } else { /* old approach */
            l_aset = Opt->aset; l_Bset = Opt->Bset;
         }  
         en = SUMA_DsetEdgeEnergy(l_aset, Opt->cset, 
                                  Opt->cmask, l_Bset, 
                                  skelset, Opt->cs, Opt->edge,
                                  UseK, N_kok); 
         SUMA_Seg_Write_Dset(Opt->proot, "PreSkel", skelset, iter, Opt->hist);
         SUMA_S_Notev("Edge Enenergy, Pre MAP : %f\n", en);
         
         #if 1
         if (!SUMA_MAP_EdgeEnergy(  l_aset, Opt->cmask, Opt->cmask_count,
                                    l_Bset, Opt->cs, 
                                    Opt->cset, Opt->edge, 
                                    Opt->priCgALL, Opt->pCgN,
                                    Opt->B, Opt->T, 0.4, 0.4,
                                    Opt)) {
            SUMA_S_Err("Failed in MAP_EdgeEnergy");
            exit(1);
         }  
         
         en = SUMA_DsetEdgeEnergy(l_aset, Opt->cset, 
                                  Opt->cmask, 
                                  l_Bset, skelset, Opt->cs, Opt->edge,
                                  UseK, N_kok);
         SUMA_Seg_Write_Dset(Opt->proot, "PstSkel", skelset, iter, Opt->hist); 
         SUMA_S_Notev("Edge Enenergy, Post MAP : %f\n", en);
         #endif

         DSET_delete(skelset); skelset=NULL;
         if (l_Bset && l_Bset != Opt->Bset) DSET_delete(l_Bset); l_Bset=NULL;
         SUMA_ifree(UseK);
      }

      if (Opt->bias_param > 0) {
         if (Opt->debug > 1) 
            SUMA_S_Notev("Wells Bias field correction, FWHM %f, iteration %d\n", 
                           Opt->bias_param, iter);
         if (!strcmp(Opt->bias_meth,"Wells")) { 
            if (!(SUMA_estimate_bias_field_Wells(Opt, Opt->cmask, Opt->cs,
                                             Opt->bias_param, Opt->bias_classes,
                                             Opt->aset, Opt->pstCgALL, 
                                             &Opt->Bset ))) {
               SUMA_S_Err("Failed to estimate bias");
               SUMA_RETURN(0);
            }
         } else {
            SUMA_S_Errv("Only Wells is allowed for now, have %s\n", 
                     Opt->bias_meth);
            SUMA_RETURN(0);
         }
         
         if (!(SUMA_apply_bias_field(Opt, Opt->aset, Opt->Bset,
                                &Opt->xset))) {
            SUMA_S_Err("Failed to apply field");
            SUMA_RETURN(0);
         }
      } else {
         if (iter == 0) {
            if (Opt->debug > 1) 
               SUMA_S_Note("Skipping bias field correction");
            if (!Opt->xset) Opt->xset = EDIT_full_copy(Opt->aset, Opt->xrefix);
            if (!Opt->Bset) {
               float vv=1.0;
               NEW_SHORTY(Opt->aset,1, "ConstantField", Opt->Bset);
               if (!SUMA_InitDset(Opt->Bset, &vv, 1, Opt->cmask, 1)) {
                  SUMA_S_Err("Failed to initialize Bset");
                  SUMA_RETURN(0);
               } 
            }
         }
      }

      
      
      if (Opt->B > 0) {
         if (Opt->debug > 1 && iter==0) {
            SUMA_Seg_Write_Dset(Opt->proot, "MAPlabel.-1", Opt->cset, 
                                 -1, Opt->hist);
         }
         if (!(SUMA_MAP_labels(Opt->xset, Opt->cmask, 
                               Opt->cs, 6, Opt->priCgALL, &Opt->cset, 
                               &Opt->pCgN, Opt))) {
            SUMA_S_Err("Failed in SUMA_MAP_labels");
            SUMA_RETURN(0);
         }
         if (Opt->debug > 1) {
            SUMA_Seg_Write_Dset(Opt->proot, "MAPlabel", Opt->cset, 
                                iter, Opt->hist);
            SUMA_Seg_Write_Dset(Opt->proot, "pCgN", Opt->pCgN, iter, 
                                 Opt->hist);
         }
         AFNI_FEED(Opt->ps->cs, "MAPlabel", iter, Opt->cset);
      }
                                  
      if (!(SUMA_pst_C_giv_ALL(Opt->xset, 
                Opt->cmask, Opt->cmask_count,
                Opt->cs,  
                Opt->priCgALL, Opt->pCgN,
                Opt->B, Opt->T, 
                (!Opt->mixopt || strcmp(Opt->mixopt,"IGNORE")) ? 1:0,
                               &Opt->pstCgALL))) {
         SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL");
         SUMA_RETURN(0);
      }
      if (Opt->debug > 1) {
         SUMA_Seg_Write_Dset(Opt->proot, "pstCgALL", Opt->pstCgALL, 
                            iter, Opt->hist);
      }
      
      if (Opt->B <= 0.0f) { /* no need if B > 0 because cset is 
                              set in SUMA_MAP_labels*/
         /* update class based on max(Opt->pstCgALL) */
         if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, 
                                    Opt->cmask, &Opt->cset))) { 
            SUMA_S_Err("Failed in assign_classes");
            SUMA_RETURN(0);
         }
      }
      
      /* Now update class stats  */
      if (!SUMA_Class_stats(  Opt->xset, Opt->cset, 
                              Opt->cmask, Opt->cmask_count,
                              Opt->pstCgALL, Opt->priCgALL, Opt->gold, 
                              Opt->cs, Opt->mix_frac_floor)) {
         SUMA_S_Err("Failed in class stats");
         SUMA_RETURN(0);
      }
   

      
      if (Opt->debug || Opt->gold || Opt->gold_bias) {
         double bad_bias_thresh, bias_bad_count;
         char *sbig=NULL;
         sprintf(sinf, "Class Stat iter %d:\n", iter+1);
         if (iter == Opt->N_main-1 || Opt->debug) {
            SUMA_show_Class_Stat(Opt->cs, sinf, NULL);
            if (Opt->proot) sprintf(sreport, 
                     "%s/ClassStat.i%02d%s.txt", Opt->proot, 
                                  iter+1, (iter==Opt->N_main-1) ? ".FINAL":"");
            else snprintf(sreport, 500, 
                     "%s.ClassStat.i%02d%s.txt",  
                     Opt->prefix, iter+1, (iter==Opt->N_main-1) ? ".FINAL":"");
            sbig = SUMA_append_replace_string(Opt->hist, sinf,"\n",0);
            SUMA_show_Class_Stat(Opt->cs, sbig, sreport);
            SUMA_ifree(sbig);
         }
         
         /* Report on bias correction */
         bad_bias_thresh = 0.06;
         if ((Opt->gold_bias && Opt->Bset) && 
             (iter == Opt->N_main-1 || Opt->debug)) {
            FILE *fout = fopen(sreport,"a");
            bias_bad_count = SUMA_CompareBiasDsets(Opt->gold_bias, Opt->Bset, 
                                 Opt->cmask, Opt->cmask_count, 
                                 bad_bias_thresh, NULL);
            SUMA_S_Notev("bad_count at thresh %f = %f%% of mask.\n",
                  bad_bias_thresh, bias_bad_count);
            if (fout) {
               fprintf(fout, "bad_count at thresh %f = %f%% of mask.\n",
                  bad_bias_thresh, bias_bad_count);
               fclose(fout); fout = NULL;
            }
         }
      }
      
   }
   
   if (Opt->Split) {
      THD_3dim_dataset *Gcset=NULL;
      THD_3dim_dataset *GpstCgALL=NULL;
      /* need to put things back */
      if (!SUMA_Regroup_classes(Opt, 
                        Opt->cs->label, Opt->cs->N_label, Opt->cs->keys,
                        Opt->Gcs->label, Opt->Gcs->N_label, Opt->Gcs->keys,
                        Opt->cmask, Opt->pstCgALL, Opt->cset,
                        &GpstCgALL, &Gcset)) {
      }
      /* switch dsets */
      DSET_delete(Opt->pstCgALL); Opt->pstCgALL = GpstCgALL; GpstCgALL = NULL;
      DSET_delete(Opt->cset); Opt->cset = Gcset; Gcset = NULL;
   }
   
   SUMA_RETURN(1);
}
Ejemplo n.º 11
0
int main( int argc , char *argv[] )
{
   int nx,ny,nz , nxyz , ii,kk , num1,num2 , num_tt=0 , iv ,
       piece , fim_offset;
   float dx,dy,dz , dxyz ,
         num1_inv=0.0 , num2_inv , num1m1_inv=0.0 , num2m1_inv , dof ,
         dd,tt,q1,q2 , f1,f2 , tt_max=0.0 ;
   THD_3dim_dataset *dset=NULL , *new_dset=NULL ;
   THD_3dim_dataset * base_dset;
   float *av1 , *av2 , *sd1 , *sd2 , *ffim , *gfim ;
   float *base_ary=NULL;

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

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

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

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

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

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

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

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

   TT_read_opts( argc , argv ) ;

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

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

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

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

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

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

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

   new_dset = EDIT_empty_copy( dset ) ;

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

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

   iv = DSET_PRINCIPAL_VALUE(dset) ;

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

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

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

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

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

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

   THD_delete_3dim_dataset( dset , False ) ; dset = NULL ;

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

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

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

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

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

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

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

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

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

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

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

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

     dof_dset = EDIT_empty_copy( new_dset ) ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

      fim_offset = 0 ;

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

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

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

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

         /** read in the data **/

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

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

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

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

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

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

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

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

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

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

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

         /* accumulate into av2 and sd2 */

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

      }  /* end of loop over set2 datasets */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   exit(0) ;
}
Ejemplo n.º 12
0
int main(int argc, char **argv)
{
   static char FuncName[]={"3dGenFeatureDist"};
   SEG_OPTS *Opt=NULL;
   char *atr=NULL, sbuf[512], *methods=NULL;
   int  cc, /* class counter */
        kk, /* key counter */
        aa, /* feature counter */
        nn, /* sub-brick index */
        vv, /* voxel index */
        ss, /* subjects counter */
        iii, /* dummy counter */
        nbins, /* number of bins */
        *ifeat=NULL, key, 
        **N_alloc_FCset=NULL, /* Number of values allocated for each 
                                 vector in FCset */
        **N_FCset=NULL, /* Number of filled values for each vector in FCset */ 
        N_ffalloc=0, N_ff, isneg=0,
        missfeatwarn=-1 /* Missing feature warning for some subject */;
   float fsf=0.0, fsb=0.0, 
         ***FCset=NULL, /* Table holding samples for each feature/class combo */ 
         hrange[2]={-3.0, 3.0}, bwidth1=0.05, bwidth=0.0,
         *ff=NULL;
   short *sf=NULL, *sb=NULL;
   byte **masks=NULL;
   SUMA_HIST ***hh=NULL, **hf=NULL;
   double ff_m, ff_s;   
   SUMA_Boolean LocalHead = NOPE;

   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;
   
   SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   Opt = GenFeatureDist_Default(argv,  argc);
   Opt = GenFeatureDist_ParseInput (Opt, argv,  argc);
   Opt->hist = tross_commandline( FuncName , argc , argv ) ;
   
   if (!GenFeatureDist_CheckOpts(Opt)) {
      ERROR_exit("Failed on option check");
   }
   
   /* labeltable? */
   if (Opt->labeltable_name) {
      Dtable *vl_dtable=NULL;
      char *labeltable_str=NULL;
      
      /* read the table */
      if (!(labeltable_str = AFNI_suck_file( Opt->labeltable_name))) {
         ERROR_exit("Failed to read %s", Opt->labeltable_name);
      }
      if (!(vl_dtable = Dtable_from_nimlstring(labeltable_str))) {
         ERROR_exit("Could not parse labeltable");
      }
      /* make sure all classes are in the labeltable */
      for (cc=0; cc<Opt->clss->num; ++cc) {
         if ((key = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[cc]))<0){
            ERROR_exit("Key not found in %s for %s ", 
                        Opt->labeltable_name, Opt->clss->str[cc]);
         }
         if (Opt->keys) {
            if (Opt->keys[cc]!=key) {
               ERROR_exit("Key mismatch %d %d", Opt->keys[cc], key);
            }
         }   
      }   
      if (!Opt->keys) { /* get them from table */
         Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int));
         for (cc=0; cc<Opt->clss->num; ++cc) {
            if ((key = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[cc]))<0){
               ERROR_exit("(should noy happen) Key not found in %s for %s ", 
                           Opt->labeltable_name, Opt->clss->str[cc]);
            }
            Opt->keys[cc] = key;
         }
      }
      destroy_Dtable(vl_dtable); vl_dtable=NULL;
   } 
   
   if (!Opt->keys) {
      /* add default keys */
      SUMA_S_Note("Keys not available, assuming defaults");
      Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int));
      for (cc=0; cc<Opt->clss->num; ++cc) {
         Opt->keys[cc] = cc+1;
      }
   }
   
   /* Show the match between keys and classes */
   SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys);
   /* For each feature, each class, collect the values */
   SUMA_S_Notev("Collecting data from %d subjects\n", Opt->sig_names->num);
   
   missfeatwarn = -1;
   for (ss=0; ss<Opt->sig_names->num; ++ss) { /* for each subject */
      /* load the input data */   
      if (!(Opt->sig = Seg_load_dset( Opt->sig_names->str[ss] ))) {      
         exit(1);
      }
      if (Opt->debug > 1) {
         SUMA_S_Notev("Have %d sub-bricks in signatures of dude %d\n",
                   DSET_NVALS(Opt->sig), ss);
      }
      
      if (ss == 0) { /* some setup based on initial grid */
         if (!Opt->feats) { /* create features from signature */
            char *allfeats=NULL;
            for (nn=0; nn<DSET_NVALS(Opt->sig); ++nn) {
               allfeats = 
                  SUMA_append_replace_string(allfeats,
                                          DSET_BRICK_LABEL(Opt->sig,nn),";", 1);
            }
            Opt->feats = NI_strict_decode_string_list(allfeats,";, ");
            SUMA_free(allfeats); allfeats=NULL;
         } 

         SUMA_S_Notev("Have to work with %d classes, %d features\n",
                      Opt->clss->num, Opt->feats->num);

         SUMA_S_Note("Initializing storage");
         /* Receptacles for all observations for each feature 
            and class combination */
         FCset = (float ***)SUMA_calloc(Opt->feats->num, sizeof(float **));
         N_FCset = (int **)SUMA_calloc(Opt->feats->num, sizeof(int *));
         N_alloc_FCset = (int **)SUMA_calloc(Opt->feats->num, sizeof(int *));
         ifeat = (int *)SUMA_calloc(Opt->feats->num, sizeof(int));
         for (aa=0; aa<Opt->feats->num; ++aa) {
            FCset[aa] = (float **)calloc(Opt->clss->num, sizeof(float *));
            N_FCset[aa] = (int *)SUMA_calloc(Opt->clss->num, sizeof(int));
            N_alloc_FCset[aa] = (int *)SUMA_calloc(Opt->clss->num, sizeof(int));
         }
         masks = (byte **)SUMA_calloc(Opt->sig_names->num, sizeof (byte *));

         /* Fix VoxDbg */
         if (Opt->VoxDbg >= 0) {
            Vox1D2Vox3D(Opt->VoxDbg, 
                        DSET_NX(Opt->sig), DSET_NX(Opt->sig)*DSET_NY(Opt->sig),
                        Opt->VoxDbg3);
         } else if (Opt->VoxDbg3[0]>=0) {
            Opt->VoxDbg =  Opt->VoxDbg3[0] + 
                           Opt->VoxDbg3[1]*DSET_NX(Opt->sig) +
                           Opt->VoxDbg3[2]*DSET_NX(Opt->sig)*DSET_NY(Opt->sig);
         }
      }
      
      /* allocate for mask which will be non-zero whenever a voxel is in at least         1 mask. It will have the 1st assignment */
      masks[ss] = (byte *)SUMA_calloc(DSET_NVOX(Opt->sig), sizeof(byte));
      
      /* create mapping between feature names and sub-briks */
      for (aa=0; aa<Opt->feats->num; ++aa) {
         ifeat[aa] = 0;
         while (ifeat[aa] < DSET_NVALS(Opt->sig) &&
            strcmp(DSET_BRICK_LABEL(Opt->sig,ifeat[aa]),
                   Opt->feats->str[aa])) ++ifeat[aa];
         if (ifeat[aa] >= DSET_NVALS(Opt->sig)) ifeat[aa]=-1;
         if (Opt->debug > 1) {
            SUMA_S_Notev("Have feature %s in sub-brick %d\n",
                      Opt->feats->str[aa], ifeat[aa]);
         }
      }
      
      SUMA_S_Notev("Loading sample classes for subject #%d\n", ss);
      if (!(Opt->samp = Seg_load_dset( Opt->samp_names->str[ss] ))) {      
         exit(1);
      }
      
      if (THD_dataset_mismatch(Opt->samp, Opt->sig)) {
         SUMA_S_Err(
            "Grid mismatch between -samp [%dx%dx%d] and \n"
            "                      -sig  [%dx%dx%d] volumes for pair #%d\n", 
            DSET_NX(Opt->samp), DSET_NY(Opt->samp), DSET_NZ(Opt->samp),
            DSET_NX(Opt->sig), DSET_NY(Opt->sig), DSET_NZ(Opt->sig), ss);
         exit(1);
      }
      
      if (Opt->debug > 1) {
         SUMA_S_Notev("Have %d sub-bricks in samples of dude %d\n", 
                     DSET_NVALS(Opt->samp), ss);
      }
      
      /* Now collect features for each class */
      SUMA_S_Note("Collecting features for each class");
      for (cc=0; cc<Opt->clss->num; ++cc) {
         if (Opt->debug > 1) {
            SUMA_S_Notev("Working class %s\n", Opt->clss->str[cc]);
         }
         key = Opt->keys[cc];
         for (nn=0; nn<DSET_NVALS(Opt->samp); ++nn) {
            if (Opt->debug > 2) {
               SUMA_S_Notev("Looking for key %d for class %s in sb %d\n",
                  key, Opt->clss->str[cc], nn);
            }
            sb = (short *)DSET_ARRAY(Opt->samp,nn);
            fsb = DSET_BRICK_FACTOR(Opt->samp,nn);
            if (fsb == 0.0) fsb = 1.0;
            if (fsb != 1.0) {
               SUMA_S_Err("Non-integral dset, possibly.");
               exit(1);
            }
            for (vv=0; vv<DSET_NVOX(Opt->samp); ++vv) {
               if (sb[vv] == key) {
                  for (aa=0; aa<Opt->feats->num; ++aa) {
                     if (ifeat[aa]>-1) {
                        if (N_alloc_FCset[aa][cc] <= N_FCset[aa][cc]) {
                           N_alloc_FCset[aa][cc] += 10000;
                           FCset[aa][cc] = 
                              (float*)SUMA_realloc(FCset[aa][cc],
                                           N_alloc_FCset[aa][cc]*sizeof(float));
                        }
                        sf = (short *)DSET_ARRAY(Opt->sig, ifeat[aa]);
                        fsf = DSET_BRICK_FACTOR(Opt->sig,ifeat[aa]);
                        if (fsf == 0.0) fsf = 1.0;
                        FCset[aa][cc][N_FCset[aa][cc]] = sf[vv]*fsf; 
                        ++N_FCset[aa][cc];
                        if (!masks[ss][vv]) {
                           masks[ss][vv] = (short)key; /* fcfs */
                                       /* in case we exceed short range */
                           if (masks[ss][vv]) masks[ss][vv] = 1; 
                        }
                     } else {
                        if (missfeatwarn != ss) {
                           SUMA_S_Warnv("Feature %s not found in subject %d\n",
                                 Opt->feats->str[aa], ss);
                           missfeatwarn = ss;
                        }
                     }  
                  }
               }  
            }
         }
      }
      DSET_delete(Opt->sig); Opt->sig=NULL;
      DSET_delete(Opt->samp); Opt->samp=NULL;
   } /* loop across all subjects */
   
   /* compute histograms of features across all classes and save them */
   hf = (SUMA_HIST **)SUMA_calloc(Opt->feats->num, sizeof(SUMA_HIST *));
   SUMA_S_Note("Computing histograms of features across all classes");
   ff = NULL; N_ffalloc = 0;
   for (aa=0; aa<Opt->feats->num; ++aa) {
      N_ff=0;
      for (cc=0; cc<Opt->clss->num; ++cc) {
         N_ff += N_FCset[aa][cc]; /* more than I need because same voxel 
                                     can belong to multiple classes, but just 
                                     to be safe */
      }
      if (N_ffalloc < N_ff) {
         N_ffalloc = N_ff;
         if (ff) SUMA_free(ff); ff=NULL;
         if (!(ff = (float*)SUMA_calloc(N_ff, sizeof(float)))) {
            SUMA_S_Crit("Failed to allocate");
            exit(1);
         }
      } 
      N_ff=0; isneg = 0; ff_m=0.0;
      for (ss=0; ss<Opt->sig_names->num; ++ss) { /* Once again, unfortunately  */
         /* load the input data */   
         if (!(Opt->sig = Seg_load_dset( Opt->sig_names->str[ss] ))) {      
            exit(1);
         }
         if (Opt->debug > 1) {
            SUMA_S_Notev("Have %d sub-bricks in signatures of dude %d\n",
                      DSET_NVALS(Opt->sig), ss);
         }
         if (ifeat[aa]>-1) {
            sb = (short *)DSET_ARRAY(Opt->sig,ifeat[aa]);
            fsb = DSET_BRICK_FACTOR(Opt->sig,ifeat[aa]);
            if (fsb == 0.0) fsb = 1.0;
            for (vv=0; vv<DSET_NVOX(Opt->sig); ++vv) {
               if (masks[ss][vv]) {
                  ff[N_ff] = sb[vv]*fsb;
                  if (ff[N_ff] < 0) ++isneg;
                  ff_m += ff[N_ff];
                  ++N_ff;
               }
            }
         }
         DSET_delete(Opt->sig); Opt->sig=NULL;
      }
      ff_m /= N_ff; ff_s=0.0;
      for (iii=0; iii<N_ff; ++iii) {
          ff_s += SUMA_POW2(ff[iii]-ff_m);
      }
      ff_s = sqrt(ff_s/N_ff);
      sprintf(sbuf, "h(%s)",Opt->feats->str[aa]);
      
      /* Check if you have user specified binning specs */
      bwidth = -1; nbins = -1;
      for (iii=0; iii<Opt->N_hspec; ++iii) {
         if (!strcmp(Opt->feats->str[aa], Opt->hspec[iii]->label)) {
            hrange[0] =  Opt->hspec[iii]->min;
            hrange[1] =  Opt->hspec[iii]->max;
            nbins     =  Opt->hspec[iii]->K;
            bwidth    = 0;
            methods   =  "hands off sir";
            break;
         }
      }
      

         
      if (bwidth < 0) {
         int nmatch = -1;
         /* Check the wildcard option */
         for (iii=0; iii<Opt->N_hspec; ++iii) {
            if ((nmatch = SUMA_is_wild_hspec_label(Opt->hspec[iii]->label))>=0) {
               if (!nmatch || !strncmp(Opt->feats->str[aa], 
                                       Opt->hspec[iii]->label, nmatch)) {
                  SUMA_S_Note("Feature %s matched with hspec %s\n",
                              Opt->feats->str[aa], Opt->hspec[iii]->label);
                  hrange[0] =  Opt->hspec[iii]->min;
                  hrange[1] =  Opt->hspec[iii]->max;
                  nbins     =  Opt->hspec[iii]->K;
                  bwidth    = 0;
                  methods   =  "hands woff sir";
                  break;
               }
            }
         }
      }
      
      if (bwidth < 0) { /* no user specs found */
         nbins = 0;
         methods = "Range|OsciBinWidth";
         if ((float)isneg/(float)N_ff*100.0 > 1.0) {
            hrange[0] =  ff_m-3*ff_s;
            hrange[1] =  ff_m+3*ff_s;
            bwidth = bwidth1*ff_s;
         } else if (ff_m-3*ff_s > 0) {
            hrange[0] =  ff_m-3*ff_s;
            hrange[1] =  ff_m+3*ff_s;
            bwidth = bwidth1*ff_s;
         } else {
            hrange[0] =  0;
            hrange[1] =  6.0*ff_s/2.0;
            bwidth = bwidth1*ff_s/2.0;
         }
      }
      SUMA_S_Notev("Feature %s: mean %f, std %f\n"
                   "Hist params: [%f %f], binwidth %f\n", 
                        Opt->feats->str[aa], ff_m, ff_s,
                        hrange[0], hrange[1], bwidth);
      if (!(hf[aa] = SUMA_hist_opt(ff, N_ff, nbins, bwidth, hrange, sbuf, 1, 
                                    0.1, methods))) {
         SUMA_S_Errv("Failed to generate histogram for %s. \n"
                     "This will cause trouble at classification.\n",
                     Opt->feats->str[aa]);
      } else {
         if ((float)hf[aa]->N_ignored/(float)hf[aa]->n > 0.05) {
            SUMA_S_Warnv("For histogram %s, %.2f%% of the samples were\n"
                         "ignored for being outside the range [%f %f]\n",
                   Opt->feats->str[aa],
                   100*(float)hf[aa]->N_ignored/(float)hf[aa]->n, 
                   hf[aa]->min, hf[aa]->max);
         }
         if (Opt->debug > 1) SUMA_Show_hist(hf[aa], 1, NULL);
         /* save the histogram */
         if (!SUMA_write_hist(hf[aa],
                  SUMA_hist_fname(Opt->proot, 
                                  Opt->feats->str[aa], NULL, 0))) {
            SUMA_S_Errv("Failed to write histog to %s\n", sbuf);
         } 
      }
   }  
   if (ff) SUMA_free(ff); ff = NULL;
   
   
   /* Compute histograms of features per class && save them*/
   hh = (SUMA_HIST ***)SUMA_calloc(Opt->feats->num, sizeof(SUMA_HIST **));
   for (aa=0; aa<Opt->feats->num; ++aa) {
      hh[aa] = (SUMA_HIST **)SUMA_calloc(Opt->clss->num, sizeof(SUMA_HIST *));
   }

   SUMA_S_Note("Computing histograms of features per class");
   for (cc=0; cc<Opt->clss->num; ++cc) {
      if (N_FCset[0][cc] < 10) {
         SUMA_S_Errv("Requested class %s (%d) has just %d samples.\n"
                     "Not enough to grease your pan.\n",
                     Opt->clss->str[cc], Opt->keys[cc], N_FCset[0][cc]);
         exit(1);
      }
      for (aa=0; aa<Opt->feats->num; ++aa) {
         sprintf(sbuf, "h(%s|%s)",Opt->feats->str[aa], Opt->clss->str[cc]);
         hrange[0] = hf[aa]->min; hrange[1] = hf[aa]->max; 
         /* Do not optimize hist range and binwidth anymore, 
            but allow smoothing. This is needed when a particular 
            class has very few samples */
         if (!(hh[aa][cc] = SUMA_hist_opt(FCset[aa][cc], N_FCset[aa][cc], 
                                    hf[aa]->K, hf[aa]->W, 
                                    hrange, sbuf, 1,
                                    0.1, "OsciSmooth"))) {
            SUMA_S_Errv("Failed to generate histogram for %s|%s. \n"
                        "This will cause trouble at classification.\n",
                        Opt->feats->str[aa], Opt->clss->str[cc])
         } else {
            if (Opt->debug > 1) SUMA_Show_hist(hh[aa][cc], 1, NULL);
            /* save the histogram */
            if (!SUMA_write_hist(hh[aa][cc],
                     SUMA_hist_fname(Opt->proot, 
                              Opt->feats->str[aa], Opt->clss->str[cc], 0))) {
               SUMA_S_Errv("Failed to write histog to %s\n", sbuf);
            } 
         }
      }
   }
   
   SUMA_S_Note("Computing Correlation matrices");
   /* L2 normalize all of FCset */
   for (cc=0; cc<Opt->clss->num; ++cc) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         THD_normalize(N_FCset[aa][cc], FCset[aa][cc]);
      }
   }
   
   {
      NI_element **CC=NULL;
      float *fm=NULL, *fn=NULL;
      NI_element *nel = NULL;
      int suc;
      
   /* Compute the correlation matrices for each class */
   CC = (NI_element **) SUMA_calloc(Opt->clss->num, sizeof(NI_element *));
   
   for(cc=0; cc<Opt->clss->num; ++cc) {
      sprintf(sbuf, "CorrMat(%s)", Opt->clss->str[cc]);
      CC[cc] = NI_new_data_element(sbuf, Opt->feats->num);
      NI_set_attribute(CC[cc],"Measure","correlation");
      atr = SUMA_NI_str_ar_2_comp_str(Opt->feats, " ; ");
      NI_set_attribute(CC[cc],"ColumnLabels", atr);SUMA_free(atr); atr = NULL;
      atr = SUMA_HistString (FuncName, argc, argv, NULL);
      NI_set_attribute(CC[cc],"CommandLine", atr);SUMA_free(atr); atr = NULL;
      for (aa=0; aa<Opt->feats->num; ++aa) {
         NI_add_column_stride ( CC[cc], NI_FLOAT, NULL, 1 );
      }
      for (aa=0; aa<Opt->feats->num; ++aa) {
         fm = (float*)CC[cc]->vec[aa];
         for (iii=0; iii<aa; ++iii) fm[iii] = 0.0; /* will fill later */
         fm[aa]=1.0;
         for (iii=aa+1; iii<Opt->feats->num; ++iii) {
            if (N_FCset[aa][cc]!=N_FCset[iii][cc]) {
               SUMA_S_Errv("Sanity check failed, %d != %d\n",
                              N_FCset[aa][cc], N_FCset[iii][cc]);
            }
            SUMA_DOTP_VEC(FCset[aa][cc], FCset[iii][cc], 
                          fm[iii], N_FCset[aa][cc], 
                          float, float);
         }
      }
      /* Now fill the remainder */
      for (aa=0; aa<Opt->feats->num; ++aa) {
         fm = (float*)CC[cc]->vec[aa];
         for (iii=0; iii<aa; ++iii) {
            fn = (float*)CC[cc]->vec[iii];
            fm[iii] = fn[aa];
         }
      }
      snprintf(sbuf, 510, "file:%s.niml.cormat", 
               SUMA_corrmat_fname(Opt->proot, Opt->clss->str[cc], 0));
      NEL_WRITE_TXH(CC[cc], sbuf, suc);
   }
   
   }
   /* free everything */
   if (FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         for (cc=0; cc<Opt->clss->num; ++cc) {
            if (FCset[aa][cc]) SUMA_free(FCset[aa][cc]);
         }
         SUMA_free(FCset[aa]); 
      }
      SUMA_free(FCset); FCset=NULL;
   }
   if (N_FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         SUMA_free(N_FCset[aa]);
      }
      SUMA_free(N_FCset); N_FCset=NULL;
   }
   if (N_alloc_FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         SUMA_free(N_alloc_FCset[aa]);
      }
      SUMA_free(N_alloc_FCset); N_alloc_FCset=NULL;
   }
   if (ifeat) SUMA_free(ifeat); ifeat=NULL;
   
   if (hh) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         for (cc=0; cc<Opt->clss->num; ++cc) {
            if (hh[aa][cc]) hh[aa][cc] = SUMA_Free_hist(hh[aa][cc]);
         }
         SUMA_free(hh[aa]);
      }
      SUMA_free(hh); hh=NULL;
   }
   
   if (hf) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         if (hf[aa]) hf[aa] = SUMA_Free_hist(hf[aa]);
      }
      SUMA_free(hf); hf=NULL;
   }
   
   if (masks) {
      for (ss=0; ss<Opt->sig_names->num; ++ss) {
         if (masks[ss]) SUMA_free(masks[ss]);
      }
      masks[ss]=NULL;
   }
   
   SUMA_S_Notev("\n"
                "Consider running this script to examine the distributions:\n"
                "   @ExamineGenFeatDists -fdir %s -odir %s\n",
                Opt->proot, Opt->proot);
   
   /* all done, free */
   Opt = free_SegOpts(Opt);
   
   PRINT_COMPILE_DATE ; exit(0);
}
Ejemplo n.º 13
0
void UC_read_opts( int argc , char * argv[] )
{
   int nopt = 1 ;
   float val ;
   int  kk, nxyz, mm,nn ;
   float * vv , * bb ;

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

      /**** -verbose ****/

      if( strncmp(argv[nopt],"-verbose",5) == 0 ){
         UC_be_quiet = 0 ;
         nopt++ ; continue ;
      }

      /**** -ref file.1D ****/

      if( strncmp(argv[nopt],"-ref",4) == 0 ){
         MRI_IMAGE * im ;
         nopt++ ;
         if( nopt >= argc ) UC_syntax("-ref needs an argument!") ;
         im = mri_read( argv[nopt] ) ;
         if( im == NULL ) UC_syntax("Can't read -ref file!") ;
         if( im->kind == MRI_float ){
            UC_ref = im ;
         } else {
            UC_ref = mri_to_float(im) ; mri_free(im) ;
         }
         im = mri_transpose(UC_ref) ; mri_free(UC_ref) ; UC_ref = im ;
         nopt++ ; continue ;
      }

      /**** -prefix prefix ****/

      if( strncmp(argv[nopt],"-prefix",6) == 0 ){
         nopt++ ;
         if( nopt >= argc ) UC_syntax("-prefix needs an argument!") ;
         MCW_strncpy( UC_prefix , argv[nopt++] , THD_MAX_PREFIX ) ;
         continue ;
      }

      /**** -mask mset ****/

      if( strncmp(argv[nopt],"-mask",5) == 0 ){
         THD_3dim_dataset * mset ; int ii ;
         nopt++ ;
         if( nopt >= argc ) UC_syntax("need arguments after -mask!") ;
         mset = THD_open_dataset( argv[nopt] ) ;
         if( mset == NULL ) UC_syntax("can't open -mask dataset!") ;
         UC_mask = THD_makemask( mset , 0 , 1.0,0.0 ) ;
         UC_mask_nvox = DSET_NVOX(mset) ;
         DSET_delete(mset) ;
         if( UC_mask == NULL ) UC_syntax("can't use -mask dataset!") ;
         UC_mask_hits = THD_countmask( UC_mask_nvox , UC_mask ) ;
         if( UC_mask_hits == 0 ) UC_syntax("mask is all zeros!") ;
         if( !UC_be_quiet ) printf("--- %d voxels in mask\n",UC_mask_hits) ;
         nopt++ ; continue ;
      }

      /**** unknown switch ****/

      fprintf(stderr,"\n*** unrecognized option %s\n",argv[nopt]) ;
      exit(1) ;

   }  /* end of loop over options */

   /*--- a simple consistency check ---*/

   /*--- last input is dataset name ---*/

   if( nopt >= argc ) UC_syntax("no input dataset name?") ;

   UC_dset = THD_open_dataset( argv[nopt] ) ;
   if( !ISVALID_3DIM_DATASET(UC_dset) ){
      fprintf(stderr,"\n*** can't open dataset file %s\n",argv[nopt]) ;
      exit(1) ;
   }

   nxyz = DSET_NVOX(UC_dset) ;
   if( UC_mask != NULL && nxyz != UC_mask_nvox )
      UC_syntax("mask and input dataset size mismatch!") ;

   /*--- load vectors ---*/

   UC_nvec = (UC_mask_hits > 0) ? UC_mask_hits : nxyz ;
   UC_vdim = DSET_NVALS(UC_dset) ;
   if( UC_vdim < 4 )
      UC_syntax("input dataset needs at least 4 sub-bricks!") ;

   if( UC_ref == NULL || UC_ref->nx < UC_vdim )
      UC_syntax("input ref not long enough for input dataset!") ;

   vv     = (float *) malloc( sizeof(float) * UC_nvec * UC_vdim ) ;
   UC_vec = (float **) malloc( sizeof(float *) * UC_nvec ) ;
   for( kk=0 ; kk < UC_nvec ; kk++ ) UC_vec[kk] = vv + (kk*UC_vdim) ;

   if( !UC_be_quiet ) printf("--- reading dataset\n") ;
   DSET_load(UC_dset) ;  CHECK_LOAD_ERROR(UC_dset) ;

   /* copy brick data into float storage */

   if( !UC_be_quiet ) printf("--- loading vectors\n") ;

   bb = (float *) malloc( sizeof(float) * nxyz ) ;
   for( mm=0 ; mm < UC_vdim ; mm++ ){

      EDIT_coerce_type( nxyz , DSET_BRICK_TYPE(UC_dset,mm) ,
                               DSET_ARRAY(UC_dset,mm) ,
                        MRI_float , bb ) ;

      DSET_unload_one( UC_dset , mm ) ;

      if( UC_mask == NULL ){
         for( kk=0 ; kk < nxyz ; kk++ ) UC_vec[kk][mm] = bb[kk] ;
      } else {
         for( nn=kk=0 ; kk < nxyz ; kk++ )
            if( UC_mask[kk] ) UC_vec[nn++][mm] = bb[kk] ;
      }
   }
   free(bb) ; DSET_unload( UC_dset ) ;

   /* detrend and normalize vectors */

   if( !UC_be_quiet ) printf("--- normalizing vectors\n") ;

   for( kk=0 ; kk < UC_nvec ; kk++ )
      normalize( UC_vdim , UC_vec[kk] ) ;

   for( kk=0 ; kk < UC_ref->ny ; kk++ )
      normalize( UC_vdim , MRI_FLOAT_PTR(UC_ref) + kk*UC_ref->nx ) ;

   return ;
}
Ejemplo n.º 14
0
/*! compute the overall minimum and maximum voxel values for a dataset */
int main( int argc , char * argv[] )
{
   THD_3dim_dataset * old_dset , * new_dset ;  /* input and output datasets */
   int nopt, nbriks;
   int slow_flag, quick_flag, min_flag, max_flag, mean_flag, 
       automask,count_flag, sum_flag, var_flag, absolute_flag;
   int positive_flag, negative_flag, zero_flag, nan_flag, perc_flag, vol_flag;

   byte * mmm=NULL ;
   int    mmvox=0 ;
   int nxyz, i;
   float *dvec = NULL, mmin=0.0, mmax=0.0;
   int N_mp;
   double *mpv=NULL, *perc = NULL;
   double mp =0.0f, mp0 = 0.0f, mps = 0.0f, mp1 = 0.0f, di =0.0f ;
   byte *mmf = NULL;
   MRI_IMAGE *anat_im = NULL;
   char *mask_dset_name=NULL;

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

   mainENTRY("3dBrickStat main"); machdep(); AFNI_logger("3dBrickStat",argc,argv);
   nopt = 1 ;

   min_flag  = 0;
   max_flag = -1;
   mean_flag = 0;
   sum_flag = 0;
   var_flag = 0;
   slow_flag = 0;
   quick_flag = -1;
   automask = 0;
   count_flag = 0;
   vol_flag = 0;
   positive_flag = -1;
   negative_flag = -1;
   absolute_flag = 0;
   zero_flag = -1;
   nan_flag = -1;
   perc_flag = 0;
   mmin = 1.0;
   mmax = -1.0;
   mask_dset_name = NULL;      
   
   datum = MRI_float;
   while( nopt < argc && argv[nopt][0] == '-' ){
      if( strcmp(argv[nopt],"-help") == 0 ||
          strcmp(argv[nopt],"-h") == 0){
        usage_3dBrickStat(strlen(argv[nopt])> 3 ? 2:1);
        exit(0);
      }
      
      if( strcmp(argv[nopt],"-ver") == 0 ){
        PRINT_VERSION("3dBrickStat"); AUTHOR("Daniel Glen");
        nopt++; continue;
      }

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

      if( strcmp(argv[nopt],"-percentile") == 0 ){
	perc_flag = 1;
        ++nopt;
        if (nopt + 2 >= argc) {
           ERROR_exit( "** Error: Need 3 parameter after -percentile\n"); 
        }
        mp0 = atof(argv[nopt])/100.0f; ++nopt;
        mps = atof(argv[nopt])/100.0f; ++nopt;
        mp1 = atof(argv[nopt])/100.0f; 
        if (mps == 0.0f) {
         ERROR_exit( "** Error: step cannot be 0" ); 
        }
        if (mp0 < 0 || mp0 > 100 || mp1 < 0 || mp1 > 100) {
         ERROR_exit( "** Error: p0 and p1 must be >=0 and <= 100" ); 
        }
        
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-median") == 0 ){
	perc_flag = 1;
        mp0 = 0.50f; 
        mps = 0.01f; 
        mp1 = 0.50f;
        nopt++; continue;
      }

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

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

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

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

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

      if( strcmp(argv[nopt],"-var") == 0 ){
	if (var_flag) {
      ERROR_message("Looks like -stdev is already used.\n"
                    "-var and -stdev are mutually exclusive");
      exit (1);
   }
	var_flag = 1;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-stdev") == 0 ){
	if (var_flag) {
      ERROR_message("Looks like -var is already used.\n"
                    "-var and -stdev are mutually exclusive");
      exit (1);
   }
   var_flag = 2;
        nopt++; continue;
      }

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

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

      if( strcmp(argv[nopt],"-positive") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 1;
	negative_flag = 0;
        zero_flag = 0;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-negative") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 0;
	negative_flag = 1;
        zero_flag = 0;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-zero") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 0;
        negative_flag = 0;
	zero_flag = 1;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-non-positive") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 0;
	negative_flag = 1;
        zero_flag = 1;
        nopt++; continue;
      }
      if( strcmp(argv[nopt],"-non-negative") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 1;
	negative_flag = 0;
        zero_flag = 1;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-non-zero") == 0 ){
        if(positive_flag!=-1) {
          ERROR_exit( "Can not use multiple +/-/0 options");
          
        }
        positive_flag = 1;
	negative_flag = 1;
        zero_flag = 0;
        nopt++; continue;
      }

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

      if( strcmp(argv[nopt],"-nan") == 0 ){
        if(nan_flag!=-1) {
          ERROR_exit( "Can not use both -nan -nonan options");
          
        }
        nan_flag = 1;
        nopt++; continue;
      }

      if( strcmp(argv[nopt],"-nonan") == 0 ){
        if(nan_flag!=-1) {
          ERROR_exit( "Can not use both -nan -nonan options");
          
        }
        nan_flag = 0;
        nopt++; continue;
      }

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

         if( mmm != NULL ){
           ERROR_exit(" ERROR: can't use -autoclip/mask with -mask!");
           
         }
         automask = 1 ; nopt++ ; continue ;
      }

      if( strcmp(argv[nopt],"-mrange") == 0 ){
         if (nopt+2 >= argc) {
            ERROR_exit(" ERROR: Need two values after -mrange");
         }
         mmin = atof(argv[++nopt]);
         mmax = atof(argv[++nopt]);
         if (mmax < mmin) {
            ERROR_exit(
               "1st value in -mrange %s %s should be the smallest one",
               argv[nopt-1], argv[nopt]);
         } 
         nopt++ ; continue ;
      }
      
      if( strcmp(argv[nopt],"-mvalue") == 0 ){
         if (nopt+1 >= argc) {
            ERROR_exit(" ERROR: Need 1 value after -mvalue");
         }
         mmin = atof(argv[++nopt]);
         mmax = mmin ;
         nopt++ ; continue ;
      }
      
      if( strcmp(argv[nopt],"-mask") == 0 ){
         if( mask_dset_name != NULL )
            ERROR_exit(" ERROR: can't have 2 -mask options!");         
         mask_dset_name = argv[++nopt];
         nopt++ ; continue ;
      }

      ERROR_message( " Error - unknown option %s", argv[nopt]);
      suggest_best_prog_option(argv[0], argv[nopt]);
      exit(1);
   }

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      ERROR_message("Too few options");
      usage_3dBrickStat(0);
      exit(1) ;
   }

   if (mask_dset_name) {
      int ninmask = 0;
      THD_3dim_dataset * mask_dset ;
      if( automask ){
        ERROR_exit(" ERROR: can't use -mask with -automask!");
      }
      mask_dset = THD_open_dataset(mask_dset_name) ;
      CHECK_OPEN_ERROR(mask_dset,mask_dset_name) ;
       
      mmm = THD_makemask( mask_dset , 0 , mmin, mmax ) ;
      mmvox = DSET_NVOX( mask_dset ) ;
      ninmask = THD_countmask (mmvox, mmm);
      if (!ninmask) {
         ERROR_exit(" No voxels in mask !");
      }  
      /* text output program, so avoid extras   26 Dec 2013 [rickr] */
      /* INFO_message("%d voxels in mask\n", ninmask); */
      DSET_delete(mask_dset) ; 
   }
         
   if(((mmm!=NULL) && (quick_flag))||(automask &&quick_flag)) {
      if(quick_flag==1)
         WARNING_message( "+++ Warning - can't have quick option with mask");
      quick_flag = 0;
      slow_flag = 1;
   }

  /* if max_flag is not set by user, check if other user options set */
   if(max_flag==-1) {                
     if(min_flag || mean_flag || count_flag || vol_flag || sum_flag
                 || perc_flag || var_flag) 
         max_flag = 0;
      else
	max_flag = 1;                  /* otherwise check only for max */
     }

   if((var_flag==1)||(mean_flag==1)||(count_flag==1)||
      (vol_flag==1)||(absolute_flag==1) ||
      (positive_flag!=-1)||(nan_flag!=-1)||
      (sum_flag == 1)||(perc_flag == 1) || (var_flag==2)) {
          /* mean flag or count_flag implies slow */
     slow_flag = 1;
   }
   
   /* check slow and quick options */
   if((slow_flag)&&(quick_flag!=1))  /* if user asked for slow give it to him */
      quick_flag = 0;
   else
      quick_flag = 1;

   if((max_flag==0)&&(min_flag==0))   /* if the user only asked for mean */
     quick_flag = 0;                  /*  no need to do quick way */

   if((quick_flag) && 
      ((absolute_flag==1)||(positive_flag==1)||(negative_flag==1)||(zero_flag==1)))
     WARNING_message( " Warning - ignoring +/-/0/abs flags for quick computations");

   if(positive_flag==-1) {   /* if no +/-/0 options set, allow all voxels */
     positive_flag = 1;
     negative_flag = 1;
     zero_flag = 1;
   }

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

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

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

   nxyz = DSET_NVOX(old_dset) ;
   if( mmm != NULL && mmvox != nxyz ){
      ERROR_exit(" Mask and input datasets not the same size!") ;
      
   }

   if(automask && mmm == NULL ){
      mmm = THD_automask( old_dset ) ;
      for(i=0;i<nxyz;i++) {
        if(mmm[i]!=0) ++mmvox;
      }
   }

   if(quick_flag)
      Print_Header_MinMax(min_flag, max_flag, old_dset);
 
   if(slow_flag!=1)
      exit(0);

   /* ZSS do some diddlyiddly sorting - DO not affect Daniel's function later on*/
   if (perc_flag == 1) {
      DSET_mallocize (old_dset);
      DSET_load (old_dset);	                
      if (DSET_NVALS(old_dset) != 1) {
         ERROR_exit( "-percentile can only be used on one sub-brick only.\n"
                     "Use sub-brick selectors '[.]' to specify sub-brick of interest.\n");
      }
      
     /* prep for input and output of percentiles */
      if (mp0 > mp1) {
         N_mp = 1; 
      } else {
         /* allocate one above ceiling to prevent truncation error (and crash),
            N_mp is recomputed anyway      16 Mar 2009 [rickr]               */
         N_mp = (int)((double)(mp1-mp0)/(double)mps) + 2;
      } 
      mpv = (double *)malloc(sizeof(double)*N_mp);
      perc = (double *)malloc(sizeof(double)*N_mp);
      if (!mpv || !perc) {
         ERROR_message("Failed to allocate for mpv or perc");
         exit(1);
      }  
      N_mp = 0;
      mp = mp0;
      do {
         mpv[N_mp] = mp; ++N_mp; mp += mps;
      } while (mp <= mp1+.00000001);

      if (!Percentate (DSET_ARRAY(old_dset, 0), mmm, nxyz,
               DSET_BRICK_TYPE(old_dset,0), mpv, N_mp,
               0, perc,
               zero_flag, positive_flag, negative_flag )) {

         ERROR_message("Failed to compute percentiles.");
         exit(1);         
      }
      
      /* take care of brick factor */
      if (DSET_BRICK_FACTOR(old_dset,0)) {
         for (i=0; i<N_mp; ++i) {
            perc[i] = perc[i]*DSET_BRICK_FACTOR(old_dset,0);
         }
      }
      
      for (i=0; i<N_mp; ++i) {
         fprintf(stdout,"%.1f %f   ", mpv[i]*100.0f, perc[i]); 
      }
      free(mpv); mpv = NULL;
      free(perc); perc = NULL;
      
   }

   Max_func(min_flag, max_flag, mean_flag,count_flag,
        positive_flag, negative_flag, zero_flag, absolute_flag,
        nan_flag, sum_flag, var_flag, vol_flag,old_dset, mmm, mmvox);

   
   if(mmm!=NULL)
     free(mmm);
   
   exit(0);

/* unused code time series method for extracting data */
#if 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 ) ;
   nbriks = 1;

   /*------------- ready to compute new min, max -----------*/
   new_dset = MAKER_4D_to_typed_fbuc(
                 old_dset ,             /* input dataset */
                 "temp" ,               /* output prefix */
                 datum ,                /* output datum  */
                 0 ,                    /* ignore count  */
                 0 ,              /* can't detrend in maker function  KRH 12/02*/
                 nbriks ,               /* number of briks */
		 Max_tsfunc ,         /* timeseries processor */
                 NULL,                   /* data for tsfunc */
                 NULL,  /* mask */
                 0   /* Allow auto scaling of output */
              ) ;
   if(min_flag)
     printf("%-13.6g ", minvalue); 
   if(max_flag)
     printf("%-13.6g", maxvalue); 
   printf("\n");
   exit(0) ;
#endif
}
Ejemplo n.º 15
0
static char * BFIT_main( PLUGIN_interface * plint )
{
   MCW_idcode * idc ;
   THD_3dim_dataset * input_dset , * mask_dset = NULL ;

   BFIT_data * bfd ;
   BFIT_result * bfr ;

   int nvals,ival , nran,nvox , nbin , miv=0 , sqr,sqt ;
   float abot,atop,bbot,btop,pcut , eps,eps1 , hlast ;
   float *bval , *cval ;
   double aa,bb,xc ;
   double chq,ccc,cdf ;
   int    ihqbot,ihqtop ;

   int mcount,mgood , ii , jj , ibot,itop ;
   float mask_bot=666.0 , mask_top=-666.0 , hbot,htop,dbin ;
   char buf[THD_MAX_NAME+128] , tbuf[THD_MAX_NAME+128] , * tag ;
   int   * hbin , * jbin,*kbin=NULL , *jist[2] ;
   MRI_IMAGE * flim ;

   double aext=-1.0,bext=-1.0 ;

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

   if( plint == NULL )
      return "************************\n"
             "BFIT_main:  NULL input\n"
             "************************"  ;

   /*-- read 1st line --*/

   PLUTO_next_option(plint) ;
   idc        = PLUTO_get_idcode(plint) ;
   input_dset = PLUTO_find_dset(idc) ;
   if( input_dset == NULL )
      return "****************************\n"
             "BFIT_main: bad input dataset\n"
             "****************************"  ;

   nvox  = DSET_NVOX(input_dset) ;
   nvals = DSET_NVALS(input_dset) ;
   ival  = (int) PLUTO_get_number(plint) ;
   if( ival < 0 || ival >= nvals )
      return "**************************\n"
             "BFIT_main: bad Brick index\n"
             "**************************" ;

   DSET_load(input_dset) ;
   if( DSET_ARRAY(input_dset,0) == NULL )
      return "*****************************\n"
             "BFIT_main: can't load dataset\n"
             "*****************************"  ;

   tag = PLUTO_get_string(plint) ;
   sqr = PLUTO_string_index(tag,NYESNO,YESNO_strings) ;

   /*-- read 2nd line --*/

   PLUTO_next_option(plint) ;
   abot = PLUTO_get_number(plint) ;
   atop = PLUTO_get_number(plint) ;
   if( atop <= abot )
      return "*** atop <= abot! ***" ;

   PLUTO_next_option(plint) ;
   bbot = PLUTO_get_number(plint) ;
   btop = PLUTO_get_number(plint) ;
   if( atop <= abot )
      return "*** btop <= bbot! ***" ;
   hlast = PLUTO_get_number(plint) ;

   PLUTO_next_option(plint) ;
   nran = (int) PLUTO_get_number(plint) ;
   pcut = PLUTO_get_number(plint) ;

   tag = PLUTO_get_string(plint) ;
   sqt = PLUTO_string_index(tag,NYESNO,YESNO_strings) ;

   /*-- read optional lines --*/

   while( (tag=PLUTO_get_optiontag(plint)) != NULL ){

      /*-- Mask itself --*/

      if( strcmp(tag,"Mask") == 0 ){

         idc       = PLUTO_get_idcode(plint) ;
         mask_dset = PLUTO_find_dset(idc) ;

         if( mask_dset == NULL ){
            return "******************************\n"
                   "BFIT_main:  bad mask dataset\n"
                   "******************************"  ;
         }

         if( DSET_NVOX(mask_dset) != nvox ){
           return "************************************************************\n"
                  "BFIT_main: mask input dataset doesn't match source dataset\n"
                  "************************************************************" ;
         }

         miv = (int) PLUTO_get_number(plint) ;
         if( miv >= DSET_NVALS(mask_dset) || miv < 0 ){
            return "****************************************************\n"
                   "BFIT_main: mask dataset sub-brick index is illegal\n"
                   "****************************************************"  ;
         }

         DSET_load(mask_dset) ;
         if( DSET_ARRAY(mask_dset,miv) == NULL ){
            return "*************************************\n"
                   "BFIT_main:  can't load mask dataset\n"
                   "*************************************"  ;
         }
         continue ;
      }

      /*-- Mask range of values --*/

      if( strcmp(tag,"Range") == 0 ){
         if( mask_dset == NULL ){
            return "******************************************\n"
                   "BFIT_main:  Can't use Range without Mask\n"
                   "******************************************"  ;
         }

         mask_bot = PLUTO_get_number(plint) ;
         mask_top = PLUTO_get_number(plint) ;
         continue ;
      }

      /*-- Extra plot --*/

      if( strcmp(tag,"Extra") == 0 ){
         aext = PLUTO_get_number(plint) ;
         bext = PLUTO_get_number(plint) ;
         continue ;
      }
   }

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

   bfd = BFIT_prepare_dataset( input_dset , ival , sqr ,
                               mask_dset , miv , mask_bot , mask_top ) ;

   if( bfd == NULL ) return "*** BFIT_prepare_dataset fails ***" ;

   bfr = BFIT_compute( bfd ,
                       pcut , abot,atop , bbot,btop , nran,200 ) ;

   if( bfr == NULL ){
      BFIT_free_data( bfd ) ;
      return "*** BFIT_compute fails! ***" ;
   }

   itop  = bfr->itop ;
   mgood = bfr->mgood ;

   ibot   = bfd->ibot ;
   bval   = bfd->bval ;
   cval   = bfd->cval ;
   mcount = bfd->mcount ;

   xc   = bfr->xcut ;
   aa   = bfr->a ;
   bb   = bfr->b ;
   eps  = bfr->eps ;
   eps1 = 1.0 - eps ;
   if( eps1 > 1.0 ) eps1 = 1.0 ;
   eps1 = (mcount-ibot) * eps1 ;

   /*-- compute and plot histogram --*/

   /* original data was already squared (e.g., R**2 values) */

   if( !sqr ){
      hbot = 0.0 ; htop = 1.0 ; nbin = 200 ;
      if( bval[mcount-1] < 1.0 ) htop = bval[mcount-1] ;
      dbin = (htop-hbot)/nbin ;

      hbin = (int *) calloc((nbin+1),sizeof(int)) ;  /* actual histogram */
      jbin = (int *) calloc((nbin+1),sizeof(int)) ;  /* theoretical fit */

      for( ii=0 ; ii < nbin ; ii++ ){  /* beta fit */
         jbin[ii] = (int)( eps1 * ( beta_t2p(hbot+ii*dbin,aa,bb)
                                   -beta_t2p(hbot+ii*dbin+dbin,aa,bb) ) ) ;
      }

      jist[0] = jbin ;

      flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ;
      mri_fix_data_pointer( bval+ibot , flim ) ;
      mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ;

      /* "extra" histogram (nominal values?) */

      if( aext > 0.0 ){
         kbin = (int *) calloc((nbin+1),sizeof(int)) ;
         jist[1] = kbin ;
         for( ii=0 ; ii < nbin ; ii++ ){  /* beta fit */
            kbin[ii] = (int)( eps1 * ( beta_t2p(hbot+ii*dbin,aext,bext)
                                      -beta_t2p(hbot+ii*dbin+dbin,aext,bext) ) ) ;
         }
      }

   } else {   /* original data was not squared (e.g., correlations) */

      double hb,ht ;
      htop = 1.0 ; nbin = 200 ;
      if( bval[mcount-1] < 1.0 ) htop = sqrt(bval[mcount-1]) ;
      hbot = -htop ;
      dbin = (htop-hbot)/nbin ;

      hbin = (int *) calloc((nbin+1),sizeof(int)) ;  /* actual histogram */
      jbin = (int *) calloc((nbin+1),sizeof(int)) ;  /* theoretical fit */

      for( ii=0 ; ii < nbin ; ii++ ){  /* beta fit */
         hb = hbot+ii*dbin ; ht = hb+dbin ;
         hb = hb*hb ; ht = ht*ht ;
         if( hb > ht ){ double qq=hb ; hb=ht ; ht=qq ; }
         jbin[ii] = (int)( 0.5*eps1 * ( beta_t2p(hb,aa,bb)
                                       -beta_t2p(ht,aa,bb) ) ) ;
      }

      jist[0] = jbin ;

      flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ;
      mri_fix_data_pointer( cval+ibot , flim ) ;
      mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ;

      /* nominal fit */

      if( aext > 0.0 ){
         kbin = (int *) calloc((nbin+1),sizeof(int)) ;
         jist[1] = kbin ;
         for( ii=0 ; ii < nbin ; ii++ ){  /* beta fit */
            hb = hbot+ii*dbin ; ht = hb+dbin ;
            hb = hb*hb ; ht = ht*ht ;
            if( hb > ht ){ double qq=hb ; hb=ht ; ht=qq ; }
            kbin[ii] = (int)( 0.5*eps1 * ( beta_t2p(hb,aext,bext)
                                          -beta_t2p(ht,aext,bext) ) ) ;
         }
      }
   }

   sprintf(buf,"%s[%d] a=%.2f b=%.2f \\epsilon=%.2f %%=%.0f",
           DSET_FILECODE(input_dset),ival,aa,bb,eps,pcut ) ;

   ccc = bfr->q_chisq ;

   /* blow up histogram details by sqrt-ing, if ordered */

   if( sqt ){
      for( ii=0 ; ii < nbin ; ii++ ){
         hbin[ii] = (int) sqrt( (double)(100*hbin[ii]+0.5) ) ;
         jbin[ii] = (int) sqrt( (double)(100*jbin[ii]+0.5) ) ;
         if( kbin!=NULL )
            kbin[ii] = (int) sqrt( (double)(100*kbin[ii]+0.5) ) ;
      }
   }

   /* and plot */

   sprintf(tbuf,"\\beta fit: cutoff=%.2f nvox=%d q(\\chi^2)=%8.2e",
           (sqr)?sqrt(xc):xc , mgood , ccc ) ;
   if( sqt ){
      ii = strlen(tbuf) ;
      sprintf( tbuf+ii , " \\surd ogram" ) ;
   }

   if( hlast > 0.0 ){
      hbin[nbin-1] = jbin[nbin-1] = hlast ;
      if( kbin != NULL ) kbin[nbin-1] = hlast ;
   }

   PLUTO_histoplot( nbin,hbot,htop,hbin ,
                    tbuf,NULL,buf , (kbin==NULL)?1:2 , jist ) ;

   /* cleanup */

   mri_clear_data_pointer(flim) ; mri_free(flim) ;
   free(hbin) ; free(jbin) ; if( kbin != NULL ) free(kbin);

   BFIT_free_data(bfd) ; BFIT_free_result(bfr) ;
   return NULL ;
}
Ejemplo n.º 16
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) ;
}
Ejemplo n.º 17
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 ;
}
Ejemplo n.º 18
0
int main(int argc, char **argv)
{
   static char FuncName[]={"3dSeg"};
   SEG_OPTS *Opt=NULL;
   char *atr=NULL;
   float *mixfrac= NULL;
   int i=0;
   double ff;
   SUMA_SEND_2AFNI SS2A;
   SUMA_Boolean LocalHead = NOPE;

   
   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;
   
   SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   
   Opt = Seg_Default(argv, argc);
   Opt = Seg_ParseInput (Opt,argv,  argc);
   Opt->hist = tross_commandline( FuncName , argc , argv ) ;
   
   /* load the input data */
   if (!(Opt->aset = Seg_load_dset( Opt->aset_name ))) {      
      SUMA_RETURN(1);
   }
   
   if (!Seg_CheckOpts(Opt)) {
      SUMA_S_Err("Failed on option check");
      SUMA_RETURN(1);
   }
   
   /* Load mask dataset */
   if (Opt->mset_name) {
      if (!strncasecmp(Opt->mset_name,"auto", 4)) {
         byte *mm=NULL;
         int j;
         short *sb=NULL;
         if (!(mm = THD_automask(Opt->aset))) {
            SUMA_RETURN(1);
         }
         NEW_SHORTY(Opt->aset, DSET_NVALS(Opt->aset), 
                              "automask.cp", Opt->mset);
         sb = (short *)DSET_ARRAY(Opt->mset,0);
         for (j=0; j<DSET_NVOX(Opt->mset); ++j) {
               sb[j] = (short)mm[j];
         }
         free(mm); mm=NULL;
      } else if (!(Opt->mset = Seg_load_dset( Opt->mset_name ))) {      
         SUMA_RETURN(1);
      }
   }

   /* reference classes */
   if (Opt->gold_name) {
      if (!(Opt->gold = Seg_load_dset( Opt->gold_name ))) {      
         SUMA_RETURN(1);
      }   
   }
   
   if (Opt->gold_bias_name) {
      if (!(Opt->gold_bias = Seg_load_dset( Opt->gold_bias_name ))) {      
         SUMA_RETURN(1);
      }   
   }
   
   if (!Opt->clss) {
      SUMA_S_Err("Need -classes option");
      SUMA_RETURN(1);
   } 
      
   /* Talk ? */
   if (Opt->ps->cs->talk_suma) {
      Opt->ps->cs->istream = SUMA_BRAINWRAP_LINE;
      Opt->ps->cs->afni_istream = SUMA_AFNI_STREAM_INDEX2;
      if (!SUMA_SendToAfni (Opt->ps->cs, NULL,  0)) {
         SUMA_SL_Err("Failed to initialize SUMA_SendToAfni");
         Opt->ps->cs->afni_Send = NOPE;
         Opt->ps->cs->Send = NOPE;
      } else {
         /* send in_vol to afni */
            SUMA_SL_Note("Sending anat volume to AFNI");
            SS2A.dset = Opt->aset; SS2A.at_sb=-1;
            if (!SUMA_SendToAfni(Opt->ps->cs, &SS2A, 1)) {
               SUMA_SL_Err("Failed to send volume to AFNI");
               Opt->ps->cs->afni_Send = NOPE;
            }
      }
   }

   /* classified set ? */
   if (Opt->this_cset_name) { /* user supplied initializer */
      if (!(Opt->cset = Seg_load_dset( Opt->this_cset_name ))) {      
         SUMA_RETURN(1);
      }
   }
   

   /* labeltable? */
   if (Opt->labeltable_name) {
      Dtable *vl_dtable=NULL;
      char *labeltable_str=NULL;
      int kk=0;
      
      /* read the table */
      if (!(labeltable_str = AFNI_suck_file( Opt->labeltable_name))) {
         ERROR_exit("Failed to read %s", Opt->labeltable_name);
      }
      if (!(vl_dtable = Dtable_from_nimlstring(labeltable_str))) {
         ERROR_exit("Could not parse labeltable");
      }
      CLASS_KEYS_FROM_LT(vl_dtable);

      destroy_Dtable(vl_dtable); vl_dtable=NULL;
   } 
   
   if (!Opt->keys) {
      Dtable *vl_dtable=NULL;
      if (Opt->cset && (vl_dtable = DSET_Label_Dtable(Opt->cset))) { 
         if (Opt->debug) SUMA_S_Note("Getting keys from -cset dataset");
         /* try getting keys from cset */
         CLASS_KEYS_FROM_LT(vl_dtable);
         /* Do not delete vl_dtable, it is the same pointer in Opt->cset */
      } else {
         /* add default keys */
         if (Opt->debug) SUMA_S_Note("Keys not available, assuming defaults");
         Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int));
         for (i=0; i<Opt->clss->num; ++i) {
            Opt->keys[i] = i+1;
         }
      }
   }
   
   /* Make sure you have no negative values and requesting bias field correction.
      The implementation uses log() for this so the negative values would be
      ill advised */
   {
      float amin, amax;
      THD_subbrick_minmax(Opt->aset, 0, 1,&amin, &amax);
      if (amin < 0 && Opt->bias_param > 0) {
         SUMA_S_Err("Cannot use field bias correction on volumes with negative\n"
           "values. Either turn off bias field estimation with -bias_fwhm 0.0\n"
           "or shift the values of the input by something like:\n"
           "   3dcalc -a %s -expr 'a+bool(a)*%d' -prefix SHIFTED\n"
           "and rerun the segmentation on SHIFTED. Note the suggested shift\n"
           "leaves zero values unchanged.",
              DSET_HEADNAME(Opt->aset), (int)ceil(-amin+1.0));
         exit(1);
      }
   }
   /* Show the match between keys and classes */
   if (Opt->debug > 1) {
      SUMA_S_Note("Class-->key map");
      SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys);
   }
   if (Opt->clss->num < 2) {
      if (Opt->debug <= 1) {
         SUMA_S_Note("Class-->key map");
         SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys);
      }
      SUMA_S_Err("Less than 2 classes? I am out of here");
      SUMA_RETURN(0);
   }
   
   /* Mask setup */
   if (Opt->debug > 1) {
      SUMA_S_Note("MaskSetup");
   }
   Opt->cmask = MaskSetup(Opt, Opt->aset, 1,
                &(Opt->mset), &(Opt->cmask), Opt->dimcmask, 
                Opt->mask_bot, Opt->mask_top, &(Opt->cmask_count));
   
   if (Opt->VoxDbg >= 0) {
   SUMA_S_Note("DBG setup");
      fprintf(Opt->VoxDbgOut, "Command:");
      for (i=0; i<argc; ++i) {
         fprintf(Opt->VoxDbgOut, "%s ", argv[i]);
      }
      fprintf(Opt->VoxDbgOut, "\nDebug info for voxel %d\n", Opt->VoxDbg);
   }
   
   Opt->cs = SUMA_New_Class_Stat(Opt->clss->str, Opt->clss->num, 
                                 Opt->keys, 3, NULL);
   
     
   /* Load prob. of class given features */
   if (Opt->priCgAname && strcmp(Opt->priCgAname, "INIT_MIXFRAC")) {
      if (!(Opt->priCgA = Seg_load_dset(Opt->priCgAname))) {
         SUMA_S_Errv("Failed to read priCgA %s\n", Opt->priCgAname);
         SUMA_RETURN(1);
      }
      if (GRID_MISMATCH(Opt->priCgA, Opt->aset)) {
         SUMA_S_Err("All input data must have same grid (-priCgA != -aset)"); 
         SUMA_RETURN(1);   
      }
      /* Make sure dset is properly formatted */
      if (!SUMA_ShortizeProbDset(&Opt->priCgA, 
                        Opt->cs, 
                        Opt->cmask, Opt->cmask_count, 
                        Opt, &Opt->priCgA)) {
         SUMA_S_Errv("Failed to shortize priCgA %s\n", Opt->priCgAname);
         SUMA_RETURN(1);
      }
      /* set the floor of the input dset */
      if (0) {
         SUMA_S_Note("Setting probability floor, USEFULNESS NOT TESTED...");
         if (!set_p_floor(Opt->priCgA, 0.1, Opt->cmask)) {
            SUMA_S_Errv("Failed to set p floor for priCgA %s\n", 
                        Opt->priCgAname);
            SUMA_RETURN(1);
         }
      }
   } else {
      /* uniform probability */
   }
   
   
   /* Load prob. of class given location */
   if (Opt->priCgLname && strcmp(Opt->priCgLname, "INIT_MIXFRAC")) {
      if (!(Opt->priCgL = Seg_load_dset(Opt->priCgLname))) {
         SUMA_S_Errv("Failed to read priCgL %s\n", Opt->priCgLname);
         SUMA_RETURN(1);
      }
      if (GRID_MISMATCH(Opt->priCgL, Opt->aset)) {
         SUMA_S_Err("All input data must have same grid (-priCgL != -aset)"); 
         SUMA_RETURN(1);   
      }
      /* Make sure dset is properly formatted */
      if (!SUMA_ShortizeProbDset(&Opt->priCgL, 
                        Opt->cs, 
                        Opt->cmask, Opt->cmask_count, 
                        Opt, &Opt->priCgL)) {
         SUMA_S_Errv("Failed to shortize priCgL %s\n", Opt->priCgLname);
         SUMA_RETURN(1);
      }
   } else {
      /* uniform probability */
   }

   /* check on weights of priors */
   if (Opt->wA >= 0.0 && Opt->wL < 0.0) {
      Opt->wL = 1.0 - Opt->wA;
   } else if (Opt->wL >= 0.0 && Opt->wA < 0.0) {
      Opt->wA = 1.0 - Opt->wL;
   } else if (Opt->wA < 0.0 && Opt->wL < 0.0) { /* defaults */
      Opt->wA = 0.5; Opt->wL = 0.5;
   }
   ff = Opt->wA+Opt->wL;
   Opt->wA = Opt->wA/ff; Opt->wL = Opt->wL/ff;
   
   if (!Opt->cset) {
      if (!SUMA_SegInitCset(Opt->aset, 
                            &Opt->cset, 
                            Opt->cmask, Opt->cmask_count,
                            Opt->mixopt, 
                            Opt->cs,
                            Opt)) {
         SUMA_S_Err("Failed to get initializer");
         SUMA_RETURN(1);
      }
   }
   if (Opt->debug > 1) {
      SUMA_Seg_Write_Dset(Opt->proot, "classes_init", Opt->cset, 
                            -1, Opt->hist);
   }
   
   /* Now add the 'OTHER' class if needed */
   if (Opt->Other) {
      if (!SUMA_AddOther( Opt->clss, &Opt->keys, 
                     Opt->cmask, Opt->cmask_count,
                     Opt->cset, Opt->pstCgALL,
                     Opt->priCgA, Opt->priCgL,
                     Opt->cs)) {
         SUMA_S_Err("Failed to add other");
         SUMA_RETURN(0);              
      }
   }

   

   /* store mixfrac in class stats */
   for (i=0;i<Opt->cs->N_label; ++i) {
      if ((ff = SUMA_mixopt_2_mixfrac(Opt->mixopt, Opt->cs->label[i], 
                                   Opt->cs->keys[i], Opt->cs->N_label,
                                   Opt->cmask, Opt->cset))<0.0) {
         SUMA_S_Errv("Can't get mixfrac for %s\n", Opt->mixopt);
         SUMA_RETURN(1);
      }
      SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "init.mix", ff); 
      SUMA_set_Stat(Opt->cs, Opt->cs->label[i], "mix", ff);
   }

   
   /* Now call the workhorse */
   if (!SUMA_SegEngine(Opt)) {
      SUMA_S_Err("Failed in SUMA_SegEngine");
      exit(1);
   }
   
   /* write output */
   if (Opt->Bset && !Opt->this_fset_name) {
      tross_Append_History(Opt->Bset, Opt->hist);
      SUMA_Seg_Write_Dset(Opt->proot, "BiasField", /* DSET_PREFIX(Opt->Bset) */
                              Opt->Bset, -1, Opt->hist);
   }
   if (Opt->xset && !Opt->this_xset_name) {
      AFNI_FEED(Opt->ps->cs, "BiasCorrect", -1, Opt->xset);
      SUMA_Seg_Write_Dset(Opt->proot, "AnatUB", /* DSET_PREFIX(Opt->xset)*/
                              Opt->xset, -1, Opt->hist);
   }
   if (Opt->cset) {
      SUMA_Seg_Write_Dset(Opt->proot, "Classes", /* Opt->crefix */ 
                          Opt->cset, -1, Opt->hist);
      AFNI_FEED(Opt->ps->cs, "FinalClasses", -1, Opt->cset);
   }
   if (Opt->pstCgALL) {
      SUMA_Seg_Write_Dset(Opt->proot, "Posterior",  /* Opt->prefix */
                          Opt->pstCgALL, -1, Opt->hist);
      AFNI_FEED(Opt->ps->cs, "pstCgALL-final", -1, Opt->pstCgALL);
   }
   if (Opt->aset) {
      SUMA_Seg_Write_Dset(Opt->proot, "Anat",  
                          Opt->aset, -1, Opt->hist);
   }
   if (Opt->debug) SUMA_S_Note("Writing Unmodulated output");
   if (!(SUMA_pst_C_giv_ALL(Opt->xset, 
                               Opt->cmask, Opt->cmask_count,
                               Opt->cs,  
                               NULL, NULL,
                               Opt->B, Opt->T, 0,
                               &Opt->pstCgALL))) {
         SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL unmodulated");
         SUMA_RETURN(1);
   }
   SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.p", 
                        Opt->pstCgALL, -1, Opt->hist);
   
   if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, 
                              Opt->cmask, &Opt->cset))) { 
      SUMA_S_Err("Failed in assign_classes");
      SUMA_RETURN(1);
   }
   SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.c", 
                       Opt->cset, -1, Opt->hist);
                       
   /* all done, free */
   Opt = free_SegOpts(Opt);
  
   PRINT_COMPILE_DATE ; 
   SUMA_RETURN(0);
}
Ejemplo n.º 19
0
MRI_IMAGE * FD_brick_to_mri( int kslice , int ival , FD_brick * br )
{
   MRI_IMAGE * im ;  /* output */
   register int ii,di,ei , jj,dj,ej , base , pp ;
   char * iar ;      /* brick in the input */
   MRI_TYPE typ ;

   /** desire a fake image **/

   if( ival < 0 ){
      im     = mri_new( br->n1 , br->n2 , MRI_short ) ;
      im->dx = br->del1 ;
      im->dy = br->del2 ;
      im->dz = br->del3 ;
      return im ;
   }

   /** otherwise, get ready for a real image **/

   if( ival >= br->dset->dblk->nvals ) return NULL ;

   iar = DSET_ARRAY(br->dset,ival) ;

   if( iar == NULL ){  /* if data needs to be loaded from disk */
      (void) THD_load_datablock( br->dset->dblk ) ;
      iar = DSET_ARRAY(br->dset,ival) ;
      if( iar == NULL ) return NULL ;
   }

   typ    = DSET_BRICK_TYPE(br->dset,ival) ;
   im     = mri_new( br->n1 , br->n2 , typ ) ;
   im->dx = br->del1 ;
   im->dy = br->del2 ;
   im->dz = br->del3 ;

   switch( typ ){

      default:             /* don't know what to do --> return nada */
         mri_free( im ) ;
         return NULL ;

      case MRI_byte:{
         register byte * ar  = MRI_BYTE_PTR(im) ;
         register byte * bar = (byte *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_short:{
         register short * ar  = MRI_SHORT_PTR(im) ;
         register short * bar = (short *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_float:{
         register float * ar  = MRI_FLOAT_PTR(im) ;
         register float * bar = (float *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_int:{
         register int * ar  = MRI_INT_PTR(im) ;
         register int * bar = (int *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_double:{
         register double * ar  = MRI_DOUBLE_PTR(im) ;
         register double * bar = (double *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_complex:{
         register complex * ar  = MRI_COMPLEX_PTR(im) ;
         register complex * bar = (complex *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

      case MRI_rgb:{                                           /* 15 Apr 2002 */
         register rgbyte * ar  = (rgbyte *) MRI_RGB_PTR(im) ;
         register rgbyte * bar = (rgbyte *) iar ;

         di = br->d1 ; dj = br->d2 ;  /* strides */
         ei = br->e1 ; ej = br->e2 ;  /* final indices */
         base = br->start + kslice * br->d3 ;

         pp = 0 ;
         for( jj=0 ; jj != ej ; jj += dj )
            for( ii=0 ; ii != ei ; ii += di ) ar[pp++] = bar[ii+(jj+base)] ;
      }
      break ;

   }

   if( DSET_BRICK_FACTOR(br->dset,ival) != 0.0 ){
      MRI_IMAGE * qim ;
STATUS(" scaling to float");
      qim = mri_scale_to_float( DSET_BRICK_FACTOR(br->dset,ival) , im ) ;
      mri_free(im) ; im = qim ;
   }

   return im ;
}
Ejemplo n.º 20
0
/*----------------------------------------------------------------------
**
**  Subtract hemispheres assuming we need floats.
**
**----------------------------------------------------------------------
*/
static char *
process_as_floats( THD_3dim_dataset * dset, hemi_s * hs )
{
    int     count, cx, type = hs->thresh_type;
    int     nx, ny, nz, nvox;
    short * sp, * sdata;
    float * fdata, * fp, * fp2;
    float   factor, maxabs;

    nx   = dset->daxes->nxx;
    ny   = dset->daxes->nyy;
    nz   = dset->daxes->nzz;
    nvox = nx * ny * nz;

    sdata = (short *)DSET_ARRAY( dset, 0 );

    factor = DSET_BRICK_FACTOR( dset, 0 );
    factor = factor == 0.0 ? 1.0 : factor;

    /* first get the data into a float array */

    if ( ( fdata = (float *)malloc( nvox * sizeof( float ) ) ) == NULL )
	return  "------------------------------\n"
		"paf: failed allocation of floats"
		"------------------------------\n";

    fp = fdata;
    sp = sdata;
    for ( count = 0; count < nvox; count++ )
    {
	*fp = *sdata * factor;

	if ( ( type == 1 ) && ( *fp < 0 ) )
	    *fp = 0;
	else if ( ( type == 2 ) && ( *fp > 0 ) )
	    *fp = 0;

	fp++;
	sp++;
    }

    /* now make the subtraction as floats */

    for ( count = 0; count < ny*nz; count++ )
    {
	fp  = fdata + count * nx;
	fp2 = fp + nx - 1;

	for ( cx = 0; cx < (nx+1)/2; cx++ )
	{
	    *fp  = *fp - *fp2;
	    *fp2 = -*fp;

	    fp++;
	    fp2--;
	}
    }

    /* now make a new factor */

    maxabs = MCW_vol_amax( nvox, 1, 1, MRI_float, fdata );

    /* result is all zero, let the user worry */
    if ( maxabs != 0.0 )
    {
	factor = MRI_TYPE_maxval[MRI_short] /maxabs;        /* 32767? / maxabs */
    
	EDIT_coerce_scale_type( nvox, factor, MRI_float, fdata, MRI_short, sdata );
    
	DSET_BRICK_FACTOR( dset, 0 ) = factor == 0.0 ? 0.0 : 1.0 / factor;
    
	THD_load_statistics( dset );
    }
    free(fdata);
    return NULL;        /* success */
}
Ejemplo n.º 21
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset=NULL ;
   MCW_cluster *nbhd=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ;
   char *prefix="./LocalCormat" ;
   int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ;
   int mmlag=10 , ii,jj , do_arma=0 , nvout ;
   MRI_IMAGE *concim=NULL ; float *concar=NULL ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

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

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

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

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

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

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

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

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

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

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

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

   /** create output dataset **/

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

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

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

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

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

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

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

   exit(0) ;
}
Ejemplo n.º 22
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 */
}
Ejemplo n.º 23
0
int main( int argc , char * argv[] )
{
   int ninp , ids , nv , iv,jv,kv , ivout , new_nvals , have_fdr = 0, nfdr = 0 ;
   THD_3dim_dataset * new_dset=NULL , * dset ;
   char buf[256] ;
   double angle;

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

   /*** read input options ***/


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

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

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

   BUCK_read_opts( argc , argv ) ;

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

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

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

   new_dset = EDIT_empty_copy( DSUB(0) ) ;

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

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

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

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

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

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

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

   THD_force_malloc_type( new_dset->dblk , DATABLOCK_MEM_MALLOC ) ;

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

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

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

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

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

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

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

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

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

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

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

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

            kv = DSET_BRICK_STATCODE(dset,jv) ;

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

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

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

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

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

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

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

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

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

            /** print a message? **/

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

         ivout++ ;
      }

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

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

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

   } /* end of loop over input datasets */

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

   exit(0) ;
}
Ejemplo n.º 24
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() ) ;
}
Ejemplo n.º 25
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 .... */

}
Ejemplo n.º 26
0
int main( int argc , char *argv[] )
{
   int iarg , nerr=0 , nvals,nvox , nx,ny,nz , ii,jj,kk ;
   char *prefix="LSSout" , *save1D=NULL , nbuf[256] ;
   THD_3dim_dataset *inset=NULL , *outset ;
   MRI_vectim   *inset_mrv=NULL ;
   byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0, automask=0, nmask=0 ;
   NI_element *nelmat=NULL ; char *matname=NULL ;
   char *cgl ;
   int Ngoodlist,*goodlist=NULL , nfull , ncmat,ntime ;
   NI_int_array *giar ; NI_str_array *gsar ; NI_float_array *gfar ;
   MRI_IMAGE *imX, *imA, *imC, *imS ; float *Xar, *Sar ; MRI_IMARR *imar ;
   int nS ; float *ss , *oo , *fv , sum ; int nvec , iv ;
   int nbstim , nst=0 , jst_bot,jst_top ; char *stlab="LSS" ;
   int nodata=1 ;

   /*--- help me if you can ---*/

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

   /*--- bureaucratic startup ---*/

   PRINT_VERSION("3dLSS"); mainENTRY("3dLSS main"); machdep();
   AFNI_logger("3dLSS",argc,argv); AUTHOR("RWCox");
   (void)COX_clock_time() ;

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

   iarg = 1 ;
   while( iarg < argc ){

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

     /**==========   -mask  ==========**/

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

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

     /**==========   -matrix  ==========**/

     if( strcasecmp(argv[iarg],"-matrix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       if( nelmat != NULL ) ERROR_exit("More than 1 -matrix option!?");
       nelmat = NI_read_element_fromfile( argv[iarg] ) ; /* read NIML file */
       matname = argv[iarg];
       if( nelmat == NULL || nelmat->type != NI_ELEMENT_TYPE )
         ERROR_exit("Can't process -matrix file '%s'!?",matname) ;
       iarg++ ; continue ;
     }

     /**==========   -nodata  ===========**/

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

     /**==========   -input  ==========**/

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

     /**==========   -prefix  =========**/

     if( strcasecmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       prefix = strdup(argv[iarg]) ;
       if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal string after %s",argv[iarg-1]) ;
       if( verb && strcmp(prefix,"NULL") == 0 )
         INFO_message("-prefix NULL ==> no dataset will be written") ;
       iarg++ ; continue ;
     }

     /**==========   -save1D  =========**/

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

     /***** Loser User *****/

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

   }  /* end of loop over options */

   /*----- check for errors -----*/

   if( nelmat == NULL ){ ERROR_message("No -matrix option!?") ; nerr++ ; }
   if( nerr > 0 ) ERROR_exit("Can't continue without these inputs!") ;

   if( inset != NULL ){
     nvals = DSET_NVALS(inset) ; nvox = DSET_NVOX(inset) ;
     nx = DSET_NX(inset) ; ny = DSET_NY(inset) ; nz = DSET_NZ(inset) ;
   } else {
     automask = nvals = 0 ;
     nvox = nx = ny = nz = nodata = 1 ;  /* nodata */
     mask = NULL ;
   }

   /*----- masque -----*/

   if( mask != NULL ){     /* check -mask option for compatibility */
     if( mask_nx != nx || mask_ny != ny || mask_nz != nz )
       ERROR_exit("-mask dataset grid doesn't match input dataset :-(") ;

   } else if( automask ){  /* create a mask from input dataset */
     mask = THD_automask( inset ) ;
     if( mask == NULL )
       ERROR_message("Can't create -automask from input dataset :-(") ;
     nmask = THD_countmask( nvox , mask ) ;
     if( verb || nmask < 1 )
       INFO_message("Number of voxels in automask = %d (out of %d = %.1f%%)",
                    nmask, nvox, (100.0f*nmask)/nvox ) ;
     if( nmask < 1 ) ERROR_exit("Automask is too small to process") ;

   } else if( !nodata ) {       /* create a 'mask' for all voxels */
     if( verb )
       INFO_message("No mask ==> computing for all %d voxels",nvox) ;
     mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ;
     memset( mask , 1 , sizeof(byte)*nvox ) ;

   }

   /*----- get matrix info from the NIML element -----*/

   if( verb ) INFO_message("extracting matrix info") ;

   ncmat = nelmat->vec_num ;  /* number of columns */
   ntime = nelmat->vec_len ;  /* number of rows */
   if( ntime < ncmat+2 )
     ERROR_exit("Matrix has too many columns (%d) for number of rows (%d)",ncmat,ntime) ;

   /*--- number of rows in the full matrix (without censoring) ---*/

   cgl = NI_get_attribute( nelmat , "NRowFull" ) ;
   if( cgl == NULL ) ERROR_exit("Matrix is missing 'NRowFull' attribute!") ;
   nfull = (int)strtod(cgl,NULL) ;
   if( nodata ){
     nvals = nfull ;
   } else if( nvals != nfull ){
     ERROR_exit("-input dataset has %d time points, but matrix indicates %d",
                nvals , nfull ) ;
   }

   /*--- the goodlist = mapping from matrix row index to time index
                        (which allows for possible time point censoring) ---*/

   cgl = NI_get_attribute( nelmat , "GoodList" ) ;
   if( cgl == NULL ) ERROR_exit("Matrix is missing 'GoodList' attribute!") ;
   giar = NI_decode_int_list( cgl , ";," ) ;
   if( giar == NULL || giar->num < ntime )
     ERROR_exit("Matrix 'GoodList' badly formatted?!") ;
   Ngoodlist = giar->num ; goodlist = giar->ar ;
   if( Ngoodlist != ntime )
     ERROR_exit("Matrix 'GoodList' incorrect length?!") ;
   else if( verb > 1 && Ngoodlist < nfull )
     ININFO_message("censoring reduces time series length from %d to %d",nfull,Ngoodlist) ;

   /*--- extract the matrix from the NIML element ---*/

   imX = mri_new( ntime , ncmat , MRI_float ) ;
   Xar = MRI_FLOAT_PTR(imX) ;

   if( nelmat->vec_typ[0] == NI_FLOAT ){  /* from 3dDeconvolve_f */
     float *cd ;
     for( jj=0 ; jj < ncmat ; jj++ ){
       cd = (float *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) Xar[ii+jj*ntime] = cd[ii] ;
     }
   } else if( nelmat->vec_typ[0] == NI_DOUBLE ){  /* from 3dDeconvolve */
     double *cd ;
     for( jj=0 ; jj < ncmat ; jj++ ){
       cd = (double *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) Xar[ii+jj*ntime] = cd[ii] ;
     }
   } else {
     ERROR_exit("Matrix file stored with illegal data type!?") ;
   }

   /*--- find the stim_times_IM option ---*/

   cgl = NI_get_attribute( nelmat , "BasisNstim") ;
   if( cgl == NULL ) ERROR_exit("Matrix doesn't have 'BasisNstim' attribute!") ;
   nbstim = (int)strtod(cgl,NULL) ;
   if( nbstim <= 0 ) ERROR_exit("Matrix 'BasisNstim' attribute is %d",nbstim) ;
   for( jj=1 ; jj <= nbstim ; jj++ ){
     sprintf(nbuf,"BasisOption_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl == NULL || strcmp(cgl,"-stim_times_IM") != 0 ) continue ;
     if( nst > 0 )
       ERROR_exit("More than one -stim_times_IM option was found in the matrix") ;
     nst = jj ;
     sprintf(nbuf,"BasisColumns_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl == NULL )
       ERROR_exit("Matrix doesn't have %s attribute!",nbuf) ;
     jst_bot = jst_top = -1 ;
     sscanf(cgl,"%d:%d",&jst_bot,&jst_top) ;
     if( jst_bot < 0 || jst_top < 0 )
       ERROR_exit("Can't decode matrix attribute %s",nbuf) ;
     if( jst_bot == jst_top )
       ERROR_exit("Matrix attribute %s shows only 1 column for -stim_time_IM:\n"
                  "      -->> 3dLSS is meant to be used when more than one stimulus\n"
                  "           time was given, and then it computes the response beta\n"
                  "           for each stim time separately. If you have only one\n"
                  "           stim time with -stim_times_IM, you can use the output\n"
                  "           dataset from 3dDeconvolve (or 3dREMLfit) to get that\n"
                  "           single beta directly.\n" , nbuf ) ;
     if( jst_bot >= jst_top || jst_top >= ncmat )
       ERROR_exit("Matrix attribute %s has illegal value: %d:%d (ncmat=%d)",nbuf,jst_bot,jst_top,ncmat) ;
     sprintf(nbuf,"BasisName_%06d",jj) ;
     cgl = NI_get_attribute( nelmat , nbuf ) ;
     if( cgl != NULL ) stlab = strdup(cgl) ;
     if( verb > 1 )
       ININFO_message("-stim_times_IM at stim #%d; cols %d..%d",jj,jst_bot,jst_top) ;
   }
   if( nst == 0 )
     ERROR_exit("Matrix doesn't have any -stim_times_IM options inside :-(") ;

   /*--- mangle matrix to segregate IM regressors from the rest ---*/

   if( verb ) INFO_message("setting up LSS vectors") ;

   imar = LSS_mangle_matrix( imX , jst_bot , jst_top ) ;
   if( imar == NULL )
     ERROR_exit("Can't compute LSS 'mangled' matrix :-(") ;

   /*--- setup for LSS computations ---*/

   imA = IMARR_SUBIM(imar,0) ;
   imC = IMARR_SUBIM(imar,1) ;
   imS = LSS_setup( imA , imC ) ; DESTROY_IMARR(imar) ;
   if( imS == NULL )
     ERROR_exit("Can't complete LSS setup :-((") ;
   nS = imS->ny ; Sar = MRI_FLOAT_PTR(imS) ;

   if( save1D != NULL ){
     mri_write_1D( save1D , imS ) ;
     if( verb ) ININFO_message("saved LSS vectors into file %s",save1D) ;
   } else if( nodata ){
     WARNING_message("-nodata used but -save1D not used ==> you get no output!") ;
   }

   if( nodata || strcmp(prefix,"NULL") == 0 ){
     INFO_message("3dLSS ends since prefix is 'NULL' or -nodata was used") ;
     exit(0) ;
   }

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

   if( verb ) INFO_message("creating output datset in memory") ;

   outset = EDIT_empty_copy(inset) ;
   EDIT_dset_items( outset ,
                      ADN_prefix    , prefix    ,
                      ADN_datum_all , MRI_float ,
                      ADN_brick_fac , NULL      ,
                      ADN_nvals     , nS        ,
                      ADN_ntt       , nS        ,
                    ADN_none ) ;
   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dLSS" , argc,argv , outset ) ;
   for( kk=0 ; kk < nS ; kk++ ){
     EDIT_substitute_brick( outset , kk , MRI_float , NULL ) ;
     sprintf(nbuf,"%s#%03d",stlab,kk) ;
     EDIT_BRICK_LABEL( outset , kk , nbuf ) ;
   }

   /*----- convert input dataset to vectim -----*/

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

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   inset_mrv = THD_dset_to_vectim( inset , mask , 0 ) ;
   DSET_unload(inset) ;

   /*----- compute dot products, store results -----*/

   if( verb ) INFO_message("computing away, me buckos!") ;

   nvec = inset_mrv->nvec ;
   for( kk=0 ; kk < nS ; kk++ ){
     ss = Sar + kk*ntime ;
     oo = DSET_ARRAY(outset,kk) ;
     for( iv=0 ; iv < nvec ; iv++ ){
       fv = VECTIM_PTR(inset_mrv,iv) ;
       for( sum=0.0f,ii=0 ; ii < ntime ; ii++ )
         sum += ss[ii] * fv[goodlist[ii]] ;
       oo[inset_mrv->ivec[iv]] = sum ;
     }
   }

   DSET_write(outset) ; WROTE_DSET(outset) ;

   /*-------- Hasta la vista, baby --------*/

   if( verb )
     INFO_message("3dLSS finished: total CPU=%.2f Elapsed=%.2f",
                  COX_cpu_time() , COX_clock_time() ) ;
   exit(0) ;
}
Ejemplo n.º 27
0
/*! Replace a voxel's value by the value's rank in the entire set of input datasets */
int main( int argc , char * argv[] )
{
   THD_3dim_dataset ** dsets_in = NULL, *dset=NULL; /*input and output datasets*/
   int nopt=0, nbriks=0, nsubbriks=0, ib=0, isb=0;
   byte *cmask=NULL;
   int *all_uniques=NULL, **uniques=NULL, *final_unq=NULL, *N_uniques=NULL;
   int N_final_unq=0, iun=0, total_unq=0;
   INT_HASH_DATUM *rmap=NULL, *hd=NULL;
   int imax=0, iunq=0, ii=0, id = 0;
   long int off=0;
   char *prefix=NULL;
   char stmp[THD_MAX_PREFIX+1]={""}; 
   FILE *fout=NULL;

   /*----- Read command line -----*/
   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      Rank_help ();
      exit(0) ;
   }

   mainENTRY("3dRank main"); machdep(); AFNI_logger("3dRank",argc,argv);
   nopt = 1 ;
   
   while( nopt < argc && argv[nopt][0] == '-' ){
      if( strcmp(argv[nopt],"-ver") == 0 ){
         PRINT_VERSION("3dRank"); AUTHOR("Ziad Saad");
         nopt++; continue;
      }

      if( strcmp(argv[nopt],"-help") == 0 ){
         Rank_help();
         exit(0) ;
      }

      if( strcmp(argv[nopt],"-prefix") == 0 ){
         ++nopt;
         if (nopt>=argc) {
            fprintf(stderr,"**ERROR: Need string after -prefix\n");
            exit(1);
         }
         prefix = argv[nopt] ;
         ++nopt; continue;
      }
      if( strcmp(argv[nopt],"-input") == 0 ){
         dsets_in = (THD_3dim_dataset**)
                        calloc(argc-nopt+1, sizeof(THD_3dim_dataset*));
         ++nopt; nbriks=0;
         while (nopt < argc ) {
            dsets_in[nbriks] = THD_open_dataset( argv[nopt] );
            if( !ISVALID_DSET(dsets_in[nbriks]) ){
              fprintf(stderr,"**ERROR: can't open dataset %s\n",argv[nopt]) ;
              exit(1);
            }
            ++nopt; ++nbriks; 
         }
         continue;
      }
      
      ERROR_exit( " Error - unknown option %s", argv[nopt]);
   } 
   if (nopt < argc) {
      ERROR_exit( " Error unexplained trailing option: %s\n", argv[nopt]);
   }
   if (!nbriks) {
      ERROR_exit( " Error no volumes entered on command line?");
   }
   
   /* some checks and inits*/
   nsubbriks = 0;
   for (ib = 0; ib<nbriks; ++ib) {
      if (!is_integral_dset(dsets_in[ib], 0)) {
         ERROR_exit("Dset %s is not of an integral data type.", 
                        DSET_PREFIX(dsets_in[ib]));
      }
      nsubbriks += DSET_NVALS(dsets_in[ib]);
   }
   
   /* Now get unique arrays */
   uniques = (int **)calloc(nsubbriks, sizeof(int*));
   N_uniques = (int *)calloc(nsubbriks, sizeof(int));
   total_unq = 0;
   iun = 0;
   for (ib = 0; ib<nbriks; ++ib) {
      DSET_mallocize(dsets_in[ib]); DSET_load(dsets_in[ib]);
      for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) {
         uniques[iun] = THD_unique_vals(dsets_in[ib], isb,
                                        &(N_uniques[iun]), cmask);
         total_unq += N_uniques[iun]; 
         ++iun;
      }
   }
   
   /* put all the arrays together and get the unique of the uniques */
   all_uniques = (int *)calloc(total_unq, sizeof(int));
   off=0;
   for (iun=0; iun<nsubbriks; ++iun) {
      memcpy(all_uniques+off, uniques[iun], N_uniques[iun]*sizeof(int));
      off += N_uniques[iun];
   }
   
   /* free intermediate unique arrays */
   for (iun=0; iun<nsubbriks; ++iun) {
      free(uniques[iun]);
   }
   free(uniques); uniques=NULL;
   free(N_uniques); N_uniques=NULL;
   
   /* get unique of catenated array */
   if (!(final_unq = UniqueInt (all_uniques, total_unq, &N_final_unq, 0 ))) {
      ERROR_exit( " Failed to get unique list (%d, %d, %d) ", 
                  total_unq, N_final_unq, nsubbriks);
   }
   free(all_uniques); all_uniques=NULL;
  
   if (prefix) {
      snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
               "%s.rankmap.1D", prefix);
   } else {
      if (nbriks == 1) {
        snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "%s.rankmap.1D", DSET_PREFIX(dsets_in[0]));
      } else { 
         snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "%s+.rankmap.1D", DSET_PREFIX(dsets_in[0]));
      }
   }
      
   if (stmp[0]) {
      if ((fout = fopen(stmp,"w"))) {
         fprintf(fout, "#Rank Map (%d unique values)\n", N_final_unq);
         fprintf(fout, "#Col. 0: Rank\n");
         fprintf(fout, "#Col. 1: Input Dset Value\n");
      }
   } 

   
   /* get the maximum integer in the unique array */
   imax = 0;
   for (iunq=0; iunq<N_final_unq; ++iunq) {
      if (final_unq[iunq] > imax) imax = final_unq[iunq]; 
      if (fout) fprintf(fout, "%d   %d\n", iunq, final_unq[iunq]);
      hd = (INT_HASH_DATUM*)calloc(1,sizeof(INT_HASH_DATUM));
      hd->id = final_unq[iunq];
      hd->index = iunq;
      HASH_ADD_INT(rmap, id, hd); 
   }
   
   fclose(fout); fout=NULL;

   /* now cycle over all dsets and replace their voxel values with rank */
   for (ib = 0; ib<nbriks; ++ib) {
      for (isb=0; isb<DSET_NVALS(dsets_in[ib]); ++isb) {
         EDIT_BRICK_LABEL(  dsets_in[ib],isb, "rank" ) ;
         EDIT_BRICK_TO_NOSTAT(  dsets_in[ib],isb ) ;
         EDIT_BRICK_FACTOR( dsets_in[ib],isb, 0.0);/* no factors for rank*/
         switch (DSET_BRICK_TYPE(dsets_in[ib],isb) ){
            default:
               fprintf(stderr,
                        "** Bad dset type for unique operation.\n"
                        "Only Byte, Short, and float dsets are allowed.\n");
               break ; /* this should not happen here, 
                        so don't bother returning*/
            case MRI_short:{
               short *mar = (short *) DSET_ARRAY(dsets_in[ib],isb) ;
               if (imax >  MRI_TYPE_maxval[MRI_short]) {
                  WARNING_message("Maximum rank value of %d is\n"
                                  "than maximum value for dset datatype of %d\n",
                                  imax, MRI_TYPE_maxval[MRI_short]);
               }
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii];
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (short)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;
            case MRI_byte:{
               byte *mar ;
               if (imax >  MRI_TYPE_maxval[MRI_short]) {
                  WARNING_message("Maximum rank value of %d is\n"
                                  "than maximum value for dset datatype of %d\n",
                                  imax, MRI_TYPE_maxval[MRI_byte]);
               }
               mar = (byte *) DSET_ARRAY(dsets_in[ib],isb) ;
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii];
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (byte)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;
            case MRI_float:{
               float *mar = (float *) DSET_ARRAY(dsets_in[ib],isb) ;
               for( ii=0 ; ii < DSET_NVOX(dsets_in[ib]) ; ii++ )
                  if (!cmask || cmask[ii]) {
                     id = (int)mar[ii]; /* Assuming float is integral valued */
                     HASH_FIND_INT(rmap,&id ,hd);
                     if (hd) mar[ii] = (float)(hd->index); 
                     else 
                       ERROR_exit("** Failed to find key %d in hash table\n",id);
                  } else mar[ii] = 0;
            }
            break ;

         }
      }

      /* update range, etc. */
      THD_load_statistics(dsets_in[ib]);
      
      /* Now write the bricks */
      if (prefix) {
         if (nbriks == 1) { 
            snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                     "%s", prefix);
         } else {
            snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                     "r%02d.%s", ib, prefix);
         }
      } else {
         snprintf(stmp, sizeof(char)*THD_MAX_PREFIX, 
                  "rank.%s", DSET_PREFIX(dsets_in[ib]));
      }
      EDIT_dset_items( dsets_in[ib] ,
                       ADN_prefix   , stmp ,
                       ADN_none ) ;
      
      /* change storage mode, this way prefix will determine
         format of output dset */
      dsets_in[ib]->dblk->diskptr->storage_mode = STORAGE_BY_BRICK;
      
      tross_Make_History( "3dRank" , argc, argv , dsets_in[ib] ) ;
      if (DSET_IS_MASTERED(dsets_in[ib])) {
         /*  THD_write_3dim_dataset won't write a mastered dude */
         dset = EDIT_full_copy(dsets_in[ib],stmp); 
      } else {
         dset = dsets_in[ib];
      }
      
      /* New ID */
      ZERO_IDCODE(dset->idcode);
      dset->idcode = MCW_new_idcode() ;
      
      if (!THD_write_3dim_dataset( NULL, stmp, dset,True )) {
         ERROR_message("Failed to write %s", stmp);
         exit(1);  
      } else {
         WROTE_DSET(dsets_in[ib]); 
         if (dset != dsets_in[ib]) DSET_deletepp(dset);
         DSET_deletepp(dsets_in[ib]);
         
      }
   }
   
   /* destroy hash */
   while (rmap) {
      hd = rmap;
      HASH_DEL(rmap,hd);
      free(hd);
   }

   free(final_unq);  final_unq=NULL;
   
   exit(0);
}
Ejemplo n.º 28
0
char * MASKAVE_main( PLUGIN_interface * plint )
{
   MCW_idcode * idc ;
   THD_3dim_dataset * input_dset , * mask_dset ;
   int iv , mcount , nvox , ii , sigmait , nvals=0 , doall , ivbot,ivtop ;
   float mask_bot=666.0 , mask_top=-666.0 ;
   double sum=0.0 , sigma=0.0 ;
   float * sumar=NULL , * sigmar=NULL ;
   char * tag , * str , buf[64] , abuf[32],sbuf[32] ;
   byte * mmm ;

   char * cname=NULL ;  /* 06 Aug 1998 */
   int    cdisk=0 ;     /* 22 Aug 2000 */
   int miv=0 ;

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

   if( plint == NULL )
      return "*************************\n"
             "MASKAVE_main:  NULL input\n"
             "*************************"  ;

   /*-- read 1st line --*/

   PLUTO_next_option(plint) ;
   idc        = PLUTO_get_idcode(plint) ;
   input_dset = PLUTO_find_dset(idc) ;
   if( input_dset == NULL )
      return "********************************\n"
             "MASKAVE_main:  bad input dataset\n"
             "********************************"  ;

   iv = (int) PLUTO_get_number(plint) ;
   if( iv >= DSET_NVALS(input_dset) )
      return "**********************************\n"
             "MASKAVE_main:  bad input sub-brick\n"
             "**********************************" ;
   doall = (iv < 0) ;
   if( doall ){
      nvals  = DSET_NVALS(input_dset) ;
      ivbot  = 0 ; ivtop = nvals-1 ;
   } else {
      ivbot = ivtop = iv ;
   }
   DSET_load(input_dset) ;
   if( DSET_ARRAY(input_dset,ivbot) == NULL )
      return "*********************************\n"
             "MASKAVE_main:  can't load dataset\n"
             "*********************************"  ;
   nvox = DSET_NVOX(input_dset) ;

   /*-- read 2nd line --*/

   PLUTO_next_option(plint) ;
   idc       = PLUTO_get_idcode(plint) ;
   mask_dset = PLUTO_find_dset(idc) ;

   if( mask_dset == NULL )
      return "*******************************\n"
             "MASKAVE_main:  bad mask dataset\n"
             "*******************************"  ;

   if( DSET_NVOX(mask_dset) != nvox )
      return "*************************************************************\n"
             "MASKAVE_main: mask input dataset doesn't match source dataset\n"
             "*************************************************************"  ;

   miv = (int) PLUTO_get_number(plint) ;  /* 06 Aug 1998 */
   if( miv >= DSET_NVALS(mask_dset) )
      return "*****************************************************\n"
             "MASKAVE_main: mask dataset sub-brick index is too big\n"
             "*****************************************************"  ;

   DSET_load(mask_dset) ;
   if( DSET_ARRAY(mask_dset,0) == NULL )
      return "**************************************\n"
             "MASKAVE_main:  can't load mask dataset\n"
             "**************************************"  ;

   /*-- read optional lines --*/

   while( (tag=PLUTO_get_optiontag(plint)) != NULL ){

      if( strcmp(tag,"Range") == 0 ){
         mask_bot = PLUTO_get_number(plint) ;
         mask_top = PLUTO_get_number(plint) ;
         continue ;
      }

      if( strcmp(tag,"1D Save") == 0 ){
         char * yn ;
         cname = PLUTO_get_string(plint) ;
         yn    = PLUTO_get_string(plint) ;
         cdisk = (strcmp(yn,yesno_list[0]) == 0) ;
         continue ;
      }

   }

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

   /*-- build a byte mask array --*/

   mmm = (byte *) malloc( sizeof(byte) * nvox ) ;
   if( mmm == NULL )
      return "*** Can't malloc workspace! ***" ;

   /* separate code for each input data type */

   switch( DSET_BRICK_TYPE(mask_dset,miv) ){
      default:
         free(mmm) ;
         return "*** Can't use mask dataset -- illegal data type! ***" ;

      case MRI_short:{
         short mbot , mtop ;
         short * mar = (short *) DSET_ARRAY(mask_dset,miv) ;
         float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ;
         if( mfac == 0.0 ) mfac = 1.0 ;
         if( mask_bot <= mask_top ){
            mbot = SHORTIZE(mask_bot/mfac) ;
            mtop = SHORTIZE(mask_top/mfac) ;
         } else {
            mbot = (short) -MRI_TYPE_maxval[MRI_short] ;
            mtop = (short)  MRI_TYPE_maxval[MRI_short] ;
         }
         for( mcount=0,ii=0 ; ii < nvox ; ii++ )
            if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; }
            else                                                    { mmm[ii] = 0 ; }
      }
      break ;

      case MRI_byte:{
         byte mbot , mtop ;
         byte * mar = (byte *) DSET_ARRAY(mask_dset,miv) ;
         float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ;
         if( mfac == 0.0 ) mfac = 1.0 ;
         if( mask_bot <= mask_top ){
            mbot = BYTEIZE(mask_bot/mfac) ;
            mtop = BYTEIZE(mask_top/mfac) ;
            if( mtop == 0 ){
               free(mmm) ;
               return "*** Illegal mask range for mask dataset of bytes. ***" ;
            }
         } else {
            mbot = 0 ;
            mtop = (byte) MRI_TYPE_maxval[MRI_short] ;
         }
         for( mcount=0,ii=0 ; ii < nvox ; ii++ )
            if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; }
            else                                                    { mmm[ii] = 0 ; }
      }
      break ;

      case MRI_float:{
         float mbot , mtop ;
         float * mar = (float *) DSET_ARRAY(mask_dset,miv) ;
         float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ;
         if( mfac == 0.0 ) mfac = 1.0 ;
         if( mask_bot <= mask_top ){
            mbot = (float) (mask_bot/mfac) ;
            mtop = (float) (mask_top/mfac) ;
         } else {
            mbot = -WAY_BIG ;
            mtop =  WAY_BIG ;
         }
         for( mcount=0,ii=0 ; ii < nvox ; ii++ )
            if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; }
            else                                                    { mmm[ii] = 0 ; }
      }
      break ;
   }

   if( mcount == 0 ){
      free(mmm) ;
      return "*** No voxels survive the masking operations! ***" ;
   }
   sigmait = (mcount > 1) ;

   /*-- compute statistics --*/

   if( doall ){
      sumar  = (float *) malloc( sizeof(float) * nvals ) ;
      sigmar = (float *) malloc( sizeof(float) * nvals ) ;
   }

   for( iv=ivbot ; iv <= ivtop ; iv++ ){
      sum = sigma = 0.0 ;                         /* 13 Dec 1999 */
      switch( DSET_BRICK_TYPE(input_dset,iv) ){

         default:
            free(mmm) ; if( doall ){ free(sumar) ; free(sigmar) ; }
            return "*** Can't use source dataset -- illegal data type! ***" ;

         case MRI_short:{
            short * bar = (short *) DSET_ARRAY(input_dset,iv) ;
            float mfac = DSET_BRICK_FACTOR(input_dset,iv) ;
            if( mfac == 0.0 ) mfac = 1.0 ;

            for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ;
            sum = sum / mcount ;

            if( sigmait ){
               for( ii=0 ; ii < nvox ; ii++ )
                  if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ;
               sigma = mfac * sqrt( sigma/(mcount-1) ) ;
            }
            sum = mfac * sum ;
         }
         break ;

         case MRI_byte:{
            byte * bar = (byte *) DSET_ARRAY(input_dset,iv) ;
            float mfac = DSET_BRICK_FACTOR(input_dset,iv) ;
            if( mfac == 0.0 ) mfac = 1.0 ;

            for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ;
            sum = sum / mcount ;

            if( sigmait ){
               for( ii=0 ; ii < nvox ; ii++ )
                  if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ;
               sigma = mfac * sqrt( sigma/(mcount-1) ) ;
            }
            sum = mfac * sum ;
         }
         break ;

         case MRI_float:{
            float * bar = (float *) DSET_ARRAY(input_dset,iv) ;
            float mfac = DSET_BRICK_FACTOR(input_dset,iv) ;
            if( mfac == 0.0 ) mfac = 1.0 ;

            for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ;
            sum = sum / mcount ;

            if( sigmait ){
               for( ii=0 ; ii < nvox ; ii++ )
                  if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ;
               sigma = mfac * sqrt( sigma/(mcount-1) ) ;
            }
            sum = mfac * sum ;
         }
         break ;
      }

      if( doall ){ sumar[iv] = sum ; sigmar[iv] = sigma ; }
   }

   free(mmm) ;

   /*-- send report --*/

   if( doall ){
      str = (char *) malloc( 1024 + 64*nvals ) ;
      sprintf(str," ****** ROI statistics ****** \n"
                  " Source  = %s [all sub-bricks] \n"
                  " Mask    = %s [%s]" ,
              DSET_FILECODE(input_dset) ,
              DSET_FILECODE(mask_dset)  , DSET_BRICK_LABEL(mask_dset,miv) ) ;
      if( mask_bot <= mask_top ){
         sprintf(buf," [range %g .. %g]" , mask_bot , mask_top ) ;
         strcat(str,buf) ;
      }
      strcat(str," \n") ;
      sprintf(buf," Count   = %d voxels\n",mcount) ; strcat(str,buf) ;
      for( iv=0 ; iv < nvals ; iv++ ){
         AV_fval_to_char( sumar[iv]  , abuf ) ;
         AV_fval_to_char( sigmar[iv] , sbuf ) ;
         sprintf(buf," Average = %9.9s  Sigma = %9.9s [%s]  \n",
                 abuf,sbuf , DSET_BRICK_LABEL(input_dset,iv) ) ;
         strcat(str,buf) ;
      }
      PLUTO_popup_textwin( plint , str ) ;

      /* 06 Aug 1998 */

      if( cname != NULL && cname[0] != '\0' ){
         MRI_IMAGE * qim = mri_new_vol_empty( nvals,1,1 , MRI_float ) ;
         mri_fix_data_pointer( sumar , qim ) ;
         PLUTO_register_timeseries( cname , qim ) ;

         if( cdisk ){                         /* 22 Aug 2000 */
            if( PLUTO_prefix_ok(cname) ){
               char * cn ;
               if( strstr(cname,".1D") == NULL ){
                  cn = malloc(strlen(cname)+8) ;
                  strcpy(cn,cname) ; strcat(cn,".1D") ;
               } else {
                  cn = cname ;
               }
               mri_write_1D( cn , qim ) ;
               if( cn != cname ) free(cn) ;
            } else {
               PLUTO_popup_transient(plint," \n"
                                           "** Illegal filename **\n"
                                           "** in 'To Disk?' !! **\n" ) ;
            }
         }

         mri_fix_data_pointer( NULL , qim ) ; mri_free(qim) ;
      }

      free(str) ; free(sumar) ; free(sigmar) ;

   } else if( mask_bot <= mask_top ){
      str = (char *) malloc( 1024 ) ;
      sprintf( str , " *** ROI Statistics *** \n"
                     " Source  = %s [%s] \n"
                     " Mask    = %s [%s] [range %g .. %g] \n"
                     " Count   = %d voxels \n"
                     " Average = %g \n"
                     " Sigma   = %g " ,
               DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) ,
               DSET_FILECODE(mask_dset)  , DSET_BRICK_LABEL(mask_dset,miv)    ,
               mask_bot , mask_top , mcount , sum , sigma ) ;
      PLUTO_popup_message(plint,str) ;
      free(str) ;

   } else {
      str = (char *) malloc( 1024 ) ;
      sprintf( str , " *** ROI Statistics *** \n"
                     " Source  = %s [%s] \n"
                     " Mask    = %s [%s] \n"
                     " Count   = %d voxels \n"
                     " Average = %g \n"
                     " Sigma   = %g " ,
               DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) ,
               DSET_FILECODE(mask_dset)  , DSET_BRICK_LABEL(mask_dset,miv)    ,
               mcount , sum , sigma ) ;
      PLUTO_popup_message(plint,str) ;
      free(str) ;
   }

   return NULL ;
}
Ejemplo n.º 29
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);
}
THD_3dim_dataset * THD_deghoster( THD_3dim_dataset *inset ,
                                  THD_3dim_dataset *filset,
                                  int pe , int fe , int se )
{
    MRI_IMAGE *medim=NULL , *tim=NULL , *oim=NULL ;
    float cval, *mar=NULL , *tar=NULL , *oar=NULL ;
    float *xzero_t=NULL , *thet1_t=NULL , *dparr_t=NULL , t1med,t1bmv;
    byte *bmask=NULL , *amask=NULL , sm ;
    int nvox , nx,ny,nz , dp=0,df=0,ds=0 , np=0,nf=0,ns=0,np2,nf2 ;
    int pp,ff,ss,nfp , ii , ppg , nsm,ism , vv,nv , iim , sskip ;
    THD_3dim_dataset *outset=NULL ;
    float iy,iyn ;
    float_pair mp ;

    /* create brain mask (bmask) */

    medim = THD_median_brick(inset) ;
    bmask = DEG_automask_image(medim) ;  /* brain mask (we hope) */

    nx = medim->nx ;
    ny = medim->ny ;
    nz = medim->nz ;
    nvox = medim->nvox ;
    nv = DSET_NVALS(inset) ;

    /* estimate noise level from data outside the mask (crudely) */

    mar  = MRI_FLOAT_PTR(medim) ;
    cval = THD_cliplevel(medim,CLFRAC) ;
    for( noise_estimate=0.0f,iim=ii=0 ; ii < nvox ; ii++ ) {
        if( !bmask[ii] && mar[ii] < cval ) {
            noise_estimate += mar[ii] ;
            iim++ ;
        }
    }
    if( iim < 9 ) {
        FREEUP;    /* should not happen */
        return NULL;
    }
    noise_estimate /= iim ;  /* initial estimate of noise level */
    if( verb > 1 )
        INFO_message("Global crude noise_estimate = %g",noise_estimate) ;

    /* chop out all sub-threshold voxels (amask) */

    amask = (byte *)malloc(sizeof(byte)*nvox) ;  /* clipped brain mask */
    memcpy(amask,bmask,sizeof(byte)*nvox) ;
    for( ii=0 ; ii < nvox ; ii++ )
        if( amask[ii] && mar[ii] < cval ) amask[ii] = 0 ;

    /* setting up slice coordinates f,p,s */

    if( pe == 1 ) {
        dp = 1     ;
        np = nx ;
    }
    else if( pe == 2 ) {
        dp = nx    ;
        np = ny ;
    }
    else if( pe == 3 ) {
        dp = nx*ny ;
        np = ns ;
    }

    if( fe == 1 ) {
        df = 1     ;
        nf = nx ;
    }
    else if( fe == 2 ) {
        df = nx    ;
        nf = ny ;
    }
    else if( fe == 3 ) {
        df = nx*ny ;
        nf = nz ;
    }

    if( se == 1 ) {
        ds = 1     ;
        ns = nx ;
    }
    else if( se == 2 ) {
        ds = nx    ;
        ns = ny ;
    }
    else if( se == 3 ) {
        ds = nx*ny ;
        ns = nz ;
    }

#undef  IJK
#define IJK(f,p,s) ((f)*df+(p)*dp+(s)*ds)

    nvim = nfp = nf * np ;
    np2 = np / 2 ;
    nf2 = nf / 2 ;
    smask = (byte * )malloc(sizeof(byte) *nfp) ;
    bvec  = (float *)malloc(sizeof(float)*nfp) ;
    gvec  = (float *)malloc(sizeof(float)*nfp) ;
    xvec  = (float *)malloc(sizeof(float)*nfp) ;
    yvec  = (float *)malloc(sizeof(float)*nfp) ;
    ctvec = (float *)malloc(sizeof(float)*nfp) ;
    stvec = (float *)malloc(sizeof(float)*nfp) ;

    bvim  = (float *)malloc(sizeof(float)*nvim) ;
    gvim  = (float *)malloc(sizeof(float)*nvim) ;
    xvim  = (float *)malloc(sizeof(float)*nvim) ;
    yvim  = (float *)malloc(sizeof(float)*nvim) ;
    ctvim = (float *)malloc(sizeof(float)*nvim) ;
    stvim = (float *)malloc(sizeof(float)*nvim) ;

    xzero_t = (float *)malloc(sizeof(float)*nv) ;
    thet1_t = (float *)malloc(sizeof(float)*nv) ;
    dparr_t = (float *)malloc(sizeof(float)*nv) ;

    /* copy input to output (will be ghost edited later) */

    outset = EDIT_empty_copy(inset) ;
    for( vv=0 ; vv < nv ; vv++ ) {
        oim = THD_extract_float_brick(vv,inset) ;
        oar = MRI_FLOAT_PTR(oim) ;
        EDIT_BRICK_FACTOR( outset , vv , 0.0f ) ;
        EDIT_substitute_brick( outset , vv , MRI_float , oar ) ;
        mri_clear_and_free(oim) ;
    }

    /* loop over slices */

    for( ss=0 ; ss < ns ; ss++ ) {

        /* make copy of brain mask in this slice,
           then edit it down to voxels in the brain
           whose N/2 point is outside the brain (smask) */

        for( iim=nsm=pp=0 ; pp < np ; pp++ ) {
            if( pp >= np2 ) ppg = pp-np2 ;
            else ppg = pp+np2 ;
            for( ff=0 ; ff < nf ; ff++,iim++ ) {
                smask[iim] = sm = amask[IJK(ff,pp,ss)] && !bmask[IJK(ff,ppg,ss)] ;
                xvim[iim] = ff-nf2 ;
                yvim[iim] = pp-np2 ;
                if( sm ) {
                    xvec[nsm] = xvim[iim];
                    yvec[nsm] = yvim[iim];
                    nsm++;
                }
            }
        }
        if( nsm < nfp/20 ) {     /* skip this slice */
            if( verb )
                INFO_message("deghost: skipping slice #%d -- too few points in smask",ss) ;
            continue ;
        }
        nvec = nsm ;
        if( verb )
            INFO_message("deghost: processing slice #%d",ss) ;

        /* smask is now the mask of brain voxels whose
           Nyquist ghost locations are NOT in the brain mask */

        /* loop over time points, estimate the ghost correction parameters */

        for( vv=0 ; vv < nv ; vv++ ) {

            tim = THD_extract_float_brick(vv,filset) ;
            tar = MRI_FLOAT_PTR(tim) ;

            /* extract the vector of image values in smask,
               and the vector of image values at the ghost locations */

            for( iim=ism=pp=0 ; pp < np ; pp++ ) {
                if( pp >= np2 ) ppg = pp-np2 ;
                else ppg = pp+np2 ;
                for( ff=0 ; ff < nf ; ff++,iim++ ) {
                    bvim[iim] = tar[IJK(ff,pp,ss)] ;
                    gvim[iim] = tar[IJK(ff,ppg,ss)] ;
                    if( smask[iim] ) {
                        bvec[ism] = bvim[iim];
                        gvec[ism++] = gvim[iim];
                    }
                }
            }

            /* fit the theta parameters from the smask region and save them */

            optimize_theta() ;

            xzero_t[vv] = theta_par[0] ;
            thet1_t[vv] = theta_par[1] ;
            dparr_t[vv] = d_par ;

            mri_free(tim) ;
            tim = NULL ;
        }

        /* now check the slice parameters for reasonability */

        sskip = 0 ;
        if( nv > 4 ) {
            orfilt_len = 3 ;
            orfilt_vector(nv,xzero_t) ;
            orfilt_vector(nv,thet1_t) ;
            orfilt_vector(nv,dparr_t) ;
            qmedmadbmv_float(nv,thet1_t,&t1med,NULL,&t1bmv) ;
            if( verb )
                ININFO_message("  slice #%d -- median(theta1)=%g stdev=%g ratio=%g",
                               ss,t1med,t1bmv,(t1bmv>0.0f)?t1med/t1bmv:0.0f) ;
            if( t1med == 0.0f || fabsf(t1med) <= 0.111f*t1bmv ) {
                sskip = 1 ;
                ININFO_message("  skipping slice #%d -- theta1 too small",ss) ;
            }
        }
        if( sskip ) continue ;  /* skip processing this slice */

        /* loop over time points, estimate the un-ghosted image */

        for( vv=0 ; vv < nv ; vv++ ) {

            tim = THD_extract_float_brick(vv,inset) ; /* input data for slice */
            tar = MRI_FLOAT_PTR(tim) ;
            oar = DSET_ARRAY(outset,vv) ;             /* output data for volume */

            /* compute theta at each voxel */

            if( thet1_t[vv] == 0.0f ) continue ; /* ghost amplitude is 0 ==> skip this time point */

            if( verb > 1 )
                ININFO_message("  slice=%d index=%d  theta = %g  %g  %g",
                               ss,vv,xzero_t[vv],thet1_t[vv],dparr_t[vv]) ;

            theta_par[0] = xzero_t[vv];
            theta_par[1] = thet1_t[vv];
            d_par = dparr_t[vv];
            compute_thvim() ;

            /* compute output values at each voxel:
                (a) inside the smask                  == voxel in brain, N/2 ghost isn't
                (b) not in the smask but in the bmask == voxel && N/2 ghost are in brain
                (c) otherwise                         == voxel is unimportant effluvium  */

            for( iim=pp=0 ; pp < np ; pp++ ) {
                if( pp >= np2 ) ppg = pp-np2 ;
                else ppg = pp+np2 ;
                for( ff=0 ; ff < nf ; ff++,iim++ ) {
                    iy  = tar[IJK(ff,pp,ss)] ;
                    iyn = tar[IJK(ff,ppg,ss)] ;
                    if( smask[iim] ) {
                        oar[IJK(ff,pp,ss)] = find_mhat( iy,iyn , ctvim[iim],stvim[iim] , d_par ) ;
                        oar[IJK(ff,ppg,ss)] = 0.0f ;
                    } else if( bmask[IJK(ff,pp,ss)] && bmask[IJK(ff,ppg,ss)] ) {
                        if( ppg > pp ) {
                            mp = find_mpair( iy,iyn , ctvim[iim],stvim[iim] , d_par ) ;
                            oar[IJK(ff,pp,ss)] = mp.a ;
                            oar[IJK(ff,ppg,ss)] = mp.b ;
                        }
                    } else {
                        /* nada: output is already a copy of input */
                    }
                }
            }
        }

    } /* end of loop over slices */

    FREEUP ;
    return outset ;
}