Exemplo n.º 1
0
float * read_time_series 
(
  char * ts_filename,          /* time series file name (plus column index) */
  int * ts_length              /* output value for time series length */
)

{
  char message[THD_MAX_NAME];    /* error message */
  char * cpt;                    /* pointer to column suffix */
  char filename[THD_MAX_NAME];   /* time series file name w/o column index */
  char subv[THD_MAX_NAME];       /* string containing column index */
  MRI_IMAGE * im, * flim;  /* pointers to image structures 
			      -- used to read 1D ASCII */
  float * far;             /* pointer to MRI_IMAGE floating point data */
  int nx;                  /* number of time points in time series */
  int ny;                  /* number of columns in time series file */
  int iy;                  /* time series file column index */
  int ipt;                 /* time point index */
  float * ts_data = NULL;  /* input time series data */


  /*----- First, check for empty filename -----*/
  if (ts_filename == NULL)
    FDR_error ("Missing input time series file name");


  /*----- Read the time series file -----*/
  flim = mri_read_1D(ts_filename) ;
  if (flim == NULL)
    {
      sprintf (message,  "Unable to read time series file: %s",  ts_filename);
      FDR_error (message);
    }

  far = MRI_FLOAT_PTR(flim);
  nx = flim->nx;
  ny = flim->ny; iy = 0 ;
  if( ny > 1 ){
    fprintf(stderr,"WARNING: time series %s has more than 1 column\n",ts_filename);
  }
  

  /*----- Save the time series data -----*/
  *ts_length = nx;
  ts_data = (float *) malloc (sizeof(float) * nx);
  MTEST (ts_data);
  for (ipt = 0;  ipt < nx;  ipt++)
    ts_data[ipt] = far[ipt + iy*nx];   
  
  
  mri_free (flim);  flim = NULL;

  return (ts_data);
}
Exemplo n.º 2
0
void conv_set_ref( int num , float * ref )
{
   if( num > 0 && ref != NULL ){ /*** if have inputs, make space & copy in ***/
      int ii ;

      /* get rid of old data */

      if(refts != NULL){ free(refts); refts = NULL; free(refin); refin = NULL; }

      refnum = num ;
      refts  = (float *) malloc( sizeof(float) * num ) ;
      refin  = (int *)   malloc( sizeof(int)   * num ) ;
      memcpy( refts , ref , sizeof(float) * num ) ;
      for( ii=0,refnz=0 ; ii < num ; ii++ )        /* build list of nonzero */
         if( refts[ii] != 0 ) refin[refnz++] = ii ;      /* points in refts */
      if( refnz == 0 )
         ERREX("model_conv_diffgamma: All zero reference timeseries!") ;

      if( g_debug ) {
         fprintf(stderr,"+d conv_set_ref: num=%d nonzero=%d\n",num,refnz) ;
         if( g_debug > 1 ) {
            fprintf(stderr,"  TR locked stimuli :");
            for( ii = 0; ii < refnz; ii++ ) fprintf(stderr," %d", refin[ii]);
            fputc('\n',stderr);
         }
      }

      return ;

   } else { /*** if no inputs, read it from AFNI_CONVMODEL_REF 1D file ***/

     char * cp ;
     MRI_IMAGE * flim ;
     float one = 1.0 ;

     cp = my_getenv("AFNI_CONVMODEL_REF") ;  /* get name of reference file */
     if( cp == NULL )
        ERREX("model_conv_diffgamma: need ref file as AFNI_CONVMODEL_REF") ;

     flim = mri_read_1D(cp) ;      /* 16 Nov 1999: replaces mri_read_ascii */
     if( flim == NULL ){
        char buf[256] ;
        sprintf(buf,"model_conv_diffgamma: Can't read timeseries file %s",cp) ;
        ERREX(buf) ;
     }

     if( g_debug )
        fprintf(stderr,"+d conv_set_ref: refts=%s  nx=%d\n",cp,flim->ny) ;

     conv_set_ref( flim->nx , MRI_FLOAT_PTR(flim) ) ;  /* recursion! */
     mri_free(flim) ;
   }
   return ;
}
Exemplo n.º 3
0
float * custom_filter( int dummy )
{
   MRI_IMAGE * filter_data=NULL;
   float * filter_coefficients = NULL;

   filter_data = mri_read_1D(custom_file);
   if MRI_IS_1D(filter_data) {
     custom_ntaps = filter_data->nx;
     if (custom_ntaps % 2) {
       filter_coefficients = MRI_FLOAT_PTR(filter_data);
     } else {
       /*ERROR, EVEN NUMBER OF FILTER TAPS */
     }
   }

   return filter_coefficients ;
}
Exemplo n.º 4
0
int main( int argc , char * argv[] )
{
   int nim , ii , jj , kk , nx ;
   MRI_IMAGE ** inim ;
   float * far ;
   int ncol , ic ;
   float * csum ;
   int nn_ignore=0 , mm_use=0 , iarg=1 ;

   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf("Usage: 1dsum [options] a.1D b.1D ...\n"
            "where each file a.1D, b.1D, etc. is an ASCII file of numbers arranged\n"
            "in rows and columns. The sum of each column is written to stdout.\n"
            "\n"
            "Options:\n"
            "  -ignore nn = skip the first nn rows of each file\n"
            "  -use    mm = use only mm rows from each file\n"
           ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   machdep() ;

   /* parse options */

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

      if( strncmp(argv[iarg],"-ignore",4) == 0 ){
         nn_ignore = (int) strtod(argv[++iarg],NULL) ;
         if( nn_ignore < 0 ){fprintf(stderr,"** Illegal -ignore value!\n");exit(1);}
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-use",4) == 0 ){
         mm_use = (int) strtod(argv[++iarg],NULL) ;
         if( mm_use < 0 ){fprintf(stderr,"** Illegal -use value!\n");exit(1);}
         iarg++ ; continue ;
      }

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

   /* read input files */

   nim = argc-iarg ;
   inim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * nim ) ;
   ncol = 0 ;
   for( jj=0 ; jj < nim ; jj++ ){
      inim[jj] = mri_read_1D( argv[jj+iarg] ) ;
      if( inim[jj] == NULL ){
         fprintf(stderr,"** Can't read input file %s\n",argv[jj+iarg]) ;
         exit(1) ;
      }
      if( jj > 0 && inim[jj]->nx != inim[0]->nx ){
         fprintf(stderr,
                 "** Input file %s doesn't match first file %s in length!\n",
                 argv[jj+iarg],argv[iarg]) ;
         exit(1) ;
      }
      ncol += inim[jj]->ny ;
   }

   if( mm_use == 0 ){
      mm_use = inim[0]->nx - nn_ignore ;
      if( mm_use < 0 ){fprintf(stderr,"** -ignore is too big for these files!\n");exit(1);}
   }
   if( nn_ignore + mm_use > inim[0]->nx ){
      fprintf(stderr,"** -ignore + -use is too big for these files!\n");exit(1);
   }

   csum = (float *) malloc(sizeof(float)*ncol) ;
   for( ic=0 ; ic < ncol ; ic++ ) csum[ic] = 0.0 ;

   nx = inim[0]->nx ;
   for( ii=nn_ignore ; ii < nn_ignore+mm_use ; ii++ ){
      for( ic=jj=0 ; jj < nim ; jj++ ){
         far = MRI_FLOAT_PTR(inim[jj]) ;
         for( kk=0 ; kk < inim[jj]->ny ; kk++ ) csum[ic++] += far[ii+kk*nx] ;
      }
   }

   for( ic=0 ; ic < ncol ; ic++ ) printf("%g ",csum[ic]) ;
   printf("\n");
   exit(0) ;
}
Exemplo n.º 5
0
int main( int argc , char *argv[] )
{
   int iarg , ii,jj,kk,mm , nvec , nx=0,ny , ff , vlen=4 ;
   MRI_IMAGE *tim , *vsim=NULL ;
   MRI_IMARR *tar ;
   char **vecnam , *tnam ;
   float *far , **tvec , *vsig=NULL , xsig,ysig ;
   float_quad qcor ; float_pair pci ; float corst, cor025, cor500, cor975 ;
   char fmt[256] ;
   int cormeth=0 ;    /* 0=Pearson, 1=Spearman, 2=Quadrant, 3=Kendall tau_b */
   float (*corfun)(int,float *,float *) ;

   /*-- start the AFNI machinery --*/

   mainENTRY("1dCorrelate main") ; machdep() ;

   /* check for options */

   iarg = 1 ; nvec = 0 ;
   while( iarg < argc && argv[iarg][0] == '-' ){
      /* I get by with a little help from my friends? */

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

     /*--- methods ---*/

     if( toupper(argv[iarg][1]) == 'P' ){ cormeth = 0 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'S' ){ cormeth = 1 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'Q' ){ cormeth = 2 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'K' ){ cormeth = 3 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'T' ){ cormeth = 4 ; iarg++ ; continue ; }
     if( toupper(argv[iarg][1]) == 'U' ){ cormeth = 5 ; iarg++ ; continue ; }

     /*--- set nboot ---*/

     if( strcasecmp(argv[iarg],"-nboot") == 0 || strcasecmp(argv[iarg],"-num") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-nboot'") ;
       nboot = (int)strtod(argv[iarg],NULL) ;
       if( nboot < NBMIN ){
         WARNING_message("Replacing -nboot %d with %d",nboot,NBMIN) ;
         nboot = NBMIN ;
       }
       iarg++ ; continue ;
     }

     /*--- set alpha ---*/

     if( strcasecmp(argv[iarg],"-alpha") == 0 ){
       iarg++ ; if( iarg >= argc ) ERROR_exit("Need argument after '-alpha'") ;
       alpha = (float)strtod(argv[iarg],NULL) ;
       if( alpha < 1.0f ){
         WARNING_message("Replacing -alpha %.1f with 1",alpha) ;
         alpha = 0.01f ;
       } else if( alpha > 20.0f ){
         WARNING_message("Replacing -alpha %.1f with 20",alpha) ;
         alpha = 0.20f ;
       } else {
         alpha *= 0.01f ;  /* convert from percent to fraction */
       }
       iarg++ ; continue ;
     }

     /*--- block resampling ---*/

     if( strcasecmp(argv[iarg],"-blk") == 0 || strcasecmp(argv[iarg],"-block") == 0 ){
       doblk = 1 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-vsig") == 0 ){
       if( vsim != NULL ) ERROR_exit("Can't use -vsig twice!") ;
       if( ++iarg >= argc ) ERROR_exit("Need argument after -vsig") ;
       vsim = mri_read_1D(argv[iarg]) ;
       if( vsim == NULL ) ERROR_exit("Can't read -vsig file '%s'",argv[iarg]) ;
       iarg++ ; continue ;
     }

     /*--- user should be flogged ---*/

     ERROR_message("Monstrously illegal option '%s'",argv[iarg]) ;
     suggest_best_prog_option(argv[0], argv[iarg]);
     exit(1);
   }

   /*--- user should be flogged twice ---*/

   if( argc < 2 ){
     usage_1dCorrelate(1) ; exit(0) ; 
   }

   if( iarg == argc )
     ERROR_exit("No 1D files on command line!?\n") ;

   /* the function to compute the correlation */

   corfun = cor_func[cormeth] ;

   /* check and assemble list of input 1D files */

   ff = iarg ;
   INIT_IMARR(tar) ;
   for( ; iarg < argc ; iarg++ ){
     tim = mri_read_1D( argv[iarg] ) ;
     if( tim == NULL ) ERROR_exit("Can't read 1D file '%s'",argv[iarg]) ;
     if( nx == 0 ){
       nx = tim->nx ;
       if( nx < 3 )
         ERROR_exit("1D file '%.77s' length=%d is less than 3",argv[iarg],nx) ;
       else if( nx < 7 )
         WARNING_message("1D file '%.77s' length=%d is less than 7",argv[iarg],nx) ;
     } else if( tim->nx != nx ){
       ERROR_exit("Length of 1D file '%.77s' [%d] doesn't match first file [%d]",
                   argv[iarg] , tim->nx , nx );
     }
     nvec += tim->ny ;
     ADDTO_IMARR(tar,tim) ;
   }

   /* user is really an idiot -- flogging's too good for him */

   if( nvec < 2 ) ERROR_exit("Must have at least 2 input columns!") ;

   if( nx < 20 && doblk ){
     doblk = 0 ;
     WARNING_message("Column length %d < 20 ==> cannot use block resampling",nx) ;
   }

   if( vsim != NULL ){
     if( vsim->nvox < nvec )
       ERROR_exit("-vsig file only has %d entries, but needs at least %d",vsim->nvox,nvec) ;
     vsig = MRI_FLOAT_PTR(vsim) ;
   }

   /* create vectors from 1D files */

   tvec = (float **)malloc( sizeof(float *)*nvec ) ;
   vecnam = (char **)malloc( sizeof(char *)*nvec ) ;
   for( jj=0 ; jj < nvec ; jj++ ){
     tvec[jj] = (float *)malloc( sizeof(float)*nx ) ;
     vecnam[jj] = (char *)malloc(sizeof(char)*THD_MAX_NAME) ;
   }

   /* copy data into new space, create output labels, check for stoopiditees */

   for( kk=mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     far = MRI_FLOAT_PTR(tim) ;
     tnam = tim->name ; if( tnam == NULL ) tnam = "File" ;
     for( jj=0 ; jj < tim->ny ; jj++,kk++ ){
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] = far[ii+jj*nx] ;
       sprintf(vecnam[kk],"%s[%d]",THD_trailname(tnam,0),jj) ; /* vector name */
       iarg = strlen(vecnam[kk]) ; vlen = MAX(vlen,iarg) ;
       if( THD_is_constant(nx,tvec[kk]) )
         ERROR_exit("Column %s is constant!",vecnam[kk]) ;
     }
   }
   DESTROY_IMARR(tar) ;

   /*--- Print a beeyootiful header ---*/

   printf("# %s correlation [n=%d #col=%d]\n",cor_name[cormeth],nx,nvec) ;
   sprintf(fmt,"# %%-%ds  %%-%ds",vlen,vlen) ;
   printf(fmt,"Name","Name") ;
   printf("   Value   BiasCorr  %5.2f%%   %5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   if( cormeth == 0 )  /* Pearson */
     printf("  N:%5.2f%% N:%5.2f%%",50.0f*alpha,100.0f-50.0f*alpha) ;
   printf("\n") ;
   printf("# ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf("  ") ;
   for( ii=0 ; ii < vlen ; ii++ ) printf("-") ;
   printf(" ") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   printf(" --------") ;
   if( cormeth == 0 ){ printf(" --------") ; printf(" --------") ; }
   printf("\n") ;
   if( cormeth != 0 )  /* non-Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;
   else                /* Pearson */
     sprintf(fmt,"  %%-%ds  %%-%ds  %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f %%+8.5f\n",vlen,vlen) ;

   /*--- Do some actual work for a suprising change ---*/

   for( jj=0 ; jj < nvec ; jj++ ){       /* loops over column pairs */
     for( kk=jj+1 ; kk < nvec ; kk++ ){

       if( vsig != NULL ){ xsig = vsig[jj]; ysig = vsig[kk]; } else { xsig = ysig = 0.0f; }

       qcor = Corrboot( nx, tvec[jj], tvec[kk], xsig, ysig, corfun ) ;  /* outsourced */

       corst = qcor.a ; cor025 = qcor.b ; cor500 = qcor.c ; cor975 = qcor.d ;

       if( cormeth == 0 ){                      /* Pearson */
         pci = PCorrCI( nx , corst , alpha ) ;
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975, pci.a,pci.b ) ;
       } else {                                 /* all other methods */
         printf(fmt, vecnam[jj], vecnam[kk], corst, cor500, cor025, cor975 ) ;
       }

     }
   }

   /* Finished -- go back to watching Star Trek reruns -- Tribbles ahoy, Cap'n! */

   exit(0) ;
}
Exemplo n.º 6
0
int
main (int argc, char *argv[])
{
  THD_3dim_dataset *old_dset, *new_dset, *I0_dset;	/* input and output datasets */
  int nopt, nbriks, nvox;
  int i;
  MRI_IMAGE *grad1Dptr = NULL;
  MRI_IMAGE *anat_im = NULL;
  MRI_IMAGE *data_im = NULL;
  double fac;
  short *sar = NULL, *tempsptr = NULL, tempval;
  byte *maskptr = NULL, *tempbptr = NULL;
  char tempstr[25];

   /*----- Read command line -----*/
  if (argc < 2 || strcmp (argv[1], "-help") == 0)
    {
      printf ("Usage: 3dDTtoDWI [options] gradient-file I0-dataset DT-dataset\n"
	      "Computes  multiple gradient images from 6 principle direction tensors and\n"
              "    corresponding gradient vector coordinates applied to the I0-dataset.\n"
	      " The program takes three parameters as input :  \n"
	      "    a 1D file of the gradient vectors with lines of ASCII floats Gxi,Gyi,Gzi.\n"
              "    Only the non-zero gradient vectors are included in this file (no G0 line).\n"
              " The I0 dataset is a volume without any gradient applied.\n"
              " The DT dataset is the 6-sub-brick dataset containing the diffusion tensor data,\n"
              "    Dxx, Dxy, Dyy, Dxz, Dyz, Dzz (lower triangular row-wise order)\n"
	      " Options:\n"
              "   -prefix pname = Use 'pname' for the output dataset prefix name.\n"
              "    [default='DWI']\n"
	      "   -automask =  mask dataset so that the gradient images are computed only for\n"
	      "    high-intensity (presumably brain) voxels.  The intensity level is\n"
              "    determined the same way that 3dClipLevel works.\n\n"
              "   -datum type = output dataset type [float/short/byte] (default is float).\n"
              "   -help = show this help screen.\n"
              " Example:\n"
              "  3dDTtoDWI -prefix DWI -automask tensor25.1D 'DT+orig[26]' DT+orig.\n\n"
	      " The output is a n sub-brick bucket dataset containing computed DWI images.\n"
              "    where n is the number of vectors in the gradient file + 1\n"
	      "\n");
      printf ("\n" MASTER_SHORTHELP_STRING);
      exit (0);
    }

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

  nopt = 1;
  datum = MRI_float;


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

      /*-- prefix --*/

      if (strcmp (argv[nopt], "-prefix") == 0)
	{
	  if (++nopt >= argc)
	    {
	      fprintf (stderr, "*** Error - prefix needs an argument!\n");
	      exit (1);
	    }
	  MCW_strncpy (prefix, argv[nopt], THD_MAX_PREFIX);	/* change name from default prefix */
          /* check file name to be sure not to overwrite - mod drg 12/9/2004 */
	  if (!THD_filename_ok (prefix))
	    {
	      fprintf (stderr, "*** Error - %s is not a valid prefix!\n", prefix);
	      exit (1);
	    }
	  nopt++;
	  continue;
	}

      /*-- datum --*/

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

	fprintf(stderr, "*** Error - unknown option %s\n", argv[nopt]);
	exit(1);
    }
  
   /*----- read input datasets -----*/

  if (nopt >= argc)
    {
      fprintf (stderr, "*** Error - No input dataset!?\n");
      exit (1);
    }

  /* first input dataset - should be gradient vector file of ascii floats Gx,Gy,Gz */

  /* read gradient vector 1D file */
  grad1Dptr = mri_read_1D (argv[nopt]);
  if (grad1Dptr == NULL)
    {
      fprintf (stderr, "*** Error reading gradient vector file\n");
      exit (1);
    }

  if (grad1Dptr->ny != 3)
    {
      fprintf (stderr, "*** Error - Only 3 columns of gradient vectors allowed\n");
      fprintf (stderr, "%d columns found\n", grad1Dptr->nx);
      mri_free (grad1Dptr);
      exit (1);
    }

  if (grad1Dptr->nx < 6)
    {
      fprintf (stderr, "*** Error - Must have at least 6 gradient vectors\n");
      fprintf (stderr, "%d columns found\n", grad1Dptr->nx);
      mri_free (grad1Dptr);
      exit (1);
    }

  nbriks = grad1Dptr->nx + 1;    /* number of gradients specified here from file */     
  nopt++;

  /* open I0 dataset - idealized no gradient image */
  I0_dset = THD_open_dataset (argv[nopt]);
  CHECK_OPEN_ERROR(I0_dset,argv[nopt]) ;

   DSET_mallocize (I0_dset);
   DSET_load (I0_dset);	                /* load dataset */
   data_im = DSET_BRICK (I0_dset, 0);	/* set pointer to the 0th sub-brik of the dataset */
   fac = DSET_BRICK_FACTOR(I0_dset, 0); /* get scale factor for each sub-brik*/
   if(fac==0.0) fac=1.0;
   if((data_im->kind != MRI_float)) {
       fprintf (stderr, "*** Error - Can only open float datasets. Use 3dcalc to convert.\n");
       mri_free (grad1Dptr);
       mri_free (data_im);
       exit (1);
   }

   I0_ptr = mri_data_pointer(data_im) ; /* pointer to I0 data */

   nopt++;

  /* Now read in all the MRI volumes for each gradient vector */
  /* assumes first one is no gradient */
  old_dset = THD_open_dataset (argv[nopt]);
  CHECK_OPEN_ERROR(old_dset,argv[nopt]) ;

  /* expect at least 6 values per voxel - 6 sub-briks as input dataset */
  if (DSET_NVALS (old_dset) <6)
    {
      fprintf (stderr,
      "*** Error - Dataset must have at least 6 sub-briks to describe the diffusion tensor\n");
      mri_free (grad1Dptr);
      mri_free (data_im);
      exit (1);
    }


  InitGlobals (grad1Dptr->nx + 1);	/* initialize all the matrices and vectors */
  Computebmatrix (grad1Dptr, BMAT_NZ);	/* compute bij=GiGj */
  INFO_message("The maximum magnitude of the bmatrix appears to be: %.2f", MAX_BVAL);

  if (automask)
    {
      DSET_mallocize (old_dset);
      DSET_load (old_dset);	/* get B0 (anatomical image) from dataset */
      /*anat_im = THD_extract_float_brick( 0, old_dset ); */
      anat_im = DSET_BRICK (old_dset, 0);	/* set pointer to the 0th sub-brik of the dataset */
      maskptr = mri_automask_image (anat_im);	/* maskptr is a byte pointer for volume */

      /* convert byte mask to same format type as dataset */
      nvox = DSET_NVOX (old_dset);
      sar = (short *) calloc (nvox, sizeof (short));
      /* copy maskptr values to far ptr */
      tempsptr = sar;
      tempbptr = maskptr;
      for (i = 0; i < nvox; i++)
	{
	  *tempsptr++ = (short) *tempbptr++;
	  tempval = *(tempsptr - 1);
	}

      free (maskptr);

      /*old_dset->dblk->malloc_type = DATABLOCK_MEM_MALLOC; *//* had to set this? */
      EDIT_add_brick (old_dset, MRI_short, 0.0, sar);	/* add sub-brik to end */


    }

  /* temporarily set artificial timing to 1 second interval */
  EDIT_dset_items (old_dset,
		   ADN_ntt, DSET_NVALS (old_dset),
		   ADN_ttorg, 0.0,
		   ADN_ttdel, 1.0, ADN_tunits, UNITS_SEC_TYPE, NULL);

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

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



  FreeGlobals ();
  mri_free (grad1Dptr);


  if (automask)
    {
      mri_free (anat_im);
      DSET_unload_one (old_dset, 0);
      sar = NULL;
    }

  if (new_dset != NULL)
    {
      tross_Copy_History (old_dset, new_dset);
      for(i=0;i<nbriks;i++) {
        sprintf(tempstr,"grad%3.3d", i);
        EDIT_dset_items (new_dset, ADN_brick_label_one + i, tempstr, ADN_none);
      }
      tross_Make_History ("3dDTtoDWI", argc, argv, new_dset);
      DSET_write (new_dset);
      fprintf(stderr,"--- Output dataset %s\n", DSET_BRIKNAME(new_dset));
    }
  else
    {
      fprintf (stderr, "*** Error - Unable to compute output dataset!\n");
      exit (1);
    }

  exit (0);
}
Exemplo n.º 7
0
int main(int argc, char *argv[]) 
{  
   int CHECK = 0;
	int iarg;
   char *Fname_input = NULL;
   char *Fname_output = NULL;
   char *Fname_outputBV = NULL;
   char *Fname_bval = NULL;
   int opt;
   FILE *fin=NULL, *fout=NULL, *finbv=NULL, *foutBV=NULL;
   int i,j,k;
   int BZER=0,idx=0,idx2=0;

   MRI_IMAGE *flim=NULL;
   MRI_IMAGE *preREADIN=NULL;
   MRI_IMAGE *preREADBVAL=NULL;
   float *READIN=NULL;
   float *READBVAL=NULL;

   float OUT_MATR[MAXGRADS][7]; // b- or g-matrix
   float OUT_GRAD[MAXGRADS][4]; // b- or g-matrix

   int INV[3] = {1,1,1}; // if needing to switch
   int FLAG[MAXGRADS];
   float temp;
   int YES_B = 0;
   int EXTRA_ZEROS=0;
   int HAVE_BVAL = 0;
   int BVAL_OUT = 0; 
   int BVAL_OUT_SEP = 0; 
   float BMAX_REF = 1; // i.e., essentially zero
   int IN_FORM = 0; // 0 for row, 1 for col
   int OUT_FORM = 1; // 1 for col, 2 for bmatr 
   int HAVE_BMAX_REF=0 ; // referring to user input value
   int count_in=0, count_out=0;

	THD_3dim_dataset *dwset=NULL, *dwout=NULL; 
   int Nbrik = 0;
	char *prefix=NULL ;
   float **temp_arr=NULL, **temp_grad=NULL;
   int Ndwi = 0, dwi=0, Ndwout = 0, Ndwi_final = 0, Ndwout_final = 0;
   int Nvox = 0;
   int DWI_COMP_FAC = 0;
   int ct_dwi = 0;
   float MaxDP = 0;

	mainENTRY("1dDW_Grad_o_Mat"); machdep();
    
   if (argc == 1) { usage_1dDW_Grad_o_Mat(1); exit(0); }

   iarg = 1;
	while( iarg < argc && argv[iarg][0] == '-' ){
		if( strcmp(argv[iarg],"-help") == 0 || 
			 strcmp(argv[iarg],"-h") == 0 ) {
         usage_1dDW_Grad_o_Mat(strlen(argv[iarg])>3 ? 2:1);
			exit(0);
		}
      
      if( strcmp(argv[iarg],"-flip_x") == 0) {
			INV[0] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-flip_y") == 0) {
			INV[1] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-flip_z") == 0) {
			INV[2] = -1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-keep_b0s") == 0) {
			YES_B = 1;
			iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-put_zeros_top") == 0) {
			EXTRA_ZEROS = 1;
			iarg++ ; continue ;
		}

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

         Fname_input = argv[iarg];
         count_in++;

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

         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 1;

         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_gmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matT_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 2;
         
         iarg++ ; continue ;
		} 
      if( strcmp(argv[iarg],"-in_gmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matA_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 3;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_bmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matT_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 4;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-in_bmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_matA_cols'\n") ;
         
         Fname_input = argv[iarg];
         count_in++;
         IN_FORM = 5;
         
         iarg++ ; continue ;
		}

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

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 0;

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

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 1;

         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-out_gmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_gmatT_cols'\n") ;
         
         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 2;
         
         iarg++ ; continue ;
		}
      if( strcmp(argv[iarg],"-out_gmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_gmatA_cols'\n") ;
         
         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 3;
         
         iarg++ ; continue ;
		}  
      if( strcmp(argv[iarg],"-out_bmatT_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bmatT_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 4;
         
         iarg++ ; continue ;
		}
      
      if( strcmp(argv[iarg],"-out_bmatA_cols") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bmatA_cols'\n") ;

         Fname_output = argv[iarg];
         count_out++;
         OUT_FORM = 5;
         
         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-in_bvals") == 0 ){
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-in_bvals'\n") ;
         
         Fname_bval = argv[iarg];
         HAVE_BVAL = 1;

         iarg++ ; continue ;
		}

      if( strcmp(argv[iarg],"-bmax_ref") == 0) { 
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-bmax_ref'\n");
         
         BMAX_REF = atof(argv[iarg]);
         HAVE_BMAX_REF = 1;
         
         iarg++ ; continue ;
		}
      
      if( strcmp(argv[iarg],"-out_bval_col") == 0) {
			BVAL_OUT = 1;
			iarg++ ; continue ;
		}

      // May,2015
      if( strcmp(argv[iarg],"-out_bval_row_sep") == 0) {
         if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-out_bval_row_sep'\n") ;
         
         Fname_outputBV = argv[iarg];
         BVAL_OUT_SEP = 1;
         
         iarg++ ; continue ;
		}
      
		if( strcmp(argv[iarg],"-proc_dset") == 0 ){ // in DWIs
			if( ++iarg >= argc ) 
				ERROR_exit("Need argument after '-proc_dset'") ;
			dwset = THD_open_dataset( argv[iarg] ) ;
			if( dwset == NULL ) 
				ERROR_exit("Can't open DWI dataset '%s'", argv[iarg]) ;
			DSET_load(dwset) ; CHECK_LOAD_ERROR(dwset) ;
			
			iarg++ ; continue ;
		}
		
      if( strcmp(argv[iarg],"-pref_dset") == 0 ){ // will be output
			iarg++ ; if( iarg >= argc ) 
							ERROR_exit("Need argument after '-pref_dset'");
			prefix = strdup(argv[iarg]) ;
			if( !THD_filename_ok(prefix) ) 
				ERROR_exit("Illegal name after '-pref_dset'");
			iarg++ ; continue ;
		}
		
      if( strcmp(argv[iarg],"-dwi_comp_fac") == 0) { 
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-dwi_comp_fac'\n");
         
         DWI_COMP_FAC = atoi(argv[iarg]);
         if (DWI_COMP_FAC <=1)
            ERROR_exit("The compression factor after '-dwi_comp_fac'"
                       "must be >1!");

         iarg++ ; continue ;
		}

      ERROR_message("Bad option '%s'\n",argv[iarg]) ;
		suggest_best_prog_option(argv[0], argv[iarg]);
		exit(1);
      
   }

   //  * * * * * * * * * * * * * * * * * * * * * * * * * * * 

   if( (Fname_input == NULL) ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Option '-in_*' requires argument.\n");
      exit(1);
   }
   if( (Fname_output == NULL) ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Option '-out_*' requires arg.\n");
      exit(2);
   }

   if( count_in > 1 ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Can't have >1 vec file input.\n");
      exit(3);
   }
   if( count_out > 1 ) {
      fprintf(stderr,
              "\n\tBad Command-lining!  Can't have >1 output file opt.\n");
      exit(4);
   }

   if(YES_B && dwset) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have '-keep_b0s' and '-proc_dset' together.\n");
      exit(5);
   }
   
   if( !prefix && dwset) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Need an output '-pref_dset' when using '-proc_dset'.\n");
      exit(6);
   }
   
   if(YES_B && DWI_COMP_FAC) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have '-keep_b0s' and '-dwi_comp_fac' together.\n");
      exit(7);
   }
   

   if(!HAVE_BVAL && (BVAL_OUT || BVAL_OUT_SEP)) {
      fprintf(stderr,
              "\n** Bad Command-lining! "
              "Can't have ask for outputting bvals with no '-in_bvals FILE'.\n");
      exit(8);
   }


   // ********************************************************************
   // ************************* start reading ****************************
   // ********************************************************************

   flim = mri_read_1D (Fname_input);
   if (flim == NULL) {
         ERROR_exit("Error reading gradient vector file");
      }
   if( IN_FORM )
      preREADIN = mri_transpose(flim); // effectively *undoes* autotranspose
   else
      preREADIN = mri_copy(flim);
   mri_free(flim);
   idx = preREADIN->ny;

   if( HAVE_BVAL ) {
      flim = mri_read_1D (Fname_bval);
      if (flim == NULL) {
         ERROR_exit("Error reading b-value file");
      }
      if( flim->ny == 1)
         preREADBVAL = mri_transpose(flim); // effectively *undoes* autotransp
      else
         preREADBVAL = mri_copy(flim); 
      mri_free(flim);
      idx2 = preREADBVAL->ny;

   }

   if(idx>= MAXGRADS ) {
      printf("Error, too many input grads.\n");
      mri_free (preREADIN);
      if( HAVE_BVAL ) mri_free (preREADBVAL);
      exit(4);
   }

   if( ( (preREADIN->nx != 3 ) && (preREADIN->ny != 3 )) &&
       (preREADIN->nx != 6 ) )
      printf("Probably an error, "
             "because there aren't 3 or 6 numbers in columns!\n");

   if( HAVE_BVAL && ( idx != idx2 ) ) {
      printf("Error, because the number of bvecs (%d)\n"
             "and bvals (%d) don't appear to match!\n", idx, idx2);
      mri_free (preREADIN);
      mri_free (preREADBVAL);
      exit(3);
   }

   if(dwset) {
      Nbrik = DSET_NVALS(dwset);

      if( idx != Nbrik ) {
         fprintf(stderr,
                 "\n** ERROR: the number of bvecs (%d) does not match the "
                 "number of briks in '-proc_dset' (%d).\n", idx, Nbrik);
         exit(4);
      }
   }

   READIN = MRI_FLOAT_PTR( preREADIN );
   if( HAVE_BVAL )
      READBVAL = MRI_FLOAT_PTR( preREADBVAL );


   // 0 is grad row;  
   // 1 is grad col;
   // 2 is gmatrRow col T;
   // 3 is gmatrDiag col A;
   // 4 is bmatrRow col T;
   // 5 is bmatrDiag col A;

   //if( IN_FORM == 0 ) // grad rows, no binfo
   // for( i=0; i<idx ; i++ ) 
   //    for ( j=0; j<3 ; j++ )
   //       OUT_GRAD[i][j+1] = *(READIN +j*idx +i) ;
   //else 
   if ( IN_FORM <= 1 )  // grad cols, no binfo
      for( i=0; i<idx ; i++ ) 
         for ( j=0; j<3 ; j++ )
            OUT_GRAD[i][j+1] = *(READIN + 3*i+j);
   
   // A/row/3dDWItoDT: Bxx, Byy, Bzz, Bxy, Bxz, Byz
   // T/diag/TORTOISE:  b_xx 2b_xy 2b_xz b_yy 2b_yz b_zz
   else if ( (IN_FORM == 3) || (IN_FORM ==5 ) ) { // diag matr
      for( i=0; i<idx ; i++ ) { 
         for( j=0; j<3 ; j++ ) {
            OUT_MATR[i][j+1] = *(READIN+6*i+j);
            OUT_MATR[i][3+j+1] = *(READIN+6*i+3+j);
         }

         for( j=0; j<3 ; j++ ) 
            if(OUT_MATR[i][j] < 0 )
               CHECK++;
      }
      if(CHECK > 0)
         INFO_message("Warning: you *said* you input a mat'T',"
                      " but the matr diagonals don't appear to be uniformly"
                      " positive. If input cols 0, 3 and 5 are positive,"
                      " then you might have meant mat'A'?");
   }
   else if ( (IN_FORM ==2 ) || (IN_FORM ==4 ) ) { // row matr
      CHECK = 0;
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][1] = *(READIN +6*i);
         OUT_MATR[i][2] = *(READIN +6*i+3);
         OUT_MATR[i][3] = *(READIN +6*i+5);
         OUT_MATR[i][4] = *(READIN +6*i+1)/2.;
         OUT_MATR[i][5] = *(READIN +6*i+2)/2.;
         OUT_MATR[i][6] = *(READIN +6*i+4)/2.;
      }
      for( i=0; i<idx ; i++ ) 
         for( j=0; j<3 ; j++ ) 
            if(OUT_MATR[i][j] < 0 )
               CHECK++;
      if(CHECK > 0)
         INFO_message("Warning: you *said* you input a mat'A',"
                      " but the matr diagonals don't appear to be uniformly"
                      " positive. If input cols 0, 1 and 2 are positive,"
                      " then you might have meant mat'T'?");
   }
   else{
      fprintf(stderr, "Coding error with format number (%d), not allowed.\n",
              IN_FORM);
      exit(2);
   }
   
   // get bval info
   if( ( (IN_FORM ==4 ) || (IN_FORM ==5 ) ) ) { //bval
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][0] = OUT_GRAD[i][0] =
            OUT_MATR[i][1] + OUT_MATR[i][2] + OUT_MATR[i][3];
         if( OUT_MATR[i][0] > 0.000001)
            for( j=1 ; j<7 ; j++ )
               OUT_MATR[i][j]/= OUT_MATR[i][0];
      }
   }
   else if ( HAVE_BVAL )
      for( i=0; i<idx ; i++ ) {
         OUT_MATR[i][0] = OUT_GRAD[i][0] =  *(READBVAL + i);
      }
   else if ( OUT_FORM > 3 || BVAL_OUT ||  BVAL_OUT_SEP || HAVE_BMAX_REF ) {
      fprintf(stderr, "ERROR:  you asked for b-value dependent output, "
              "but gave me no bvals to work with.\n");
      exit(2);
   }
      
   // * * *  ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * *
   // at this point, all IN_FORM >1 cases which need bval have led to:
   //    + grad[0] has bval
   //    + matr[0] has bval
   //    + matr file normalized and in diagonal form
   // * * *  ** * * * * * * * * ** ** * * ** * * ** * ** * ** * * *

   for( i=0; i<idx ; i++ ) 
      if( IN_FORM > 1)
         j = GradConv_Gsign_from_BmatA( OUT_GRAD[i]+1, OUT_MATR[i]+1);
      else
         j = GradConv_BmatA_from_Gsign( OUT_MATR[i]+1, OUT_GRAD[i]+1);


   // flip if necessary
   for( i=0 ; i<idx ; i++) {
      for( j=0 ; j<3 ; j++) 
         OUT_GRAD[i][j+1]*= INV[j];
      OUT_MATR[i][4]*= INV[0]*INV[1];
      OUT_MATR[i][5]*= INV[0]*INV[2];
      OUT_MATR[i][6]*= INV[1]*INV[2];
   }
   
   BZER=0;
   for( i=0 ; i<idx ; i++) {
      if( HAVE_BVAL || (IN_FORM ==4) || (IN_FORM ==5) )
         if( OUT_GRAD[i][0] >= BMAX_REF ) 
            FLAG[i] = 1;
         else{
            if( YES_B ) 
               FLAG[i] = 1;
            BZER++;
         }
      else {
         temp = 0.;
         for( j=1 ; j<4 ; j++) 
            temp+= pow(OUT_GRAD[i][j],2);
         
         if( temp > 0.1 )
            FLAG[i] = 1;
         else{
            if( YES_B ) 
               FLAG[i] = 1;
            BZER++;
         }
      }
   }
   
   if(YES_B) {
      printf("\tChose to *keep* %d b0s,\tas well as  \t%d grads\n",
             BZER,idx-BZER);
      BZER=0;
   }
   else {
      printf("\tGetting rid of %d b0s,\tleaving the %d grads\n",
             BZER,idx-BZER);
      Ndwi = idx-BZER;
   }
   Ndwi_final = idx-BZER; // default:  all DWIs

   if( DWI_COMP_FAC ) {
      if( Ndwi % DWI_COMP_FAC != 0 ) {
         fprintf(stderr, "\n** ERROR can't compress: "
                 "Ndwi=%d, and %d/%d has a nonzero remainder (=%d).\n",
                 Ndwi,Ndwi,DWI_COMP_FAC, Ndwi % DWI_COMP_FAC );
         exit(1);
      }
      else {
         Ndwi_final = Ndwi/DWI_COMP_FAC;
         INFO_message("You have chosen a compression factor of %d, "
                      "with %d DWIs,\n"
                      "\tso that afterward there will be %d DWIs.",
                      DWI_COMP_FAC, Ndwi, Ndwi_final);
      }
   }

   if(BVAL_OUT_SEP)
      if( (foutBV = fopen(Fname_outputBV, "w")) == NULL) {
         fprintf(stderr, "\n\nError opening file %s.\n",Fname_outputBV);
         exit(1);
      }

   if( (fout = fopen(Fname_output, "w")) == NULL) {
      fprintf(stderr, "\n\nError opening file %s.\n",Fname_output);
      exit(1);
   }

   // 0 is grad row;  
   // 1 is grad col;
   // 2 is gmatrRow col T;
   // 3 is gmatrDiag col A;
   // 4 is bmatrRow col T;
   // 5 is bmatrDiag col A;

   if( OUT_FORM>0) {
      if( EXTRA_ZEROS ) {
         if( BVAL_OUT )
            fprintf(fout,"%8d  ", 0);
         if( BVAL_OUT_SEP )
            fprintf(foutBV,"%8d  ", 0);

         if( OUT_FORM == 1 )
            for( k=1 ; k<4 ; k++ )
               fprintf(fout,"%11.5f  ", 0.0);
         else if ( OUT_FORM > 1 ) // bit superfluous at this point
            for( k=1 ; k<7 ; k++ )
               fprintf(fout,"%11.5f  ", 0.0);
         fprintf(fout,"\n");
      }

      ct_dwi = 0;
      for(i=0 ; i<idx ; i++){ 
         if(FLAG[i]) {
            
            if( BVAL_OUT )
               fprintf(fout,"%8d  ", (int) OUT_GRAD[i][0]);
            if( BVAL_OUT_SEP )
               fprintf(foutBV,"%8d  ", (int) OUT_GRAD[i][0]);

            if( (OUT_FORM == 4) || (OUT_FORM ==5) )
               for( k=1 ; k<7 ; k++ )
                  OUT_MATR[i][k]*= OUT_MATR[i][0];
            
            if( OUT_FORM == 1 ) // grad col
               for( k=1 ; k<4 ; k++ )
                  fprintf(fout,"%11.5f  ", OUT_GRAD[i][k]);
            
            else if( (OUT_FORM == 3) || (OUT_FORM == 5) ) { // gmat
               for( k=1 ; k<6 ; k++ )
                  fprintf(fout,"%11.5f  ", OUT_MATR[i][k]);
               fprintf(fout,"%11.5f", OUT_MATR[i][k]);
            }
            else if ( (OUT_FORM == 2 ) || (OUT_FORM ==4)) { // bmat
               fprintf(fout,"%11.5f  ", OUT_MATR[i][1]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][4]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][5]);
               fprintf(fout,"%11.5f  ", OUT_MATR[i][2]);
               fprintf(fout,"%11.5f  ", 2*OUT_MATR[i][6]);
               fprintf(fout,"%11.5f",   OUT_MATR[i][3]);
            }
            
            fprintf(fout,"\n");
            ct_dwi++;
         }
         if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) {
            INFO_message("Reached compression level:  DWI number %d",
                         Ndwi_final);
            break;
         }
      }
   }
   else if(OUT_FORM ==0) {
      if(BVAL_OUT)
         WARNING_message("Ignoring '-out_bval_col' option, since "
                         " you are outputting in rows.");
      
      for( k=1 ; k<4 ; k++ ) {
         if(EXTRA_ZEROS){
            fprintf(fout,"% -11.5f  ", 0.0);
            if( (k==1) && BVAL_OUT_SEP ) // only output 1 zeroin bval file
               fprintf(foutBV,"%8d  ", 0);
         }
         ct_dwi = 0;
         for(i=0 ; i<idx ; i++) {
            if(FLAG[i]) {
               fprintf(fout,"% -11.5f  ", OUT_GRAD[i][k]);
               if( (k==1) && BVAL_OUT_SEP )// only output 1 zeroin bval file
                  fprintf(foutBV,"%8d  ", (int) OUT_GRAD[i][0]);
               ct_dwi++;
            }
            if( (ct_dwi == Ndwi_final) && DWI_COMP_FAC ) {
               INFO_message("Reached compression level:  DWI number %d",
                            Ndwi_final);
               break;
            }
         }
         fprintf(fout,"\n");
      }
   }

   fclose(fout);
   if( BVAL_OUT_SEP ) {
      fprintf(foutBV,"\n");
      fclose(foutBV);
   }

   if(dwset) {
      INFO_message("Processing the B0+DWI file now.");
      if(!BZER) {
         fprintf(stderr, "\n** Error in processing data set: "
                 "no b=0 values from bvecs/bval info!\n");
         exit(5);
      }

      // FLAG marks where DWIs are if not using '-keep_b0s'!

      Nvox = DSET_NVOX(dwset);
      Ndwout = Ndwi+1;

      temp_arr = calloc( Ndwout,sizeof(temp_arr));
      for( i=0 ; i<Ndwout ; i++) 
         temp_arr[i] = calloc( Nvox,sizeof(float)); 
      temp_grad = calloc( Ndwi,sizeof(temp_grad));
      for( i=0 ; i<Ndwi ; i++) 
         temp_grad[i] = calloc( 3,sizeof(float)); 

      if( (temp_arr == NULL) || (temp_grad == NULL) ) {
            fprintf(stderr, "\n\n MemAlloc failure.\n\n");
            exit(123);
      }

      dwi = 0; // keep track of DWI contraction
      for( i=0 ; i<Nbrik ; i++)
         if( !FLAG[i] ) // b=0
            for( j=0 ; j<Nvox ; j++)
               temp_arr[0][j]+= THD_get_voxel(dwset,j,i);
         else {
            for( j=0 ; j<3 ; j++)
               temp_grad[dwi][j]= OUT_GRAD[i][j+1];
            dwi++;
            for( j=0 ; j<Nvox ; j++)
               temp_arr[dwi][j]+= THD_get_voxel(dwset,j,i);
         }
      if( dwi != Ndwi ) {
         fprintf(stderr, "\n** Mismatch in internal DWI counting!\n");
         exit(6);
      }

      // average the values
      for( j=0 ; j<Nvox ; j++)
         temp_arr[0][j]/= BZER; // can't be zero here.
      
      if( DWI_COMP_FAC ) {
         INFO_message("Compressing DWI file");

         for( k=1 ; k<DWI_COMP_FAC ; k++)
            for( i=0 ; i<Ndwi_final ; i++)
               for( j=0 ; j<Nvox ; j++)
                  temp_arr[1+i][j]+= temp_arr[1+k*Ndwi_final+i][j];
         
         for( i=0 ; i<Ndwi_final ; i++)
            for( j=0 ; j<Nvox ; j++)
               temp_arr[1+i][j]/= DWI_COMP_FAC;

         INFO_message("Checking closeness of compressed gradient values");
         MaxDP = GradCloseness(temp_grad, Ndwi, DWI_COMP_FAC);

         INFO_message("The max angular difference between matched/compressed\n"
                      "\tgradients is: %f", MaxDP);
         if( MaxDP > 2)
            WARNING_message("The max angular difference seem kinda big-- you\n"
                            " sure about the compression factor?");
      }

      Ndwout_final = Ndwi_final + 1;
      INFO_message("Writing the processed data set.");
      dwout = EDIT_empty_copy( dwset ); 
      EDIT_dset_items(dwout,
                      ADN_nvals, Ndwout_final,
                      ADN_ntt, 0,
                      ADN_datum_all, MRI_float , 
                      ADN_prefix, prefix,
                      ADN_none );

      for( i=0; i<Ndwout_final ; i++) {
         EDIT_substitute_brick(dwout, i, MRI_float, temp_arr[i]);
         temp_arr[i]=NULL;
      }

      // if necessary
      for( i=Ndwout_final ; i<Ndwout ; i++)
         temp_arr[i]=NULL;

      THD_load_statistics( dwout );
      if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(dwout)) )
         ERROR_exit("Can't overwrite existing dataset '%s'",
                    DSET_HEADNAME(dwout));
      tross_Make_History("1dDW_Grad_o_Mat", argc, argv, dwout);
      THD_write_3dim_dataset(NULL, NULL, dwout, True);
      DSET_delete(dwout); 
      free(dwout); 
      DSET_delete(dwset); 
      free(dwset); 

      for( i=0 ; i<Ndwout_final ; i++)
         free(temp_arr[i]);
      free(temp_arr);
   }

   mri_free(preREADIN);
   if( HAVE_BVAL )
      mri_free(preREADBVAL);
   if(prefix)
      free(prefix);

   

   printf("\n\tDone. Check output file '%s' for results",Fname_output);
   if(dwset) {
      printf("\n\t-> as well as the data_set '%s'",DSET_FILECODE(dwout));
   }
   if(BVAL_OUT_SEP)
      printf("\n\t-> and even the b-value rows '%s'",Fname_outputBV);
   printf("\n\n");

   exit(0);   
}
Exemplo n.º 8
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL , *outset=NULL ;
   MCW_cluster *nbhd=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , automask=0 ;
   char *prefix="./LocalCormat" ;
   int iarg=1 , verb=1 , ntype=0 , kk,nx,ny,nz,nxy,nxyz,nt , xx,yy,zz, vstep ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; MRI_IMAGE *pim=NULL ;
   int mmlag=10 , ii,jj , do_arma=0 , nvout ;
   MRI_IMAGE *concim=NULL ; float *concar=NULL ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ;

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

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

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

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

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

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

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

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

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

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

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

   /** create output dataset **/

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

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

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

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

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

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

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

   exit(0) ;
}
Exemplo n.º 9
0
void conv_set_ref( int num , float ** ref )
{
   int jv ;

   if( num > 0 && ref != NULL ){ /*** if have inputs, make space & copy in ***/
      int ii ;

      for( jv=0 ; jv < NREF ; jv++ ){

         /* get rid of old data? */

         if( refts[jv] != NULL ){
            free(refts[jv]); refts[jv] = NULL;
            free(refin[jv]); refin[jv] = NULL;
         }

         /* copy new data */

         refnum[jv] = num ;
         refts[jv]  = (float *) malloc( sizeof(float) * num ) ;
         refin[jv]  = (int *)   malloc( sizeof(int)   * num ) ;
         memcpy( refts[jv] , ref[jv] , sizeof(float) * num ) ;

         /* build a list of nonzero entries in this column */

         for( ii=0,refnz[jv]=0 ; ii < num ; ii++ )
            if( refts[jv][ii] != 0.0 ) refin[jv][refnz[jv]++] = ii ;

         if( refnz[jv] == 0 )
            ERREX(__FILE__ ": All zero reference timeseries column!") ;
      }
      return ;

   } else { /*** if no inputs, do something special ***/

     char * cp ;
     MRI_IMAGE * flim ;
     int jv , nx ;
     float * ref[NREF] ;

     cp = my_getenv("AFNI_CONVMODEL_REF") ;  /* get name of reference file */
     if( cp == NULL )
        ERREX(__FILE__ ": Can't read AFNI_CONVMODEL_REF from environment") ;

     flim = mri_read_1D(cp) ;            /* 16 Nov 1999: replaces mri_read_ascii */
     if( flim == NULL ){
        char buf[256] ;
        sprintf(buf,__FILE__ ": Can't read timeseries file %s",cp) ;
        ERREX(buf) ;
     } else {
        fprintf(stderr,__FILE__ ": Read reference file %s\n",cp) ;
     }

     if( flim->ny < NREF )
        ERREX(__FILE__ ": reference file has too few columns!") ;
     else if( flim->nv > NREF )
        fprintf(stderr,__FILE__ " WARNING: reference file has too many columns!\n") ;

     nx = flim->nx ;
     for( jv=0 ; jv < NREF ; jv++ )
        ref[jv] = MRI_FLOAT_PTR(flim) + jv*nx ;

     conv_set_ref( nx , ref ) ;  /* recursion! */
     mri_free(flim) ;
   }
   return ;
}
Exemplo n.º 10
0
int main( int argc , char *argv[] )
{
   MRI_IMAGE *inim , *outim ; float *iv ;
   int iarg , ii,jj , nreg , ntime , *tau=NULL , rnum ;
   NI_element *nelmat=NULL ; char *matname=NULL ;
   MTYPE rhomax=0.7 , bmax=0.7 ; int rhonum=7 , bnum=14 ;
   char *cgl , *rst ;
   matrix X ; vector y ;
   float cput ;
   reml_collection *rrcol ;

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
      "Usage: 1dREMLfit [option] file.1D\n"
      "Least squares fit with REML estimation of the ARMA(1,1) noise.\n"
      "\n"
      "Options (the first one is mandatory)\n"
      "------------------------------------\n"
      " -matrix mmm = Read the matrix 'mmm', which should have been\n"
      "                 output from 3dDeconvolve via the '-x1D' option.\n"
      " -MAXrho rm  = Set the max allowed rho parameter to 'rm' (default=0.7).\n"
      " -Nrho nr    = Use 'nr' values for the rho parameter (default=7).\n"
      " -MAXb bm    = Set max allow MA b parameter to 'bm' (default=0.7).\n"
      " -Nb nb      = Use 'nb' values for the b parameter (default=7).\n"
     ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

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

      /** rho and del params **/

      if( strcmp(argv[iarg],"-MAXrho") == 0 ){
        rhomax = (MTYPE)strtod(argv[++iarg],NULL) ;
             if( rhomax < 0.3 ) rhomax = 0.3 ;
        else if( rhomax > 0.9 ) rhomax = 0.9 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-Nrho") == 0 ){
        rhonum = (int)strtod(argv[++iarg],NULL) ;
             if( rhonum <  2 ) rhonum =  2 ;
        else if( rhonum > 20 ) rhonum = 20 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-MAXb") == 0 ){
        bmax = (MTYPE)strtod(argv[++iarg],NULL) ;
             if( bmax < 0.3 ) bmax = 0.3 ;
        else if( bmax > 0.9 ) bmax = 0.9 ;
        iarg++ ; continue ;
      }
      if( strcmp(argv[iarg],"-Nb") == 0 ){
        bnum = (int)strtod(argv[++iarg],NULL) ;
             if( bnum <  2 ) bnum =  2 ;
        else if( bnum > 20 ) bnum = 20 ;
        iarg++ ; continue ;
      }

      /** -matrix **/

      if( strcmp(argv[iarg],"-matrix") == 0 ){
        if( nelmat != NULL ) ERROR_exit("More than 1 -matrix option!");
        nelmat = NI_read_element_fromfile( argv[++iarg] ) ; /* read NIML file */
        matname = argv[iarg];
        if( nelmat == NULL ){                     /* try to read as a 1D file */
          MRI_IMAGE *nim ; float *nar ;
          nim = mri_read_1D(argv[iarg]) ;
          if( nim != NULL ){              /* construct a minimal NIML element */
            nelmat = NI_new_data_element( "matrix" , nim->nx ) ;
            nar    = MRI_FLOAT_PTR(nim) ;
            for( jj=0 ; jj < nim->ny ; jj++ )
              NI_add_column( nelmat , NI_FLOAT , nar + nim->nx*jj ) ;
            mri_free(nim) ;
          }
        }
        if( nelmat == NULL || nelmat->type != NI_ELEMENT_TYPE )
          ERROR_exit("Can't process -matrix file!");
        iarg++ ; continue ;
      }

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

   if( iarg >= argc ) ERROR_exit("No 1D file on command line?!") ;

   inim = mri_read_1D( argv[iarg] ) ;
   if( inim == NULL ) ERROR_exit("Can't read 1D file %s",argv[iarg]) ;

   nreg  = nelmat->vec_num ;
   ntime = nelmat->vec_len ;
   if( ntime != inim->nx )
     ERROR_exit("matrix vectors are %d long but input 1D file is %d long",
                ntime,inim->nx) ;

   cgl = NI_get_attribute( nelmat , "GoodList" ) ;
   if( cgl != NULL ){
     int Ngoodlist,*goodlist , Nruns,*runs ;
     NI_int_array *giar ;
     giar = NI_decode_int_list( cgl , ";," ) ;
     if( giar == NULL || giar->num < ntime )
       ERROR_exit("-matrix 'GoodList' badly formatted?") ;
     Ngoodlist = giar->num ; goodlist = giar->ar ;
     rst = NI_get_attribute( nelmat , "RunStart" ) ;
     if( rst != NULL ){
       NI_int_array *riar = NI_decode_int_list( rst , ";,") ;
       if( riar == NULL ) ERROR_exit("-matrix 'RunStart' badly formatted?") ;
       Nruns = riar->num ; runs = riar->ar ;
     } else {
       Nruns = 1 ; runs = calloc(sizeof(int),1) ;
     }
     rnum = 0 ; tau = (int *)malloc(sizeof(int)*ntime) ;
     for( ii=0 ; ii < ntime ; ii++ ){
       jj = goodlist[ii] ;
       for( ; rnum+1 < Nruns && jj >= runs[rnum+1] ; rnum++ ) ; /*nada*/
       tau[ii] = jj + 10000*rnum ;
     }
   }

   matrix_initialize( &X ) ;
   matrix_create( ntime , nreg , &X ) ;
   if( nelmat->vec_typ[0] == NI_FLOAT ){
     float *cd ;
     for( jj=0 ; jj < nreg ; jj++ ){
       cd = (float *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) X.elts[ii][jj] = (MTYPE)cd[ii] ;
     }
   } else if( nelmat->vec_typ[0] == NI_DOUBLE ){
     double *cd ;
     for( jj=0 ; jj < nreg ; jj++ ){
       cd = (double *)nelmat->vec[jj] ;
       for( ii=0 ; ii < ntime ; ii++ ) X.elts[ii][jj] = (MTYPE)cd[ii] ;
     }
   } else {
     ERROR_exit("-matrix file stored will illegal data type!?") ;
   }

   cput = COX_cpu_time() ;
   rrcol = REML_setup( &X , tau , rhonum,rhomax,bnum,bmax ) ;
   if( rrcol == NULL ) ERROR_exit("REML setup fails?" ) ;
   cput = COX_cpu_time() - cput ;
   INFO_message("REML setup: rows=%d cols=%d %d cases CPU=%.2f",
                ntime,nreg,rrcol->nset,cput) ;

   cput = COX_cpu_time() ;
   vector_initialize( &y ) ; vector_create_noinit( ntime , &y ) ;
   for( jj=0 ; jj < inim->ny ; jj++ ){
     iv = MRI_FLOAT_PTR(inim) + ntime*jj ;
     for( ii=0 ; ii < ntime ; ii++ ) y.elts[ii] = (MTYPE)iv[ii] ;
     (void)REML_find_best_case( &y , rrcol ) ;
     INFO_message(
       "Vector #%d: best_rho=%.2f best_b=%.2f best_lam=%.2f best_ssq=%g  olsq_ssq=%g",
       jj, REML_best_rho, REML_best_bb, REML_best_lam, REML_best_ssq, REML_olsq_ssq ) ;
   }
   cput = COX_cpu_time() - cput ;
   INFO_message("REML fitting: CPU=%.2f",cput) ;
   exit(0) ;
}
Exemplo n.º 11
0
int main( int argc , char *argv[] )
{
   int iarg , ii,jj,kk,mm , nvec , do_one=0 , nx=0,ny , ff, doterse = 0 ;
   MRI_IMAGE *tim ;
   MRI_IMARR *tar ;
   double sum , *eval , *amat , **tvec , *bmat , *svec ;
   float *far ;
   int demean=0 , docov=0 ;
   char *matname ;
   int okzero = 0;

   mainENTRY("1ddot main"); machdep();
   /* options */

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

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

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

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

     if( strncmp(argv[iarg],"-dem",4) == 0 ){
       demean = 1 ; do_one = 0 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-cov",4) == 0 ){
       docov = 1 ; iarg++ ; continue ;
     }

     if( strncmp(argv[iarg],"-inn",4) == 0 ){
       docov = 2 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-rank")     == 0 ||
         strcasecmp(argv[iarg],"-spearman") == 0   ){
       do_one = 0; docov = 3; demean = 0; doterse = 1; iarg++; continue;
     }

     if( strncmp(argv[iarg],"-terse",4) == 0 ){
       doterse = 1 ; iarg++ ; continue ;
     }

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

   if( argc < 2 ){ usage_1ddot(1); exit(0) ; }

   if( iarg == argc ) ERROR_exit("No 1D files on command line!?") ;

   /* input 1D files */

   ff = iarg ;
   INIT_IMARR(tar) ; if( do_one ) nvec = 1 ;
   for( ; iarg < argc ; iarg++ ){
     tim = mri_read_1D( argv[iarg] ) ;
     if( tim == NULL ){
       fprintf(stderr,"** Can't read 1D file %s\n",argv[iarg]); exit(1);
     }
     if( nx == 0 ){
       nx = tim->nx ;
     } else if( tim->nx != nx ){
       fprintf(stderr,"** 1D file %s doesn't match first file in length!\n",
               argv[iarg]); exit(1);
     }
     nvec += tim->ny ;
     ADDTO_IMARR(tar,tim) ;
   }

   if (!doterse) {
      printf("\n") ;
      printf("++ 1ddot input vectors:\n") ;
   }
   jj = 0 ;
   if( do_one ){
     if (!doterse) printf("00..00: all ones\n") ;
     jj = 1 ;
   }
   for( mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     if (!doterse) printf("%02d..%02d: %s\n", jj,jj+tim->ny-1, argv[ff+mm] ) ;
     jj += tim->ny ;
   }

   /* create vectors from 1D files */

   tvec = (double **) malloc( sizeof(double *)*nvec ) ;
   svec = (double * ) malloc( sizeof(double  )*nvec ) ;
   for( jj=0 ; jj < nvec ; jj++ )
     tvec[jj] = (double *) malloc( sizeof(double)*nx ) ;

   kk = 0 ;
   if( do_one ){
     svec[0] = 1.0 / sqrt((double)nx) ;
     for( ii=0 ; ii < nx ; ii++ ) tvec[0][ii] = 1.0 ;
     kk = 1 ;
   }

   for( mm=0 ; mm < IMARR_COUNT(tar) ; mm++ ){
     tim = IMARR_SUBIM(tar,mm) ;
     far = MRI_FLOAT_PTR(tim) ;
     for( jj=0 ; jj < tim->ny ; jj++,kk++ ){
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] = far[ii+jj*nx] ;
       if( demean ){
         sum = 0.0 ;
         for( ii=0 ; ii < nx ; ii++ ) sum += tvec[kk][ii] ;
         sum /= nx ;
         for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] -= sum ;
       }
       sum = 0.0 ;
       for( ii=0 ; ii < nx ; ii++ ) sum += tvec[kk][ii] * tvec[kk][ii] ;
       if( sum == 0.0 ) {
         if (okzero) svec[kk] = 0.0;
         else ERROR_exit("Input column %02d is all zero!",kk) ;
       } else {
         svec[kk] = 1.0 / sqrt(sum) ;
       }
     }
   }
   DESTROY_IMARR(tar) ;

   /* normalize vectors? (for ordinary correlation) */

   if( !docov ){
     for( kk=0 ; kk < nvec ; kk++ ){
       sum = svec[kk] ;
       for( ii=0 ; ii < nx ; ii++ ) tvec[kk][ii] *= sum ;
     }
   }

   switch(docov){
     default:
     case 3:  matname = "Spearman"     ; break ;
     case 2:  matname = "InnerProduct" ; break ;
     case 1:  matname = "Covariance"   ; break ;
     case 0:  matname = "Correlation"  ; break ;
   }

   /* create matrix from dot product of vectors */

   amat = (double *) calloc( sizeof(double) , nvec*nvec ) ;

   if( docov != 3 ){
     for( kk=0 ; kk < nvec ; kk++ ){
       for( jj=0 ; jj <= kk ; jj++ ){
         sum = 0.0 ;
         for( ii=0 ; ii < nx ; ii++ ) sum += tvec[jj][ii] * tvec[kk][ii] ;
         amat[jj+nvec*kk] = sum ;
         if( jj < kk ) amat[kk+nvec*jj] = sum ;
       }
     }
   } else {  /* Spearman */
     for( kk=0 ; kk < nvec ; kk++ ){
       for( jj=0 ; jj <= kk ; jj++ ){
         amat[jj+nvec*kk] = THD_spearman_corr_dble( nx , tvec[jj] , tvec[kk] ) ;
         if( jj < kk ) amat[kk+nvec*jj] = amat[jj+nvec*kk] ;
       }
     }
   }

   /* normalize */
   if (docov==1) {
      for( kk=0 ; kk < nvec ; kk++ ){
         for( jj=0 ; jj <= kk ; jj++ ){
            sum = amat[jj+nvec*kk] / (double) (nx-1);
            amat[jj+nvec*kk] = sum;
            if( jj < kk ) amat[kk+nvec*jj] = sum ;
         }
      }
   }

   /* print matrix out */

   if (!doterse) {
      printf("\n"
             "++ %s Matrix:\n   ",matname) ;
      for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
      printf("\n   ") ;
      for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
      printf("\n") ;
   }
   for( kk=0 ; kk < nvec ; kk++ ){
     if (!doterse) printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   if (doterse) exit(0) ; /* au revoir */

   /* compute eigendecomposition */

   eval = (double *) malloc( sizeof(double)*nvec ) ;
   symeig_double( nvec , amat , eval ) ;

   printf("\n"
          "++ Eigensolution of %s Matrix:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",eval[jj]) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[kk+jj*nvec]) ;
     printf("\n") ;
   }

   /* compute matrix inverse */
   if ( eval[0]/eval[nvec-1] < 1.0e-10) {
      printf("\n"
             "-- WARNING: Matrix is near singular,\n"
             "            rubbish likely for inverses ahead.\n");
   }
   for( jj=0 ; jj < nvec ; jj++ ) eval[jj] = 1.0 / eval[jj] ;

   bmat = (double *) calloc( sizeof(double) , nvec*nvec ) ;

   for( ii=0 ; ii < nvec ; ii++ ){
     for( jj=0 ; jj < nvec ; jj++ ){
       sum = 0.0 ;
       for( kk=0 ; kk < nvec ; kk++ )
         sum += amat[ii+kk*nvec] * amat[jj+kk*nvec] * eval[kk] ;
       bmat[ii+jj*nvec] = sum ;
     }
   }

   printf("\n") ;
   printf("++ %s Matrix Inverse:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",bmat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   /* square roots of diagonals of the above */

   printf("\n") ;
   printf("++ %s sqrt(diagonal)\n   ",matname) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",sqrt(bmat[jj+jj*nvec])) ;
   printf("\n") ;

   /* normalize matrix inverse */

   for( ii=0 ; ii < nvec ; ii++ ){
     for( jj=0 ; jj < nvec ; jj++ ){
       sum = bmat[ii+ii*nvec] * bmat[jj+jj*nvec] ;
       if( sum > 0.0 )
         amat[ii+jj*nvec] = bmat[ii+jj*nvec] / sqrt(sum) ;
       else
         amat[ii+jj*nvec] = 0.0 ;
     }
   }

   printf("\n") ;
   printf("++ %s Matrix Inverse Normalized:\n   " , matname ) ;
   for( jj=0 ; jj < nvec ; jj++ ) printf("    %02d    ",jj) ;
   printf("\n   ") ;
   for( jj=0 ; jj < nvec ; jj++ ) printf(" ---------") ;
   printf("\n") ;
   for( kk=0 ; kk < nvec ; kk++ ){
     printf("%02d:",kk) ;
     for( jj=0 ; jj < nvec ; jj++ ) printf(" %9.5f",amat[jj+kk*nvec]) ;
     printf("\n") ;
   }

   /* done */

   exit(0) ;
}
Exemplo n.º 12
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfPatch"};
   SUMA_GETPATCH_OPTIONS *Opt; 
   char *ppref=NULL, ext[5]; 
   float *far=NULL;
   MRI_IMAGE *im = NULL;
   int SO_read = -1;
   int   *NodePatch=NULL, N_NodePatch=-1, *FaceSetList=NULL , 
         N_FaceSet = -1, N_Node = -1, N_Spec=0;          
   int i, inodeoff=-1, ilabeloff=-1, nvec, ncol, cnt;
   SUMA_SurfaceObject *SO = NULL;
   SUMA_PATCH *ptch = NULL; 
   SUMA_SurfSpecFile *Spec;
   SUMA_INDEXING_ORDER d_order;
   void *SO_name = NULL;
   SUMA_Boolean exists = NOPE;
   SUMA_SO_File_Type typetmp;
   SUMA_SurfaceObject *SOnew = NULL;
   float *NodeList = NULL;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_Boolean LocalHead = NOPE;
	
   SUMA_STANDALONE_INIT;
   SUMA_mainENTRY;
   
   
   ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;");
   
	/* Allocate space for DO structure */
	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   
   Opt = SUMA_GetPatch_ParseInput (argv, argc, ps);
   if (argc < 2)
    {
       SUMA_S_Err("Too few options");
       usage_SUMA_getPatch(ps, 0);
       exit (1);
    }


   /* read all surfaces */
   Spec = SUMA_IO_args_2_spec(ps, &N_Spec);
   if (N_Spec == 0) {
      SUMA_S_Err("No surfaces found.");
      exit(1);
   }

   if (N_Spec > 1 ) {
      SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options "
                  "for specifying surfaces.");
      exit(1);
   }
   
   if (Spec->N_Surfs < 1) {
      SUMA_S_Err("No surfaces");
      exit(1);
   }
     
   if (Opt->DoVol && Spec->N_Surfs != 2) {
      SUMA_S_Errv("Must specify 2 and only 2 surfaces with -vol options\n"
                  "Have %d from the command line\n",Spec->N_Surfs);
      exit(1);
   }
   
   if (Opt->oType != SUMA_FT_NOT_SPECIFIED && !Opt->VolOnly) { 
      for (i=0; i < Spec->N_Surfs; ++i) {
         if (Spec->N_Surfs > 1) {
            sprintf(ext, "_%c", 65+i);
            ppref = SUMA_append_string(Opt->out_prefix, ext);
         } else {
            ppref = SUMA_copy_string(Opt->out_prefix);
         }
         
         SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, 
                                           Opt->oType, &exists);
         if (exists && !THD_ok_overwrite()) {
            fprintf(SUMA_STDERR, "Error %s:\nOutput file(s) %s* on disk.\n"
                                 "Will not overwrite.\n", FuncName, ppref);
            exit(1);
         }
         if (ppref) SUMA_free(ppref); ppref = NULL; 
         if (SO_name) SUMA_free(SO_name); SO_name = NULL;
      } 
   }
   
   /* read in the file containing the node information */
   im = mri_read_1D (Opt->in_name);

   if (!im) {
      SUMA_S_Errv("Failed to read 1D file '%s'\n", Opt->in_name);
      exit(1);
   }

   far = MRI_FLOAT_PTR(im);
   nvec = im->nx;
   ncol = im->ny;
   if (Opt->nodecol >= ncol || Opt->labelcol >= ncol) {
      fprintf(SUMA_STDERR, "\n"
                           "Error %s: Input file has a total of %d columns.\n"
                           "One or both user-specified node (%d) and \n"
                           "label (%d) columns are too high. Maximum usable\n"
                           "column index is %d.\n"
                           , FuncName, ncol, Opt->nodecol, 
                           Opt->labelcol, ncol -1 );
      exit(1);
   }
   
   d_order = SUMA_COLUMN_MAJOR;

   if (!nvec) {
      SUMA_SL_Err("Empty file");
      exit(1);
   }
   /* form the node vector */
   NodePatch = (int *)SUMA_malloc(sizeof(int)*nvec);
   if (!NodePatch) {
      SUMA_SL_Crit("Failed to allocate.");
      exit(1);
   }
   inodeoff = Opt->nodecol*nvec;
   if (Opt->labelcol < 0) { /* all listed nodes */ 
      for (i=0; i<nvec; ++i) {
         NodePatch[i] = far[i+inodeoff];
      }
      N_NodePatch = nvec;
   } else {
      ilabeloff =  Opt->labelcol*nvec;
      if (Opt->thislabel < 0) { /* all nodes with non zero labels */
         cnt = 0;
         for (i=0; i<nvec; ++i) {
            if (far[i+ilabeloff]) {
               NodePatch[cnt] = far[i+inodeoff];
               ++cnt;
            }
         }
         N_NodePatch = cnt;     
      } else { /* select labels */
         cnt = 0;
         for (i=0; i<nvec; ++i) {
            if (far[i+ilabeloff] == Opt->thislabel) {
               NodePatch[cnt] = far[i+inodeoff];
               ++cnt;
            }
         }
         N_NodePatch = cnt;    
      }
      NodePatch = (int *) SUMA_realloc(NodePatch , sizeof(int)*N_NodePatch);
   }
   
   /* done with im, free it */
   mri_free(im); im = NULL;   
   
   if (Opt->DoVol) {
      SUMA_SurfaceObject *SO1 = 
         SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 0);
      SUMA_SurfaceObject *SO2 = 
         SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 0);
      double Vol = 0.0;
      SUMA_SurfaceObject *SOp = SUMA_Alloc_SurfObject_Struct(1);
      byte *adj_N=NULL;
      
      if (Opt->adjust_contour) 
         adj_N = SUMA_calloc(SO1->N_Node, sizeof(byte));
      
      if (!SO1 || !SO2) {
         SUMA_SL_Err("Failed to load surfaces.");
         exit(1);
      }
      /* a chunk used to test SUMA_Pattie_Volume */
      Vol = SUMA_Pattie_Volume(SO1, SO2, NodePatch, N_NodePatch, 
                               SOp, Opt->minhits, 
                               Opt->FixBowTie, Opt->adjust_contour, 
                               adj_N, Opt->verb);
      fprintf (SUMA_STDOUT,"Volume = %f\n", fabs(Vol));
      if (Opt->out_volprefix) {
         if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SOp->FileType = Opt->oType;
         if (Opt->flip) {
            if (Opt->verb > 1) 
               SUMA_S_Note("Flipping stitched surf's triangles\n");
            SUMA_FlipSOTriangles (SOp);
         }

         if (!(SUMA_Save_Surface_Object_Wrap ( Opt->out_volprefix, NULL,
                                               SOp, SUMA_PLY, SUMA_ASCII, 
                                               NULL))) {
            fprintf (SUMA_STDERR,
                     "Error %s: Failed to write surface object.\n", FuncName);
         }
         if (Opt->adjust_contour && adj_N) {
            Opt->out_volprefix = 
                     SUMA_append_replace_string(Opt->out_volprefix, 
                                                   ".adjneighb","",1);
            ppref = SUMA_Extension(Opt->out_volprefix, ".1D.dset", NOPE);
            SUMA_WRITE_IND_ARRAY_1D(adj_N, NULL, SO1->N_Node, 1, ppref);
            SUMA_free(ppref); ppref=NULL;
         }
      }
      if (SOp) SUMA_Free_Surface_Object(SOp); SOp = NULL;
   }
   
   
   if (!Opt->VolOnly) {
      FaceSetList = NULL;
      N_FaceSet = -1;
      for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */
         /* now identify surface needed */
         if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) {
            SUMA_S_Err("Failed to load surface .\n");
            exit(1);
         }
         if (SO->aSO) {
            /* otherwise, when you reset the number of FaceSets for example,
               and you still write in GIFTI, the old contents of aSO will
               prevail */
            SO->aSO = SUMA_FreeAfniSurfaceObject(SO->aSO); 
         }
         /* extract the patch */
         ptch = SUMA_getPatch (NodePatch, N_NodePatch, SO->N_Node,
                               SO->FaceSetList,  SO->N_FaceSet, 
                               SO->MF, Opt->minhits, 
                               Opt->FixBowTie, (!i && !Opt->DoVol)); 
                                    /* verbose only for first patch, and 
                                    if no volume computation was required  
                                    This is to keep the warnings to a minimum*/
         if (!ptch) {
            SUMA_SL_Err("Failed to form patch.");
            exit(1);
         }
         if (LocalHead) SUMA_ShowPatch(ptch, NULL);
      
         /* Now create a surface with that patch */
         if (Spec->N_Surfs > 1) {
            sprintf(ext, "_%c", 65+i);
            ppref = SUMA_append_string(Opt->out_prefix, ext);
         } else {
            ppref = SUMA_copy_string(Opt->out_prefix);
         }
         /* save the original type */
         typetmp = SO->FileType;
         if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SO->FileType = Opt->oType;
         SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, 
                                           SO->FileType, &exists);
         if (ppref) SUMA_free(ppref); ppref = NULL;
         /* save the original pointers to the facesets and their number */
         FaceSetList = SO->FaceSetList;
         N_FaceSet = SO->N_FaceSet;
         NodeList = SO->NodeList;
         N_Node = SO->N_Node;
         
         /* replace with Patch */
         SO->FaceSetList = ptch->FaceSetList;
         SO->N_FaceSet = ptch->N_FaceSet; 
         
         if (Opt->Do_p2s) {
            if (LocalHead) 
               fprintf (SUMA_STDERR,
                        "%s: Changing patch to surface...\n", FuncName);
            SOnew = SUMA_Patch2Surf(SO->NodeList, SO->N_Node, 
                                    SO->FaceSetList, SO->N_FaceSet, 3);
            if (!SOnew) {
               SUMA_S_Err("Failed to change patch to surface.");
               exit(1);
            }
            SO->FaceSetList = SOnew->FaceSetList;
            SO->N_FaceSet = SOnew->N_FaceSet;
            SO->N_Node = SOnew->N_Node;
            SO->NodeList = SOnew->NodeList;
         }
          
         if (SO->N_FaceSet <= 0) {
            SUMA_S_Warn("The patch is empty.\n"
                        " Non existing surface not written to disk.\n");
         } else {
            /* Is the gain wanted? */
            if (Opt->coordgain) {
               SUMA_SL_Note("Applying coord gain to surface nodes!");
               for (cnt=0; cnt < SO->NodeDim*SO->N_Node; ++cnt) 
                  SO->NodeList[cnt] *= Opt->coordgain;
            }
            if (Opt->flip) {
               if (Opt->verb > 1) SUMA_S_Note("Flipping triangles\n");
               SUMA_FlipTriangles (SO->FaceSetList, SO->N_FaceSet);
               SUMA_RECOMPUTE_NORMALS(SO);
            }

            if (!SUMA_Save_Surface_Object (SO_name, SO, SO->FileType, 
                                           SUMA_ASCII, NULL)) {
                  fprintf (SUMA_STDERR,
                           "Error %s: Failed to write surface object.\n", 
                           FuncName);
                  exit (1);
            }
         }
         
         /* bring SO back to shape */
         SO->FileType = typetmp;
         SO->FaceSetList = FaceSetList; FaceSetList = NULL;
         SO->N_FaceSet = N_FaceSet; N_FaceSet = -1;
         SO->NodeList = NodeList; NodeList = NULL;
         SO->N_Node = N_Node; N_Node = -1;
         
         if (SO_name) SUMA_free(SO_name); SO_name = NULL;
         if (ptch) SUMA_freePatch(ptch); ptch = NULL;
         if (SOnew) SUMA_Free_Surface_Object(SOnew); SOnew = NULL; 
               /* get rid of old surface object */
            

      }
   } 
   
   SUMA_LH("clean up");
   if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); }
   SUMA_free(Spec); Spec = NULL;
   if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL;
   if (Opt->out_volprefix) SUMA_free(Opt->out_volprefix); 
                                                Opt->out_volprefix = NULL;
   if (Opt) SUMA_free(Opt);   
   if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
      SUMA_SL_Err("DO Cleanup Failed!");
   }
   
   if (!SUMA_Free_CommonFields(SUMAg_CF)) {
      SUMA_SL_Err("SUMAg_CF Cleanup Failed!");
   }
   
   SUMA_RETURN(0);
} 
Exemplo n.º 13
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *xset=NULL , *cset ;
   int nopt=1, datum=MRI_float, nvals, ii;
   MRI_IMAGE *ysim=NULL ;
   char *prefix = "Tcorr1D", *smethod="pearson";
   char *xnam=NULL , *ynam=NULL ;
   byte *mask=NULL ; int mask_nx,mask_ny,mask_nz , nmask=0 ;
   int do_atanh = 0 ; /* 12 Jan 2018 */

   /*----*/

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

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
      printf("Usage: 3dTcorr1D [options] xset y1D\n"
             "Computes the correlation coefficient between each voxel time series\n"
             "in the input 3D+time dataset 'xset' and each column in the 1D time\n"
             "series file 'y1D', and stores the output values in a new dataset.\n"
             "\n"
             "OPTIONS:\n"
             "  -pearson  = Correlation is the normal Pearson (product moment)\n"
             "                correlation coefficient [this is the default method].\n"
             "  -spearman = Correlation is the Spearman (rank) correlation\n"
             "                coefficient.\n"
             "  -quadrant = Correlation is the quadrant correlation coefficient.\n"
             "  -ktaub    = Correlation is Kendall's tau_b coefficient.\n"
             "              ++ For 'continuous' or finely-discretized data, tau_b and\n"
             "                 rank correlation are nearly equivalent (but not equal).\n"
             "  -dot      = Doesn't actually compute a correlation coefficient; just\n"
             "                calculates the dot product between the y1D vector(s)\n"
             "                and the dataset time series.\n"
             "\n"
             "  -Fisher   = Apply the 'Fisher' (inverse hyperbolic tangent) transformation\n"
             "                to the results.\n"
             "              ++ It does not make sense to use this with '-ktaub', but if\n"
             "                 you want to do it, the program will not stop you.\n"
             "              ++ Cannot be used with '-dot'!\n"
             "\n"
             "  -prefix p = Save output into dataset with prefix 'p'\n"
             "               [default prefix is 'Tcorr1D'].\n"
             "\n"
             "  -mask mmm = Only process voxels from 'xset' that are nonzero\n"
             "                in the 3D mask dataset 'mmm'.\n"
             "              ++ Other voxels in the output will be set to zero.\n"
             "\n"
             "  -float    = Save results in float format [the default format].\n"
             "  -short    = Save results in scaled short format [to save disk space].\n"
             "              ++ Cannot be used with '-dot'!\n"
             "\n"
             "NOTES:\n"
             "* The output dataset is functional bucket type, with one sub-brick\n"
             "   per column of the input y1D file.\n"
             "* No detrending, blurring, or other pre-processing options are available;\n"
             "   if you want these things, see 3dDetrend or 3dTproject or 3dcalc.\n"
             "   [In other words, this program presumes you know what you are doing!]\n"
             "* Also see 3dTcorrelate to do voxel-by-voxel correlation of TWO\n"
             "   3D+time datasets' time series, with similar options.\n"
             "* You can extract the time series from a single voxel with given\n"
             "   spatial indexes using 3dmaskave, and then run it with 3dTcorr1D:\n"
             "    3dmaskave -quiet -ibox 40 30 20 epi_r1+orig > r1_40_30_20.1D\n"
             "    3dTcorr1D -pearson -Fisher -prefix c_40_30_20 epi_r1+orig r1_40_30_20.1D\n"
             "* http://en.wikipedia.org/wiki/Correlation\n"
             "* http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient\n"
             "* http://en.wikipedia.org/wiki/Spearman%%27s_rank_correlation_coefficient\n"
             "* http://en.wikipedia.org/wiki/Kendall_tau_rank_correlation_coefficient\n"
             "\n"
             "-- RWCox - Apr 2010\n"
             "         - Jun 2010: Multiple y1D columns; OpenMP; -short; -mask.\n"
            ) ;
      PRINT_AFNI_OMP_USAGE("3dTcorr1D",NULL) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

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

   /*-- option processing --*/

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

     if( strcmp(argv[nopt],"-mask") == 0 ){  /* 28 Jun 2010 */
       THD_3dim_dataset *mset ;
       if( ++nopt >= argc ) ERROR_exit("Need argument after '-mask'") ;
       if( mask != NULL )   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 ) ;
       INFO_message("Number of voxels in mask = %d",nmask) ;
       if( nmask < 2 ) ERROR_exit("Mask is too small to process") ;
       nopt++ ; continue ;
     }

      if( strcasecmp(argv[nopt],"-float") == 0 ){  /* 27 Jun 2010 */
        datum = MRI_float ; nopt++ ; continue ;
      }
      if( strcasecmp(argv[nopt],"-short") == 0 ){
        datum = MRI_short ; nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-pearson") == 0 ){
        smethod = "pearson" ; nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-dot") == 0 ){
        smethod = "dot" ; nopt++ ; continue ;
      }


      if( strcasecmp(argv[nopt],"-spearman") == 0 || strcasecmp(argv[nopt],"-rank") == 0 ){
        smethod = "spearman" ; nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-quadrant") == 0 ){
        smethod = "quadrant" ; nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-ktaub") == 0 || strcasecmp(argv[nopt],"-taub") == 0 ){
        smethod = "ktaub" ; nopt++ ; continue ;
      }

      if( strcasecmp(argv[nopt],"-fisher") == 0 ){ /* 12 Jan 2018 */
        do_atanh = 1 ; nopt++ ; continue ;
      }

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

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

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

   if( nopt+1 >= argc )
     ERROR_exit("Need 2 non-option arguments on command line!?") ;

   /* despite what the help says, if the 1D file is first, that's OK */

   if( STRING_HAS_SUFFIX(argv[nopt],"1D") ){
     ININFO_message("reading 1D file %s",argv[nopt]) ;
     ysim = mri_read_1D( argv[nopt] ) ; ynam = argv[nopt] ;
     if( ysim == NULL ) ERROR_exit("Can't read 1D file %s",argv[nopt]) ;
   } else {
     ININFO_message("reading dataset file %s",argv[nopt]) ;
     xset = THD_open_dataset( argv[nopt] ) ; xnam = argv[nopt] ;
     if( xset == NULL ) ERROR_exit("Can't open dataset %s",argv[nopt]) ;
   }

   /* read whatever type of file (3D or 1D) we don't already have */

   nopt++ ;
   if( xset != NULL ){
     ININFO_message("reading 1D file %s",argv[nopt]) ;
     ysim = mri_read_1D( argv[nopt] ) ; ynam = argv[nopt] ;
     if( ysim == NULL ) ERROR_exit("Can't read 1D file %s",argv[nopt]) ;
   } else {
     ININFO_message("reading dataset file %s",argv[nopt]) ;
     xset = THD_open_dataset( argv[nopt] ) ; xnam = argv[nopt] ;
     if( xset == NULL ) ERROR_exit("Can't open dataset %s",argv[nopt]) ;
   }

   nvals = DSET_NVALS(xset) ;  /* number of time points */
   ii    = (strcmp(smethod,"dot")==0) ? 2 : 3 ;
   if( nvals < ii )
     ERROR_exit("Input dataset %s length is less than ii?!",xnam,ii) ;

   if( ysim->nx < nvals )
     ERROR_exit("1D file %s has %d time points, but dataset has %d values",
                ynam,ysim->nx,nvals) ;
   else if( ysim->nx > nvals )
     WARNING_message("1D file %s has %d time points, dataset has %d",
                     ynam,ysim->nx,nvals) ;

   if( mri_allzero(ysim) )
     ERROR_exit("1D file %s is all zero!",ynam) ;

   if( ysim->ny > 1 )
     INFO_message("1D file %s has %d columns: correlating with ALL of them!",
                   ynam,ysim->ny) ;

   if( strcmp(smethod,"dot") == 0 && do_atanh ){
     WARNING_message("'-dot' turns off '-Fisher'") ; do_atanh = 0 ;
   }
   if( strcmp(smethod,"dot") == 0 && datum == MRI_short ){
     WARNING_message("'-dot' turns off '-short'") ; datum = MRI_float ;
   }

   cset = THD_Tcorr1D( xset, mask, nmask, ysim, smethod,
                       prefix, (datum==MRI_short) , do_atanh );
   tross_Make_History( "3dTcorr1D" , argc,argv , cset ) ;

   DSET_unload(xset) ;  /* no longer needful */

   /* finito */

   DSET_write(cset) ;
   INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(cset)) ;
   exit(0) ;
}
Exemplo n.º 14
0
int main( int argc , char * argv[] )
{
   int iarg , ii , ny , ignore=0 , use=0 , install=0 ;
   char * tsfile , * cpt ;
   char dname[THD_MAX_NAME] , subv[THD_MAX_NAME] ;
   MRI_IMAGE * flim ;
   float * far ;
   XtAppContext app ;
   Widget shell ;
   int cxx=0 , cyy=1 , cxsig=2 , cysig=3 , crho=4 ;

   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf("Usage: 1dsigplot [options] infile\n"
            "Scatterplots a 5 column *.1D file to the screen.\n"
            "The columns of the input file must be\n"
            "   x  y  sigma_x sigma_y rho_xy\n"
            "\n"
            "Options:\n"
            " -install   = Install a new X11 colormap.\n"
            " -ignore nn = Skip first 'nn' rows in the input file\n"
            "                [default = 0]\n"
            " -use mm    = Plot 'mm' points [default = all of them]\n"
            " -xlabel aa = Put string 'aa' below the x-axis\n"
            "                [default = no axis label]\n"
            " -ylabel aa = Put string 'aa' to the left of the y-axis\n"
            "                [default = no axis label]\n"
            " -pell p    = Set CDF probability contour level for ellipses.\n"
            " -col abcde = 'abcde' is a permutation of '01234', and\n"
            "                specifies the column order for the data,\n"
            "                where a=column index for x\n"
            "                      b=column index for y\n"
            "                      c=column index for sigma_x\n"
            "                      d=column index for sigma_y\n"
            "                      e=column index for rho_xy\n"
            "                [default = 01234]\n"
            "\n"
            " -xrange x1 x2 = Range of x-axis\n"
            " -yrange y1 y2 = Range of y-axis\n"
           ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   machdep() ;

   /* open X11 */

   shell = XtVaAppInitialize(
              &app , "AFNI" , NULL , 0 , &argc , argv , NULL , NULL ) ;
   if( shell == NULL ){
      fprintf(stderr,"** Cannot initialize X11!\n") ; exit(1) ;
   }

   cpt = my_getenv("TMPDIR") ;  /* just for fun */

   /*-- scan arguments that X11 didn't eat --*/

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

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

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

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

     if( strcmp(argv[iarg],"-col") == 0 ){
        int ierr=0 ;
        iarg++ ;
        cxx   = argv[iarg][0] - '0' ; if( cxx   < 0 || cxx   > 4 ) ierr++ ;
        cyy   = argv[iarg][1] - '0' ; if( cyy   < 0 || cyy   > 4 ) ierr++ ;
        cxsig = argv[iarg][2] - '0' ; if( cxsig < 0 || cxsig > 4 ) ierr++ ;
        cysig = argv[iarg][3] - '0' ; if( cysig < 0 || cysig > 4 ) ierr++ ;
        crho  = argv[iarg][4] - '0' ; if( crho  < 0 || crho  > 4 ) ierr++ ;
        if( ierr || cxx+cyy+cxsig+cysig+crho != 10 ){
           fprintf(stderr,"*** Illegal argument after -ord!\n");exit(1);
        }
        iarg++ ; continue ;
     }

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

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

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

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

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

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

     if( strcmp(argv[iarg],"-use") == 0 ){
        use = strtod( argv[++iarg] , NULL ) ;
        if( use < 2 ){fprintf(stderr,"** Illegal -use value!\n");exit(1);}
        iarg++ ; continue ;
     }

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

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

   dc = MCW_new_DC( shell , 16 ,
                    DEFAULT_NCOLOVR , INIT_colovr , INIT_labovr ,
                    1.0 , install ) ;

   flim = mri_read_1D( argv[iarg] ) ;
   if( flim == NULL ){
      fprintf(stderr,"** Can't read input file %s\n",argv[iarg]) ;
      exit(1);
   }

   if( flim->ny != 5 ){
      fprintf(stderr,"** Input file doesn't have exactly 5 columns!\n") ;
      exit(1) ;
   }
   far  = MRI_FLOAT_PTR(flim) ;
   nx   = flim->nx ;

   xx    = far + cxx  *nx ;
   yy    = far + cyy  *nx ;
   xsig  = far + cxsig*nx ;
   ysig  = far + cysig*nx ;
   xycor = far + crho *nx ;

   nx = nx - ignore ;  /* cut off the ignored points */

   if( use > 1 && nx > use ) nx = use ;

   /* start X11 */

   (void) XtAppAddTimeOut( app , 123 , startup_timeout_CB , NULL ) ;

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

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

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

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

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

       /*-- ignore --*/

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

       /*-- prefix --*/

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

       /*-- card --*/

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

       /*-- cardphase --*/

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

       /*-- threshold --*/

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

       /*-- resp --*/

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

       /*-- respphase --*/

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

       /*-- window --*/

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

       /*-- order --*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   float matar[12] ;

   int use_3dWarp=1 , matrix_type=ROTATION ;

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

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

      /*-----*/

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

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

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

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

      /*-----*/

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

         mset = THD_open_dataset( argv[iarg] ) ;

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

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

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

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

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

         iarg++ ; continue ;
      }

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

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

      /*-----*/

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

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

         wtim = mri_read_1D( argv[iarg] ) ;

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

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

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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

      /*-----*/

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


      /*-----*/

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

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

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


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

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

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

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

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

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

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

   dset = THD_open_dataset( argv[iarg] ) ;

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

   /* check if set tags match exactly */

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

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

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

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

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

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

         jj++ ;
      }
   }

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

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

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

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

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

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

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

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

   dsum = DMAT_DET(rt.mm) ;

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

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

     exit(1) ;
   }

   /*-- print summary --*/

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

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

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

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

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

   if( mfile ){
      FILE * mp ;

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

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

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

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

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

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

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

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

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

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

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

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

     if( keeptags ){
        THD_dfvec3 rv ;

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

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

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

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

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

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

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

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

     THD_rota_method( MRI_HEPTIC ) ;
     clipit = 1 ;

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

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

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

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

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

        /*- rotate it -*/

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

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

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

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

        /*- put it back into dataset -*/

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

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

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

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

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

     /* write dataset to disk */

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

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

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

     THD_3dim_dataset *oset ;
     THD_vecmat tran ;

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

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

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

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

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

     if( keeptags ){
        THD_dfvec3 rv ;

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

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

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

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

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

     DSET_write(oset) ;

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

   exit(0) ;
}
Exemplo n.º 17
0
/* if maxval >= 0, values may not exceed it */
int * get_1dcat_intlist ( char *sin , int *nret, int maxval)
{
   int ipos , slen, *ret=NULL, ii=0;
   MRI_IMAGE *aim = NULL;
   float *far=NULL;
   char *str = NULL;
   int op = 0;
   
   *nret = -1;
   if (!sin || !strstr(sin,"1dcat ") || strlen (sin) < 8) {
      fprintf(stderr, "NULL input or string does not have '1dcat '"
                      " or a 1D filename not present after '1dcat '\n");
      return (NULL);
   }
   
   str = strdup(sin);
   
   /* move past count */
   slen = strlen(str) ;
   ipos = strlen("1dcat ");
   /* find ending square */
   for (ii=ipos; ii<slen; ++ii) {
      if (str[ii]=='[') ++op;
      if (str[ii]==']') { --op; }
      if (op < 0) { str[ii] = '\0'; break; }
   }
   /* read the filename */
   deblank_name(str+ipos);
   if (!(aim = mri_read_1D(str+ipos))) {
      ERROR_message("Can't read 1D file '%s'", str+ipos) ;
      free(str); str=NULL;
      return(NULL);
   } 

   /* return the indices */
   far = MRI_FLOAT_PTR(aim);
   *nret = aim->nx*aim->ny;
   ret = (int *)malloc(sizeof(int)*(*nret+1));
   
   ret[0] = *nret;
   for (ii=0; ii<*nret; ++ii) {
      ret[ii+1] = (int)far[ii];
      /* was #if 0: leave error handling for elsewhere, 4 Jan 2016 [rickr] */
      if ( (!allow_negative && ret[ii+1]<0) ||
           (maxval >= 0 && ret[ii+1] > maxval) ) {
         ERROR_message( "Bad 1dcat brick selection value in 1D file '%s'\n"
                        "   value %d is %g (max=%d)\n",
                        str+ipos, ii, far[ii], maxval);
         mri_free(aim); aim = NULL; far=NULL;
         free(str); str=NULL;
         free(ret); ret=NULL;
         return(NULL); 
      }
   }
   
   mri_free(aim); aim = NULL; far=NULL;
   
   #if 0
      fprintf(stderr,"ZSS: Selecting %d values from '%s':\n", *nret, str+ipos);
      for (ii=1; ii<=*nret; ++ii) { 
         fprintf(stderr,"%d,",ret[ii]);
      }
      fprintf(stderr,"\n");
   #endif
   
   free(str); str=NULL;
   return(ret);
}
Exemplo n.º 18
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *yset=NULL , *aset=NULL , *mset=NULL , *wset=NULL ;
   MRI_IMAGE *fim=NULL, *qim,*tim, *pfim=NULL , *vim     , *wim=NULL  ;
   float     *flar    , *qar,*tar, *par=NULL  , *var     , *war=NULL  ;
   MRI_IMARR *fimar=NULL ;
   MRI_IMAGE *aim , *yim ; float *aar , *yar ;
   int nt=0 , nxyz=0 , nvox=0 , nparam=0 , nqbase , polort=0 , ii,jj,kk,bb ;
   byte *mask=NULL ; int nmask=0 , iarg ;
   char *fname_out="-" ;   /** equiv to stdout **/

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

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

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

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

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

     PRINT_COMPILE_DATE ; exit(0) ;
   }

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

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

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

   iarg = 1 ;
   while( iarg < argc ){

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   } /* end of switch on method */

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

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

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

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

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

   INFO_message("Writing result to '%s'",fname_out) ;
   mri_write_1D( fname_out , vim ) ;
   exit(0) ;
}
Exemplo n.º 19
0
MRI_IMARR * THD_get_all_timeseries( char * dname )
{
   THD_string_array * flist , * rlist ;
   int ir , ll , ii ;
   char * fname , * tname ;
   float * far ;
   MRI_IMARR * outar ;
   MRI_IMAGE * outim , * flim ;

#ifdef NEWWAY
   char * pat ;
#endif

   unsigned long max_fsize ;  /* 20 Jul 2004: max 1D file size to load */

   max_fsize = (unsigned long) AFNI_numenv( "AFNI_MAX_1DSIZE" ) ;
   if( max_fsize == 0 ) max_fsize = 123*1024 ;

   /*----- sanity check and initialize -----*/

   if( dname == NULL || strlen(dname) == 0 ) return NULL ;
   INIT_IMARR( outar ) ;

   /*----- find all *.1D files -----*/

#ifdef NEWWAY
   ii  = strlen(dname) ;
   pat = (char *) malloc(sizeof(char)*(ii+8)) ;
   strcpy(pat,dname) ;
   if( pat[ii-1] != '/' ) strcat(pat,"/") ;
   strcat(pat,"*.1D*") ;
   flist = THD_get_wildcard_filenames( pat ) ;
   free(pat) ;
#else
   flist = THD_get_all_filenames( dname ) ;
#endif

   if( flist == NULL || flist->num <= 0 ){
      DESTROY_SARR(flist) ;
      DESTROY_IMARR(outar) ;
      return NULL ;
   }

   rlist = THD_extract_regular_files( flist ) ;
   DESTROY_SARR(flist) ;
   if( rlist == NULL || rlist->num <= 0 ){
      DESTROY_SARR(rlist) ;
      DESTROY_IMARR(outar) ;
      return NULL ;
   }

   for( ir=0 ; ir < rlist->num ; ir++ ){
      fname = rlist->ar[ir] ; if( fname == NULL ) continue ;

      ll = strlen(fname) - 3 ; if( ll < 1 ) continue ;

      if( strcmp(fname+ll,".1D")==0 ||
          strcmp(fname+ll,"1Dx")==0 ||
          strcmp(fname+ll,"1Dv")==0   ){

         if( THD_filesize(fname) > max_fsize ) continue ;  /* 20 Jul 2004 */

         flim = mri_read_1D( fname ) ;
         if( flim != NULL ){
            far = MRI_FLOAT_PTR(flim) ;
            for( ii=0 ; ii < flim->nvox ; ii++ )
               if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;

            tname = THD_trailname(fname,1) ;
            mri_add_name( tname , flim ) ;
            ADDTO_IMARR( outar , flim ) ;
         }
      }
   }

   DESTROY_SARR(rlist) ;

   if( IMARR_COUNT(outar) == 0 ) DESTROY_IMARR(outar) ;

   return outar ;
}
Exemplo n.º 20
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *dset=NULL , *oset=NULL ;
   MRI_IMAGE *thim=NULL ; float *thar ; int nthar ;
   byte *mask=NULL ; int nmask=0 ;
   MRI_IMAGE *datim=NULL, *thrim=NULL , *outim=NULL ;
   int iarg , dind=0 , tind=1 , ith , nnlev=1 ;
   int scode ; float *spar=NULL ;
   char *prefix = "ETC.nii" ;

   /*-- some pitiful help --*/

   if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){
     printf("\n"
      "Usage: 3dETC [options] inputdataset\n"
      "\n"
      "Options:\n"
      "========\n"
      " -input dset  = alternative way to input the dataset\n"
      " -prefix ppp  = output prefix\n"
      " -thresh ttt  = 1D file with\n"
      "                 column #1 = p-value\n"
      "                 column #2 = cluster threshold\n"
      " -mask   mmm  = dataset with mask\n"
      " -1dindex ii  = output comes from sub-brick #ii\n"
      " -1tindex jj  = threshold on sub-brick #jj\n"
      " -NN      nn  = nn is 1 or 2 or 3 [default 1]\n"
      "\n"
      "-- Experimental - RWCox - 24 Dec 2015\n"
     ) ;
     exit(0) ;
   }

   /*-- scan options --*/

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

     if( strcasecmp(argv[iarg],"-input") == 0 ){
       if( dset != NULL )
         ERROR_exit("You can't use option '%s' twice!",argv[iarg]) ;
       if( ++iarg >= argc )
         ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       dset = THD_open_dataset( argv[iarg] ) ;
       CHECK_OPEN_ERROR(dset,argv[iarg]) ;
       DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-mask") == 0 ){
       bytevec *bvec ; int nmask_hits ;
       if( mask != NULL )
         ERROR_exit("Can't use '-mask' twice!") ;
       if( ++iarg >= argc )
         ERROR_exit("Need argument after '%s'",argv[iarg-1]) ;
       bvec = THD_create_mask_from_string(argv[iarg]) ;
       if( bvec == NULL )
         ERROR_exit("Can't create mask from '-mask' option") ;
       mask = bvec->ar ; nmask = bvec->nar ;
       nmask_hits = THD_countmask( nmask , mask ) ;
       if( nmask_hits > 0 )
         INFO_message("%d voxels in -mask definition (out of %d total)",
                      nmask_hits,nmask) ;
       else
         ERROR_exit("no nonzero voxels in -mask dataset") ;
       iarg++ ; continue ;
     }


     if( strcasecmp(argv[iarg],"-prefix") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       prefix = strdup(argv[iarg]) ;
       if( ! THD_filename_ok(prefix) )
         ERROR_exit("-prefix '%s' is not a good filename prefix",prefix) ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-1tindex") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       tind = (int)strtod(argv[iarg],NULL) ;
       if( tind < 0 )
         ERROR_exit("-tind '%s' is illegal!",argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-1dindex") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       dind = (int)strtod(argv[iarg],NULL) ;
       if( dind < 0 )
         ERROR_exit("-dind '%s' is illegal!",argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-NN") == 0 ){
       if( ++iarg >= argc )
         ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       nnlev = (int)strtod(argv[iarg],NULL) ;
       if( nnlev < 1 || nnlev > 3 )
         ERROR_exit("-nnlev '%s' is illegal!",argv[iarg]) ;
       iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-NN1") == 0 ){
       nnlev = 1 ; iarg++ ; continue ;
     }
     if( strcasecmp(argv[iarg],"-NN2") == 0 ){
       nnlev = 2 ; iarg++ ; continue ;
     }
     if( strcasecmp(argv[iarg],"-NN3") == 0 ){
       nnlev = 3 ; iarg++ ; continue ;
     }

     if( strcasecmp(argv[iarg],"-thresh") == 0 ){
       int nbad=0 ;
       if( thim != NULL )
         ERROR_exit("You can't use option '%s' twice!",argv[iarg]) ;
       if( ++iarg >= argc ) ERROR_exit("Option '%s' needs an argument to follow!",argv[iarg-1]) ;
       thim = mri_read_1D( argv[iarg] ) ;
       if( thim == NULL )
         ERROR_exit("Cannot read file from option -thresh '%s'",argv[iarg]) ;
       if( thim->ny < 2 )
         ERROR_exit("-thresh '%s' doesn't have at least 2 columns!",argv[iarg]) ;
       nthar = thim->nx ; thar  = MRI_FLOAT_PTR(thim) ;
       for( ith=0 ; ith < nthar ; ith++ ){
         if( thar[ith] <= 0.0f || thar[ith] > 0.10f ) nbad++ ;
       }
       if( nbad > 0 )
         ERROR_exit("Some value%s in -thresh '%s' Column #1 %s outside 0 < p <= 0.1 :-(",
                    (nbad==1)?"\0":"s" , argv[iarg] ,
                    (nbad==1)?"is":"are" ) ;
       for( ith=0 ; ith < nthar ; ith++ ){
         if( thar[ith+nthar] < 1.0f ) nbad++ ;
       }
       if( nbad > 0 )
         ERROR_exit("Some value%s in -thresh '%s' Column #2 %s less than 1 :-(",
                    (nbad==1)?"\0":"s" , argv[iarg] ,
                    (nbad==1)?"is":"are" ) ;
       INFO_message("-thresh table has %d levels of thresholding",nthar) ;
       iarg++ ; continue ;
     }

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

   /*-- did we get the input dataset yet? --*/

   if( dset == NULL ){
     if( iarg >= argc ) ERROR_exit("no input dataset?!") ;
     dset = THD_open_dataset( argv[iarg] ) ;
     CHECK_OPEN_ERROR(dset,argv[iarg]) ;
     DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;
     iarg++ ;
   }

   /*-- check things --*/

   if( nmask > 0 && DSET_NVOX(dset) != nmask )
     ERROR_exit("mask and input datasets don't match in number of voxels") ;

   if( thim == NULL ) ERROR_exit("no -thresh option was given!?") ;

   if( dind >= DSET_NVALS(dset) )
     ERROR_exit("data index %d is beyond end of input dataset!",dind) ;
   if( tind >= DSET_NVALS(dset) )
     ERROR_exit("threshold index %d is beyond end of input dataset!",tind) ;

   /*-- record things for posterity, et cetera --*/

   mainENTRY("3dETC main"); machdep(); AFNI_logger("3dETC",argc,argv);
   PRINT_VERSION("3dETC") ; AUTHOR("Bob the Equable") ;

   /*-- get the data and threshold volumes --*/

   datim = THD_extract_float_brick( dind , dset ) ;
   thrim = THD_extract_float_brick( tind , dset ) ;
   if( datim == NULL || thrim == NULL )  /* should be impossible */
     ERROR_exit("Can't get data and/or thresh data from input dataset???") ;
   DSET_unload(dset) ;

   scode = DSET_BRICK_STATCODE(dset,tind) ;
   if( scode < 0 )
     ERROR_exit("thresh sub-brick index %d is NOT a statistical volume!?",tind) ;
   spar = DSET_BRICK_STATAUX(dset,tind) ;

#if 1
INFO_message("value range in thrim = %g .. %g",mri_min(thrim),mri_max(thrim)) ;
#endif

   outim = mri_multi_threshold_clusterize(
             datim , scode,spar,thrim , mask ,
             nthar , thar , thar+nthar , nnlev , 0 ) ;

   oset = EDIT_empty_copy(dset) ;
   EDIT_dset_items( oset ,
                      ADN_prefix    , prefix ,
                      ADN_nvals     , 1 ,
                      ADN_ntt       , 0 ,
                      ADN_brick_fac , NULL ,
                      ADN_type      , HEAD_FUNC_TYPE ,
                      ADN_func_type , FUNC_BUCK_TYPE ,
                    ADN_none ) ;
   EDIT_substitute_brick( oset , 0 , MRI_float , MRI_FLOAT_PTR(outim) ) ;
   DSET_write(oset) ; WROTE_DSET(oset) ;

   INFO_message("# nonzero voxels = %d",mri_nonzero_count(outim)) ;

   exit(0) ;
}
Exemplo n.º 21
0
int main( int argc , char *argv[] )
{
   THD_3dim_dataset *inset=NULL ;
   byte *mask=NULL ; int mask_nx=0,mask_ny=0,mask_nz=0 , automask=0 , masknum=0 ;
   int iarg=1 , verb=1 , ntype=0 , nev,kk,ii,nxyz,nt ;
   float na,nb,nc , dx,dy,dz ;
   MRI_IMARR *imar=NULL ; int *ivox ; MRI_IMAGE *pim ;
   int do_vmean=0 , do_vnorm=0 , sval_itop=0 ;
   int polort=-1 ; float *ev ;
   MRI_IMARR *ortar ; MRI_IMAGE *ortim ; int nyort=0 ;
   float bpass_L=0.0f , bpass_H=0.0f , dtime ; int do_bpass=0 ;

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

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

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

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

   INIT_IMARR(ortar) ;

   mpv_sign_meth = AFNI_yesenv("AFNI_3dmaskSVD_meansign") ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   /*-- get data vectors --*/

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

   /*-- detrending --*/

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

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

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

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

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

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

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

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

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

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

   exit(0) ;
}
Exemplo n.º 22
0
int main(int argc, char *argv[]) {
   int i, k, ii;
	int iarg;


   char *prefix=NULL;
   char *maskname=NULL;
   char *gradsname=NULL;
   char *dtsname=NULL;

   THD_3dim_dataset *MASK=NULL;
   THD_3dim_dataset *DTS=NULL;
   MRI_IMAGE *GRADS=NULL, *GRADS_IN=NULL;

   int Ngrads=0, Nfull=0;
	int Nvox=-1;            // tot number vox
	int Dim[3]={0,0,0};     // dim in each dir

   float NOISESCALE_DWI = -1.;
   float NOISESCALE_B0 = -1;
   float S0 = 1000.;
   float bval = 1.;
   int NOISE_IN_S0 = 0;

   byte *mskd2=NULL; // not great, but another format of mask

   float **dwi=NULL;
   THD_3dim_dataset *DWI_OUT=NULL;

   const gsl_rng_type * T;
   gsl_rng *r;
   long seed;


   srand(time(0));
   seed = time(NULL) ;
   gsl_rng_env_setup();
   T = gsl_rng_default;
   r = gsl_rng_alloc (T);
   gsl_rng_set (r, seed);
   
   // ###################################################################
   // #########################  load  ##################################
   // ###################################################################

   mainENTRY("3dDTtoNoisyDWI"); machdep(); 
	if (argc == 1) { usage_DTtoNoisyDWI(1); exit(0); }
   
   iarg = 1;
	while( iarg < argc && argv[iarg][0] == '-' ){
		if( strcmp(argv[iarg],"-help") == 0 || 
			 strcmp(argv[iarg],"-h") == 0 ) {
			usage_DTtoNoisyDWI(strlen(argv[iarg])>3 ? 2:1);
			exit(0);
		}
     
      if( strcmp(argv[iarg],"-dt_in") == 0) {
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-eig_vecs'");
         dtsname = strdup(argv[iarg]) ;
         
         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],"-mask") == 0) {
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-mask'");
         maskname = strdup(argv[iarg]) ;
      
         iarg++ ; continue ;
      }

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

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

         NOISESCALE_DWI = atof(argv[iarg]);
         
         iarg++ ; continue ;
      }

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

         NOISESCALE_B0 = atof(argv[iarg]);
         
         iarg++ ; continue ;
      }

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

         S0 = atof(argv[iarg]);
         if(S0 <= 0 )
            ERROR_exit("The '-S0' value must be >0.");
         iarg++ ; continue ;
      }

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

         bval = atof(argv[iarg]);
         if(bval <= 0 )
            ERROR_exit("The '-bval' value must be >0.");
         iarg++ ; continue ;
      }

		ERROR_message("Bad option '%s'\n",argv[iarg]) ;
		suggest_best_prog_option(argv[0], argv[iarg]);
		exit(1);

   }


   // ###################################################################
   // ####################   some checks  ###############################
   // ###################################################################

   if(!prefix)
      ERROR_exit("Need to give a '-prefix'.");

   if(!dtsname)
      ERROR_exit("Need to input diffusion tensor file after '-dt_in'.");

   if(!gradsname)
      ERROR_exit("Need to input gradient file after '-grads'.");

   if( NOISESCALE_DWI<0 )
      ERROR_exit("Fractional noise value after '-snr0' needs to be >0. "
                 "It sets the noise scale of ref signal S0.");

   if(NOISESCALE_DWI > 0)
      INFO_message("You have chosen an SNR0 of approximately %.2f for DWIs",
                   1./NOISESCALE_DWI);
   else
      INFO_message("You have noiseless (i.e., infinite SNR) set of DWIs");

   if( NOISESCALE_B0 < 0 )
      NOISESCALE_B0 = NOISESCALE_DWI;

   if(NOISESCALE_B0 > 0)
      INFO_message("You have chosen an SNR0 of approximately %.2f for the B0",
                   1./NOISESCALE_B0);
   else
      INFO_message("You have noiseless (i.e., infinite SNR) reference B0.");


   // ###################################################################

   if(dtsname) {
      DTS = THD_open_dataset(dtsname);
      DSET_load(DTS);  CHECK_LOAD_ERROR(DTS);

      if( 6 != DSET_NVALS(DTS) )
         ERROR_exit("DT file '%s' must have 6 bricks-- "
                    "it has %d bricks!",
                    dtsname, DSET_NVALS(DTS));
   }

   Nvox = DSET_NVOX(DTS);
   Dim[0] = DSET_NX(DTS); 
   Dim[1] = DSET_NY(DTS); 
   Dim[2] = DSET_NZ(DTS); 
   
   if(Nvox<0)
      ERROR_exit("Error reading Nvox from eigenvalue file.");

   mskd2 = (byte *)calloc(Nvox,sizeof(byte)); 
   if( (mskd2 == NULL)) { 
      fprintf(stderr, "\n\n MemAlloc failure (masks).\n\n");
      exit(122);
   }
   
   if(maskname) {
      MASK = THD_open_dataset(maskname);
      DSET_load(MASK);  CHECK_LOAD_ERROR(MASK);
      
      if( 1 != DSET_NVALS(MASK) )
         ERROR_exit("Mask file '%s' is not scalar-- "
                    "it has %d bricks!",
                    maskname, DSET_NVALS(MASK));
      
      for( k=0 ; k<Nvox ; k++ )
         if (THD_get_voxel(MASK, k, 0) > 0 )
            mskd2[k] = 1;

      DSET_delete(MASK);
      free(MASK);
      free(maskname);
   }
   else {
      for( k=0 ; k<Nvox ; k++ )
         if( fabs(THD_get_voxel(DTS,k,0) > EPS_V) )
            mskd2[k] = 1;
   }
      

   GRADS_IN = mri_read_1D (gradsname);
   GRADS = mri_transpose(GRADS_IN); // get rid of autotranspose...
   if (GRADS == NULL) 
         ERROR_exit("Error reading gradient vector file");
   mri_free(GRADS_IN);

   Ngrads = GRADS->ny;

   if(Ngrads < 6) 
      ERROR_exit("Too few grads (there appear to be only %d).",Ngrads);
   if(GRADS->nx !=3 ) 
      ERROR_exit("Wrong number of columns in the grad file: "
                 " am reading %d instead of 3.",GRADS->nx);
   Nfull = Ngrads+1;
   INFO_message("Have surmised there are %d total grads; "
                "output file will have %d bricks", Ngrads,Nfull);
   
   dwi = calloc(Nfull,sizeof(dwi)); 
   for(i=0 ; i<Nfull ; i++) 
		dwi[i] = calloc( Nvox,sizeof(float)); 

   INFO_message("Calculating the DWIs.");
   i = RicianNoiseDWIs( dwi, Nvox, Ngrads, DTS, 
                        NOISESCALE_DWI, NOISESCALE_B0,
                        GRADS, mskd2,
                        S0, bval, r);

   INFO_message("Writing the DWIs.");
   DWI_OUT = EDIT_empty_copy( DTS ); 
   EDIT_dset_items(DWI_OUT,
                   ADN_nvals, Nfull,
						 ADN_datum_all, MRI_float , 
                   ADN_prefix, prefix,
						 ADN_none );

   for( i=0; i<Nfull ; i++) {
		EDIT_substitute_brick(DWI_OUT, i, MRI_float, dwi[i]);
		dwi[i]=NULL;
	}

	THD_load_statistics( DWI_OUT );
	if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(DWI_OUT)) )
		ERROR_exit("Can't overwrite existing dataset '%s'",
					  DSET_HEADNAME(DWI_OUT));
	tross_Make_History("3dDTtoNoisyDWI", argc, argv, DWI_OUT);
	THD_write_3dim_dataset(NULL, NULL, DWI_OUT, True);
	DSET_delete(DWI_OUT); 
  	free(DWI_OUT); 
   
   // #################################################################
   // ##########################  free  ###############################
   // #################################################################

   DSET_delete(DTS);
   free(DTS);
   
   for( i=0 ; i<Nfull ; i++)
      free(dwi[i]);
   free(dwi);

   free(prefix);
   free(gradsname);
   free(dtsname);
   mri_free(GRADS);

	return 0;
}
Exemplo n.º 23
0
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"ScaleToMap"};
   char  *IntName = NULL, *Prfx, h[9], 
         *CmapFileName = NULL, *dbfile = NULL, *MapName=NULL; 
   MRI_IMAGE *im = NULL;
   float *far=NULL;
   int N_V, N_Int, kar, k, ii, i, icol=-1, vcol=-1, Sgn, interpmode, k3;
   int Vminloc, Vmaxloc, *iV = NULL;
   float Vmin, Vmax, brfact;
   float *V = NULL, *Vsort = NULL;
   float IntRange[2], MaskColor[3], MaskRange[2]={0.0, 0.0}, arange;
   SUMA_Boolean ApplyClip, ApplyMask, setMaskCol, ApplyPercClip, Vopt;
   SUMA_Boolean iVopt, inopt, NoMaskCol, MapSpecified, alaAFNI, MaskZero;
   SUMA_Boolean brk, frf, ShowMap, ShowMapdb;
   SUMA_COLOR_MAP *CM;
   SUMA_SCALE_TO_MAP_OPT * OptScl;
   int MapType, freecm = 1;
   SUMA_COLOR_SCALED_VECT * SV;
   SUMA_AFNI_COLORS *SAC=NULL;
   SUMA_Boolean FromAFNI = NOPE;
   int imap, isPmap, isNmap;
   SUMA_Boolean LocalHead = NOPE;
   
   
   SUMA_STANDALONE_INIT;
   SUMAg_CF->isGraphical = YUP;
   SUMA_mainENTRY;
   
   /* this is placed down here to */
   /* 
   if (argc < 3) {
      SUMA_ScaleToMap_usage();
      exit (1);
   }
   */
   
   kar = 1;
   brfact = 1; /* the brightness factor */
   MaskColor[0] = MaskColor[1] = MaskColor[2] = 0.3;
   ApplyClip = NOPE;
   ApplyPercClip = NOPE;
   ApplyMask = NOPE;
   NoMaskCol = NOPE;
   MaskZero = NOPE;
   setMaskCol = NOPE;
   Vopt = NOPE;
   iVopt = NOPE;
   inopt = NOPE;
   MapType = SUMA_CMAP_RGYBR20;
   brk = NOPE;
   MapSpecified = NOPE;
   CmapFileName = NULL;
   interpmode = SUMA_UNDEFINED_MODE;
   ShowMap = NOPE;
   alaAFNI = NOPE;   /* applying the alaAFNI mapping */
   frf = NOPE;
   arange  = -1.0; /* afni range specified */
   Sgn = 0;
   ShowMapdb = NOPE;
   while (kar < argc) { /* loop accross command ine options */
      /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
      if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
         SUMA_ScaleToMap_usage();
         exit (1);
      }
      
      SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      if (!brk && strcmp(argv[kar], "-verb") == 0) {
         LocalHead = NOPE;
         brk = YUP;
      }
      
      if (!brk && strcmp(argv[kar], "-ionot") == 0) {
         SUMA_SL_Err("-ionot is obsolete. \n"
                     "Use -trace option.");
         exit (1);
         SUMA_INOUT_NOTIFY_ON;
         brk = YUP;
      }
      
      if (!brk && strcmp(argv[kar], "-msk_zero") == 0) {
         MaskZero = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-input") == 0)) {
         kar ++;
         if (kar+2 >= argc)  {
            fprintf (SUMA_STDERR, "need 3 arguments after -input \n");
            exit (1);
         }
         IntName = argv[kar]; kar ++;
         icol = atoi(argv[kar]); kar ++;
         vcol = atoi(argv[kar]); 
         inopt = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-apr") == 0)) {
         if (arange >= 0) {
            fprintf (SUMA_STDERR, "range has already been specified.\n");
            exit (1);
         }
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need argument after -apr \n");
            exit (1);
         }
         arange = atof(argv[kar]);
         if (arange < 0) {
            fprintf (SUMA_STDERR, "range must be positive.\n");
            exit (1);
         }
         Sgn = 1;
         alaAFNI = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-anr") == 0)) {
         if (arange >= 0) {
            fprintf (SUMA_STDERR, "range has already been specified.\n");
            exit (1);
         }
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need argument after -anr \n");
            exit (1);
         }
         arange = atof(argv[kar]);
         if (arange < 0) {
            fprintf (SUMA_STDERR, "range must be positive.\n");
            exit (1);
         }
         
         Sgn = -1;
         alaAFNI = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-v") == 0)) {
         fprintf (SUMA_STDERR, "\n -v option is now obsolete.\nUse -input option instead.\n");
         exit (1);
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need argument after -v \n");
            exit (1);
         }
         IntName = argv[kar];
         Vopt = YUP;
         brk = YUP;
      }      
      
      if (!brk && (strcmp(argv[kar], "-iv") == 0)) {
         fprintf (SUMA_STDERR, "\n -iv option is now obsolete.\nUse -input option instead.\n");
         exit (1);
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -iv \n");
            exit (1);
         }
         IntName = argv[kar];
         iVopt = YUP;
         brk = YUP;
      }   
      
      if (!brk && (strcmp(argv[kar], "-br") == 0)) {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -br \n");
            exit (1);
         }
         brfact = atof(argv[kar]);

         brk = YUP;
      }   
      
      if (!brk && (strcmp(argv[kar], "-frf") == 0)) {
         frf = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-showmap") == 0)) {
         ShowMap = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-showdb") == 0)) {
         ShowMapdb = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-nointerp") == 0)) {
         if (interpmode != SUMA_UNDEFINED_MODE) {
            fprintf (SUMA_STDERR, "Color interpolation mode already set.\n");
         }
         interpmode = SUMA_NO_INTERP;
         brk = YUP;
      } 
      
      if (!brk && (strcmp(argv[kar], "-direct") == 0)) {
         if (interpmode != SUMA_UNDEFINED_MODE) {
            fprintf (SUMA_STDERR, "Color interpolation mode already set.\n");
         }
         interpmode = SUMA_DIRECT;
         brk = YUP;
      } 
      
      if (!brk && (strcmp(argv[kar], "-interp") == 0)) {
         if (interpmode != SUMA_UNDEFINED_MODE) {
            fprintf (SUMA_STDERR, "Color interpolation mode already set.\n(-nointerp, -direct and -interp are mutually exclusive.\n");
         }
         interpmode = SUMA_INTERP;
         brk = YUP;
      } 
        
      if (!brk && (strcmp(argv[kar], "-clp") == 0)) {
         kar ++;
         if (kar+1 >= argc)  {
              fprintf (SUMA_STDERR, "need 2 arguments after -clp \n");
            exit (1);
         }
         ApplyClip = YUP;
         IntRange[0] = atof(argv[kar]); kar ++;
         IntRange[1] = atof(argv[kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-perc_clp") == 0)) {
         kar ++;
         if (kar+1 >= argc)  {
              fprintf (SUMA_STDERR, "need 2 arguments after -perc_clp ");
            exit (1);
         }
         ApplyPercClip = YUP;
         IntRange[0] = atof(argv[kar]); kar ++;
         IntRange[1] = atof(argv[kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-msk") == 0)) {
         kar ++;
         if (kar+1 >= argc)  {
              fprintf (SUMA_STDERR, "need 2 arguments after -msk ");
            exit (1);
         }
         ApplyMask = YUP;
         MaskRange[0] = atof(argv[kar]); kar ++;
         MaskRange[1] = atof(argv[kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-nomsk_col") == 0)) {
         NoMaskCol = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-msk_col") == 0)) {
         kar ++;
         if (kar+2 >= argc)  {
              fprintf (SUMA_STDERR, "need 3 arguments after -msk_col ");
            exit (1);
         }
         setMaskCol = YUP;
         MaskColor[0] = atof(argv[kar]); kar ++;
         MaskColor[1] = atof(argv[kar]); kar ++;
         MaskColor[2] = atof(argv[kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-cmapfile") ==0)) {
         if (MapSpecified) {
            fprintf (SUMA_STDERR, "Color map already specified.\n-cmap and -cmapfile are mutually exclusive\n");
            exit (1);
         }
         MapSpecified = YUP;
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need 1 arguments after -cmapfile ");
            exit (1);
         }
         
         CmapFileName = argv[kar];
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-cmapdb") ==0)) {
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need 1 arguments after -cmapdb ");
            exit (1);
         }
         
         dbfile = argv[kar];
         brk = YUP;
      }
      
      
      if (!brk && (strcmp(argv[kar], "-cmap") ==0)) {
         if (MapSpecified) {
            fprintf (SUMA_STDERR, "Color map already specified.\n-cmap and -cmapfile are mutually exclusive\n");
            exit (1);
         }
         MapSpecified = YUP;
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need 1 arguments after -cmap ");
            exit (1);
         }
         MapName = argv[kar];
         
         brk = YUP;
      }
      
      if (!brk) {
         fprintf (SUMA_STDERR,"Error %s: Option %s not understood. Try -help for usage\n", FuncName, argv[kar]);
         exit (1);
      } else {   
         brk = NOPE;
         kar ++;
      }
      
   }/* loop accross command ine options */
   
   /* Get your colors straightened out */
   if (!SUMAg_CF->scm) {   
      SUMAg_CF->scm = SUMA_Build_Color_maps();
      if (!SUMAg_CF->scm) {
         SUMA_SL_Err("Failed to build color maps.\n");
         exit(1);
      }
   }

   SAC = SUMAg_CF->scm;
   /* are there database files to read */
   if (dbfile) {
      SUMA_LH("Now trying to read db file");
      if (SUMA_AFNI_Extract_Colors ( dbfile, SAC ) < 0) {
         SUMA_S_Errv("Failed to read %s colormap file.\n", dbfile);
         exit(1);
      }
   }
   
   FromAFNI = NOPE; /* assume colormap is not coming from SAC
                       (the colormap database structure) */
   if (CmapFileName) { 
      /* load the color map */
      CM = SUMA_Read_Color_Map_1D (CmapFileName);
      if (CM == NULL) {
         SUMA_S_Err("Could not load colormap.\n");
         exit (1); 
      }
      if (frf) {
         SUMA_LH("Flipping colormap");
         SUMA_Flip_Color_Map (CM);
      }   

      if (!CM->Sgn) CM->Sgn = Sgn; 
   }else{
      /* dunno what kind of map yet. Try default first */
      if (MapName) {
         CM = SUMA_FindNamedColMap (MapName);
         freecm = 0;
         if (CM) {
            /* good, sign it and out you go */   
            CM->Sgn = Sgn;
         } else {
            SUMA_S_Err("Could not get standard colormap.\n");
            exit (1); 
         }
      } else {
         SUMA_LH("An AFNI color map ");
         /* a color from AFNI's maps */
         FromAFNI = YUP;
         imap = SUMA_Find_ColorMap ( MapName, SAC->CMv, SAC->N_maps, -2);
         if (imap < 0) {
            SUMA_S_Errv("Could not find colormap %s.\n", MapName);
            exit (1); 
         }
         CM = SAC->CMv[imap];
      }
   }
   
   
   /* show the colromap on STDERR */
   if (ShowMap) {
      fprintf (SUMA_STDERR, "%s: Colormap used:\n", FuncName);
      SUMA_Show_ColorMapVec (&CM, 1, NULL, 2);
      {
         SUMA_SurfaceObject *SO = NULL;
         float orig[3]     = { SUMA_CMAP_ORIGIN  };
         float topright[3] = { SUMA_CMAP_TOPLEFT };
         
         SO = SUMA_Cmap_To_SO (CM, orig, topright, 2);
         if (SO) SUMA_Free_Surface_Object(SO);
      }
      exit(0);
   }
   
   /* show all the colors and colormaps in SAC on STDERR */
   if (ShowMapdb) {
      fprintf (SUMA_STDERR, "%s: AFNI colormaps found in db:\n", FuncName);
      SUMA_Show_ColorVec (SAC->Cv, SAC->N_cols, NULL);
      SUMA_Show_ColorMapVec (SAC->CMv, SAC->N_maps, NULL, 2);
      exit(0);
   }


   if (!IntName) {
      fprintf (SUMA_STDERR,"Error %s: No input file specified.\n", FuncName);
      exit(1);
   }
   
   /* default interpolation mode */
   if (interpmode == SUMA_UNDEFINED_MODE) interpmode = SUMA_INTERP; 
   
   /* check input */
   if (!SUMA_filexists (IntName)) {
      fprintf (SUMA_STDERR,"Error %s: File %s could not be found.\n", FuncName, IntName);
      exit(1);
   }
   
   if (frf && !CmapFileName) {
      fprintf (SUMA_STDERR,"Error %s: -frf option is only valid with -cmapfile.\n", FuncName);
      exit(1);
   }
   
   if (ApplyPercClip && ApplyClip) {
      fprintf (SUMA_STDERR,"Error %s: Simultaneous use of -clp and -perc_clp. You should be punished.\n", FuncName);
      exit(1);
   }
   
   if ((ApplyPercClip || ApplyClip) && arange >= 0.0) {
      fprintf (SUMA_STDERR,"Error %s: Simultaneous use of -clp/-perc_clp and -apr/anr.\n Read the help.\n", FuncName);
      exit(1);
   }
   
   if (iVopt || Vopt) {
      fprintf (SUMA_STDERR,"Error %s: -v and -iv are obsolete.\n Use -input option instead.\n", FuncName);
      exit(1);
   }
   
   if (!inopt) {
      fprintf (SUMA_STDERR,"Error %s: -input option must be specified.\n", FuncName);
      exit(1);
   }
   
   im = mri_read_1D (IntName);
   
   if (!im) {
      SUMA_S_Err("Failed to read file");
      exit (1);
   }
   
   if (vcol < 0) {
      fprintf (SUMA_STDERR,"Error %s: vcol must be > 0\n", FuncName);
      exit(1);
   }
   
   far = MRI_FLOAT_PTR(im);
   if (icol < 0 && icol != -1) {
      fprintf (SUMA_STDERR,"Error %s: icol(%d) can only have -1 for a negative value\n", FuncName, icol);
      exit(1);
   }
   
   if (icol >= im->ny || vcol >= im->ny) {
      fprintf (SUMA_STDERR,"Error %s: icol(%d) and vcol(%d) must be < %d\nwhich is the number of columns in %s\n",
          FuncName, icol, vcol, im->ny, IntName);
      exit(1);
   }
   
   
   if (brfact <=0 || brfact > 1) {
      fprintf (SUMA_STDERR,"Error %s: BrightFact must be > 0 and <= 1.\n", FuncName);
      exit (1);
   }
   
   if (MaskColor[0] < 0 || MaskColor[0] > 1 || MaskColor[1] < 0 || MaskColor[1] > 1 || MaskColor[2] < 0 || MaskColor[2] > 1) {
      fprintf (SUMA_STDERR,"Error %s: MaskColor values must be >=0 <=1.\n", FuncName);
      exit(1);
   }
     
   
   N_V = im->nx;
   V = (float *) SUMA_calloc (N_V, sizeof(float));
   iV = (int *) SUMA_calloc (N_V, sizeof(int));
   if (!V || !iV) {
      fprintf (SUMA_STDERR,"Error %s: Could not allocate for V or iV.\n", FuncName);
      exit(1);
   }
   
   if (icol < 0) {
     for (ii=0; ii < N_V; ++ii) {
         iV[ii] = ii; 
         V[ii] = far[vcol*N_V+ii]; 
     } 
   } else {
      for (ii=0; ii < N_V; ++ii) {
         iV[ii] = (int)far[icol*N_V+ii]; 
         V[ii] = far[vcol*N_V+ii]; 
      }
   }
   
   mri_free(im); im = NULL;

   /* read values per node */
   /* SUMA_disp_vect (V, 3);  */
   
   /* find the min/max of V */
   SUMA_MIN_MAX_VEC(V, N_V, Vmin, Vmax, Vminloc, Vmaxloc)
   /* fprintf (SUMA_STDERR,"%s: Vmin=%f, Vmax = %f\n", FuncName, Vmin, Vmax);*/ 
   
   if (arange == 0.0) {
      if (fabs((double)Vmin) > fabs((double)Vmax)) arange = (float)fabs((double)Vmin);
      else arange = (float)fabs((double)Vmax);
   }
   /* figure out the range if PercRange is used */
   if (ApplyPercClip) {
      
      fprintf (SUMA_STDERR,"%s: Percentile range [%f..%f] is equivalent to ", FuncName, IntRange[0], IntRange[1]);
      Vsort = SUMA_PercRange (V, NULL, N_V, IntRange, IntRange, NULL);
      fprintf (SUMA_STDERR,"[%f..%f]\n", IntRange[0], IntRange[1]);
      ApplyClip = YUP;
      
      if (Vsort) SUMA_free(Vsort);
      else {
         fprintf (SUMA_STDERR,"Error %s: Error in SUMA_PercRange.\n", FuncName);
         exit(1);
      }
   }
   
   
   /* get the options for creating the scaled color mapping */
   OptScl = SUMA_ScaleToMapOptInit();
   if (!OptScl) {
      fprintf (SUMA_STDERR,
               "Error %s: Could not get scaling option structure.\n", FuncName);
      exit (1); 
   }
   
   /* work the options a bit */
   if (ApplyMask) {
      OptScl->ApplyMask = ApplyMask;
      OptScl->MaskRange[0] = MaskRange[0]; 
      OptScl->MaskRange[1] = MaskRange[1]; 
      OptScl->MaskColor[0] = MaskColor[0]; 
      OptScl->MaskColor[1] = MaskColor[1]; 
      OptScl->MaskColor[2] = MaskColor[2];
   }
   
   if (ApplyClip) {
      OptScl->ApplyClip = YUP;
      OptScl->IntRange[0] = IntRange[0]; OptScl->IntRange[1] = IntRange[1];
   }

   OptScl->interpmode = interpmode;
   
   OptScl->BrightFact = brfact;
   
   if (MaskZero) OptScl->MaskZero = YUP;
      
   /* map the values in V to the colormap */
      /* allocate space for the result */
      SV = SUMA_Create_ColorScaledVect(N_V, 0);
      if (!SV) {
         fprintf (SUMA_STDERR,
                  "Error %s: Could not allocate for SV.\n", FuncName);
         exit(1);
      }
      
      /* finally ! */
      if (alaAFNI) {
         if (LocalHead) {
            fprintf (SUMA_STDERR,
                     "%s: Calling SUMA_ScaleToMap_alaAFNI\n", FuncName);
            fprintf (SUMA_STDERR,"%s: arange = %f\n",  FuncName, arange);
         }
         if (CM->frac) {
            if (CM->frac[0] > 0 && CM->Sgn == -1) {
               SUMA_S_Err ("Color map fractions positive with -anr option");
               exit(1);
            }
            if (CM->frac[0] < 0 && CM->Sgn == 1) {
               SUMA_S_Err ("Color map fractions negative with -apr option");
               exit(1);
            }
         }
      
         if (Sgn) {
            if (Sgn != CM->Sgn) {
               SUMA_S_Warn ("Mixing positive maps (all fractions > 0) "
                            "with -anr option\n"
                            "or vice versa. That is allowed but know what"
                            " you're doing.\n");
            }
         }
         if (!SUMA_ScaleToMap_alaAFNI (V, N_V, arange, CM, OptScl, SV)) {
            fprintf (SUMA_STDERR,
               "Error %s: Failed in SUMA_ScaleToMap_alaAFNI.\n", FuncName);
            exit(1);
         }
      } else {
         if (LocalHead) 
            fprintf (SUMA_STDERR,"%s: Calling SUMA_ScaleToMap\n", FuncName);
         if (!SUMA_ScaleToMap (V, N_V, Vmin, Vmax, CM, OptScl, SV)) {
            fprintf (SUMA_STDERR,
                     "Error %s: Failed in SUMA_ScaleToMap.\n", FuncName);
            exit(1);
         }
      }
   
   /* Now write the colored vector back to disk */
   if (NoMaskCol) {
      for (k=0; k < N_V; ++k) {
         k3 = 3*k;
         if (!SV->isMasked[k]) 
            fprintf (SUMA_STDOUT, "%d %f %f %f\n", 
                     iV[k], SV->cV[k3  ], SV->cV[k3+1], SV->cV[k3+2]);
      }
   } else {
      for (k=0; k < N_V; ++k) {
         k3 = 3*k;
         fprintf (SUMA_STDOUT, "%d %f %f %f\n", 
                  iV[k], SV->cV[k3  ], SV->cV[k3+1], SV->cV[k3+2]);
      }
   }
   
   /* freeing time */
   if (V) SUMA_free(V);
   if (iV) SUMA_free(iV);
   if (!FromAFNI && freecm) if (CM) SUMA_Free_ColorMap (CM); /* only free CM if 
                                       it was a pointer copy from a map in SAC */
   if (OptScl) SUMA_free(OptScl);
   if (SV) SUMA_Free_ColorScaledVect (SV);
   #if 0
      if (SAC) SAC = SUMA_DestroyAfniColors(SAC); /* destroy SAC */
   #else
      SAC = NULL; /* freeing is done in SUMAg_CF */
   #endif
   SUMA_Free_CommonFields(SUMAg_CF); 
   
   SUMA_RETURN (0);
}   
void initialize_program
(
    int * im1,               /* index of 1st image in time series for analysis */
    char ** nname,           /* noise model name */
    char ** sname,           /* signal model name */
    vfp * nmodel,            /* pointer to noise model */
    vfp * smodel,            /* pointer to signal model */
    int * r,                 /* number of parameters in the noise model */
    int * p,                 /* number of parameters in the signal model */
    char *** npname,         /* noise parameter names */
    char *** spname,         /* signal parameter names */
    float ** min_nconstr,    /* minimum parameter constraints for noise model */
    float ** max_nconstr,    /* maximum parameter constraints for noise model */
    float ** min_sconstr,    /* minimum parameter constraints for signal model */
    float ** max_sconstr,    /* maximum parameter constraints for signal model */
    int * nabs,              /* use absolute constraints for noise parameters */
    int * nrand,             /* number of random vectors to generate */
    int * nbest,             /* number of random vectors to keep */
    float * rms_min,         /* minimum rms error to reject reduced model */

    float ** par_rdcd,       /* estimated parameters for the reduced model */
    float ** par_full,       /* estimated parameters for the full model */
    float ** tpar_full,      /* t-statistic of parameters in the full model */

    int ts_length,           /* length of time series data */
    char ** tfilename,       /* file name for time point series */
    float *** x_array,       /* independent variable matrix */

    float ** fit
)

{
    int dimension;           /* dimension of full model */
    int ip;                  /* parameter index */
    int it;                  /* time index */
    MRI_IMAGE * im, * flim;  /* pointers to image structures
                              -- used to read 1D ASCII */
    int nt;                  /* number of points in 1D x data file */
    float * tar;


    /*----- intialize options -----*/
    initialize_options (im1, nname, sname, nmodel, smodel, r, p, npname, spname,
                        min_nconstr, max_nconstr, min_sconstr, max_sconstr,
                        nabs, nrand, nbest, rms_min, tfilename);

    /*----- check for valid inputs -----*/
    check_for_valid_inputs ();


    /*----- allocate space for independent variable matrix -----*/
    *x_array = (float **) malloc (sizeof(float *) * ts_length);
    if (*x_array == NULL)
        NLfit_error ("Unable to allocate memory for x_array");
    for (it = 0;  it < ts_length;  it++)
    {
        (*x_array)[it] = (float *) malloc (sizeof(float) * 3);
        if ((*x_array)[it] == NULL)
            NLfit_error ("Unable to allocate memory for x_array[it]");
    }

    /*----- initialize independent variable matrix -----*/
    if (!plug_timeref)
    {
        static float old_DELT = -1.0 ;
        DELT = (inTR && dsTR > 0.0) ? dsTR : 1.0 ;  /* 22 July 1998 */
        if( DELT != old_DELT ) {
            old_DELT = DELT ;
            printf("NLfit: switch to TR = %g\n",DELT) ;
        }

        for (it = 0;  it < ts_length;  it++)
        {
            (*x_array)[it][0] = 1.0;
            (*x_array)[it][1] = it * DELT;
            (*x_array)[it][2] = (it * DELT) * (it * DELT);
        }
    }
    else
    {
        flim = mri_read_1D (*tfilename);
        if (flim == NULL)
            NLfit_error ("Unable to read time reference file \n");
        nt = flim -> nx;
        if (nt < ts_length)
            NLfit_error ("Time reference array is too short");
        tar = MRI_FLOAT_PTR(flim) ;
        for (it = 0;  it < ts_length;  it++)
        {
            (*x_array)[it][0] = 1.0;
            (*x_array)[it][1] = tar[it] ;
            (*x_array)[it][2] = tar[it] * tar[it];
        }
        mri_free (flim);
    }

    /*--- 24 Jul 2006: special change to x_array[][2] for Linear+Ort [RWCox] ---*/
    if( strcmp(*nname,"Linear+Ort") == 0 ) {
        char *fname=NULL;
        MRI_IMAGE *fim=NULL;
        int nx;
        float *far;
        static int nwarn=0;
        fname = my_getenv("AFNI_ORTMODEL_REF") ;
        if( fname == NULL ) {
            ERROR_message("Linear+Ort model: 'AFNI_ORTMODEL_REF' not set") ;
            goto PLO_done ;
        }

        fim = mri_read_1D(fname) ;
        if( fim == NULL || fim->nx < 2 ) {
            ERROR_message(
                "Linear+Ort model: can't read AFNI_ORTMODEL_REF='%s'",fname) ;
            goto PLO_done ;
        }

        if( fim->ny > 1 && nwarn < 2 ) {
            WARNING_message(
                "Linear+Ort model: file AFNI_ORTMODEL_REF='%s' has more than 1 column",
                fname ) ;
            nwarn++ ;
        }

        nx = fim->nx ;
        far = MRI_FLOAT_PTR(fim) ;
        if( nx != ts_length && nwarn ) {
            WARNING_message("Linear+Ort: length(%s)=%d but length(dataset)=%d",
                            fname , nx , ts_length ) ;
            nwarn++ ;
        }
        for( it=0 ; it < ts_length;  it++)
            (*x_array)[it][2] = (it < nx) ? far[it] : 0.0f ;

PLO_done: ; /* nada */
    }


    dimension = (*r) + (*p);

    /*----- allocate memory space -----*/
    *par_rdcd = (float *) malloc (sizeof(float) * dimension);
    if (*par_rdcd == NULL)
        NLfit_error ("Unable to allocate memory for par_rdcd");
    *par_full = (float *) malloc (sizeof(float) * dimension);
    if (*par_full == NULL)
        NLfit_error ("Unable to allocate memory for par_full");
    *tpar_full = (float *) malloc (sizeof(float) * dimension);
    if (*tpar_full == NULL)
        NLfit_error ("Unable to allocate memory for tpar_full");
    *fit = (float *) malloc (sizeof(float) * (ts_length));
    if (*fit == NULL)
        NLfit_error ("Unable to allocate memory for fit");

}
Exemplo n.º 25
0
/* get and read rate file, and get computational time delta */
int get_init_data( float ** rtime, float ** rates, int * len, float * dt )
{
    MRI_IMAGE * im;
    char      * rate_file;
    char      * dt_text;

    if( !rtime || !rates || !len || !dt )
    {
        fprintf(stderr,"** get_init_data: bad params %p,%p,%p,%p\n",
                rtime, rates, len, dt);
        return 1;
    }

    /* get rate file name, and then try to read it */
    rate_file = my_getenv("AFNI_MM_MODEL_RATE_FILE");
    if( !rate_file )
    {
        fprintf(stderr,"\n** NLfim: need env var AFNI_MM_MODEL_RATE_FILE\n");
        fprintf(stderr,"   (might also want AFNI_MM_MODEL_DT)\n");
        return 1;
    }

    im = mri_read_1D(rate_file);
    if( !im )
    {
        fprintf(stderr,"** failed to open rate file %s\n",rate_file);
        return 1;
    }

    /* set the pointers and let the image dangle...  rates is second row */
    /* (should add cleanup function to MODEL_interface...)               */
    *rtime = MRI_FLOAT_PTR(im);
    *rates = *rtime + im->nx;
    *len   = im->nx;

    /* check to see if the rate times are in seconds */
    dt_text = my_getenv("AFNI_MM_MODEL_RATE_IN_SECS");
    if( dt_text && (*dt_text == 'y' || *dt_text == 'Y') )
    {
        int c;
        fprintf(stderr,"NLfim: rate times are taken in seconds\n");
        /* so convert to minutes */
        for( c = 0; c < *len; c++ ) (*rtime)[c] /= 60.0;
    }

    /* get dt from another env var */
    dt_text = my_getenv("AFNI_MM_MODEL_DT");
    if( dt_text )
        *dt = atof(dt_text);
    else  /* if user did not provide it... */
    {
        fprintf(stderr,"NLfim: MM: using default dt of %.3f s\n", NL_MM_DEF_DT);
        fprintf(stderr,"       (use env var AFNI_MM_MODEL_DT to override)\n");
        *dt = NL_MM_DEF_DT;
    }

    /* get debug level (abuse now unneeded dt_text variable) */
    dt_text = my_getenv("AFNI_MM_MODEL_DEBUG");
    if( dt_text ) debug = atoi( dt_text );
    if( dt_text && debug )
    {
        int c;
        fprintf(stderr,"+d NLfim: debug level set to %d\n", debug);
        fprintf(stderr,"          dt = %f, rate file = %s\n", *dt, rate_file);
        if( debug > 1 )
        {
            fprintf(stderr,"    time        rate\n    --------    --------\n");
            for( c = 0; c < *len; c++ )
                fprintf(stderr, "    %8f    %8f\n", (*rtime)[c], (*rates)[c]);
        }
    }

    return 0;
}
Exemplo n.º 26
0
int main( int argc , char * argv[] )
{
   int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ;
   float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ;
   MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ;
   THD_3dim_dataset **ortset=NULL ; int nortset=0 ;
   THD_3dim_dataset *inset=NULL , *outset=NULL;
   char *prefix="RSFC" ;
   byte *mask=NULL ;
   int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , 
		nx,ny,nz,nvox , nfft=0 , kk ;
   float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime  ;
   MRI_vectim *mrv ;
   float pvrad=0.0f ; int nosat=0 ;
   int do_despike=0 ;

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

   /*-- help? --*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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




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

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

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

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

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

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

			nopt++ ; continue ;
		}

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

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

   /** check inputs for reasonablositiness **/

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

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

		nopt++ ;
   }
   DSET_UNMSEC(inset) ;

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

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

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

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

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

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

   /* check mask, or create it */

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

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

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

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

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

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

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

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

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

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

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

		/* similarly for the ort vectors */

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

		/* all the real work now */

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

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

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

		/* OK, maybe a little more work */

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

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

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

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

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

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

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

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


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

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

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




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

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

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

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

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

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

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

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

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



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

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



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

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

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

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

	exit(0) ;
}
Exemplo n.º 27
0
int main( int argc , char * argv[] )
{
   int nim , ii,nii , jj , kk , nx ;
   MRI_IMAGE **inim ;
   float *far ;
   int ncol , ic ;
   float *csum ;
   int nn_ignore=0 , mm_use=0 , iarg=1 , do_mean=0 , do_comments=1 ;
   char *comments=NULL ; /* 04 Aug 2016 */

   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf("Usage: 1dsum [options] a.1D b.1D ...\n"
            "where each file a.1D, b.1D, etc. is an ASCII file of numbers arranged\n"
            "in rows and columns. The sum of each column is written to stdout.\n"
            "\n"
            "Options:\n"
            "  -ignore nn = skip the first nn rows of each file\n"
            "  -use    mm = use only mm rows from each file\n"
            "  -mean      = compute the average instead of the sum\n"
            "  -nocomment = the # comments from the header of the first\n"
            "               input file will be reproduced to the output;\n"
            "               if you do NOT want this to happen, use the\n"
            "               '-nocomment' option.\n"
           ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   machdep() ;

   /* parse options */

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

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

      if( strncmp(argv[iarg],"-ignore",4) == 0 ){
         nn_ignore = (int) strtod(argv[++iarg],NULL) ;
         if( nn_ignore < 0 ){fprintf(stderr,"** Illegal -ignore value!\n");exit(1);}
         iarg++ ; continue ;
      }

      if( strncmp(argv[iarg],"-use",4) == 0 ){
         mm_use = (int) strtod(argv[++iarg],NULL) ;
         if( mm_use < 0 ){fprintf(stderr,"** Illegal -use value!\n");exit(1);}
         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-mean") == 0 ){  /* 17 Dec 2015 */
        do_mean = 1 ; iarg++ ; continue ;
      }

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

   /* read input files */

   nim = argc-iarg ;
   inim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * nim ) ;
   ncol = 0 ;
   for( jj=0 ; jj < nim ; jj++ ){
      inim[jj] = mri_read_1D( argv[jj+iarg] ) ;
      if( inim[jj] == NULL ){
         fprintf(stderr,"** Can't read input file %s\n",argv[jj+iarg]) ;
         exit(1) ;
      }
      if( do_comments && comments == NULL && inim[jj]->comments != NULL )  /* 04 Aug 2016 */
        comments = strdup(inim[jj]->comments) ;

      if( jj > 0 && inim[jj]->nx != inim[0]->nx ){
         fprintf(stderr,
                 "** Input file %s doesn't match first file %s in length!\n",
                 argv[jj+iarg],argv[iarg]) ;
         exit(1) ;
      }
      ncol += inim[jj]->ny ;
   }

   if( mm_use == 0 ){
      mm_use = inim[0]->nx - nn_ignore ;
      if( mm_use < 0 ){fprintf(stderr,"** -ignore is too big for these files!\n");exit(1);}
   }
   if( nn_ignore + mm_use > inim[0]->nx ){
      fprintf(stderr,"** -ignore + -use is too big for these files!\n");exit(1);
   }

   csum = (float *) malloc(sizeof(float)*ncol) ;
   for( ic=0 ; ic < ncol ; ic++ ) csum[ic] = 0.0 ;

   nx = inim[0]->nx ;
   for( nii=0,ii=nn_ignore ; ii < nn_ignore+mm_use ; ii++,nii++ ){
      for( ic=jj=0 ; jj < nim ; jj++ ){
         far = MRI_FLOAT_PTR(inim[jj]) ;
         for( kk=0 ; kk < inim[jj]->ny ; kk++ ) csum[ic++] += far[ii+kk*nx] ;
      }
   }

   if( do_mean ){
     for( ic=0 ; ic < ncol ; ic++ ) csum[ic] /= nii ;
   }

   if( comments != NULL ) printf("%s",comments) ;  /* 04 Aug 2016 */

   for( ic=0 ; ic < ncol ; ic++ ) printf("%g ",csum[ic]) ;
   printf("\n");
   exit(0) ;
}
Exemplo n.º 28
0
int main( int argc , char * argv[] )
{
   int do_norm=0 , qdet=2 , have_freq=0 , do_automask=0 ;
   float dt=0.0f , fbot=0.0f,ftop=999999.9f , blur=0.0f ;
   MRI_IMARR *ortar=NULL ; MRI_IMAGE *ortim=NULL ;
   THD_3dim_dataset **ortset=NULL ; int nortset=0 ;
   THD_3dim_dataset *inset=NULL , *outset ;
   char *prefix="bandpass" ;
   byte *mask=NULL ;
   int mask_nx=0,mask_ny=0,mask_nz=0,nmask , verb=1 , 
       nx,ny,nz,nvox , nfft=0 , kk ;
   float **vec , **ort=NULL ; int nort=0 , vv , nopt , ntime  ;
   MRI_vectim *mrv ;
   float pvrad=0.0f ; int nosat=0 ;
   int do_despike=0 ;

   /*-- help? --*/

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

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

   /*-- startup --*/

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

   nosat =  AFNI_yesenv("AFNI_SKIP_SATCHECK") ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   /** check inputs for reasonablositiness **/

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

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

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

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

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

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

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

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

   /* check mask, or create it */

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

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

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

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

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

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

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

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

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

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

   /* similarly for the ort vectors */

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

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

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

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

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

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

   /* all the real work now */

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

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

   /* OK, maybe a little more work */

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

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

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

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

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

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

   exit(0) ;
}
Exemplo n.º 29
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfToSurf"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_SurfaceObject *SO1=NULL, *SO2 = NULL;
   SUMA_SurfSpecFile *Spec = NULL;
   SUMA_M2M_STRUCT *M2M = NULL;
   int N_Spec=0, *nodeind = NULL, N_nodeind, icol, i, j;
   MRI_IMAGE *im = NULL, *im_data=NULL;
	int nvec=0, ncol=0, nvec_data=0, ncol_data=0, Nchar=0;
   float *far = NULL, *far_data=NULL, *dt = NULL, *projdir=NULL;
   char *outname = NULL, *s=NULL, sbuf[100];
   void *SO_name = NULL;   
   FILE *outptr=NULL;
   SUMA_Boolean exists = NOPE;
   SUMA_INDEXING_ORDER d_order = SUMA_NO_ORDER;
   SUMA_STRING *SS=NULL;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;

   /* Allocate space for DO structure */
	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;-o;");
   
   Opt = SUMA_SurfToSurf_ParseInput (argv, argc, ps);
   if (argc < 2) {
      SUMA_S_Err("Too few options");
      usage_SurfToSurf(ps, 0);
      exit (1);
   }
   

   /* if output surface requested, check on pre-existing file */
   if (ps->o_N_surfnames) {
      SO_name = SUMA_Prefix2SurfaceName(ps->o_surfnames[0], 
                                        NULL, NULL, ps->o_FT[0], &exists);
      if (exists) {
         fprintf(SUMA_STDERR,
                  "Error %s:\nOutput file(s) %s* on disk.\n"
                  "Will not overwrite.\n", FuncName, ps->o_surfnames[0]);
         exit(1);
      }
   } 
   
   if (Opt->debug > 2) LocalHead = YUP;
   outname = SUMA_append_extension(Opt->out_prefix,".1D");
   if (SUMA_filexists(outname) && !THD_ok_overwrite()) {
      fprintf(SUMA_STDERR,"Output file %s exists.\n", outname);
      exit(1);
   }
   
   /* Load the surfaces from command line*/
   Spec = SUMA_IO_args_2_spec(ps, &N_Spec);
   if (N_Spec != 1) {
      SUMA_S_Err( "Multiple spec at input.\n"
                  "Do not mix surface input types together\n");
      exit(1);
   }

      if (Spec->N_Surfs != 2) {
      SUMA_S_Err("2 surfaces expected.");
      exit(1);
   }
   
   SO1 = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0);
   if (!SO1) {
         fprintf (SUMA_STDERR,"Error %s:\n"
                              "Failed to find surface\n"
                              "in spec file. \n",
                              FuncName );
         exit(1);
   }
   if (!SUMA_SurfaceMetrics(SO1, "EdgeList|MemberFace", NULL)) { 
      SUMA_SL_Err("Failed to create edge list for SO1"); 
      exit(1);  
   }
   if (Opt->fix_winding) {
      int orient, trouble;
      if (LocalHead) 
         fprintf(SUMA_STDERR,
                  "%s: Making sure S1 is consistently orientated\n", FuncName);
      if (!SUMA_MakeConsistent (SO1->FaceSetList, SO1->N_FaceSet, 
                                SO1->EL, Opt->debug, &trouble)) {
         SUMA_SL_Err("Failed in SUMA_MakeConsistent");
      }
      if (trouble && LocalHead) {
         fprintf(SUMA_STDERR,
                     "%s: trouble value of %d from SUMA_MakeConsistent.\n"
                     "Inconsistencies were found and corrected unless \n"
                     "stderr output messages from SUMA_MakeConsistent\n"
                     "indicate otherwise.\n", FuncName, trouble);
      }
      if (LocalHead) 
         fprintf(SUMA_STDERR,"%s: Checking orientation.\n", FuncName);
      orient = SUMA_OrientTriangles (SO1->NodeList, SO1->N_Node, 
                                     SO1->FaceSetList, SO1->N_FaceSet, 
                                     1, 0, NULL, NULL);
      if (orient < 0) { 
         /* flipping was done, dump the edge list since it is not 
            automatically updated (should do that in function, 
            just like in SUMA_MakeConsistent,  shame on you) 
            
            If you revisit this section, use the newer:
            SUMA_OrientSOTriangles
         */ 
         if (SO1->EL) SUMA_free_Edge_List(SO1->EL); SO1->EL = NULL; 
         if (!SUMA_SurfaceMetrics(SO1, "EdgeList", NULL)) { 
            SUMA_SL_Err("Failed to create edge list for SO1"); exit(1);  
         }
         /* free normals, new ones needed (Normals should be flipped inside  of 
            SUMA_OrientTriangles! (just like in SUMA_MakeConsistent) ) */
         if (SO1->NodeNormList) SUMA_free(SO1->NodeNormList); 
            SO1->NodeNormList = NULL;
         if (SO1->FaceNormList) SUMA_free(SO1->FaceNormList); 
            SO1->FaceNormList = NULL;
      }
      if (!orient) { 
         fprintf(SUMA_STDERR,
                  "Error %s:\nFailed in SUMA_OrientTriangles\n", FuncName); 
      }
      if (LocalHead) {
         if (orient < 0) { SUMA_SL_Note("S1 was reoriented"); }
         else { SUMA_SL_Note("S1 was properly oriented"); }
      }
   }
  
   
   if (!SO1->NodeNormList || !SO1->FaceNormList) { 
      SUMA_LH("Node Normals"); SUMA_RECOMPUTE_NORMALS(SO1); 
   }
   if (Opt->NodeDbg >= SO1->N_Node) {
      SUMA_SL_Warn(  "node_debug index is larger than number "
                     "of nodes in surface, ignoring -node_debug.");
      Opt->NodeDbg = -1;
   }
      
   SO2 = SUMA_Load_Spec_Surf(Spec, 1, ps->sv[1], 0);
   if (!SO2) {
      fprintf (SUMA_STDERR,"Error %s:\n"
                           "Failed to find surface\n"
                           "in spec file. \n",
                           FuncName );
      exit(1);
   }  
   if (!SUMA_SurfaceMetrics(SO2, "EdgeList|MemberFace", NULL)) { 
      SUMA_SL_Err("Failed to create edge list for SO2"); exit(1);  
   }
   if (!SO2->NodeNormList || !SO2->FaceNormList) { 
      SUMA_LH("Node Normals"); SUMA_RECOMPUTE_NORMALS(SO2); 
   }
   
   if (LocalHead) { 
      SUMA_LH("Surf1");
      SUMA_Print_Surface_Object(SO1, NULL);
      SUMA_LH("Surf2");
      SUMA_Print_Surface_Object(SO2, NULL);
   }
   
   /* a select list of nodes? */
   nodeind = NULL; N_nodeind = 0;
   if (Opt->in_nodeindices) {
      im = mri_read_1D(Opt->in_nodeindices);
      if (!im) { SUMA_SL_Err("Failed to read 1D file of node indices"); exit(1);}
      far = MRI_FLOAT_PTR(im);
      N_nodeind = nvec = im->nx;
      ncol = im->ny;
      if (ncol != 1) { 
         SUMA_SL_Err("More than one column in node index input file."); exit(1);
      }
      nodeind = (int *)SUMA_calloc(nvec, sizeof(int));
      if (!nodeind) { SUMA_SL_Crit("Failed to allocate"); exit(1); }
      for (i=0;i<nvec;++i) { 
         nodeind[i] = (int)far[i]; 
         if (nodeind[i] < 0 || nodeind[i] >= SO1->N_Node) {
            fprintf(SUMA_STDERR, 
                    "Error %s:\n"
                    "A node index of %d was found in input file %s, entry %d.\n"
                    "Acceptable indices are positive and less than %d\n", 
                    FuncName, nodeind[i], Opt->in_nodeindices, i, SO1->N_Node);
            exit(1);
         }
      } 
      mri_free(im); im = NULL;   /* done with that baby */
   }
   
   /* a preset directions vector ?*/
   projdir = NULL; 
   if (Opt->in_1D) {
      im = mri_read_1D(Opt->in_1D);
      if (!im) { 
         SUMA_SL_Err("Failed to read 1D file of projection directions"); exit(1);
      }
      far = MRI_FLOAT_PTR(im);
      if (im->ny != 3) { 
         SUMA_SL_Err("Need three columns in projection directions file."); 
         exit(1); 
      }
      if (im->nx != SO1->N_Node) {
         fprintf(SUMA_STDERR, 
                  "Error %s: You must have a direction for each node in SO1.\n"
                  "%d directions found but SO1 has %d nodes.\n", 
                  FuncName, im->nx, SO1->N_Node);
         exit(1);
      }

      /* change to row major major and make it match nodeind */
      projdir = (float *)SUMA_calloc(SO1->N_Node*3, sizeof(float));
      if (!projdir) { SUMA_SL_Crit("Failed to allocate"); exit(1); }
      for (i=0; i<SO1->N_Node; ++i) {
         projdir[3*i  ] = far[i              ];
         projdir[3*i+1] = far[i+  SO1->N_Node];
         projdir[3*i+2] = far[i+2*SO1->N_Node];
      }
      mri_free(im); im = NULL;   /* done with that baby */

   }
   
   if (SO_name) {
      /* user is interpolating surface coords, check on other input insanity */
      if (nodeind) {
         fprintf( SUMA_STDERR, 
                  "Error %s: You cannot combine "
                  "option -o_TYPE with -node_indices", FuncName);
         exit(1);
      }
      if (Opt->in_name) {
         fprintf(SUMA_STDERR, 
                  "Error %s: You cannot combine option -o_TYPE with -data", 
                  FuncName);
         exit(1);
      }
   } 
   /* a 1D file containing data, or Data parameter (for XYZ)? */
   if (Opt->Data > 0) {
      if (Opt->in_name) {
         /* When you are ready to work with dsets, you should 
         checkout the function morphDsetToStd. It uses M2M */
         im_data = mri_read_1D(Opt->in_name);
         if (!im_data) { 
            SUMA_SL_Err("Failed to read 1D file of data"); exit(1);}
         far_data = MRI_FLOAT_PTR(im_data);
         nvec_data = im_data->nx;
         ncol_data = im_data->ny;
         if (nvec_data != SO2->N_Node) {
            SUMA_SL_Err("Your data file must have one row "
                        "for each node in surface 2.\n"); exit(1);
         }
         d_order = SUMA_COLUMN_MAJOR;
      } else { 
         im_data = NULL;
         far_data = SO2->NodeList;
         nvec_data = SO2->N_Node;
         ncol_data = 3;
         d_order = SUMA_ROW_MAJOR;
      }
   } else {
      /* just -dset */
   }
   
     

   
   if (!Opt->s) {
      SUMA_LH("Going for the mapping of SO1 --> SO2");
      M2M = SUMA_GetM2M_NN( SO1, SO2, nodeind, N_nodeind, 
                            projdir, 0, Opt->NodeDbg, Opt->iopt);
      SUMA_S_Notev("Saving M2M into %s\n\n",
               Opt->out_prefix);
      if (!(SUMA_Save_M2M(Opt->out_prefix, M2M))) {
         SUMA_S_Err("Failed to save M2M");
         exit(1);
      }
   } else {
      SUMA_S_Notev("Reusing mapping of SO1 --> SO2 from %s\n\n", 
               Opt->s);   
      if (!(M2M = SUMA_Load_M2M(Opt->s))) {
         SUMA_S_Errv("Failed to load %s\n", Opt->s);
         exit(1);
      }
   }

   /* Now show the mapping results for a debug node ? */
   if (Opt->NodeDbg >= 0) {
      char *s = NULL;
      s = SUMA_M2M_node_Info(M2M, Opt->NodeDbg);
      fprintf(SUMA_STDERR,"%s: Debug for node %d ([%f, %f, %f])of SO1:\n%s\n\n", 
                           FuncName, Opt->NodeDbg, 
                           SO1->NodeList[3*Opt->NodeDbg], 
                           SO1->NodeList[3*Opt->NodeDbg+1], 
                           SO1->NodeList[3*Opt->NodeDbg+2],
                           s); 
      SUMA_free(s); s = NULL;
   }
   
   /* Now please do the interpolation */
   if (Opt->Data > 0) {
      if (Opt->NearestNode > 1) 
         dt = SUMA_M2M_interpolate( M2M, far_data, ncol_data, 
                                    nvec_data, d_order, 0 );
      else if (Opt->NearestNode == 1) 
         dt = SUMA_M2M_interpolate( M2M, far_data, ncol_data, 
                                    nvec_data, d_order, 1 );
      if (!dt) {
         SUMA_SL_Err("Failed to interpolate");
         exit(1);
      }
   } else if (Opt->Data < 0) {
         SUMA_DSET *dset=NULL, *dseto=NULL;
         char *oname=NULL, *uname=NULL, *s1=NULL, *s2=NULL;
         int iform=SUMA_NO_DSET_FORMAT;
         if (Opt->NodeDbg>= 0) {
            SUMA_S_Notev("Processing dset %s\n", Opt->in_name);
         }
         iform = SUMA_NO_DSET_FORMAT;
         if (!(dset = SUMA_LoadDset_s (Opt->in_name, &iform, 0))) {
            SUMA_S_Errv("Failed to load %s\n", Opt->in_name);
            exit(1);
         }
         if (!(dseto = SUMA_morphDsetToStd ( dset, M2M, 
                                             Opt->NearestNode == 1 ? 1:0))) {
            SUMA_S_Errv("Failed to map %s\n", Opt->in_name);
            exit(1);
         }
         s1 = SUMA_append_string(
                  SUMA_FnameGet(Opt->in_name,"pa", SUMAg_CF->cwd),
                  Opt->out_prefix); 
         s2 = SUMA_RemoveDsetExtension_s(
               SUMA_FnameGet(Opt->in_name,"l",SUMAg_CF->cwd), 
               SUMA_NO_DSET_FORMAT);
         uname = SUMA_append_extension(s1,s2);      
         SUMA_free(s1); SUMA_free(s2);
         oname = SUMA_WriteDset_s (uname, dseto, Opt->oform, 1, 1);
         if (Opt->NodeDbg>= 0) SUMA_S_Notev("Wrote %s\n", oname);
         if (oname) SUMA_free(oname); oname=NULL;
         if (uname) SUMA_free(uname); oname=NULL;
         if (dseto) SUMA_FreeDset(dseto); dseto = NULL;
         if (dset) SUMA_FreeDset(dset); dset = NULL;      
   }
   
   SUMA_LH("Forming the remaining output");
   outptr = fopen(outname,"w");
   if (!outptr) {
      SUMA_SL_Err("Failed to open file for output.\n");
      exit(1);
   }
   
   /* first create the header of the output */
   SS = SUMA_StringAppend(NULL, NULL);
   SS = SUMA_StringAppend_va(SS, 
      "#Mapping from nodes on surf 1 (S1) to nodes on surf 2 (S2)\n"
      "#  Surf 1 is labeled %s, idcode:%s\n"
      "#  Surf 2 is labeled %s, idcode:%s\n",
      SO1->Label, SO1->idcode_str, SO2->Label, SO2->idcode_str);
   icol = 0;
   SS = SUMA_StringAppend_va(SS, "#Col. %d:\n"
                                 "#     S1n (or nj): Index of node on S1\n"
                                 , icol); 
   ++icol;
   if (Opt->NearestNode > 1) {
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d..%d:\n"
         "#     S2ne_S1n: Indices of %d nodes on S2 \n"
         "#     that are closest neighbors of nj.\n"
         "#     The first index is that of the node on S2 that is closest \n"
         "#     to nj. If -1 then these values should be ignored because\n"
         "#     in such cases, nj's projection failed.\n" 
         , icol, icol+Opt->NearestNode-1, Opt->NearestNode); 
      icol += Opt->NearestNode;
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d..%d:\n"
         "#     S2we_S1n: Weights assigned to nodes on surf 2 (S2) \n"
         "#     that are closest neighbors of nj.\n"
         , icol, icol+Opt->NearestNode-1, Opt->NearestNode); 
      icol += Opt->NearestNode;
   } else if (Opt->NearestNode == 1) {
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d:\n"
         "#     S2ne_S1n: Index of the node on S2 (label:%s idcode:%s)\n"
         "#     that is the closest neighbor of nj.\n"
         "#     If -1 then this value should be ignored because\n"
         "#     nj's projection failed.\n" 
         , icol, SO2->Label, SO2->idcode_str); 
      ++icol;
   }
   if (Opt->NearestTriangle) { 
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d:\n"
         "#     S2t_S1n: Index of the S2 triangle that hosts node nj on S1.\n"
         "#     In other words, nj's closest projection onto S2 falls on \n"
         "#     triangle S2t_S1n\n"
         "#     If -1 then this value should be ignored because \n"
         "#     nj's projection failed.\n" 
         , icol); 
      ++icol; 
   }
   if (Opt->ProjectionOnMesh) { 
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d..%d:\n"
         "#     S2p_S1n: Coordinates of projection of nj onto S2\n"
         , icol, icol+2); 
      icol += 3; 
   }
   if (Opt->DistanceToMesh) {
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d:\n"
         "#     Closest distance from nj to S2\n"
         , icol); 
         ++icol;
   }
   if (Opt->NearestNodeCoords) {
      SS = SUMA_StringAppend_va(SS, 
         "#Col. %d .. %d:\n"
         "#     X Y Z coords of nearest node\n"
         , icol,  icol+2); 
      icol += 3; 
   }
   if (Opt->Data > 0) {
      if (!Opt->in_name) {
         SS = SUMA_StringAppend_va(SS, 
      "#Col. %d..%d:\n"
      "#     Interpolation using XYZ coordinates of S2 nodes that neighbor nj\n"
      "#     (same as coordinates of node's projection onto triangle in S2, \n"
      "#     if using barycentric interpolation)\n"
         , icol, icol+2); 
      icol += 3; 
} else {
SS = SUMA_StringAppend_va(SS, 
         "#Col. %d..%d:\n"
         "#     Interpolation of data at nodes on S2 that neighbor nj\n"
         "#     Data obtained from %s\n"
         , icol, icol+ncol_data-1, Opt->in_name);  icol += ncol_data;
      }
   } 
   s = SUMA_HistString("SurfToSurf", argc, argv, NULL);
   SS = SUMA_StringAppend_va(SS, 
                                "#History:\n"
                                "#%s\n", s); SUMA_free(s); s = NULL;
   SUMA_SS2S(SS,s);
   fprintf(outptr,"%s\n",s); SUMA_free(s); s = NULL;
   
   /* put headers atop columns */
   Nchar = 6; /* if you change this number you'll need to fix  formats below */
   for (i=0; i<icol; ++i) { 
      sprintf(sbuf,"#%s", MV_format_fval2(i, Nchar -1)); 
      fprintf(outptr,"%6s   ", sbuf); 
   }
   fprintf(outptr,"\n");
   
   /* Now put in the values, make sure you parallel columns above! */
   for (i=0; i<M2M->M1Nn; ++i) {
      fprintf(outptr,"%6s   ", MV_format_fval2(M2M->M1n[i], Nchar));
      if (Opt->NearestNode > 0) {
         for (j=0; j<Opt->NearestNode; ++j) { 
            if (j < M2M->M2Nne_M1n[i]) 
               fprintf(outptr,"%6s   ", 
                  MV_format_fval2(M2M->M2ne_M1n[i][j], Nchar)); 
            else fprintf(outptr,"%6s   ", "-1"); 
         } /* Neighboring nodes */
      } 
      if (Opt->NearestNode > 1) { /* add the weights */
         for (j=0; j<Opt->NearestNode; ++j) { 
            if (j < M2M->M2Nne_M1n[i]) 
               fprintf(outptr,"%6s   ", 
                  MV_format_fval2(M2M->M2we_M1n[i][j], Nchar)); 
            else fprintf(outptr,"%6s   ", "0.0"); 
         } 
      }
      if (Opt->NearestTriangle) {
         fprintf(outptr,"%6s   ", MV_format_fval2(M2M->M2t_M1n[i], Nchar)); 
      }
      if (Opt->ProjectionOnMesh) {
         fprintf(outptr,"%6s   ", MV_format_fval2(M2M->M2p_M1n[3*i], Nchar));
         fprintf(outptr,"%6s   ", MV_format_fval2(M2M->M2p_M1n[3*i+1], Nchar));
         fprintf(outptr,"%6s   ", MV_format_fval2(M2M->M2p_M1n[3*i+2], Nchar)); 
      }
      if (Opt->DistanceToMesh) { 
         fprintf(outptr,"%6s   ", MV_format_fval2(M2M->PD[i], Nchar)); 
      }
      if (Opt->NearestNodeCoords) {
         float x=0.0,y=0.0,z=0.0;
         int n = M2M->M2ne_M1n[i][0];
         if (n>0) {
            n = n * SO2->NodeDim;
            x = SO2->NodeList[n];
            y = SO2->NodeList[n+1];
            z = SO2->NodeList[n+2];
         }
         fprintf(outptr,"%6s   ", MV_format_fval2(x, Nchar)); 
         fprintf(outptr,"%6s   ", MV_format_fval2(y, Nchar)); 
         fprintf(outptr,"%6s   ", MV_format_fval2(z, Nchar)); 
      }
      if (dt && Opt->Data > 0) {
         if (!Opt->in_name) {
            fprintf(outptr,"%6s   ", MV_format_fval2(dt[3*i], Nchar));
            fprintf(outptr,"%6s   ", MV_format_fval2(dt[3*i+1], Nchar));
            fprintf(outptr,"%6s   ", MV_format_fval2(dt[3*i+2], Nchar));
         } else { /* Column major business */
            for (j=0; j<ncol_data; ++j) { 
               fprintf(outptr,"%6s   ", 
                     MV_format_fval2(dt[i+j*M2M->M1Nn], Nchar)); }
         }
      }
      fprintf(outptr,"\n");
   }
   
   /* do they want an output surface ? */
   if (SO_name) {
      float *tmpfv = NULL;
      SUMA_LH("Writing surface");
      tmpfv = SO1->NodeList;
      SO1->NodeList = dt;
      if (!SUMA_Save_Surface_Object (SO_name, SO1, 
                                     ps->o_FT[0], ps->o_FF[0], NULL)) {
         SUMA_S_Err("Failed to write surface object.\n");
         exit (1);
      }
      SO1->NodeList = tmpfv; tmpfv = NULL;
   }
   
   if (N_Spec) {
      int k=0; 
      for (k=0; k<N_Spec; ++k) {
         if (!SUMA_FreeSpecFields(&(Spec[k]))) {
            SUMA_S_Err("Failed to free spec fields");
         } 
      }
      SUMA_free(Spec); Spec = NULL; N_Spec = 0;
   }

   if (projdir) SUMA_free(projdir); projdir = NULL;
   if (SO_name) SUMA_free(SO_name); SO_name = NULL;   
   if (outptr) fclose(outptr); outptr = NULL;
   if (dt) SUMA_free(dt); dt = NULL;
   if (s) SUMA_free(s); s = NULL;
   if (im_data) mri_free(im_data); im_data = NULL;   /* done with the data */
   if (nodeind) SUMA_free(nodeind); nodeind = NULL;
   if (M2M) M2M = SUMA_FreeM2M(M2M);
   if (SO1) SUMA_Free_Surface_Object(SO1); SO1 = NULL;
   if (SO2) SUMA_Free_Surface_Object(SO2); SO2 = NULL;
   if (Spec) SUMA_free(Spec); Spec = NULL;
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
   exit(0);
   
} 
Exemplo n.º 30
0
int main( int argc , char * argv[] )
{
   int nim , ii , jj , kk , nx, narg, oform ;
   MRI_IMAGE **inim ;
   float *far;
   char *formatstr=NULL, *sel=NULL, *fname=NULL;
   int nonconst=0 , ncol,ncold , cc , nonfixed=0 , stack=0;
   intvec *ncv=NULL ;
   char *hline=NULL ;

   mainENTRY("1dcat:main");
   
   /*-- help? --*/

   if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
     printf(
"Usage: 1dcat [options] a.1D b.1D ...\n"
"  where each file a.1D, b.1D, etc. is a 1D file.\n"
"  In the simplest form, a 1D file is an ASCII file of numbers\n"
"  arranged in rows and columns.\n"
"\n"
"1dcat takes as input one or more 1D files, and writes out a 1D file\n"
"containing the side-by-side concatenation of all or a subset of the\n"
"columns from the input files.\n"
"\n"
"* Output goes to stdout (the screen); redirect (e.g., '>') to save elsewhere.\n"
"* All files MUST have the same number of rows!\n"
"* Any header lines (i.e., lines that start with '#') will be lost.\n"
"* For generic 1D file usage help and information, see '1dplot -help'\n"
"\n"
"OPTIONS:\n"
"--------\n"
"  -nonconst: Columns that are identically constant should be omitted\n"
"             from the output.\n"
"\n"
"  -nonfixed: Keep only columns that are marked as 'free' in the \n"
"             3dAllineate header from '-1Dparam_save'.\n"
"             If there is no such header, all columns are kept.\n"
"\n"
"  -form FORM: Format of the numbers to be output.\n"
"              You can also substitute -form FORM with shortcuts such \n"
"              as -i, -f, or -c.\n"
"              For help on -form's usage, and its shortcut versions\n"
"              see ccalc's help for the option of the same name. \n"
"\n"
"  -stack: Stack the columns of the resultant matrix in the output.\n"
"\n"
"  -sel SEL: Apply the same column/row selection string to all filenames\n"
"            on the command line.\n"
"            For example:\n"
"              1dcat -sel '[0,2]' f1.1D f2.1D\n"
"            is the same as: 1dcat f1.1D'[1,2]' f2.1D'[1,2]'\n"
"            The advantage of the option is that it allows wildcard use\n"
"            in file specification so that you can run something like:\n"
"              1dcat -sel '[0,2]' f?.1D\n"
"\n"
"EXAMPLE:\n"
"--------\n"
"  Input file 1:\n   1\n   2\n   3\n   4\n"
"  Input file 2:\n   5\n   6\n   7\n   8\n"
"\n"
"  1dcat data1.1D data2.1D > catout.1D\n" 
"  Output file: \n   1 5\n   2 6\n   3 7\n   4 8\n"
"\n"
           ) ;
      PRINT_COMPILE_DATE ; exit(0) ;
   }

   machdep() ;

   /* do we have any options? */
   oform = CCALC_NOT_SET; 
   sel = NULL;
   stack = 0;
   narg = 1;
   while (narg < argc && argv[narg][0] == '-') {

      if( strncmp(argv[narg],"-nonconst",7) == 0 ){  /* 04 Dec 2010 */
        nonconst++ ; narg++ ; continue ;
      }

      if( strncmp(argv[narg],"-nonfixed",7) == 0 ){  /* 06 Dec 2010 */
        nonfixed++ ; narg++ ; continue ;
      }
      
      if( strncmp(argv[narg],"-stack",6) == 0 ){  /* 05 Sep 2013 */
        stack = 1 ; narg++ ; continue ;
      }
      
      if (strcmp(argv[narg],"-form") == 0) {
         ++narg;
         if (narg >= argc)  {
	         fprintf (stderr, "need argument after -form ");
	         exit (1);
         }
         if (strcmp(argv[narg],"double") == 0 ) oform = CCALC_DOUBLE;
         else if (strcmp(argv[narg],"nice") == 0 ) oform = CCALC_NICE;
         else if (strcmp(argv[narg],"int") == 0 ) oform = CCALC_INT;
         else if (strcmp(argv[narg],"rint") == 0 ) oform = CCALC_INT;
         else if (strcmp(argv[narg],"fint") == 0 ) oform = CCALC_FINT;
         else if (strcmp(argv[narg],"cint") == 0 ) oform = CCALC_CINT;
         else if (strlen(argv[narg])<=256) {
            oform = CCALC_CUSTOM;
            formatstr = argv[narg];
         }
         else {
            fprintf (stderr,  "Format type '%s' not supported.\n"
                              "See -help for details.\n", argv[narg]);
            exit (1);
         }
         ++narg;
      } else if (strcmp(argv[narg],"-sel") == 0) {
         ++narg;
         if (narg >= argc)  {
	         fprintf (stderr, "need argument after -sel ");
	         exit (1);
         }
         sel = argv[narg]; ++narg;
      } else if (strncmp(argv[narg],"-d",2) == 0) {
         oform = CCALC_DOUBLE; ++narg;
      } else if (strncmp(argv[narg],"-n",2) == 0) {
         oform = CCALC_NICE; ++narg;
      } else if (strncmp(argv[narg],"-i",2) == 0) {
         oform = CCALC_INT; ++narg;
      } else if (strncmp(argv[narg],"-r",2) == 0) {
         oform = CCALC_INT; ++narg;
      } else if (strncmp(argv[narg],"-f",2) == 0) {
         oform = CCALC_FINT; ++narg;
      } else if (strncmp(argv[narg],"-c",2) == 0) {
         oform = CCALC_CINT; ++narg;
      } else { /* break if option is not recognized */
         ++narg;
         break; 
      }
   }
   
   /* read input files */

   nim = argc-narg ;
   inim = (MRI_IMAGE **) malloc( sizeof(MRI_IMAGE *) * nim ) ;
   ncol = 0 ;
   if( nonconst || nonfixed ) MAKE_intvec(ncv,1) ;
   for( jj=0 ; jj < nim ; jj++ ){

#if 0                                   /** for testing only **/
      if( AFNI_yesenv("ragged") ){
        MRI_IMAGE *qim ;
        qim      = mri_read_ascii_ragged( argv[jj+narg] , 3.e+33 ) ;
        fprintf(stderr,"qim: nx=%d ny=%d\n",qim->nx,qim->ny) ;
        inim[jj] = mri_transpose(qim) ; mri_free(qim) ;
      } else
#endif

      if (sel) {
         fname = (char *)
                  calloc((strlen(argv[jj+narg])+strlen(sel)+1), sizeof(char));
         strcat(fname, argv[jj+narg]); strcat(fname, sel);
      } else {
         fname = argv[jj+narg];  
      }
      inim[jj] = mri_read_1D( fname ) ;
      if( inim[jj] == NULL )
        ERROR_exit("Can't read input file '%s'",fname) ;
      if( jj > 0 && inim[jj]->nx != inim[0]->nx )
        ERROR_exit("Input file %s doesn't match first file %s in length!",
                   fname,argv[1]) ;

      ncold = ncol ; ncol += inim[jj]->ny ;
      if( ncv != NULL ){     /* check for constant columns [04 Dec 2010] */
        RESIZE_intvec(ncv,ncol) ;
        for( kk=0 ; kk < inim[jj]->ny ; kk++ ) ncv->ar[ncold+kk] = 1 ;
        far = MRI_FLOAT_PTR(inim[jj]) ; nx = inim[jj]->nx ;
        if( nonconst ){
          for( kk=0 ; kk < inim[jj]->ny ; kk++ ){ /* loop over columns */
            for( ii=1 ; ii < nx ; ii++ ){         /* loop down column */
              if( far[ii+kk*nx] != far[kk*nx] ) break ;
            }
            if( ii == nx ) ncv->ar[ncold+kk] = 0 ; /* constant */
          }
        }
        if( nonfixed ){
          char *hl = mri_read_1D_headerlines( fname ) ;
          if( hl != NULL && *hl == '#' ){
            char *spt = strchr(hl,'\n') ;
            if( spt != NULL ) spt = strchr(spt,'#') ; /* start of line 2 */
            if( spt != NULL ){
              NI_str_array *sar = NI_decode_string_list( spt+1 , "~" ) ;
              if( sar != NULL && sar->num >= inim[jj]->ny ){
                for( kk=0 ; kk < inim[jj]->ny ; kk++ ){
                  spt = strchr(sar->str[kk],'$') ;
                  if( spt != NULL && spt[1] == '\0' ) ncv->ar[ncold+kk] = 0 ;
                  else {
                    if( hline == NULL ) hline = strdup("#") ;
                    hline = THD_zzprintf( hline , " %s" , sar->str[kk] ) ;
                  }
                }
              }
              NI_delete_str_array(sar) ;
            }
          }
        }
      } /* end of computing ncv = array marking non-constant vectors */
      if (sel) {
         free(fname); fname = NULL;
      }
   } /* end of input loop */

   /* now do the output */

   if( hline != NULL ) printf("%s\n",hline) ;

   nx = inim[0]->nx ;

   if (stack) {
      if (oform == CCALC_NOT_SET) {
         for( cc=jj=0 ; jj < nim ; jj++ ){
            far = MRI_FLOAT_PTR(inim[jj]) ;
            for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
               for( ii=0 ; ii < nx ; ii++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %g\n", far[ii+kk*nx] ) ; 
               }
            }
         }
      } else {
         for( cc=jj=0 ; jj < nim ; jj++ ){
            far = MRI_FLOAT_PTR(inim[jj]) ;
            for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
               for( ii=0 ; ii < nx ; ii++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %s\n", 
                        format_value_4print(far[ii+kk*nx], oform, formatstr )); 
               }
            }
         }
      }
   } else {
      if (oform == CCALC_NOT_SET) {
         for( ii=0 ; ii < nx ; ii++ ){
            for( cc=jj=0 ; jj < nim ; jj++ ){
               far = MRI_FLOAT_PTR(inim[jj]) ;
               for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %g", far[ii+kk*nx] ) ; 
                 /* printf(" %+.2f", far[ii+kk*nx] ) ;*/
               }
            }
            printf("\n") ;
         }
      } else {
         for( ii=0 ; ii < nx ; ii++ ){
            for( cc=jj=0 ; jj < nim ; jj++ ){
               far = MRI_FLOAT_PTR(inim[jj]) ;
               for( kk=0 ; kk < inim[jj]->ny ; kk++,cc++ ){
                  if( ncv == NULL || ncv->ar[cc] )
                    printf(" %s", 
                        format_value_4print(far[ii+kk*nx], oform, formatstr )); 
               }
            }
            printf("\n") ;
         }
      }
   }
   exit(0) ;
}