コード例 #1
0
/*---------------------------------------------------------------------
  23 Feb 2012: Return the absolute value of the difference between 
               two volumes, divided by the number of voxels
               and the number of sub-bricks. Voxels that are zero
               in both sets are not counted.
               Comparisons are done after conversion of data to double
    return = -1.0 ERROR
           =  0.0 Exactly the same
-----------------------------------------------------------------------*/
double THD_diff_vol_vals(THD_3dim_dataset *d1, THD_3dim_dataset *d2, int scl) {
   double dd=0.0, denom=0.0;
   int i=0, k=0;
   double *a1=NULL, *a2=NULL;
   MRI_IMAGE *b1 = NULL , *b2 = NULL;
   
   ENTRY("THD_diff_vol_vals");
   
   if (!d1 && !d2) RETURN(dd);
   if (!d1 || !d2) RETURN(-1.0);

   if (!EQUIV_GRIDS(d1,d2)) RETURN(-1.0);
   if (DSET_NVALS(d1) != DSET_NVALS(d2)) RETURN(-1.0);
  
   DSET_mallocize(d1) ; DSET_load(d1) ;
   DSET_mallocize(d2) ; DSET_load(d2) ;
   dd = 0.0; denom = 0;
   for (i=0; i<DSET_NVALS(d1); ++i) {
      b1 = THD_extract_double_brick(i, d1);
      b2 = THD_extract_double_brick(i, d2);
      a1 = MRI_DOUBLE_PTR(b1);
      a2 = MRI_DOUBLE_PTR(b2);
      for (k=0; k<DSET_NVOX(d1); ++k) {
         dd += ABS(a1[k]-a2[k]);
         if (a1[k]!=0.0 || a2[k]!=0.0) ++denom;
      }
      mri_clear_data_pointer(b1); mri_free(b1) ;
      mri_clear_data_pointer(b2); mri_free(b2) ;
   }
   if (scl && denom>0.0) dd /= denom;
   
   RETURN(dd);   
}  
コード例 #2
0
ファイル: 3dmask_tool.c プロジェクト: LJWilliams/Neuroimaging
/*
 * for each input dataset name
 *    open (check dims, etc.)
 *    dilate (zeropad, make binary, dilate, unpad, apply)
 *    fill list of bytemask datasets
 *
 * also, count total volumes
 */
int process_input_dsets(param_t * params)
{
   THD_3dim_dataset * dset, * dfirst=NULL;
   int                iset, nxyz;

   ENTRY("process_input_dsets");

   if( !params ) ERROR_exit("NULL inputs to PID");

   if( params->ndsets <= 0 ) {
      ERROR_message("process_input_dsets: no input datasets");
      RETURN(1);
   }

   /* allocate space for dsets array */
   params->dsets = (THD_3dim_dataset **)malloc(params->ndsets*
                                               sizeof(THD_3dim_dataset*));
   if( !params->dsets ) ERROR_exit("failed to allocate dset pointers");

   if( params->verb ) INFO_message("processing %d input datasets...",
                                   params->ndsets);
   
   /* warn user of dilations */
   if(params->verb && params->ndsets) {
      int pad = needed_padding(&params->IND);
      INFO_message("padding all datasets by %d (for dilations)", pad);
   }

   /* process the datasets */
   nxyz = 0;
   for( iset=0; iset < params->ndsets; iset++ ) {
      /* open and verify dataset */
      dset = THD_open_dataset(params->inputs[iset]);
      if( !dset ) ERROR_exit("failed to open mask dataset '%s'",
                             params->inputs[iset]);
      DSET_load(dset);  CHECK_LOAD_ERROR(dset);

      if( params->verb>1 ) INFO_message("loaded dset %s, with %d volumes",
                                        DSET_PREFIX(dset), DSET_NVALS(dset));

      if( nxyz == 0 ) { /* make an empty copy of the first dataset */
         nxyz = DSET_NVOX(dset);
         dfirst = EDIT_empty_copy(dset);
      }

      /* check for consistency in voxels and grid */
      if( DSET_NVOX(dset) != nxyz ) ERROR_exit("nvoxel mis-match");
      if( ! EQUIV_GRIDS(dset, dfirst) )
         WARNING_message("grid from dset %s does not match that of dset %s",
                         DSET_PREFIX(dset), DSET_PREFIX(dfirst));

      /* apply dilations to all volumes, returning bytemask datasets */
      params->dsets[iset] = apply_dilations(dset, &params->IND,1,params->verb);
      if( ! params->dsets[iset] ) RETURN(1);
   } 

   DSET_delete(dfirst); /* and nuke */

   RETURN(0);
}
コード例 #3
0
ファイル: 3dSatCheck.c プロジェクト: LJWilliams/Neuroimaging
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset ; int aa,ll ; char *cpt ; float val ;

   if( argc < 2 ){
     printf("Usage: 3dSatCheck dataset [...]\n"
            "\n"
            "Prints the 'raw' initial transient (saturation) check\n"
            "value for each dataset on the command line.  Round this\n"
            "number to the nearest integer to get an estimate of\n"
            "how many non-saturated time points start a dataset.\n"
           ) ;
     exit(0) ;
   }
   for( aa=1 ; aa < argc ; aa++ ){
     dset = THD_open_dataset( argv[aa] ) ; if( !ISVALID_DSET(dset) ) continue ;
     if( DSET_NVALS(dset) < 9 ) continue ;
     DSET_load(dset) ; if( !DSET_LOADED(dset) ) continue ;
     val = THD_saturation_check( dset , NULL , 0,0 ) ;
     ll = strlen(argv[aa]) ;
     cpt = (ll <= 50) ? argv[aa] : argv[aa]+(ll-50) ;
     INFO_message("%-50.50s = %.3f",cpt,val) ;
     DSET_delete(dset) ;
   }
   exit(0) ;
}
コード例 #4
0
/*----------------------------------------------------------------------
**
**  Main routine for this plugin (will be called from AFNI).
**
**----------------------------------------------------------------------
*/
char * HEMISUB_main( PLUGIN_interface * plint )
{
    THD_3dim_dataset * dset, * new_dset;
    MCW_idcode       * idc;
    hemi_s             hs = { 0 };
    char             * new_prefix;
    char             * ret_string = NULL;
    char             * tag;


    if ( plint == NULL )
	return  "------------------------\n"
		"HEMISUB_main: NULL input\n"
		"------------------------\n";

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

    if( dset == NULL )
	return "-------------------------------\n"
	       "HEMISUB_main: bad input dataset\n"
	       "-------------------------------";

    DSET_load( dset );

    PLUTO_next_option( plint );
    new_prefix = PLUTO_get_string( plint );
    if ( ! PLUTO_prefix_ok( new_prefix ) )
	return  "------------------------\n"
		"HEMISUB_main: bad prefix\n"
		"------------------------\n";

    if ( ( new_dset = PLUTO_copy_dset( dset, new_prefix ) ) == NULL )
	return  "------------------------------------------\n"
		"HEMISUB_main: failed to copy input dataset\n"
		"------------------------------------------\n";

    tag = PLUTO_get_optiontag( plint );
    if ( tag && ! strcmp( tag, "Thresh Type" ) )
    {
	tag = PLUTO_get_string( plint );
	if ( tag != NULL )
	    hs.thresh_type = PLUTO_string_index( tag, NUM_T_OPTS, thresh_opts );
    }

    if ( ret_string = process_data( new_dset, &hs ) )
	return  ret_string;

    if ( PLUTO_add_dset( plint, new_dset, DSET_ACTION_MAKE_CURRENT ) )
    {
	THD_delete_3dim_dataset( new_dset, False );

	return  "---------------------------------------\n"
		"HEMISUB_main: failed to add new dataset\n"
		"---------------------------------------\n";
    }

    return NULL;
}
コード例 #5
0
/* - moved from 3dhistog.c               18 Dec 2012 [rickr] */
int THD_slow_minmax_dset(THD_3dim_dataset *dset, float *dmin, float *dmax,
                         int iv_bot, int iv_top)
{
   int iv_fim;
   float fimfac;
   float vbot , vtop, temp_fbot=1.0, temp_ftop=0.0 ;

   DSET_load(dset);

   for( iv_fim=iv_bot ; iv_fim <= iv_top ; iv_fim++ ){
     /* minimum and maximum for sub-brick */
     vbot = mri_min( DSET_BRICK(dset,iv_fim) ) ;
     vtop = mri_max( DSET_BRICK(dset,iv_fim) ) ;
     fimfac = DSET_BRICK_FACTOR(dset,iv_fim) ;
     if (fimfac == 0.0)  fimfac = 1.0;
     vbot *= fimfac ; vtop *= fimfac ;

     /* update global min and max */
     if ( temp_fbot > temp_ftop ) { /* first time, just copy */
        temp_fbot = vbot;
        temp_ftop = vtop;
     } else {
        if( vbot < temp_fbot ) temp_fbot = vbot;
        if( vtop > temp_ftop ) temp_ftop = vtop;
     }
   }
   *dmin = temp_fbot;
   *dmax = temp_ftop;

   return(0);
}
コード例 #6
0
ファイル: thd_orient.c プロジェクト: LJWilliams/Neuroimaging
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset ;
   MRI_IMAGE *im ;
   int iarg=1 ;

   if( strcmp(argv[1],"-nper") == 0 ){
      nper = strtol( argv[2] , NULL , 10 ) ;
      iarg = 3 ;
   }

   for( ; iarg < argc ; iarg++ ){
     printf("======= dataset %s  nper=%d ========\n",argv[iarg],nper) ;
     dset = THD_open_dataset(argv[iarg]) ;
     if( dset == NULL ) continue ;
     DSET_load(dset) ;
     im = DSET_BRICK(dset,0) ;
     im->dx = DSET_DX(dset) ;
     im->dy = DSET_DY(dset) ;
     im->dz = DSET_DZ(dset) ;
     (void) THD_orient_guess( im ) ;

     printf( "Data Axes Orientation:\n"
             "  first  (x) = %s\n"
             "  second (y) = %s\n"
             "  third  (z) = %s\n" ,
        ORIENT_typestr[dset->daxes->xxorient] ,
        ORIENT_typestr[dset->daxes->yyorient] ,
        ORIENT_typestr[dset->daxes->zzorient]  ) ;
     DSET_delete(dset) ;
   }

   exit(0) ;
}
コード例 #7
0
ファイル: thd_median.c プロジェクト: LJWilliams/Neuroimaging
MRI_IMAGE * THD_median_brick( THD_3dim_dataset *dset )
{
   int nvox , nvals , ii ;
   MRI_IMAGE *tsim , *medim ;
   float *medar ;
   float *tsar ;  /* 05 Nov 2001 */

ENTRY("THD_median_brick") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   DSET_load(dset) ;
   if( !DSET_LOADED(dset) ) RETURN(NULL) ;

   nvals = DSET_NVALS(dset) ;
   tsim  = DSET_BRICK(dset,0) ;

   if( nvals == 1 ){
     medim = mri_scale_to_float( DSET_BRICK_FACTOR(dset,0), tsim ) ;
     RETURN(medim) ;
   }

   medim = mri_new_conforming( tsim , MRI_float ) ;
   medar = MRI_FLOAT_PTR(medim) ;
   nvox  = DSET_NVOX(dset) ;

   tsar = (float *) calloc( sizeof(float),nvals+1 ) ; /* 05 Nov 2001 */
   for( ii=0 ; ii < nvox ; ii++ ){
     THD_extract_array( ii , dset , 0 , tsar ) ;     /* 05 Nov 2001 */
     medar[ii] = qmed_float( nvals , tsar ) ;
   }

   free(tsar) ; RETURN(medim) ;
}
コード例 #8
0
ファイル: thd_median.c プロジェクト: LJWilliams/Neuroimaging
MRI_IMARR * THD_medmad_bricks( THD_3dim_dataset *dset )
{
   int nvox , nvals , ii ;
   MRI_IMAGE *tsim , *madim, *medim ;
   float             *madar, *medar ;
   MRI_IMARR *imar ;
   float *tsar ;

ENTRY("THD_medmad_bricks") ;

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

   nvals = DSET_NVALS(dset) ; if( nvals == 1 ) RETURN(NULL) ;

   DSET_load(dset) ;  if( !DSET_LOADED(dset) ) RETURN(NULL) ;
   tsim  = DSET_BRICK(dset,0) ;

   madim = mri_new_conforming( tsim , MRI_float ) ;
   madar = MRI_FLOAT_PTR(madim) ;
   medim = mri_new_conforming( tsim , MRI_float ) ;
   medar = MRI_FLOAT_PTR(medim) ;
   nvox  = DSET_NVOX(dset) ;

   tsar = (float *) calloc( sizeof(float),nvals+1 ) ;
   for( ii=0 ; ii < nvox ; ii++ ){
     THD_extract_array( ii , dset , 0 , tsar ) ;
     qmedmad_float( nvals , tsar , medar+ii , madar+ii ) ;
   }

   free(tsar) ;
   INIT_IMARR(imar) ; ADDTO_IMARR(imar,medim) ; ADDTO_IMARR(imar,madim) ;
   RETURN(imar) ;
}
コード例 #9
0
ファイル: thd_median.c プロジェクト: LJWilliams/Neuroimaging
MRI_IMAGE * THD_rms_brick( THD_3dim_dataset *dset )
{
   int nvox , nvals , ii , jj ;
   MRI_IMAGE *tsim , *medim ;
   float *medar , sum,fac ;
   float *tsar ;

ENTRY("THD_rms_brick") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   DSET_load(dset) ;
   if( !DSET_LOADED(dset) ) RETURN(NULL) ;

   nvals = DSET_NVALS(dset)   ; fac = 1.0 / nvals ;
   tsim  = DSET_BRICK(dset,0) ;

   if( nvals == 1 ){
     medim = mri_scale_to_float( DSET_BRICK_FACTOR(dset,0), tsim ) ;
     RETURN(medim) ;
   }

   medim = mri_new_conforming( tsim , MRI_float ) ;
   medar = MRI_FLOAT_PTR(medim) ;
   nvox  = DSET_NVOX(dset) ;

   tsar = (float *) calloc( sizeof(float),nvals+1 ) ;
   for( ii=0 ; ii < nvox ; ii++ ){
     THD_extract_array( ii , dset , 0 , tsar ) ;
     for( sum=0.0,jj=0 ; jj < nvals ; jj++ ) sum += tsar[jj]*tsar[jj] ;
     medar[ii] = sqrtf(fac * sum) ;
   }

   free(tsar) ; RETURN(medim) ;
}
コード例 #10
0
ファイル: thd_entropy16.c プロジェクト: neurodebian/afni
double ENTROPY_dataset( THD_3dim_dataset *dset )
{
   if( !ISVALID_DSET(dset) ) return(0.0) ;
   DSET_load(dset) ;
   if( !DSET_LOADED(dset) ) return(0.0) ;
   return ENTROPY_datablock( dset->dblk ) ;
}
コード例 #11
0
ファイル: retroicor.c プロジェクト: LJWilliams/Neuroimaging
/* Calculates the average value for each voxel in dset across all timepoints.

   PRE:
   dset is a valid 3D+T dataset with at least 1 timepoint;
   ignore is the number of timepoints to ignore at the beginning of dset;
   0 <= ignore < number of timepoints in dset;

   POST:
   return value is NULL on error,
   else, return value is an array of floats with the same dimensions as the
   subbricks of dset, containing the voxel value averages;

   Note: The caller is responsible for free()ing the returned block of memory
   when done.

   Note2: The complex datatype is not supported, and any such bricks will
   result in an error (NULL return value).
*/
double * RIC_CalcVoxelMeans(const THD_3dim_dataset * dset, int ignore) {

    double * avg;       /* The voxel averages to be returned */
    float scalefactor; /* Current dset brick scaling factor */
    int ival, nvals;   /* Current, number of dset timepoints */
    int ivox, nvoxs;   /* Current, number of dset brick voxels */

    /* Quick check of arguments */
    if (!ISVALID_3DIM_DATASET(dset) || DSET_NVALS(dset) < 1 ||
	ignore < 0 || ignore >= DSET_NVALS(dset)) {

	return NULL;
    }

    /* Initialize */
    DSET_load(dset);
    nvals = DSET_NVALS(dset);
    nvoxs = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz;
    avg = malloc(sizeof(double) * nvoxs);
    if (avg == NULL) {
	return NULL;
    }

    /* Calculate the voxel averages; treat matrices as 1-D arrays */

    /* Zero the voxel sums */
    for (ivox = 0; ivox < nvoxs; ivox += 1) {
	avg[ivox] = 0.0;
    }

    /* Sum each voxel across time (and hope there are not too many points) */
    for (ival = ignore; ival < nvals; ival += 1) {
	scalefactor = DSET_BRICK_FACTOR(dset, ival);

	switch (DSET_BRICK_TYPE(dset, ival)) {
	case MRI_short:
	    RIC_CALCVOXELMEANS__DO_VOXSUM(short);
	    break;
	case MRI_byte:
	    RIC_CALCVOXELMEANS__DO_VOXSUM(byte);
	    break;
	case MRI_float:
	    RIC_CALCVOXELMEANS__DO_VOXSUM(float);
	    break;
	default: /* Unsupported datatype */
	    free(avg);
	    return NULL;
	}
    }

    /* Divide by number of timepoints to get average */
    nvals -= ignore;  /* We do not average over the ignored timepoints */
    for (ivox = 0; ivox < nvoxs; ivox += 1) {
	avg[ivox] /= nvals;
    }

    return avg;
}
コード例 #12
0
ファイル: SUMA_SegOpts.c プロジェクト: Gilles86/afni
THD_3dim_dataset *Seg_load_dset_eng( char *set_name, char *view ) 
{
   static char FuncName[]={"Seg_load_dset_eng"};
   THD_3dim_dataset *dset=NULL, *sdset=NULL;
   int i=0;
   byte make_cp=0;
   int verb=0;
   char sprefix[THD_MAX_PREFIX+10], *stmp=NULL;
   
   SUMA_ENTRY;
   
   dset = THD_open_dataset( set_name );
   if( !ISVALID_DSET(dset) ){
     fprintf(stderr,"**ERROR: can't open dataset %s\n",set_name) ;
     SUMA_RETURN(NULL);
   }
   
   DSET_mallocize(dset)   ; DSET_load(dset);
   
   for (i=0; i<DSET_NVALS(dset); ++i) {
      if (DSET_BRICK_TYPE(dset,i) != MRI_short) {
         if (verb) INFO_message("Sub-brick %d in %s not of type short.\n"
                       "Creating new short copy of dset ", 
                       i, DSET_PREFIX(dset));
         make_cp=1; break;
      }
   }
   
   if (make_cp) {
      if (!SUMA_ShortizeDset(&dset, -1.0)) {
         SUMA_S_Err("**ERROR: Failed to shortize");
         SUMA_RETURN(NULL);
      }
   }
   
   if (DSET_IS_MASTERED(dset)) {
      if (verb) INFO_message("Dset is mastered, making copy...");
      stmp = SUMA_ModifyName(set_name, "append", ".cp", NULL);
      sdset = dset;
      dset = EDIT_full_copy(sdset, stmp);
      free(stmp); DSET_delete(sdset); sdset = NULL;  
   }
      
   
   if (view) {
      if (view) {
               if (!strstr(view,"orig")) 
            EDIT_dset_items(dset,ADN_view_type, VIEW_ORIGINAL_TYPE, ADN_none); 
         else  if (!strstr(view,"acpc")) 
            EDIT_dset_items(dset,ADN_view_type, VIEW_ACPCALIGNED_TYPE, ADN_none);
         else  if (!strstr(view,"tlrc")) 
            EDIT_dset_items(dset ,ADN_view_type, VIEW_TALAIRACH_TYPE, ADN_none);
         else SUMA_S_Errv("View of %s is rubbish", view);
      }
   }
   
   SUMA_RETURN(dset);
}
コード例 #13
0
ファイル: 3destpdf.c プロジェクト: CesarCaballeroGaudes/afni
void get_options
(
  int argc,                        /* number of input arguments */
  char ** argv                     /* array of input arguments */ 
)

{
  int nopt = 1;                     /* input option argument counter */
  int ival, index;                  /* integer input */
  float fval;                       /* float input */
  char message[MAX_STRING_LENGTH];  /* error message */


  /*----- does user request help menu? -----*/
  if (argc < 2 || strncmp(argv[1], "-help", 5) == 0)  display_help_menu();  
   

  /*----- main loop over input options -----*/
  while (nopt < argc )
    {

      /*-----   -anat filename   -----*/
      if (strncmp(argv[nopt], "-anat", 5) == 0)
	{
	  nopt++;
	  if (nopt >= argc)  estPDF_error ("need argument after -anat ");
	  anat_filename = malloc (sizeof(char) * MAX_STRING_LENGTH);
	  MTEST (anat_filename);
	  strcpy (anat_filename, argv[nopt]);

	  anat = THD_open_one_dataset (anat_filename);
	  if (!ISVALID_3DIM_DATASET (anat))
	    {
	      sprintf (message, "Can't open dataset: %s\n", anat_filename); 
	      estPDF_error (message); 
	    } 
	  DSET_load(anat); CHECK_LOAD_ERROR(anat);

	  nopt++;
	  continue;
	}
      

      /*----- unknown command -----*/
      sprintf(message,"Unrecognized command line option: %s\n", argv[nopt]);
      estPDF_error (message);
      
    }

  
}
コード例 #14
0
ファイル: 3dTto1D.c プロジェクト: CesarCaballeroGaudes/afni
int fill_mask(options_t * opts)
{
   THD_3dim_dataset * mset;
   int nvox;

ENTRY("fill_mask");

   if( opts->automask ) {
      if( opts->verb ) INFO_message("creating automask...");

      opts->mask = THD_automask(opts->inset);
      if( ! opts->mask ) {
         ERROR_message("failed to apply -automask");
         RETURN(1);
      }

      RETURN(0);
   }

   if( opts->mask_name ) {
      if( opts->verb )
         INFO_message("reading mask dset from %s...", opts->mask_name);

      mset = THD_open_dataset( opts->mask_name );
      if( ! mset ) ERROR_exit("cannot open mask dset '%s'", opts->mask_name);
      nvox = DSET_NVOX(opts->inset);
      if( DSET_NVOX(mset) != nvox ) {
         ERROR_message("mask does not have the same voxel count as input");
         RETURN(1);
      }

      /* fill mask array and mask_nxyz, remove mask dset */
      DSET_load(mset); CHECK_LOAD_ERROR(mset);

      opts->mask = THD_makemask(mset, 0, 1, 0);
      DSET_delete(mset);

      if( ! opts->mask ) {
         ERROR_message("cannot make mask from '%s'", opts->mask_name);
         RETURN(1);
      }

      if( opts->verb > 1 )
         INFO_message("have mask with %d voxels", nvox);
   }

   RETURN(0);
}
コード例 #15
0
ファイル: thd_dset_to_vectim.c プロジェクト: ccraddock/afni
MRI_vectim * THD_dset_to_vectim_byslice( THD_3dim_dataset *dset, byte *mask ,
                                         int ignore , int kzbot , int kztop  )
{
   byte *mmm ;
   MRI_vectim *mrv=NULL ;
   int kk,iv , nvals , nvox , nmask , nxy , nz ;

ENTRY("THD_dset_to_vectim_byslice") ;

                     if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   DSET_load(dset) ; if( !DSET_LOADED(dset)  ) RETURN(NULL) ;

   nvals = DSET_NVALS(dset) ; if( nvals <= 0 ) RETURN(NULL) ;
   nvox  = DSET_NVOX(dset) ;

   nxy = DSET_NX(dset) * DSET_NY(dset) ; nz = DSET_NZ(dset) ;

   if( kzbot <  0  ) kzbot = 0 ;
   if( kztop >= nz ) kztop = nz-1 ;
   if( kztop < kzbot ) RETURN(NULL) ;
   if( kzbot == 0 && kztop == nz-1 ){
     mrv = THD_dset_to_vectim( dset , mask, ignore ) ; RETURN(mrv) ;
   }

   /* make a mask that includes cutting out un-desirable slices */

   { int ibot , itop , ii ;
#pragma omp critical (MALLOC)
     mmm = (byte *)malloc(sizeof(byte)*nvox) ;
     if( mask == NULL ) AAmemset( mmm ,    1 , sizeof(byte)*nvox ) ;
     else               AAmemcpy( mmm , mask , sizeof(byte)*nvox ) ;
     if( kzbot > 0 )
       AAmemset( mmm               , 0 , sizeof(byte)*kzbot       *nxy ) ;
     if( kztop < nz-1 )
       AAmemset( mmm+(kztop+1)*nxy , 0 , sizeof(byte)*(nz-1-kztop)*nxy ) ;
   }

   /* and make the vectim using the standard function */

   mrv = THD_dset_to_vectim( dset , mmm , ignore ) ;
   free(mmm) ;
   RETURN(mrv) ;
}
コード例 #16
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);
}
コード例 #17
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 ;
}
コード例 #18
0
ファイル: thd_dsetto1D.c プロジェクト: neurodebian/afni
MRI_IMAGE * THD_dset_to_1Dmri( THD_3dim_dataset *dset )
{
   MRI_IMAGE *im ; float *far ;
   int nx , ny , ii ;

ENTRY("THD_dset_to_1D") ;

   if( !ISVALID_DSET(dset) ) RETURN(NULL) ;
   DSET_load(dset) ;
   if( !DSET_LOADED(dset) ) RETURN(NULL) ;

   nx = DSET_NVALS(dset) ;
   ny = DSET_NVOX(dset) ;
   im = mri_new( nx , ny , MRI_float ) ; far = MRI_FLOAT_PTR(im) ;

   for( ii=0 ; ii < ny ; ii++ )
     THD_extract_array( ii , dset , 0 , far + ii*nx ) ;

   RETURN(im) ;
}
コード例 #19
0
ファイル: 3dUpsample.c プロジェクト: LJWilliams/Neuroimaging
int main( int argc , char *argv[] )
{
   int vstep=0 , ii,nvox , ntin , ntout , do_one=0 , nup=-1 ;
   THD_3dim_dataset *inset=NULL , *outset ;
   char *prefix="Upsam", *dsetname=NULL ;
   int verb=0 , iarg=1, datum = MRI_float;
   float *ivec , *ovec , trin , trout, *fac=NULL, *ofac=NULL, 
         top=0.0, maxtop=0.0;

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

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

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

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

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

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

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

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

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

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

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

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

   nvox = DSET_NVOX(inset) ;

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

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;


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

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

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

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

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

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

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

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

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

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

     THD_extract_array( ii , inset , 0 , ivec ) ;

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

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

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

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

   DSET_write(outset) ;
   if( verb ) WROTE_DSET(outset) ;
   if( verb ) INFO_message("Total CPU time = %.1f s",COX_cpu_time()) ;
   exit(0);
}
コード例 #20
0
ファイル: 3dRank.c プロジェクト: CesarCaballeroGaudes/afni
/*! 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);
}
コード例 #21
0
ファイル: testcox.c プロジェクト: LJWilliams/Neuroimaging
int main( int argc , char * argv[] )
{
   THD_3dim_dataset *dset ;
   int iarg=1 ;
   char *cc1="x",*cc2="y",*cc3="z" ;
   float th1=0.0, th2=0.0, th3=0.0 ;
   float thx,thy,thz ;
   int   axx,ayy,azz ;
   char *fname="testcox.ppm" , fn[128] ;
   void * rhand ;
   int bot=1 , ii , nim=0 ;
   float omap[128] , bfac ;
   MRI_IMAGE * im , * brim ;
   int hbr[256] , nperc,ibot,itop,sum ;
   byte * bar ;
   double ctim ;
   int imode=CREN_TWOSTEP ;
   int pmode=CREN_SUM_VOX ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: testcox [-rotate a b c] [-mip|-MIP] [-out f] [-bot b] [-nn|-ts|-li] dset\n") ;
      exit(0) ;
   }

   enable_mcw_malloc() ;

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

      if( strcmp(argv[iarg],"-MIP") == 0 ){
        pmode = CREN_MIP_VOX ; iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-mip") == 0 ){
        pmode = CREN_MINIP_VOX ; iarg++ ; continue ;
      }

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

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

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

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

      if( strcmp(argv[iarg],"-rotate") == 0 ){
         th1 = (PI/180.0) * strtod( argv[++iarg] , &cc1 ) ;
         th2 = (PI/180.0) * strtod( argv[++iarg] , &cc2 ) ;
         th3 = (PI/180.0) * strtod( argv[++iarg] , &cc3 ) ;

         iarg++ ; continue ;
      }

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

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

   if( iarg >= argc ){fprintf(stderr,"No dataset?\n"); exit(1); }

   dset = THD_open_dataset( argv[iarg] ) ;
   if( dset == NULL ){fprintf(stderr,"Can't open dataset!\n");exit(1);}
   if( DSET_BRICK_TYPE(dset,0) != MRI_byte ){
      fprintf(stderr,"Non-byte dataset input!\n");exit(1);
   }
   DSET_mallocize(dset) ; DSET_load(dset) ;
   if( !DSET_LOADED(dset) ){
      fprintf(stderr,"Can't load dataset!\n");exit(1);
   }

   rhand = new_CREN_renderer() ;

#if 0
   THD_rotangle_user_to_dset( dset ,
                              th1,*cc1  , th2,*cc2  , th3,*cc3 ,
                              &thx,&axx , &thy,&ayy , &thz,&azz ) ;
   CREN_set_viewpoint( rhand , axx,thx,ayy,thy,azz,thz ) ;
#else
   CREN_set_angles( rhand , th1,th2,th3 ) ;
#endif

   for( ii=0 ; ii < 128 ; ii++ )
      omap[ii] = (ii <= bot) ? 0.0
                             : (ii-bot)/(127.0-bot) ;

   CREN_set_opamap( rhand , omap , 1.0 ) ;

   brim = DSET_BRICK(dset,0) ; bar = MRI_BYTE_PTR(brim) ;
   mri_histobyte( brim , hbr ) ;
   nperc = 0.02 * brim->nvox ;
   for( sum=0,ibot=0   ; ibot < 128  && sum < nperc ; ibot++ ) sum += hbr[ibot] ;
   for( sum=0,itop=255 ; itop > ibot && sum < nperc ; itop-- ) sum += hbr[itop] ;
   if( ibot >= itop ){ ibot = 64 ; itop = 192 ; }
   bfac = 127.5 / (itop-ibot) ;
   for( ii=0 ; ii < brim->nvox ; ii++ )
           if( bar[ii] <= ibot ) bar[ii] = 0 ;
      else if( bar[ii] >= itop ) bar[ii] = 127 ;
      else                       bar[ii] = bfac * (bar[ii]-ibot) ;


   ctim = COX_cpu_time() ;

   CREN_set_databytes( rhand , brim->nx,brim->ny,brim->nz , bar ) ;
   CREN_dset_axes( rhand , dset ) ;

   CREN_set_render_mode( rhand , pmode ) ;

   CREN_set_interp( rhand , imode ) ;

   for( th3=0 ; th3 < 360.0 ; th3+=5.0 ){
      CREN_set_angles( rhand , th1,th2,(PI/180.0)*th3 ) ;
      im = CREN_render( rhand, NULL ) ;  /* added NULL   2002.08.28 - rickr */
      if( im == NULL ){
        fprintf(stderr,"renderer fails!\n") ; exit(1) ;
      }

      sprintf(fn,"tc%03d.jpg",(int)rint(th3)) ;
      mri_write_pnm( fn, im ) ;
      fprintf(stderr,"+++ Output to file %s\n",fn);
      mri_free(im) ; nim++ ;
   }
   ctim = COX_cpu_time() - ctim ;
   fprintf(stderr,"+++ Rendering CPU time = %g s = %g/im\n",ctim,ctim/nim) ;

   exit(0) ;
}
コード例 #22
0
THD_3dim_dataset * THD_localhistog( int nsar , THD_3dim_dataset **insar ,
                                    int numval , int *rlist , MCW_cluster *nbhd ,
                                    int do_prob , int verb )
{
   THD_3dim_dataset *outset=NULL , *inset ;
   int nvox=DSET_NVOX(insar[0]) ;
   int ids, iv, bb, nnpt=nbhd->num_pt ;
   MRI_IMAGE *bbim ; int btyp ;
   float **outar , **listar ;

ENTRY("THD_localhistog") ;

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

   outset = EDIT_empty_copy(insar[0]) ;
   EDIT_dset_items( outset ,
                      ADN_nvals     , numval    ,
                      ADN_datum_all , MRI_float ,
                      ADN_nsl       , 0         ,
                      ADN_brick_fac , NULL      ,
                    ADN_none ) ;
   outar = (float **)malloc(sizeof(float *)*numval) ;
   for( bb=0 ; bb < numval ; bb++ ){
     EDIT_substitute_brick( outset , bb , MRI_float , NULL ) ;
     outar[bb] = DSET_BRICK_ARRAY(outset,bb) ;
   }

   /*---- make mapping between values and arrays to get those values ----*/

   listar = (float **)malloc(sizeof(float *)*TWO16) ;
   for( bb=0 ; bb < TWO16 ; bb++ ) listar[bb] = outar[0] ;
   for( bb=1 ; bb < numval ; bb++ ){
     listar[ rlist[bb] + TWO15 ] = outar[bb] ;
   }

   /*----------- loop over datasets, add in counts for all voxels -----------*/

   for( ids=0 ; ids < nsar ; ids++ ){              /* dataset loop */
     inset = insar[ids] ; DSET_load(inset) ;
     for( iv=0 ; iv < DSET_NVALS(inset) ; iv++ ){  /* sub-brick loop */
       if( verb ) fprintf(stderr,".") ;
       bbim = DSET_BRICK(inset,iv) ; btyp = bbim->kind ;
       if( nnpt == 1 ){                            /* only 1 voxel in nbhd */
         int qq,ii,jj,kk,ib,nb ;
         switch( bbim->kind ){
           case MRI_short:{
             short *sar = MRI_SHORT_PTR(bbim) ;
             for( qq=0 ; qq < nvox ; qq++ ) listar[sar[qq]+TWO15][qq]++ ;
           }
           break ;
           case MRI_byte:{
             byte *bar = MRI_BYTE_PTR(bbim) ;
             for( qq=0 ; qq < nvox ; qq++ ) listar[bar[qq]+TWO15][qq]++ ;
           }
           break ;
           case MRI_float:{
             float *far = MRI_FLOAT_PTR(bbim) ; short ss ;
             for( qq=0 ; qq < nvox ; qq++ ){ ss = SHORTIZE(far[qq]); listar[ss+TWO15][qq]++; }
           }
           break ;
         }
       } else {                                    /* multiple voxels in nbhd */
 AFNI_OMP_START ;
#pragma omp parallel
 { int qq,ii,jj,kk,ib,nb ; void *nar ; short *sar,ss ; byte *bar ; float *far ;
   nar = malloc(sizeof(float)*nnpt) ;
   sar = (short *)nar ; bar = (byte *)nar ; far = (float *)nar ;
#pragma omp for
         for( qq=0 ; qq < nvox ; qq++ ){           /* qq=voxel index */
           ii = DSET_index_to_ix(inset,qq) ;
           jj = DSET_index_to_jy(inset,qq) ;
           kk = DSET_index_to_kz(inset,qq) ;
           nb = mri_get_nbhd_array( bbim , NULL , ii,jj,kk , nbhd , nar ) ;
           if( nb == 0 ) continue ;
           switch( btyp ){
             case MRI_short:
               for( ib=0 ; ib < nb ; ib++ ) listar[sar[ib]+TWO15][qq]++ ;
             break ;
             case MRI_byte:
               for( ib=0 ; ib < nb ; ib++ ) listar[bar[ib]+TWO15][qq]++ ;
             break ;
             case MRI_float:
               for( ib=0 ; ib < nb ; ib++ ){ ss = SHORTIZE(far[ib]); listar[ss+TWO15][qq]++; }
             break ;
           }
         } /* end of voxel loop */
   free(nar) ;
 } /* end of OpenMP */
 AFNI_OMP_END ;
       }
     } /* end of sub-brick loop */
     DSET_unload(inset) ;
   } /* end of dataset loop */

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

   free(listar) ;

   /*---- post-process output ---*/

   if( do_prob ){
     byte **bbar ; int pp ;
 
     if( verb ) INFO_message("Conversion to probabilities") ;

 AFNI_OMP_START ;
#pragma omp parallel
 { int qq , ib ; float pfac , val ; byte **bbar ;
#pragma omp for
     for( qq=0 ; qq < nvox ; qq++ ){
       pfac = 0.0001f ;
       for( ib=0 ; ib < numval ; ib++ ) pfac += outar[ib][qq] ;
       pfac = 250.0f / pfac ;
       for( ib=0 ; ib < numval ; ib++ ){
         val = outar[ib][qq]*pfac ; outar[ib][qq] = BYTEIZE(val) ;
       }
     }
 } /* end OpenMP */
 AFNI_OMP_END ;

     bbar = (byte **)malloc(sizeof(byte *)*numval) ;
     for( bb=0 ; bb < numval ; bb++ ){
       bbar[bb] = (byte *)malloc(sizeof(byte)*nvox) ;
       for( pp=0 ; pp < nvox ; pp++ ) bbar[bb][pp] = (byte)outar[bb][pp] ;
       EDIT_substitute_brick(outset,bb,MRI_byte,bbar[bb]) ;
       EDIT_BRICK_FACTOR(outset,bb,0.004f) ;
     }
     free(bbar) ;

   } /* end of do_prob */

   free(outar) ;
   RETURN(outset) ;
}
コード例 #23
0
ファイル: plug_aslA3D3.c プロジェクト: ccraddock/afni
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 */
}
コード例 #24
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset ;
   THD_3dim_dataset **insar=NULL ; int nsar=0 ;
   int iarg=1 , ii,kk , ids ;
   MCW_cluster *nbhd=NULL ;
   char *prefix="./localhistog" ;
   int ntype=0 ; float na=0.0f,nb=0.0f,nc=0.0f ;
   int verb=1 , do_prob=0 ;
   int nx=0,ny=0,nz=0,nvox=0, rbot,rtop ;
   char *labfile=NULL ; NI_element *labnel=NULL ;
   int nlab=0 , *labval=NULL ; char **lablab=NULL ; char buf[THD_MAX_SBLABEL] ;
   UINT32 *ohist , *mhist=NULL ; char *ohist_name=NULL ; int ohzadd=0 ;
   int *rlist , numval ; float mincount=0.0f ; int mcc ;
   int *exlist=NULL, numex=0 ;
   int do_excNONLAB=0 ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   } /* end of dataset loop */

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

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

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

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

   /* excNONLAB? */

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

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

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

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

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

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

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

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

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

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

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

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

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

   /* save overall histogram? */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   EDIT_dset_items( outset , ADN_prefix,prefix , ADN_none ) ;

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

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

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

   DSET_write( outset ) ;
   if( verb ) WROTE_DSET( outset ) ;
   exit(0) ;
}
コード例 #25
0
ファイル: plug_4Ddump.c プロジェクト: ccraddock/afni
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 .... */

}
コード例 #26
0
ファイル: 3dRSFC.c プロジェクト: ccraddock/afni
int main( int argc , char * argv[] )
{
   int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ;
   float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ;
   MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ;
   THD_3dim_dataset **ortset=NULL ; int nortset=0 ;
   THD_3dim_dataset *inset=NULL , *outset=NULL;
   char *prefix="RSFC" ;
   byte *mask=NULL ;
   int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , 
		nx,ny,nz,nvox , nfft=0 , kk ;
   float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime  ;
   MRI_vectim *mrv ;
   float pvrad=0.0f ; int nosat=0 ;
   int do_despike=0 ;

	// @@ non-BP variables
	float fbotALL=0.0f, ftopALL=999999.9f; // do full range version
	int NumDen = 0; // switch for doing numerator or denom
	THD_3dim_dataset *outsetALL=NULL ; 	
	int m, mm;
	float delf; // harmonics
	int ind_low,ind_high,N_ny, ctr;
	float sqnt,nt_fac;
	gsl_fft_real_wavetable *real1, *real2; // GSL stuff
	gsl_fft_real_workspace *work;
	double *series1, *series2;	
	double *xx1,*xx2;
	float numer,denom,val;
	float *alff=NULL,*malff=NULL,*falff=NULL,
         *rsfa=NULL,*mrsfa=NULL,*frsfa=NULL; // values
	float meanALFF=0.0f,meanRSFA=0.0f; // will be for mean in brain region
	THD_3dim_dataset *outsetALFF=NULL;
	THD_3dim_dataset *outsetmALFF=NULL;
	THD_3dim_dataset *outsetfALFF=NULL;
	THD_3dim_dataset *outsetRSFA=NULL;
	THD_3dim_dataset *outsetmRSFA=NULL;
	THD_3dim_dataset *outsetfRSFA=NULL;
	char out_lff[300];
	char out_alff[300];
	char out_malff[300];
	char out_falff[300];
	char out_rsfa[300];
	char out_mrsfa[300];
	char out_frsfa[300];
	char out_unBP[300];
	int SERIES_OUT = 1;
	int UNBP_OUT = 0; 
	int DO_RSFA = 1;
	int BP_LAST = 0; // option for only doing filter to LFFs at very end of proc
	float de_rsfa=0.0f,nu_rsfa=0.0f;
	double pow1=0.0,pow2=0.0;

   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
		printf(
"\n  Program to calculate common resting state functional connectivity (RSFC)\n"
"  parameters (ALFF, mALFF, fALFF, RSFA, etc.) for resting state time\n"
"  series.  This program is **heavily** based on the existing\n"
"  3dBandPass by RW Cox, with the amendments to calculate RSFC\n"
"  parameters written by PA Taylor (July, 2012).\n"
"  This program is part of FATCAT (Taylor & Saad, 2013) in AFNI. Importantly,\n"
"  its functionality can be included in the `afni_proc.py' processing-script \n"
"  generator; see that program's help file for an example including RSFC\n"
"  and spectral parameter calculation via the `-regress_RSFC' option.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
"  All options of 3dBandPass may be used here (with a couple other\n"
"  parameter options, as well): essentially, the motivation of this\n"
"  program is to produce ALFF, etc. values of the actual RSFC time\n"
"  series that you calculate.  Therefore, all the 3dBandPass processing\n"
"  you normally do en route to making your final `resting state time\n"
"  series' is done here to generate your LFFs, from which the\n"
"  amplitudes in the LFF band are calculated at the end.  In order to\n"
"  calculate fALFF, the same initial time series are put through the\n"
"  same processing steps which you have chosen but *without* the\n"
"  bandpass part; the spectrum of this second time series is used to\n"
"  calculate the fALFF denominator.\n"
" \n"
"  For more information about each RSFC parameter, see, e.g.:   \n"
"  ALFF/mALFF -- Zang et al. (2007),\n"
"  fALFF --      Zou et al. (2008),\n"
"  RSFA --       Kannurpatti & Biswal (2008).\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
" + USAGE: 3dRSFC [options] fbot ftop dataset\n"
"\n"
"* One function of this program is to prepare datasets for input\n"
"   to 3dSetupGroupInCorr.  Other uses are left to your imagination.\n"
"\n"
"* 'dataset' is a 3D+time sequence of volumes\n"
"   ++ This must be a single imaging run -- that is, no discontinuities\n"
"       in time from 3dTcat-ing multiple datasets together.\n"
"\n"
"* fbot = lowest frequency in the passband, in Hz\n"
"   ++ fbot can be 0 if you want to do a lowpass filter only;\n"
"       HOWEVER, the mean and Nyquist freq are always removed.\n"
"\n"
"* ftop = highest frequency in the passband (must be > fbot)\n"
"   ++ if ftop > Nyquist freq, then it's a highpass filter only.\n"
"\n"
"* Set fbot=0 and ftop=99999 to do an 'allpass' filter.\n"
"  ++ Except for removal of the 0 and Nyquist frequencies, that is.\n"
"\n"
"* You cannot construct a 'notch' filter with this program!\n"
"  ++ You could use 3dRSFC followed by 3dcalc to get the same effect.\n"
"  ++ If you are understand what you are doing, that is.\n"
"  ++ Of course, that is the AFNI way -- if you don't want to\n"
"     understand what you are doing, use Some other PrograM, and\n"
"     you can still get Fine StatisticaL maps.\n"
"\n"
"* 3dRSFC will fail if fbot and ftop are too close for comfort.\n"
"  ++ Which means closer than one frequency grid step df,\n"
"     where df = 1 / (nfft * dt) [of course]\n"
"\n"
"* The actual FFT length used will be printed, and may be larger\n"
"   than the input time series length for the sake of efficiency.\n"
"  ++ The program will use a power-of-2, possibly multiplied by\n"
"     a power of 3 and/or 5 (up to and including the 3rd power of\n"
"     each of these: 3, 9, 27, and 5, 25, 125).\n"
"\n"
"* Note that the results of combining 3dDetrend and 3dRSFC will\n"
"   depend on the order in which you run these programs.  That's why\n"
"   3dRSFC has the '-ort' and '-dsort' options, so that the\n"
"   time series filtering can be done properly, in one place.\n"
"\n"
"* The output dataset is stored in float format.\n"
"\n"
"* The order of processing steps is the following (most are optional), and\n"
"  for the LFFs, the bandpass is done between the specified fbot and ftop,\n"
"  while for the `whole spectrum' (i.e., fALFF denominator) the bandpass is:\n"
"  done only to exclude the time series mean and the Nyquist frequency:\n"
" (0) Check time series for initial transients [does not alter data]\n"
" (1) Despiking of each time series\n"
" (2) Removal of a constant+linear+quadratic trend in each time series\n"
" (3) Bandpass of data time series\n"
" (4) Bandpass of -ort time series, then detrending of data\n"
"      with respect to the -ort time series\n"
" (5) Bandpass and de-orting of the -dsort dataset,\n"
"      then detrending of the data with respect to -dsort\n"
" (6) Blurring inside the mask [might be slow]\n"
" (7) Local PV calculation     [WILL be slow!]\n"
" (8) L2 normalization         [will be fast.]\n"
" (9) Calculate spectrum and amplitudes, for RSFC parameters.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"--------\n"
"OPTIONS:\n"
"--------\n"
" -despike        = Despike each time series before other processing.\n"
"                   ++ Hopefully, you don't actually need to do this,\n"
"                      which is why it is optional.\n"
" -ort f.1D       = Also orthogonalize input to columns in f.1D\n"
"                   ++ Multiple '-ort' options are allowed.\n"
" -dsort fset     = Orthogonalize each voxel to the corresponding\n"
"                    voxel time series in dataset 'fset', which must\n"
"                    have the same spatial and temporal grid structure\n"
"                    as the main input dataset.\n"
"                   ++ At present, only one '-dsort' option is allowed.\n"
" -nodetrend      = Skip the quadratic detrending of the input that\n"
"                    occurs before the FFT-based bandpassing.\n"
"                   ++ You would only want to do this if the dataset\n"
"                      had been detrended already in some other program.\n"
" -dt dd          = set time step to 'dd' sec [default=from dataset header]\n"
" -nfft N         = set the FFT length to 'N' [must be a legal value]\n"
" -norm           = Make all output time series have L2 norm = 1\n"
"                   ++ i.e., sum of squares = 1\n"
" -mask mset      = Mask dataset\n"
" -automask       = Create a mask from the input dataset\n"
" -blur fff       = Blur (inside the mask only) with a filter\n"
"                    width (FWHM) of 'fff' millimeters.\n"
" -localPV rrr    = Replace each vector by the local Principal Vector\n"
"                    (AKA first singular vector) from a neighborhood\n"
"                    of radius 'rrr' millimiters.\n"
"                   ++ Note that the PV time series is L2 normalized.\n"
"                   ++ This option is mostly for Bob Cox to have fun with.\n"
"\n"
" -input dataset  = Alternative way to specify input dataset.\n"
" -band fbot ftop = Alternative way to specify passband frequencies.\n"
"\n"
" -prefix ppp     = Set prefix name of output dataset. Name of filtered time\n"
"                   series would be, e.g., ppp_LFF+orig.*, and the parameter\n"
"                   outputs are named with obvious suffices.\n"
" -quiet          = Turn off the fun and informative messages. (Why?)\n"
" -no_rs_out      = Don't output processed time series-- just output\n"
"                   parameters (not recommended, since the point of\n"
"                   calculating RSFC params here is to have them be quite\n"
"                   related to the time series themselves which are used for\n"
"                   further analysis)."
" -un_bp_out      = Output the un-bandpassed series as well (default is not \n"
"                   to).  Name would be, e.g., ppp_unBP+orig.* .\n"
"                   with suffix `_unBP'.\n"
" -no_rsfa        = If you don't want RSFA output (default is to do so).\n"
" -bp_at_end      = A (probably unnecessary) switch to have bandpassing be \n"
"                   the very last processing step that is done in the\n"
"                   sequence of steps listed above; at Step 3 above, only \n"
"                   the time series mean and nyquist are BP'ed out, and then\n"
"                   the LFF series is created only after Step 9.  NB: this \n"
"                   probably makes only very small changes for most\n"
"                   processing sequences (but maybe not, depending usage).\n"
"\n"
" -notrans        = Don't check for initial positive transients in the data:\n"
"  *OR*             ++ The test is a little slow, so skipping it is OK,\n"
" -nosat               if you KNOW the data time series are transient-free.\n"
"                   ++ Or set AFNI_SKIP_SATCHECK to YES.\n"
"                   ++ Initial transients won't be handled well by the\n"
"                      bandpassing algorithm, and in addition may seriously\n"
"                      contaminate any further processing, such as inter-\n"
"                      voxel correlations via InstaCorr.\n"
"                   ++ No other tests are made [yet] for non-stationary \n"
"                      behavior in the time series data.\n"
"\n"
"* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"
"\n"
"  If you use this program, please reference the introductory/description\n"
"  paper for the FATCAT toolbox:\n"
"        Taylor PA, Saad ZS (2013).  FATCAT: (An Efficient) Functional\n"
"        And Tractographic Connectivity Analysis Toolbox. Brain \n"
"        Connectivity 3(5):523-535.\n"
"____________________________________________________________________________\n"
);
		PRINT_AFNI_OMP_USAGE(
" 3dRSFC" ,
" * At present, the only part of 3dRSFC that is parallelized is the\n"
"   '-blur' option, which processes each sub-brick independently.\n"
									) ;
		PRINT_COMPILE_DATE ; exit(0) ;
   }
	
   /*-- startup --*/
	
   mainENTRY("3dRSFC"); machdep();
   AFNI_logger("3dRSFC",argc,argv);
   PRINT_VERSION("3dRSFC (from 3dBandpass by RW Cox): version THETA"); 
	AUTHOR("PA Taylor");
	
   nosat =  AFNI_yesenv("AFNI_SKIP_SATCHECK") ;
	
   nopt = 1 ;
   while( nopt < argc && argv[nopt][0] == '-' ){

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

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

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

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

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

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

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

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

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

		if( strcmp(argv[nopt],"-no_rs_out") == 0 ){ // @@
			SERIES_OUT = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-un_bp_out") == 0 ){ // @@
			UNBP_OUT = 1 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-no_rsfa") == 0 ){ // @@
			DO_RSFA = 0 ; nopt++ ; continue ;
		}

		if( strcmp(argv[nopt],"-bp_at_end") == 0 ){ // @@
			BP_LAST = 1 ; nopt++ ; continue ;
		}




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

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

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

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

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

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

			nopt++ ; continue ;
		}

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

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

   /** check inputs for reasonablositiness **/

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

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

		nopt++ ;
   }
   DSET_UNMSEC(inset) ;

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

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

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

   if( dt <= 0.0f ){
		dt = DSET_TR(inset) ;
		if( dt <= 0.0f ){
			WARNING_message("Setting dt=1.0 since input dataset lacks a time axis!") ;
			dt = 1.0f ;
		}
   }
   ftopALL = 1./dt ;// Aug,2016: should solve problem of a too-large
                    // value for THD_bandpass_vectors(), while still
                    // being >f_{Nyquist}

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

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

   /* check mask, or create it */

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

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

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

   } else {
		mask = (byte *)malloc(sizeof(byte)*nvox) ; nmask = nvox ;
		memset(mask,1,sizeof(byte)*nvox) ;
		// if( verb ) // @@ alert if aaaalllllll vox are going to be analyzed!
		INFO_message("No mask ==> processing all %d voxels",nvox);
   }

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

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

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

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

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

	// @@ convert BP'ing ftop/bot into indices for the DFT (below)
	delf = 1.0/(ntime*dt); 
	ind_low = (int) rint(fbot/delf);
	ind_high = (int) rint(ftop/delf);
	if( ntime % 2 ) // nyquist number
		N_ny = (ntime-1)/2;
	else
		N_ny = ntime/2;
	sqnt = sqrt(ntime);
	nt_fac = sqrt(ntime*(ntime-1));

	// @@ if BP_LAST==0:
	// now we go through twice, doing LFF bandpass for NumDen==0 and
	// `full spectrum' processing for NumDen==1.
	// if BP_LAST==1:
	// now we go through once, doing only `full spectrum' processing
	for( NumDen=0 ; NumDen<2 ; NumDen++) {
		//if( NumDen==1 ){ // full spectrum
		//	fbot = fbotALL;
		//	ftop = ftopALL;
		//}
		
		// essentially, just doesn't BP here, and the perfect filtering at end
		// is used for both still; this makes the final output spectrum
		// contain only frequencies in range of 0.01-0.08
		if( BP_LAST==1 )
			INFO_message("Only doing filtering to LFFs at end!");
		
		
		mrv = THD_dset_to_vectim( inset , mask , 0 ) ;
		if( mrv == NULL ) ERROR_exit("Can't load time series data!?") ;
		if( NumDen==1 )
			DSET_unload(inset) ; // @@ only unload on 2nd pass

		/* similarly for the ort vectors */

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

		/* all the real work now */

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

		if( verb ) INFO_message("Bandpassing data time series") ;

		if( (BP_LAST==0) && (NumDen==0) )
			(void)THD_bandpass_vectim( mrv , dt,fbot,ftop , qdet , nort,ort ) ;
		else
			(void)THD_bandpass_vectim( mrv , dt,fbotALL,ftopALL, qdet,nort,ort ) ;

		/* OK, maybe a little more work */

		if( nortset == 1 ){
			MRI_vectim *orv ;
			orv = THD_dset_to_vectim( ortset[0] , mask , 0 ) ;
			if( orv == NULL ){
				ERROR_message("Can't load -dsort %s",DSET_BRIKNAME(ortset[0])) ;
			} else {
				float *dp , *mvv , *ovv , ff ;
				if( verb ) INFO_message("Orthogonalizing to bandpassed -dsort") ;
				//(void)THD_bandpass_vectim( orv , dt,fbot,ftop , qdet , nort,ort ) ; //@@
				if( (BP_LAST==0) && (NumDen==0) )
					(void)THD_bandpass_vectim(orv,dt,fbot,ftop,qdet,nort,ort);
				else
					(void)THD_bandpass_vectim(orv,dt,fbotALL,ftopALL,qdet,nort,ort);

				THD_vectim_normalize( orv ) ;
				dp = malloc(sizeof(float)*mrv->nvec) ;
				THD_vectim_vectim_dot( mrv , orv , dp ) ;
				for( vv=0 ; vv < mrv->nvec ; vv++ ){
					ff = dp[vv] ;
					if( ff != 0.0f ){
						mvv = VECTIM_PTR(mrv,vv) ; ovv = VECTIM_PTR(orv,vv) ;
						for( kk=0 ; kk < ntime ; kk++ ) mvv[kk] -= ff*ovv[kk] ;
					}
				}
				VECTIM_destroy(orv) ; free(dp) ;
			}
		}

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

		/* create output dataset, populate it, write it, then quit */
		if( (NumDen==0) ) { // @@ BP'ed version;  will do filt if BP_LAST

			if(BP_LAST) // do bandpass here for BP_LAST
				(void)THD_bandpass_vectim(mrv,dt,fbot,ftop,qdet,0,NULL);

			if( verb ) INFO_message("Creating output dataset in memory, then writing it") ;
			outset = EDIT_empty_copy(inset) ;
			if(SERIES_OUT){
				sprintf(out_lff,"%s_LFF",prefix); 
				EDIT_dset_items( outset , ADN_prefix,out_lff , ADN_none ) ;
				tross_Copy_History( inset , outset ) ;
				tross_Make_History( "3dBandpass" , argc,argv , outset ) ;
			}
			for( vv=0 ; vv < ntime ; vv++ )
				EDIT_substitute_brick( outset , vv , MRI_float , NULL ) ;
		
#if 1
			THD_vectim_to_dset( mrv , outset ) ;
#else
			AFNI_OMP_START ;
#pragma omp parallel
			{ float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ;
#pragma omp for
				for( vv=0 ; vv < ntime ; vv++ ){
					far = DSET_BRICK_ARRAY(outset,vv) ; var = mrv->fvec + vv ;
					for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ;
				}
			}
			AFNI_OMP_END ;
#endif
			VECTIM_destroy(mrv) ;
			if(SERIES_OUT){ // @@
				DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ;
			}
		}
		else{ // @@ non-BP'ed version
			if( verb ) INFO_message("Creating output dataset 2 in memory") ;

			// do this here because LFF version was also BP'ed at end.
			if(BP_LAST) // do bandpass here for BP_LAST
				(void)THD_bandpass_vectim(mrv,dt,fbotALL,ftopALL,qdet,0,NULL);

			outsetALL = EDIT_empty_copy(inset) ;
			if(UNBP_OUT){ 
				sprintf(out_unBP,"%s_unBP",prefix); 
				EDIT_dset_items( outsetALL, ADN_prefix, out_unBP, ADN_none );
				tross_Copy_History( inset , outsetALL ) ;
				tross_Make_History( "3dRSFC" , argc,argv , outsetALL ) ;
			}
			for( vv=0 ; vv < ntime ; vv++ )
				EDIT_substitute_brick( outsetALL , vv , MRI_float , NULL ) ;
		
#if 1
			THD_vectim_to_dset( mrv , outsetALL ) ;
#else
			AFNI_OMP_START ;
#pragma omp parallel
			{ float *far , *var ; int *ivec=mrv->ivec ; int vv,kk ;
#pragma omp for
				for( vv=0 ; vv < ntime ; vv++ ){
					far = DSET_BRICK_ARRAY(outsetALL,vv) ; var = mrv->fvec + vv ;
					for( kk=0 ; kk < nmask ; kk++ ) far[ivec[kk]] = var[kk*ntime] ;
				}
			}
			AFNI_OMP_END ;
#endif
			VECTIM_destroy(mrv) ;
			if(UNBP_OUT){ 
				DSET_write(outsetALL) ; if( verb ) WROTE_DSET(outsetALL) ;
			}
		}
	}// end of NumDen loop


	// @@
	INFO_message("Starting the (f)ALaFFel calcs") ;

	// allocations
	series1 = (double *)calloc(ntime,sizeof(double)); 
	series2 = (double *)calloc(ntime,sizeof(double)); 
	xx1 = (double *)calloc(2*ntime,sizeof(double)); 
	xx2 = (double *)calloc(2*ntime,sizeof(double)); 
	alff = (float *)calloc(nvox,sizeof(float)); 
	malff = (float *)calloc(nvox,sizeof(float)); 
	falff = (float *)calloc(nvox,sizeof(float)); 

	if( (series1 == NULL) || (series2 == NULL) 
		 || (xx1 == NULL) || (xx2 == NULL) 
		 || (alff == NULL) || (malff == NULL) || (falff == NULL)) { 
		fprintf(stderr, "\n\n MemAlloc failure.\n\n");
		exit(122);
	}
	if(DO_RSFA) {
		rsfa = (float *)calloc(nvox,sizeof(float)); 
		mrsfa = (float *)calloc(nvox,sizeof(float)); 
		frsfa = (float *)calloc(nvox,sizeof(float)); 
		if( (rsfa == NULL) || (mrsfa == NULL) || (frsfa == NULL)) { 
			fprintf(stderr, "\n\n MemAlloc failure.\n\n");
			exit(123);
		}	
	}
	
	
	work = gsl_fft_real_workspace_alloc (ntime);
	real1 = gsl_fft_real_wavetable_alloc (ntime);
	real2 = gsl_fft_real_wavetable_alloc (ntime);
	gsl_complex_packed_array compl_freqs1 = xx1;
	gsl_complex_packed_array compl_freqs2 = xx2;




	// *********************************************************************
	// *********************************************************************
	// **************    Falafelling = ALFF/fALFF calcs    *****************
	// *********************************************************************
	// *********************************************************************

	// Be now have the BP'ed data set (outset) and the non-BP'ed one
	// (outsetALL).  now we'll FFT both, get amplitudes in appropriate
	// ranges, and calculate:  ALFF, mALFF, fALFF,

	ctr = 0;
	for( kk=0; kk<nvox ; kk++) {
		if(mask[kk]) {
			
			// BP one, and unBP one, either for BP_LAST or !BP_LAST
			for( m=0 ; m<ntime ; m++ ) {
				series1[m] = THD_get_voxel(outset,kk,m);
				series2[m] = THD_get_voxel(outsetALL,kk,m);
			}
			
			
			mm = gsl_fft_real_transform(series1, 1, ntime, real1, work);
			mm = gsl_fft_halfcomplex_unpack(series1, compl_freqs1, 1, ntime);
			mm = gsl_fft_real_transform(series2, 1, ntime, real2, work);
			mm = gsl_fft_halfcomplex_unpack(series2, compl_freqs2, 1, ntime);

			numer = 0.0f; 
			denom = 0.0f;
			de_rsfa = 0.0f;
			nu_rsfa = 0.0f;
			for( m=1 ; m<N_ny ; m++ ) {
				mm = 2*m;
				pow2 = compl_freqs2[mm]*compl_freqs2[mm] +
					compl_freqs2[mm+1]*compl_freqs2[mm+1]; // power
				//pow2*=2;// factor of 2 since ampls are even funcs
				denom+= (float) sqrt(pow2); // amplitude 
				de_rsfa+= (float) pow2;
				
				if( ( m>=ind_low ) && ( m<=ind_high ) ){
					pow1 = compl_freqs1[mm]*compl_freqs1[mm]+
						compl_freqs1[mm+1]*compl_freqs1[mm+1];
					//pow1*=2;
					numer+= (float) sqrt(pow1);
					nu_rsfa+= (float) pow1;
				}
			}

			if( denom>0.000001 )
			  falff[kk] = numer/denom;
			else
			  falff[kk] = 0.;
			alff[kk] = 2*numer/sqnt;// factor of 2 since ampl is even funct
			meanALFF+= alff[kk];

			if(DO_RSFA){
			  nu_rsfa = sqrt(2*nu_rsfa); // factor of 2 since ampls 
			  de_rsfa = sqrt(2*de_rsfa); // are even funcs
			  if( de_rsfa>0.000001 )
			    frsfa[kk] = nu_rsfa/de_rsfa;
			  else
			    frsfa[kk]=0.;
			  rsfa[kk] = nu_rsfa/nt_fac;
			  meanRSFA+= rsfa[kk];
			}
			
			ctr+=1;
		}
	}
	meanALFF/= ctr;
	meanRSFA/= ctr;

	gsl_fft_real_wavetable_free(real1);
	gsl_fft_real_wavetable_free(real2);
	gsl_fft_real_workspace_free(work);

	// ALFFs divided by mean of brain value
	for( kk=0 ; kk<nvox ; kk++ ) 
		if(mask[kk]){
			malff[kk] = alff[kk]/meanALFF;
			if(DO_RSFA)
				mrsfa[kk] = rsfa[kk]/meanRSFA;
		}
	// **************************************************************
	// **************************************************************
	//                 Store and output
	// **************************************************************
	// **************************************************************
	
	outsetALFF = EDIT_empty_copy( inset ) ; 
	sprintf(out_alff,"%s_ALFF",prefix); 
	EDIT_dset_items( outsetALFF,
                    ADN_nvals, 1,
						  ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_alff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetALFF));
	EDIT_substitute_brick(outsetALFF, 0, MRI_float, alff); 
	alff=NULL;
	THD_load_statistics(outsetALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetALFF, True);

	outsetfALFF = EDIT_empty_copy( inset ) ;
	sprintf(out_falff,"%s_fALFF",prefix); 
	EDIT_dset_items( outsetfALFF,
                    ADN_nvals, 1,
						  ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_falff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetfALFF));
	EDIT_substitute_brick(outsetfALFF, 0, MRI_float, falff); 
	falff=NULL;
	THD_load_statistics(outsetfALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetfALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetfALFF, True);



	outsetmALFF = EDIT_empty_copy( inset ) ;
	sprintf(out_malff,"%s_mALFF",prefix); 
	EDIT_dset_items( outsetmALFF,
                    ADN_nvals, 1,
                    ADN_datum_all , MRI_float , 
						  ADN_prefix    , out_malff,
						  ADN_none ) ;
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmALFF)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(outsetmALFF));
	EDIT_substitute_brick(outsetmALFF, 0, MRI_float, malff); 
	malff=NULL;
	THD_load_statistics(outsetmALFF);
	tross_Make_History("3dRSFC", argc, argv, outsetmALFF);
	THD_write_3dim_dataset(NULL, NULL, outsetmALFF, True);

	if(DO_RSFA){
     outsetRSFA = EDIT_empty_copy( inset ) ;
		sprintf(out_rsfa,"%s_RSFA",prefix); 
		EDIT_dset_items( outsetRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_rsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetRSFA));
		EDIT_substitute_brick(outsetRSFA, 0, MRI_float, rsfa); 
		rsfa=NULL;
		THD_load_statistics(outsetRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetRSFA, True);
		
      outsetfRSFA = EDIT_empty_copy( inset ) ;
		sprintf(out_frsfa,"%s_fRSFA",prefix); 
		EDIT_dset_items( outsetfRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_frsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetfRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetfRSFA));
		EDIT_substitute_brick(outsetfRSFA, 0, MRI_float, frsfa); 
		frsfa=NULL;
		THD_load_statistics(outsetfRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetfRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetfRSFA, True);
		
		outsetmRSFA = EDIT_empty_copy( inset ) ; 
		sprintf(out_mrsfa,"%s_mRSFA",prefix); 
		EDIT_dset_items( outsetmRSFA,
                       ADN_nvals, 1,
                       ADN_datum_all , MRI_float , 
							  ADN_prefix    , out_mrsfa,
							  ADN_none ) ;
		if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outsetmRSFA)) )
			ERROR_exit("Can't overwrite existing dataset '%s'",
						  DSET_HEADNAME(outsetmRSFA));
		EDIT_substitute_brick(outsetmRSFA, 0, MRI_float, mrsfa); 
		mrsfa=NULL;
		THD_load_statistics(outsetmRSFA);
		tross_Make_History("3dRSFC", argc, argv, outsetmRSFA);
		THD_write_3dim_dataset(NULL, NULL, outsetmRSFA, True);
	}



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

	DSET_delete(inset);
	DSET_delete(outsetALL);
	DSET_delete(outset);
	DSET_delete(outsetALFF);
	DSET_delete(outsetmALFF);
	DSET_delete(outsetfALFF);
	DSET_delete(outsetRSFA);
	DSET_delete(outsetmRSFA);
	DSET_delete(outsetfRSFA);

	free(inset);
	free(outsetALL);
	free(outset);
	free(outsetALFF);
	free(outsetmALFF);
	free(outsetfALFF);
	free(outsetRSFA);
	free(outsetmRSFA);
	free(outsetfRSFA);

	free(rsfa);
	free(mrsfa);
	free(frsfa);
	free(alff);
	free(malff);
	free(falff);
	free(mask);
	free(series1);
	free(series2);
	free(xx1);
	free(xx2);

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

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

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

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

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

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

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

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

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

	INFO_message("version: MU");

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

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

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

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

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

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

			iarg++ ; continue ;
		}

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

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

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

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

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


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

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


	}
	 
	 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	//free(mode);
	
	return 0;
}
コード例 #28
0
ファイル: 3dDegreeCentrality.c プロジェクト: Gilles86/afni
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) ;
}
コード例 #29
0
ファイル: 3dZFillin.c プロジェクト: CesarCaballeroGaudes/afni
int main( int argc , char * argv[] )
{
   int iarg=1 , dcode=0 , maxgap=2 , nftot=0 ;
   char * prefix="zfillin" , * dstr=NULL;
   THD_3dim_dataset * inset , * outset ;
   MRI_IMAGE * brim ;
   int verb=0 ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: 3dZFillin [options] dataset\n"
             "Extracts 1D rows in the given direction from a 3D dataset,\n"
             "searches for zeros that are 'close' to nonzero values in the row,\n"
             "and replaces the zeros with the closest nonzero neighbor.\n"
             "\n"
             "OPTIONS:\n"
             " -maxstep N  = set the maximum distance to a neighbor\n"
             "                [default=2].\n"
             " -dir D     = set the direction of fill to 'D', which can\n"
             "                be one of the following:\n"
             "                  A-P, P-A, I-S, S-I, L-R, R-L, x, y, z\n"
             "                The first 6 are anatomical directions;\n"
             "                the last 3 are reference to the dataset\n"
             "                internal axes [no default value].\n"
             " -prefix P  = set the prefix to 'P' for the output dataset.\n"
             "\n"
             "N.B.: * If the input dataset has more than one sub-brick,\n"
             "        only the first one will be processed.\n"
             "      * At this time, 3dZFillin only works on byte-valued datasets\n"
             "\n"
             "This program's only purpose is to fill up the Talairach Daemon\n"
             "bricks obtained from the UT San Antonio database.\n"
             "\n"
            ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

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

   /*-- scan args --*/

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

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

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

      if( strcmp(argv[iarg],"-maxstep") == 0 ){
         maxgap = strtol( argv[++iarg] , NULL , 10 ) ;
         if( maxgap < 1 ){
            fprintf(stderr,"*** Illegal value after -maxgap!\n"); exit(1);
         }
         iarg++ ; continue ;
      }

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

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

   if( dstr == NULL ){
      fprintf(stderr,"*** No -dir option on command line!\n"); exit(1);
   }
   if( iarg >= argc ){
      fprintf(stderr,"*** No input dataset on command line!\n"); exit(1);
   }

   inset = THD_open_dataset( argv[iarg] ) ;
   if( inset == NULL ){
      fprintf(stderr,"*** Can't open dataset %s\n",argv[iarg]); exit(1);
   }

   outset = EDIT_empty_copy( inset ) ;
   EDIT_dset_items( outset , ADN_prefix , prefix , ADN_none ) ;
   if( THD_deathcon() && THD_is_file( DSET_HEADNAME(outset) ) ){
      fprintf(stderr,"** Output file %s exists -- cannot overwrite!\n",
              DSET_HEADNAME(outset) ) ;
      exit(1) ;
   }

   tross_Copy_History( inset , outset ) ;
   tross_Make_History( "3dZFillin" , argc,argv , outset ) ;

   if( DSET_NVALS(inset) > 1 ){
      fprintf(stderr,"++ WARNING: input dataset has more than one sub-brick!\n");
      EDIT_dset_items( outset ,
                         ADN_ntt   , 0 ,
                         ADN_nvals , 1 ,
                       ADN_none ) ;
   }

   if( DSET_BRICK_TYPE(outset,0) != MRI_byte ){
      fprintf(stderr,"*** This program only works on byte datasets!\n");
      exit(1) ;
   }

   switch( *dstr ){
      case 'x': dcode = 1 ; break ;
      case 'y': dcode = 2 ; break ;
      case 'z': dcode = 3 ; break ;

      default:
        if( *dstr == ORIENT_tinystr[outset->daxes->xxorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->xxorient][1]   ) dcode = 1 ;

        if( *dstr == ORIENT_tinystr[outset->daxes->yyorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->yyorient][1]   ) dcode = 2 ;

        if( *dstr == ORIENT_tinystr[outset->daxes->zzorient][0] ||
            *dstr == ORIENT_tinystr[outset->daxes->zzorient][1]   ) dcode = 3 ;
      break ;
   }
   if( dcode == 0 ){
      fprintf(stderr,"*** Illegal -dir direction!\n") ; exit(1) ;
   }
   if( verb )
      fprintf(stderr,"++ Direction = axis %d in dataset\n",dcode) ;

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;
   brim = mri_copy( DSET_BRICK(inset,0) ) ;
   DSET_unload(inset) ;
   EDIT_substitute_brick( outset , 0 , brim->kind , mri_data_pointer(brim) ) ;
   nftot = THD_dataset_zfillin( outset , 0 , dcode , maxgap ) ;
   fprintf(stderr,"++ Number of voxels filled = %d\n",nftot) ;
   if (DSET_write(outset) != False) {
      fprintf(stderr,"++ output dataset: %s\n",DSET_BRIKNAME(outset)) ;
      exit(0) ;
   } else {
      fprintf(stderr,
         "** 3dZFillin: Failed to write output!\n" ) ;
      exit(1) ;
   }
   
}
コード例 #30
0
int main( int argc , char *argv[] )
{
   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) ;
}