Пример #1
0
int GenFeatureDist(SEG_OPTS *Opt) 
{
   
   ENTRY("GenFeatureDist");
   
   
   /* get the probability maps */
   if (!Opt->pset && Opt->DO_p) {
      if (!(Opt->pset = p_C_GIV_A(Opt))) {
         ERROR_message("Failed miserably");
         RETURN(0);
      }
   }
      
   /* Get the classes */
   if (!Opt->cset && Opt->crefix && Opt->DO_c) {
      if (!(SUMA_assign_classes_eng(Opt->pset, 
                           Opt->clss->str, Opt->clss->num, Opt->keys, 
                           Opt->cmask, &Opt->cset))) {
         ERROR_message("Failed aimlessly");
         RETURN(0);
      }
      EDIT_dset_items(Opt->cset, ADN_prefix, Opt->crefix, ADN_none);
      if( !THD_ok_overwrite() && THD_is_file( DSET_HEADNAME(Opt->cset) ) ){
      ERROR_exit("Output file %s already exists -- cannot continue!\n",
                  DSET_HEADNAME(Opt->cset) ) ;
      }
   }  
   
   /* group classes ? */
   if (Opt->group_classes) {
      THD_3dim_dataset *gcset=NULL;
      THD_3dim_dataset *gpset=NULL;
      if (!SUMA_Regroup_classes (Opt, 
                     Opt->clss->str, Opt->clss->num, Opt->keys,
                     Opt->group_classes->str,
                     Opt->group_classes->num,
                     Opt->group_keys, Opt->cmask,
                     Opt->pset, 
                     Opt->cset,
                     &gpset, 
                     &gcset) ) {
         ERROR_message("Failed to regroup");
         RETURN(0);
      }
      DSET_write(gpset);
      DSET_write(gcset);
   }
          
   RETURN(1);
}
Пример #2
0
static FILE * fopen_maybe( char *fname )  /* 05 Feb 2008 */
{
   FILE *imfile ;
   char *tname = NULL;
   int   tlen;

   if( fname == NULL || *fname == '\0' ) return NULL ;  /* bad input */

   /* special case -- be sure not to fclose() stdout! */

   /* ------------------------------------------------------------- */
   /* test file streams with tname, where any .1D has been stripped */
   /* note: the .1D suffix might come from EDIT_dset_items()        */
   /* problem noted by I Schwabacher            13 Nov 2012 [rickr] */
   tlen = strlen(fname);
   if( tlen > 3 && !strcmp(fname+tlen-3, ".1D") ) {
      tname = strdup(fname);
      tname[tlen-3] = '\0';
   } else tname = fname;

   if( strcmp(tname,"-") == 0 || strcmp(tname,"stdout")  == 0
                              || strcmp(tname,"stdout:") == 0 ) return stdout ;

   if( strcmp(tname,"stderr" ) == 0 ||
       strcmp(tname,"stderr:") == 0  ) return stderr ;

   if( tname != fname ) free(tname);             /* done with tname */
   /* ------------------------------------------------------------- */

   if( THD_is_ondisk(fname) ){   /* check for existing file */
     if( !THD_ok_overwrite() ){  /* if not allowed to overwrite */
       ERROR_message("(FAILED) attempt to over-write file %s",fname) ;
       return NULL ;
     } else {
       WARNING_message("over-writing file %s",fname) ;  /* tell the user */
     }
   }

   imfile = fopen(fname,"w") ;
   if( imfile == NULL ) ERROR_message("Can't open for output: %s",fname) ;
   return imfile ;
}
Пример #3
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SpharmReco"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_SurfSpecFile *Spec = NULL;
   int *isin=NULL;
   int   i = -1, ii, jj, kk, il, N_Spec=0, i3, OK, 
         l, lc, ncol=0, nrow=0, dims[20], N_dims=0, N_surfs=0, j, j_l;
   SUMA_Boolean exists=NOPE;
   float *far=NULL, *xbuf=NULL, *ybuf=NULL, *zbuf=NULL;
   double  *dv=NULL, fac = 0.0;
   complex *cv=NULL;
   SUMA_FORM_AFNI_DSET_STRUCT *OptDs = NULL;
   SUMA_SurfaceObject *SO = NULL, *SOt=NULL;
   SUMA_VOLPAR *vp = NULL;
   SUMA_MX_VEC *y_l=NULL, *y_l_t=NULL;
   SUMA_MX_VEC *betal=NULL;
   SUMA_MX_VEC *xe=NULL, *sm=NULL, *yc=NULL;
   SUMA_MX_VEC **axe=NULL, **abeta=NULL;
   char *oname=NULL, stmp[100], *pref=NULL;
   SUMA_SO_File_Format form=SUMA_FF_NOT_SPECIFIED;
   SUMA_SO_File_Type tp=SUMA_FT_NOT_SPECIFIED;
   SUMA_OPT_SPHERICAL_BASES optb;
   void *SO_name=NULL;
   struct  timeval tt; 
   int oform= SUMA_NO_DSET_FORMAT;
   char *ooo=NULL;
   float *fbuf=NULL;
   SUMA_DSET *out_dset = NULL;
   SUMA_Boolean do_surf_xyz = NOPE;
   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;-spec;-talk;-o;");
 
   if (argc < 2) {
      usage_SpharmReco(ps);
      exit (1);
   }
   
   Opt = SUMA_SpharmReco_ParseInput (argv, argc, ps);
   
   if (Opt->debug) LocalHead = YUP;
   if (Opt->n_in_namev < 1) {
      SUMA_S_Err("No Coef!");
      exit (1);
   }
   if (ps->o_N_surfnames) do_surf_xyz = YUP;
   
   if (!ps->o_N_surfnames && !Opt->out_prefix) {
      SUMA_S_Notev("Using default prefix of %s\n", "spharm_sm");
      Opt->out_prefix = SUMA_copy_string("spharm_sm");
   }

   if ((Opt->n_in_namev % 3) && do_surf_xyz) {
      SUMA_S_Errv("Number of coefficient options (%d) must be\n"
                  "a multiple of three if output is \n"
                  "to be treated as x, y, z coordinates\n", Opt->n_in_namev);
      exit(1);            
   }
   /* decide on output form */
   if (Opt->out_prefix) {
      oform = SUMA_GuessFormatFromExtension(Opt->out_prefix,"something.1D.dset");
   }
   if (Opt->debug > 2) LocalHead = YUP;
   
   /* check on inputs */
   optb.SOu=NULL;
   optb.BasesFileRoot=Opt->bases_prefix;
   optb.SaveBases=Opt->bases_prefix;
   optb.debug = Opt->debug;
   
   N_surfs = ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames;
   if (( N_surfs != 1)) {
      SUMA_S_Errv("You must provide only one surface.\n"
                  "Have %d on command line.\n", N_surfs);
      exit(1);
   } 
   
   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("Multiple spec at input.");
      exit(1);
   }

   for (i=0; i<N_surfs; ++i) {
      SO = SUMA_Load_Spec_Surf(Spec, i, ps->sv[i], 0);
      if (!SO) {
            fprintf (SUMA_STDERR,"Error %s:\n"
                                 "Failed to find surface\n"
                                 "in spec file. \n",
                                 FuncName );
            exit(1);

      }   
      if (Opt->debug > 2) SUMA_Print_Surface_Object(SO, SUMA_STDERR); 
      if (!SO->normdir) SO->normdir = 1;  /* set it to something */
      SOt = SUMA_CreateChildSO( SO, NULL, -1, NULL, -1, 0);
      if (!SOt->State) {SOt->State = SUMA_copy_string("spharm_domain"); }
      if (!SOt->Group) {SOt->Group = SUMA_copy_string("spharm_domain"); }
   }
   
   /* see if SUMA talk is turned on */
   if (ps->cs->talk_suma) {
      ps->cs->istream = SUMA_GEOMCOMP_LINE;
      if (!SUMA_SendToSuma (SO, ps->cs, NULL, SUMA_NO_DSET_TYPE, 0)) {
         SUMA_SL_Err("Failed to initialize SUMA_SendToSuma");
         ps->cs->Send = NOPE;
         ps->cs->talk_suma = NOPE;
      }
      SUMA_SendSumaNewSurface(SO, ps->cs);
   }
   
   /* Number of coefficients */
   axe   = (SUMA_MX_VEC **)SUMA_calloc(Opt->n_in_namev, sizeof(SUMA_MX_VEC*));
   abeta = (SUMA_MX_VEC **)SUMA_calloc(Opt->n_in_namev, sizeof(SUMA_MX_VEC*));
   
   /* initialize output variables  */
   for (i=0; i<Opt->n_in_namev; ++i) {
      dims[0] = SO->N_Node; dims[1] = 1;  N_dims = 2;
      axe[i]   = SUMA_NewMxVec(SUMA_double, 2, dims, 1);
      if (Opt->debug > 1)  SUMA_ShowMxVec(axe[i], 1, NULL, "\naxe[i]\n");
      N_dims = -1;            /* take whatever is in file, otherwise, 
                                 should setup dims[0] and dims[1]    */
      abeta[i] = SUMA_Read1DMxVec(SUMA_double, Opt->in_namev[i], dims, &N_dims);
      if (Opt->debug > 1)  SUMA_ShowMxVec(abeta[i], 1, NULL, "\nabeta[i]\n");
   }

   SUMA_Spherical_Bases(&l, NULL);  /* init SUMA_Spherical_Bases */
  
   /* start timer*/
   SUMA_etime2(FuncName, NULL, NULL);
   
   /* A record of matrices and processes to follow for spharm reconstruction
      Here y_l, for each l, and beta are loaded from files created by SpharmDeco  
      N_Node   : Number of points in parametrization of sphere
      sigma    : the smoothing kernel 0 == No smoothing, 0.01 
               (quite a bit of smoothing).
                 the higher the sigma the more the attenuation of higher 
                 degree harmonics. 
      for l = 0;
         y_l      : l th degree harmonic             complex l+1      x  N_Node
                    turned to real since 
                    imaginary is all 0
         y_l_t    : y_l'                              double  N_Node   x  l+1
         XX vt       : y_l * y_l_t                    double  l+1      x  l+1
         XX vt2      : inv(vt)                        double  l+1      x  l+1  
         XX Ycommon  : vt2 * y_l                      double  l+1      x  N_Node
         XX betal    : Ycommon * x                    double  l+1      x  1
         betal    : filled from beta(l,0:2l)          double  l+1      x  1
                    (beta(0,0), really)  
         xe       : y_l_t * betal                     double  N_Node   x  1
      
      for l > 0;
         y_l      : l th degree harmonic              complex l+1      x  N_Node
                    turned to real of dimensions:     double  2*l+1    x  N_Node
                    where the imaginary part of y_l 
                    is appended below the real part
         y_l_t    : y_l'                               double  N_Node   x  2*l+1
         XX vt       : y_l * y_l_t                     double  2*l+1    x  2*l+1
         XX vt2      : inv(vt)                         double  2*l+1    x  2*l+1
         XX Ycommon  : vt2 * y_l                       double  2*l+1    x  N_Node
         XX dif_vec_x: x - xe                          double  N_Node   x  1
         betal    : filled from beta(l,0:2l)           double  2*l+1    x  1
         sm       : y_l_t * betal                      double  N_Node   x  1
         fac      : exp((-l*(l+1))*sigma)              double  1        x  1          
         xe       : xe + fac * sm                      double  N_Node   x  1
                    xe is the estimate of x up to order l harmonics
      
      beta     : lower triangular matrix where betal   double  l+1      x 2l+1
                 are  stored for all l degrees
   */
   l=0;
   do {
      
      lc = l;
      y_l = SUMA_Spherical_Bases(&lc, &optb);   
         /*  y_l is equal to Y' in Moo's SPHARsmooth.m function   */
      if (lc < l) {                             
         /*  The function will read in the bases from disk        */
         Opt->iopt = lc;   /*  y_l is a (l+1 x N_Node) complex matrix.    */
         SUMA_S_Notev("Cannot go for order higher than %d\n.", lc);
         goto NEXT_L;
      }
      
      do {
         if (SO) {
            if ((LocalHead && l == 0) || Opt->debug > 1) 
               SUMA_S_Notev("Using the mesh from %s for \n"
                            "a reconstruction of degree %d.\n", SO->Label, l);
            if (Opt->debug > 2) SUMA_Print_Surface_Object (SO, SUMA_STDERR);
         } else {
            SUMA_S_Err("NULL SO!!!");
            exit(1);
         }
         if (LocalHead || Opt->debug > 1)  {
                  fprintf(SUMA_STDERR,"%s: Doing l = %d\n", FuncName, l);
                  SUMA_etime2(FuncName, "Entering loop", FuncName);
         }
         if (l==0) {
            yc = SUMA_CoerceMxVec(y_l, SUMA_double, 0, NULL); 
               /* for l == 0, all imaginary comp. are 0 */
            y_l = SUMA_FreeMxVec(y_l); y_l = yc; yc = NULL; 
            y_l_t = SUMA_MxVecTranspose(y_l, NULL);
               /*  y_l is equal to Y' in Moo's SPHARsmooth.m function*/
            if (Opt->debug > 1)  
               SUMA_ShowMxVec(y_l_t, 1, NULL, "\ny_l_t matrix\n");
            dims[0] = 2*l+1; dims[1] = 1;
            betal = SUMA_NewMxVec(SUMA_double, 2, dims, 1);
            for (jj=0; jj<Opt->n_in_namev; ++jj) {
               for (i=0;i<=2*l;++i) { mxvd2(betal,i,0) = mxvd2(abeta[jj],l, i); }
               if (Opt->debug > 1) 
                  SUMA_ShowMxVec(betal, 1, NULL, "\nbetal matrix\n");
               xe = SUMA_MxVecMult(y_l_t, betal, NULL, 0);
               if (Opt->debug > 1) {
                  SUMA_ShowMxVec(xe, 1, NULL, "\nxe vector\n");
                  if (Opt->debug > 2) 
                     SUMA_WriteMxVec(xe, "xe_l0.1D", "#xe vector");
               }
               axe[jj] = xe; xe = NULL;
            }
         } else { /* higher order, need to deal with real and imaginary parts*/
            /* Catenate the columns of y_l with the real columns first 
            (negative harmonics), followed by imaginary ones (positive harms.)*/ 
            
            sprintf(stmp, "Starting with order l=%d", l);
            if (Opt->debug) SUMA_etime2(FuncName, stmp, FuncName);
            y_l = SUMA_YLcomp_to_YLdoub(&y_l, Opt->debug); /* Now y_l is real */
            if (Opt->debug ) SUMA_etime2(FuncName, "Created y_l", FuncName);
            
            if (Opt->debug > 2) {
               SUMA_WriteMxVec(y_l, "y_l.1D.dset", "#y_l real matrix\n");
            }
            y_l_t = SUMA_MxVecTranspose(y_l, NULL);   
               /*  y_l is equal to Y' in Moo's SPHARsmooth.m function*/
            if (Opt->debug > 1)  
               SUMA_ShowMxVec(y_l_t, 1, NULL, "\ny_l_t matrix\n");
            if (Opt->debug ) SUMA_etime2(FuncName, "Trasnposed y_l", FuncName);
            
            fac = exp((double)(-l*(l+1))*Opt->v0);
            dims[0] = 2*l+1; dims[1] = 1;
            betal = SUMA_NewMxVec(SUMA_double, 2, dims, 1);
            for (jj=0; jj<Opt->n_in_namev; ++jj) {
               xe = axe[jj];
               for (i=0;i<=2*l;++i) { mxvd2(betal,i,0) = mxvd2(abeta[jj],l, i); }
               if (Opt->debug > 1) 
                  SUMA_ShowMxVec(betal, 1, NULL, "\nbetal matrix\n");
               sm = SUMA_MxVecMult(y_l_t, betal, sm, 0); 
               if (Opt->debug > 1) { 
                  sprintf(stmp,"\nsm_%d  vector\n", jj);   
                  SUMA_ShowMxVec(sm , 1, NULL, stmp); 
               }  
               for (i=0;i<xe->N_vals;++i) {   
                  mxvd1(xe,i) += fac * mxvd1(sm,i);   
               }  
               if (Opt->debug > 1) { 
                  sprintf(stmp,"\n%d_estimate  vector\n", jj);   
                  SUMA_ShowMxVec(xe, 1, NULL, stmp);    
                  sprintf(stmp,"%d_estimate_l%d.1D.dset", jj, l);   
                  if (Opt->debug > 2) 
                     SUMA_WriteMxVec(xe, stmp, "#estimate at last l\n"); 
               }
            }  
            if (Opt->debug) SUMA_etime2(FuncName, "Refit residual", FuncName);
         }
         
         /* store new coordinates, in a temp surface, fun to update as we're
            progressing in case want to feed suma at some point*/
         if (do_surf_xyz) {
            if (l==0 && ps->cs->Send && Opt->debug) {
               SUMA_S_Warn("Assuming coefficients are XYZ of surfaces !\n"
                           "Only the 1st three data columns will be used\n"
                           "in talk_suma mode.\n"
                           "Warnings muted for l > 0\n");
            }
            for (i=0; i<SO->N_Node; ++i) {
               i3 = 3*i;
               SOt->NodeList[i3  ] = mxvd1(axe[0], i);
               SOt->NodeList[i3+1] = mxvd1(axe[1], i);
               SOt->NodeList[i3+2] = mxvd1(axe[2], i);
            }
         }
         
         if (ps->cs->Send) { /* send the smoothed coords  */
            if (do_surf_xyz) { /* surface coordinates */
               if (l > 0) {
                  if (Opt->debug) {
                     SUMA_S_Notev("[%f %f %f]\n", 
                              SOt->NodeList[0], 
                              SOt->NodeList[1], SOt->NodeList[2]);
                  }
                  if (!SUMA_SendToSuma (  SO, ps->cs, (void *)SOt->NodeList, 
                                          SUMA_NODE_XYZ, 1)) {
                     SUMA_SL_Warn(  "Failed in SUMA_SendToSuma\n"
                                    "Communication halted.");
                  }
               }
            } else {
               if (l > 0) {
                  if (!fbuf) fbuf = (float *)SUMA_malloc(SO->N_Node*
                                                         sizeof(float));
                  for (i=0; i<SO->N_Node; ++i) fbuf[i] = mxvd1(axe[0], i);
                  if (!SUMA_SendToSuma (  SO, ps->cs, 
                                          (void *)fbuf, 
                                          SUMA_NODE_RGBAb, 1)) {
                     SUMA_SL_Warn(  "Failed in SUMA_SendToSuma\n"
                                    "Communication halted.");
                  }
               }
            }
         }

         /* Done with order l */
         if (y_l) y_l = SUMA_FreeMxVec(y_l);
         if (y_l_t) y_l_t = SUMA_FreeMxVec(y_l_t);
         if (betal) betal = SUMA_FreeMxVec(betal);
         
         if (Opt->debug ) {
            SUMA_S_Note("MemCheck:");
            MCHECK;
         }
         
      } while (0);
      NEXT_L:
      ++l; 
   } while (l <= Opt->iopt);
   --l; /* back to where you stopped, kid */
   
   
   /* Now create an output data set for the reconstructed data */
   out_dset = SUMA_CreateDsetPointer(
         Opt->out_prefix ? Opt->out_prefix:"spharm_reco",  
         SUMA_NODE_BUCKET,                /* mix and match */
         NULL,    /* no idcode, let the function create one from the filename*/
         NULL,       /* no domain str specified */
         SO->N_Node    /* Number of nodes allocated for */
         );
   /* add results */
   for (jj=0; jj<Opt->n_in_namev; ++jj) {
      if (!fbuf) fbuf = (float *)SUMA_malloc(SO->N_Node*sizeof(float));
      for (i=0; i<SO->N_Node; ++i) fbuf[i] = mxvd1(axe[jj], i);
      if (!SUMA_AddDsetNelCol(  out_dset, "sp_reco", SUMA_NODE_FLOAT, 
                                fbuf, NULL, 1)) {
            SUMA_S_Err("Failed to update output.");
            exit(1);
      }
      axe[jj] = SUMA_FreeMxVec(axe[jj]); 
   }
   
   if (Opt->out_prefix) {
      /* write out the data */
      ooo = SUMA_WriteDset_s( Opt->out_prefix, out_dset, 
                              oform, THD_ok_overwrite(), 0);
      if (Opt->debug) SUMA_S_Notev("Wrote %s\n", ooo);
      SUMA_free(ooo); ooo=NULL;   
   }
   
   /* do we need to write out surfaces? */
   if (do_surf_xyz && ps->o_N_surfnames) {
      for (i=0; i<Opt->n_in_namev/3; ++i) {   
         if (ps->o_N_surfnames == Opt->n_in_namev/3) {
            pref = SUMA_copy_string(ps->o_surfnames[i]);
            tp = ps->o_FT[i];
            form = ps->o_FF[i];
         } else {
            sprintf(stmp, "s%02d", i);
            pref = SUMA_append_string(ps->o_surfnames[0], stmp);
            tp = ps->o_FT[0];
            form = ps->o_FF[0];
         }
         if (Opt->debug) {
            SUMA_S_Notev("Prepping to write surface %s\n"
                         "with X Y Z from cols. %d %d %d\n"
                         , pref, i*3, 1+i*3, 2+i*3);
         }
         xbuf = (float*)out_dset->dnel->vec[0+i*3];
         ybuf = (float*)out_dset->dnel->vec[1+i*3];
         zbuf = (float*)out_dset->dnel->vec[2+i*3];
         for (ii=0; ii<SO->N_Node; ++ii) {
            i3 = 3*ii;
            SO->NodeList[i3  ] = xbuf[ii];
            SO->NodeList[i3+1] = ybuf[ii];
            SO->NodeList[i3+2] = zbuf[ii];
         }
         /* write the surface */
         SO_name = SUMA_Prefix2SurfaceName(pref, NULL, NULL, tp, &exists);
         if (!THD_ok_overwrite() && exists) {
            fprintf(SUMA_STDERR,"Warning %s:\nOutput surface %s* on disk.\n"
                                "Will not overwrite.\n", FuncName, pref);
            exit(1);
         }
         if (Opt->debug) {
            SUMA_S_Notev("Saving surface under prefix %s\n", pref);
         }
         if (!SUMA_Save_Surface_Object (SO_name, SO, tp, form, NULL)) {
            SUMA_S_Err("Failed to write reconstructed surface!");
            exit(1);   
         }
      }
   }
   
   /* clean and quit */
   if (fbuf) SUMA_free(fbuf);
   
   for (i=0; i<Opt->n_in_namev; ++i) {
      SUMA_FreeMxVec(abeta[i]);
   }
   SUMA_free(axe); axe = NULL;
   SUMA_free(abeta); abeta = NULL;
   
   if (sm) sm = SUMA_FreeMxVec(sm);
   
   SUMA_Spherical_Bases(&l, NULL);  /* clean SUMA_Spherical_Bases */

   /* you don't want to exit rapidly because the 
      SUMA might not be done processing the last elements*/
   if (ps->cs->Send && !ps->cs->GoneBad) {
      /* cleanup and close connections */
      if (!SUMA_SendToSuma (SO, ps->cs, NULL, SUMA_NODE_XYZ, 2)) {
         SUMA_SL_Warn("Failed in SUMA_SendToSuma\nCleanup failed");
      }
   }   
   
   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 (out_dset) SUMA_FreeDset(out_dset); out_dset = 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);
   
} 
Пример #4
0
int main(int argc, char *argv[]) {
	int i,j,k,m,n,aa,ii,jj,kk,mm,rr;
	int iarg;
	int nmask1=0;
	int nmask2=0;
	THD_3dim_dataset *insetFA = NULL, *insetV1 = NULL, 
		*insetMD = NULL, *insetL1 = NULL;
	THD_3dim_dataset *insetEXTRA=NULL; 
	THD_3dim_dataset *mset2=NULL; 
	THD_3dim_dataset *mset1=NULL; 
	THD_3dim_dataset *outsetMAP=NULL, *outsetMASK=NULL;
	char *prefix="tracky";
	int LOG_TYPE=0;
	char in_FA[300];
	char in_V1[300];
	char in_MD[300];
	char in_L1[300];
	int EXTRAFILE=0; // switch for whether other file is input as WM map

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

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

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

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

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

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

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

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

	INFO_message("version: MU");

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

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

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

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

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

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

			iarg++ ; continue ;
		}

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

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

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

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

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


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

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


	}
	 
	 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	//free(mode);
	
	return 0;
}
Пример #5
0
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"FSread_annot"};
   int kar, Showct, testmode;
   char *fname = NULL, *fcmap = NULL, *fdset = NULL, 
         *froi = NULL, *fcol = NULL, *ctfile=NULL, sbuf[1024]={""};
   SUMA_Boolean SkipCoords = NOPE, brk;
   SUMA_DSET *dset=NULL;
   int lbl1,lbl2, ver, hemi, FSdefault;
   SUMA_Boolean LocalHead = NOPE;	
   
   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;
   
	/* allocate space for CommonFields structure */
	SUMAg_CF = SUMA_Create_CommonFields ();
	if (SUMAg_CF == NULL) {
		fprintf( SUMA_STDERR,
               "Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
		exit(1);
	}

   /* parse command line */
   kar = 1;
   fname = NULL;
   froi = NULL;
   fcmap = NULL;
   fcol = NULL;
	brk = NOPE;
   ctfile = NULL;
   Showct = 0;
   testmode = 0;
   lbl1 = -1;
   lbl2 = -1;
   ver = -1;
   FSdefault = 0;
   hemi=0;
	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) {
			 usage_SUMA_FSread_annot_Main();
          exit (0);
		}
      
      if (!brk && (strcmp(argv[kar], "-show_FScmap") == 0)) {
         Showct = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-testmode") == 0)) {
         testmode = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-input") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -input\n");
				exit (1);
			}
         fname = argv[kar];
			brk = YUP;
		}

      if (!brk && (strcmp(argv[kar], "-FScmap") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -FScmap\n");
				exit (1);
			}
         ctfile = argv[kar];
         if (!strcmp(ctfile,"FS_DEFAULT")) {
            char *eee = getenv("FREESURFER_HOME");
            if (!eee) {
               SUMA_S_Err("Environment variable FREESURFER_HOME not set.\n"
                          "Cannot locate FreeSurferColorLUT.txt\n");
               exit (1);
            } else {
               sprintf(sbuf, "%s/FreeSurferColorLUT.txt", eee);
               ctfile = sbuf;
               FSdefault = 1;
               SUMA_S_Notev("Using %s\n", ctfile);
            }              
         }
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-FSversion") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -FSversion\n");
				exit (1);
			}
         if (strstr(argv[kar],"2009")) ver = 2009;
         else if (strstr(argv[kar],"2005")) ver = 2005;
         else {
            fprintf (SUMA_STDERR, 
                  "Bad value for -FSversion of %s (looking for 2005 or 2009)\n",
                  argv[kar]);
				exit (1);
         }
			brk = YUP;
		}

      if (!brk && (strcmp(argv[kar], "-hemi") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -hemi\n");
				exit (1);
			}
         if (strstr(argv[kar],"lh")) hemi = -1;
         else if (strstr(argv[kar],"rh")) hemi = 1;
         else {
            fprintf (SUMA_STDERR, 
                  "Bad value for -hemi of %s (looking for lh or rh)\n",
                  argv[kar]);
				exit (1);
         }
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-FScmaprange") == 0)) {
         kar ++;
			if (kar+1 >= argc)  {
		  		fprintf (SUMA_STDERR, "need 2 argument after -FScmaprange\n");
				exit (1);
			}
         lbl1 = atoi(argv[kar]); ++kar;
         lbl2 = atoi(argv[kar]); 
         
         if (lbl1 > lbl2 || lbl1 < -1) {
            fprintf (SUMA_STDERR, 
                  "Bad value for -FScmaprange of [%d %d]\n",
                  lbl1, lbl2);
				exit (1);
         }
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-roi_1D") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -ROI_1D\n");
				exit (1);
			}
         froi = argv[kar];
			brk = YUP;
		}
      
      if (!brk && ( (strcmp(argv[kar], "-prefix") == 0) ||
                    (strcmp(argv[kar], "-dset") == 0) ) ) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -dset\n");
				exit (1);
			}
         fdset = argv[kar];
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-cmap_1D") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -cmap_1D\n");
				exit (1);
			}
         fcmap = argv[kar];
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-col_1D") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -col_1D\n");
				exit (1);
			}
         fcol = argv[kar];
			brk = YUP;
		}
      
      if (!brk) {
			fprintf (SUMA_STDERR,
                  "Error %s:\n"
                  "Option %s not understood. Try -help for usage\n", 
                  FuncName, argv[kar]);
			exit (1);
		} else {	
			brk = NOPE;
			kar ++;
		}
   }
   
   if (!fname) {
      SUMA_SL_Err("No input file specified.");
      exit(1);
   }
   
   if (ver == -1) {
      /* guess at version */
      if (strstr(fname,"2009")) {
         ver = 2009;
         SUMA_S_Notev("Guessed FS annot version of %d\n", ver);
      } else if (strstr(fname,"2005")) {
         ver = 2005;
         SUMA_S_Notev("Guessed FS annot version of %d\n", ver);
      } else {
         SUMA_S_Notev("Assuming FS annot version of %d\n", ver);
      }
   }
   
   if (hemi == 0) {
      if (strstr(fname,"lh.")) {
         hemi = -1;
         SUMA_S_Note("Guessed left hemisphere");
      } else if (strstr(fname,"rh.")) {
         SUMA_S_Note("Guessed right hemisphere");
         hemi = 1;
      } else {
         if (ver == 2009) {
            hemi = -1;
            SUMA_S_Note("Assuming left hemisphere.\n");
         } else {
            /* leave it not set */
         }
      }
   }
   
   if (ver == 2009 && !ctfile) {
      char *eee = getenv("FREESURFER_HOME");
      if (!eee) {
         SUMA_S_Warn("Environment variable FREESURFER_HOME not set.\n"
                    "Cannot locate FreeSurferColorLUT.txt\n");
      } else {
         sprintf(sbuf, "%s/FreeSurferColorLUT.txt", eee);
         ctfile = sbuf;
         SUMA_S_Notev("Using %s\n", ctfile);
      }  
   }
   
   if (lbl1 < 0 && lbl2 < 0) {
      /* need some setup */
      if (ver == 2009) {
         if (hemi == -1) {
            lbl1 = 13100;
            lbl2 = 13199;
            SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n",
                        lbl1, lbl2);
         } else if (hemi == 1) {
            lbl1 = 14100;
            lbl2 = 14199;
            SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n",
                        lbl1, lbl2);
         } else {
            SUMA_S_Warn("-FScmaprange is not set.\n"
                         "You may need to set it, check results.\n");
         }
      } else if (ver == 2005 && FSdefault) {
         if (hemi == -1) {
            lbl1 = 3100;
            lbl2 = 3199;
            SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n",
                        lbl1, lbl2);
         } else if (hemi == 1) {
            lbl1 = 4100;
            lbl2 = 4199;
            SUMA_S_Notev("Setting -FScmaprange to [%d %d]\n",
                        lbl1, lbl2);
         } else {
            SUMA_S_Warn("-FScmaprange is not set.\n"
                         "You may need to set it, check results.\n");
         }
      }
   }
   
   if (!fcmap && !froi && !fcol && !Showct && !fdset) {
      SUMA_SL_Err("Nothing to do.\n"
                  "Use either -cmap_1D or \n"
                  " -roi_1D or -col_1D or \n"
                  " -show_FScmap options.");
      exit(1);
   }

   if (fdset) {
      int exists = 0;
      char *ooo=NULL;
      exists = SUMA_WriteDset_NameCheck_s (fdset, NULL, 
                                           SUMA_ASCII_NIML, 0, &ooo);
      if (exists != 0 && !THD_ok_overwrite()) {
         SUMA_S_Errv("Output dataset %s exists.\n", ooo);
         SUMA_free(ooo); ooo=NULL;
         exit(1);
      }
   }

   if (froi) {
      if (SUMA_filexists(froi) && !THD_ok_overwrite()) { 
         fprintf( SUMA_STDERR,
                  "Error %s: File %s exists, will not overwrite.\n", 
                  FuncName, froi);
	      SUMA_RETURN (NOPE);
      }
   }
     
   if (fcmap) {
      if (SUMA_filexists(fcmap) && !THD_ok_overwrite()) { 
         fprintf( SUMA_STDERR,
                  "Error %s: File %s exists, will not overwrite.\n", 
                  FuncName, fcmap);
	      SUMA_RETURN (NOPE);
      }
   }
     
   if (fcol) {
      if (SUMA_filexists(fcol) && !THD_ok_overwrite()) { 
         fprintf( SUMA_STDERR,
                  "Error %s: File %s exists, will not overwrite.\n", 
                  FuncName, fcol);
	      SUMA_RETURN (NOPE);
      }
   }
     
   if (!SUMA_readFSannot (fname, froi, fcmap, fcol, Showct, ctfile, 
                          lbl1, lbl2, &dset)) {
      SUMA_S_Err("Failed reading annotation file (or output file exists)");
      exit(1);
   }
   
   if (!dset && fdset) {
      SUMA_S_Err("Have no dset to write");
      exit(1);
   }
   
   if (fdset) {
      if (AFNI_yesenv("AFNI_NIML_TEXT_DATA")) {
         SUMA_WriteDset_eng(fdset, dset, SUMA_ASCII_NIML, 1, 1, 1);
      } else {
         SUMA_WriteDset_eng(fdset, dset, SUMA_BINARY_NIML, 1, 1, 1);      
      }
   }
   
   if (testmode) {
      int key, indx, ism, suc;
      SUMA_COLOR_MAP *SM2=NULL, *SM=NULL;
      char *s=NULL, stmp[256];
      SUMA_PARSED_NAME *sname=NULL;
      NI_group *ngr=NULL;
      
      SUMA_S_Note("Testing Chunk Begins");
      
      /* check */
      if (!SUMA_is_Label_dset(dset, &ngr)) {
         SUMA_S_Err("Dset is no label dset");
         exit(1);
      }
      /* write it */
      
      /* play with the colormap */
      if (ngr) {
         if (!(SM = SUMA_NICmapToCmap(ngr))){
            SUMA_S_Err("Failed to create SUMA colormap");
            exit(1);
         }
         ngr = NULL; /* that's a copy of what was in dset, do not free it */
         if (!SUMA_CreateCmapHash(SM)) {
            SUMA_S_Err("Failed to create hash");
            exit(1);
         }
         /* Now pretend you are retrieving the index in cmap of some key */
         for (ism=0; ism < SM->N_M[0]; ++ism) {
            /* the key is coming from SM, because I store all keys there
              But key normally comes from a certain node's value */
            key = SM->idvec[ism];
            indx = SUMA_ColMapKeyIndex(key, SM);
            if (indx < 0) {
               SUMA_S_Errv("Hashkey %d not found\n", key);
            } else {
               fprintf(SUMA_STDERR,
                        "hashed id %d --> index %d\n"
                        "known  id %d --> index %d\n",
                        key, indx,
                        key, ism);
            }
         }

         /* Now try it with an unknown key */
         key = -13;
         indx = SUMA_ColMapKeyIndex(key, SM);
         if (indx < 0) {
            fprintf(SUMA_STDERR,
                     "id %d is not in the hash table, as expected\n", key);
         } else {
            SUMA_S_Errv("Should not have found %d\n", key);
         }      

         SUMA_S_Note("Now Show it to me");
         s = SUMA_ColorMapVec_Info (&SM, 1, 2);
         if (s) {
            fprintf(SUMA_STDERR,"%s", s); SUMA_free(s); s = NULL;
         }

         SUMA_S_Notev("Now turn it to niml (%s)\n", SM->Name);
         ngr = SUMA_CmapToNICmap(SM);
         sname = SUMA_ParseFname(SM->Name, NULL);
         snprintf(stmp, 128*sizeof(char), 
                  "file:%s.niml.cmap", sname->FileName_NoExt); 
         NEL_WRITE_TX(ngr, stmp, suc);
         if (!suc) {
            SUMA_S_Errv("Failed to write %s\n", stmp);
         }
         SUMA_Free_Parsed_Name(sname); sname = NULL;

         SUMA_S_Note("Now turn niml colormap to SUMA's colormap");
         SM2 = SUMA_NICmapToCmap(ngr);
         SUMA_S_Note("Now Show it to me2");
         s = SUMA_ColorMapVec_Info (&SM2, 1, 2);
         if (s) {
            fprintf(SUMA_STDERR,"%s", s); SUMA_free(s); s = NULL;
         }

         NI_free_element(ngr); ngr=NULL;
         SUMA_Free_ColorMap(SM); SM = NULL;
         SUMA_Free_ColorMap(SM2); SM2 = NULL;
      }
      
      SUMA_S_Note("Testing Chunk End");
   }

   if (dset) SUMA_FreeDset(dset); dset = NULL;
   
   exit(0);
}
Пример #6
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);
   
} 
Пример #7
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfClust"}; 
	int kar, SO_read, *ni=NULL, N_ni, cnt, i, *nip=NULL, N_Spec = 0;
   float *data_old = NULL, *far = NULL, *nv=NULL, *nt = NULL;
   void *SO_name = NULL;
   SUMA_SurfaceObject *SO = NULL, *SOnew = NULL;
   MRI_IMAGE *im = NULL;
   SUMA_DSET_FORMAT iform;
   SUMA_SURFCLUST_OPTIONS *Opt;  
	SUMA_SurfSpecFile *Spec=NULL; 
   DList *list = NULL;
   SUMA_DSET *dset = NULL;
   float *NodeArea = NULL;
   FILE *clustout=NULL;
   char *ClustOutName = NULL, *params=NULL, stmp[200];
   char sapa[32]={""}, sapd[32]={""}, sapn[32]={""}, sap[100]={""};
   SUMA_GENERIC_ARGV_PARSE *ps=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, "-spec;-i;-t;-sv;-s;");
   Opt = SUMA_SurfClust_ParseInput (argv, argc, ps);
   if (argc < 6)
       {
         SUMA_S_Err("Too few options");
          usage_SUMA_SurfClust(0);
          exit (1);
       }
   
   
   if (Opt->DistLim >= 0.0) {
      sprintf(sapd, "_r%.1f", Opt->DistLim);
   } else {
      sprintf(sapd, "_e%d", -(int)Opt->DistLim);
   }
   if (Opt->AreaLim < 0) {
      sapa[0]='\0';
   } else {
      sprintf(sapa, "_a%.1f", Opt->AreaLim);
   }
   if (Opt->NodeLim < 0) {
      sapn[0]='\0';
   } else {
      sprintf(sapn, "_n%d", Opt->NodeLim);
   }
   sprintf(sap, "%s%s%s", sapd, sapa, sapn);
   
   if (Opt->WriteFile) {
      sprintf(stmp,"_ClstTable%s.1D", sap);
      
      ClustOutName = SUMA_append_string(Opt->out_prefix, stmp);   
      if (SUMA_filexists(ClustOutName) && !THD_ok_overwrite()) {
         fprintf (SUMA_STDERR,
                  "Error %s:\n"
                  "Output file %s exists, will not overwrite.\n", 
                  FuncName, ClustOutName);
         exit(1);
      }
   }

   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("Multiple spec at input.");
      exit(1);
   }
   if (Spec->N_Surfs != 1) {
      SUMA_S_Err("1 and only 1 surface expected at input");
      exit(1);
   } 
   SUMA_LH("Loading surface...");
   SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0);
   if (!SO) {
         fprintf (SUMA_STDERR,"Error %s:\n"
                              "Failed to find surface\n"
                              "in spec file. \n",
                              FuncName );
         exit(1);
      
   }   
   if (!SUMA_SurfaceMetrics(SO, "EdgeList", NULL)) {
      SUMA_S_Err("Failed to compute edgelist");
      exit(1);
   }
   NodeArea = SUMA_CalculateNodeAreas(SO, NULL);
   if (!NodeArea) {
      SUMA_S_Err("Failed to calculate Node Areas.\n");
      exit(1);
   }   
   /* load the data */   
   iform = SUMA_NO_DSET_FORMAT;
   dset = SUMA_LoadDset_s (Opt->in_name, &iform, 0); 
   if (LocalHead) SUMA_ShowDset(dset, 0, NULL);
   if (!dset) { SUMA_S_Err(  "Failed to load dataset.\n"
                              "Make sure file exists\n"
                              "and is of the specified\n"
                              "format."); 
               exit(1); }
   if (!SUMA_OKassign(dset, SO)) {
      SUMA_SL_Err("Failed to assign data set to surface.");
      exit(1);
   }
   /* get the node index column */
   nip = SUMA_GetNodeDef(dset);
   N_ni = SDSET_VECLEN(dset);
   if (!nip) {
      SUMA_S_Err("Failed to find node index column");
      exit(1);
   }
   /* copy nip's contents because you will be modifying in the 
      thresholding below */
   ni = (int *)SUMA_malloc(N_ni*sizeof(int));
   memcpy (ni, nip, N_ni*sizeof(int));
   nv = SUMA_DsetCol2Float(dset, Opt->labelcol, 0);
   if (!nv) {
      SUMA_S_Err("Failed to find node value column");
      exit(1);
   }
   
   /* any thresholding ? */
   if (Opt->DoThreshold > SUMA_NO_THRESH) {
      nt = SUMA_DsetCol2Float(dset, Opt->tind, 0);
      if (!nt) {
         SUMA_S_Err("Failed to find threshold column");
         exit(1);
      }
      cnt = 0;
      if (Opt->DoThreshold == SUMA_LESS_THAN) {
         if (Opt->update) 
            fprintf( SUMA_STDERR,
                     "%s: Thresholding at %f...\n", FuncName, Opt->ThreshR[0]);
         for (i=0;i<N_ni; ++i) {
            if (nt[i] >= Opt->ThreshR[0]) {
               ni[cnt] = ni[i];
               nv[cnt] = nv[i];
               ++cnt;
            }
         }
      } else if (Opt->DoThreshold == SUMA_ABS_LESS_THAN) {
         SUMA_LH("ABS Thresholding at %f...", Opt->ThreshR[0]);
         for (i=0;i<N_ni; ++i) {
            if (fabs(nt[i]) >= Opt->ThreshR[0]) {
               ni[cnt] = ni[i];
               nv[cnt] = nv[i];
               ++cnt;
            }
         }
      } else if (Opt->DoThreshold == SUMA_THRESH_INSIDE_RANGE) {
         SUMA_LH("Range Thresholding at %f %f...", 
                 Opt->ThreshR[0], Opt->ThreshR[1]);
         for (i=0;i<N_ni; ++i) {
            if (nt[i] >= Opt->ThreshR[0] && nt[i] <= Opt->ThreshR[1]) {
               ni[cnt] = ni[i];
               nv[cnt] = nv[i];
               ++cnt;
            }
         }
      } else if (Opt->DoThreshold ==  SUMA_THRESH_OUTSIDE_RANGE) {
         SUMA_LH("Ex Range Thresholding at %f %f...",
                  Opt->ThreshR[0], Opt->ThreshR[1]);
         for (i=0;i<N_ni; ++i) {
            if (nt[i] < Opt->ThreshR[0] || nt[i] > Opt->ThreshR[1]) {
               ni[cnt] = ni[i];
               nv[cnt] = nv[i];
               ++cnt;
            }
         }
      } else {
         SUMA_S_Err("Not ready for threshold mode of %d", Opt->DoThreshold);
      }
      N_ni = cnt;
   }
   if (Opt->update) {
      Opt->update = -(N_ni * Opt->update / 100); /* make it negative 
                                                   before you begin a 
                                                   clustering operation */
      if (LocalHead) {
         fprintf( SUMA_STDERR,
                  "Update parameter, once every %d nodes\n"
                  "%d nodes to work with.\n", 
                  -(int)Opt->update, N_ni);
      }    
   }
   
   /* make the call */
   list = SUMA_FindClusters (SO, ni, nv, N_ni, -1, Opt, NodeArea);
   if (!list) {
      SUMA_S_Err("Failed in SUMA_FindClusters"); 
      exit(1);      
   }
   
   if (list->size) {
      /* sort the list */
      if (!SUMA_Sort_ClustersList (list, Opt->SortMode)) {
         SUMA_S_Err("Failed to sort cluster list");
         exit(1);
      }
   }       
   /* Show the results */
   params = SUMA_HistString(FuncName, argc, argv, NULL);
   if (Opt->WriteFile) {
      if (0) {
         /* You can also write a NIML formatted cluster table with */
         NI_element *nel=NULL;
         int suc; char sbuf[512]={""};
         nel = SUMA_SurfClust_list_2_nel(list, 0, params, NULL);
         snprintf(sbuf, 510, "file:%s%s.niml.clstbl", Opt->out_prefix, sap);
         NEL_WRITE_TXH(nel, sbuf, suc);
         NI_free_element(nel); nel=NULL;
      }
      clustout = fopen(ClustOutName, "w");
      if (!clustout) {
         fprintf (SUMA_STDERR,
                  "Error %s:\n"
                  "Failed to open %s for writing.\n"
                  "Check permissions.\n",  
                  FuncName, ClustOutName);
         exit(1);
      }
      SUMA_Show_SurfClust_list(list, clustout, 0, params, NULL);
      fclose(clustout);clustout = NULL;  
   }  else SUMA_Show_SurfClust_list(list, NULL, 0, params, NULL);
   
   if (!list->size) {
      /* nothing left to do, quit */
      exit(0);
   }
   
   if (Opt->OutROI) {
      SUMA_DSET *dset_roi = NULL;
      char *ROIprefix = NULL;
      char *NameOut = NULL;
      
      sprintf(stmp,"_ClstMsk%s", sap);
      ROIprefix = SUMA_append_string(Opt->out_prefix, stmp);
      /* Call this function, write out the resultant dset to disk 
         then cleanup */
      dset_roi = 
         SUMA_SurfClust_list_2_DsetMask(SO, list, Opt->FullROIList, ROIprefix);
      
      if (!dset_roi) {
         SUMA_S_Err("NULL dset_roi");
         exit(1);
      }
      if (Opt->prepend_node_index) {/* prepend node index? */         
         if (!SUMA_InsertDsetNelCol (
               dset_roi, "Node Index Copy", SUMA_NODE_INT, 
               (void *)(dset_roi->inel->vec[0]), NULL ,1, 0)) {
            SUMA_S_Err("Failed to insert column");
         }
         if (LocalHead) SUMA_ShowDset(dset_roi,0, NULL); 
      }
      
      NameOut = SUMA_WriteDset_s (  ROIprefix, dset_roi, Opt->oform, 
                                    THD_ok_overwrite(), 0);
      if (!NameOut) { SUMA_SL_Err("Failed to write dataset."); exit(1); } 
      SUMA_FreeDset((void *)dset_roi); dset_roi = NULL; 
      if (NameOut) SUMA_free(NameOut); NameOut = NULL;
      if (ROIprefix) SUMA_free(ROIprefix); ROIprefix = NULL; 
   }
   
   if (Opt->OutClustDset) {
      SUMA_DSET *dset_clust = NULL;
      char *Clustprefix = NULL;
      char *NameOut = NULL;

      sprintf(stmp,"_Clustered%s", sap);
      Clustprefix = SUMA_append_string(Opt->out_prefix, stmp);
      /* Call this function, write out the resultant dset to disk 
         then cleanup */
      
      dset_clust = 
         SUMA_MaskDsetByClustList(  dset, SO, list, 
                                    Opt->FullROIList, Clustprefix);
      if (!dset_clust) {
         SUMA_S_Err("NULL dset_clust");
         exit(1);
      }
      NameOut = SUMA_WriteDset_s (  Clustprefix, dset_clust, Opt->oform, 
                                    THD_ok_overwrite(), 0);
      if (!NameOut) { SUMA_SL_Err("Failed to write dataset."); exit(1); } 
      SUMA_FreeDset((void *)dset_clust); dset_clust = NULL; 
      if (NameOut) SUMA_free(NameOut); NameOut = NULL;
      if (Clustprefix) SUMA_free(Clustprefix); Clustprefix = NULL; 
   }
   
   if (ClustOutName) SUMA_free(ClustOutName); ClustOutName = NULL;
   if (list) dlist_destroy(list); SUMA_free(list); list = NULL;
   if (ni) SUMA_free(ni); ni = NULL;
   if (nv) SUMA_free(nv); nv = NULL;
   if (nt) SUMA_free(nt); nt = NULL;
   if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL;
   if (Opt) SUMA_free_SurfClust_Opt(Opt);
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   if (dset) SUMA_FreeDset((void *)dset); dset = NULL;
   if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
      SUMA_SL_Err("DO Cleanup Failed!");
   }
   exit(0);
}
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"ConvertSurface"}; 
	int kar, volexists, i, j, Doinv, randseed, Domergesurfs=0, pciref;
   float DoR2S, fv[3], *pcxyzref;
   double xcen[3], sc[3];
   double xform[4][4];
   char  *if_name = NULL, *of_name = NULL, *if_name2 = NULL, 
         *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
         *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL,
         *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, 
         *ifpar_name2 = NULL;
   SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, 
                     iparType = SUMA_FT_NOT_SPECIFIED,
                     oType = SUMA_FT_NOT_SPECIFIED;
   SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, 
                        iparForm = SUMA_FF_NOT_SPECIFIED, 
                        oFormat = SUMA_FF_NOT_SPECIFIED;
   SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL;
   SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL;
   SUMA_SFname *SF_name = NULL;
   void *SO_name = NULL;
   char orsurf[6], orcode[6], *PCprojpref=NULL, *NodeDepthpref=NULL;
   THD_warp *warp=NULL ;
   THD_3dim_dataset *aset=NULL;
   SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Do_flip;
   SUMA_Boolean Doxmat, Do_wind, Do_p2s, onemore, Do_native, Do_PolDec;
   int Do_PCproj, Do_PCrot, Do_NodeDepth;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_Boolean exists;
   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, "-o;-i;-sv;-ipar;");
   
   
   kar = 1;
   xmat_name = NULL;
   xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0;
	brk = NOPE;
   orcode[0] = '\0'; 
   randseed = 1234;
   sprintf(orsurf,"RAI");
   Docen = NOPE;
   Doxmat = NOPE;
   Do_tlrc = NOPE;
   Do_mni_RAI = NOPE;
   Do_mni_LPI = NOPE;
   Do_acpc = NOPE;
   Do_wind = NOPE;
   Do_flip = NOPE;
   Do_p2s = NOPE;
   Do_native = NOPE;
   DoR2S = 0.0;
   Do_PolDec = NOPE;
   Do_PCproj = NO_PRJ;
   Do_PCrot = NO_ROT;
   pciref = -1;
   pcxyzref = NULL;
   PCprojpref = NULL;
   NodeDepthpref = NULL;
   Do_NodeDepth = 0;
   Doinv = 0;
   Domergesurfs = 0;
   onemore = 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) {
			 usage_SUMA_ConvertSurface(ps, strlen(argv[kar]) > 3 ? 2:1);
          exit (0);
		}
		
      SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      SUMA_TO_LOWER(argv[kar]);
		      
      if (!brk && (strcmp(argv[kar], "-seed") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 integer after -seed\n");
				exit (1);
			}
			randseed = atoi(argv[kar]); 
			brk = YUP;
		}

      if (!brk && (strcmp(argv[kar], "-xyzscale") == 0)) {
         kar ++;
			if (kar+2 >= argc)  {
		  		fprintf (SUMA_STDERR, "need 3 values after -XYZscale\n");
				exit (1);
			}
			sc[0] = strtod(argv[kar], NULL); kar ++; 
			sc[1] = strtod(argv[kar], NULL); kar ++; 
         sc[2] = strtod(argv[kar], NULL);
			xmat_name = "Scale";
         Doxmat = YUP;
         Doinv = 0;
         brk = YUP;
		}
      
      if (!brk && ( (strcmp(argv[kar], "-xmat_1d") == 0) || 
                    (strcmp(argv[kar], "-xmat_1D") == 0) ) ) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 argument after -xmat_1D\n");
				exit (1);
			}
			xmat_name = argv[kar]; 
         Doxmat = YUP;
         Doinv = 0;
			brk = YUP;
		}
      
      if (!brk && ( (strcmp(argv[kar], "-ixmat_1d") == 0) || 
                    (strcmp(argv[kar], "-ixmat_1D") == 0) ) ) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 argument after -ixmat_1D\n");
				exit (1);
			}
			xmat_name = argv[kar]; 
         Doxmat = YUP;
         Doinv = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-polar_decomp") == 0)) {
         Do_PolDec = YUP;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-merge_surfs") == 0)) {
         Domergesurfs = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-pc_proj") == 0)) {
         kar ++;
			if (kar+1 >= argc)  {
		  		fprintf (SUMA_STDERR, "need 2 argument after -pc_proj\n");
				exit (1);
			}
              if (!strcmp(argv[kar],"PC0_plane")) Do_PCproj = E1_PLN_PRJ;
         else if (!strcmp(argv[kar],"PC1_plane")) Do_PCproj = E2_PLN_PRJ;
         else if (!strcmp(argv[kar],"PC2_plane")) Do_PCproj = E3_PLN_PRJ;
         else if (!strcmp(argv[kar],"PCZ_plane")) Do_PCproj = EZ_PLN_PRJ;
         else if (!strcmp(argv[kar],"PCY_plane")) Do_PCproj = EY_PLN_PRJ;
         else if (!strcmp(argv[kar],"PCX_plane")) Do_PCproj = EX_PLN_PRJ;
         else if (!strcmp(argv[kar],"PC0_dir"))   Do_PCproj = E1_DIR_PRJ;
         else if (!strcmp(argv[kar],"PC1_dir"))   Do_PCproj = E2_DIR_PRJ;
         else if (!strcmp(argv[kar],"PC2_dir"))   Do_PCproj = E3_DIR_PRJ;
         else if (!strcmp(argv[kar],"PCZ_dir"))   Do_PCproj = EZ_DIR_PRJ;
         else if (!strcmp(argv[kar],"PCY_dir"))   Do_PCproj = EY_DIR_PRJ;
         else if (!strcmp(argv[kar],"PCX_dir"))   Do_PCproj = EX_DIR_PRJ;
         else {
            SUMA_S_Err("Bad value of %s for -pca_proj", argv[kar]);
            exit(1);
         }
         ++kar;
         if (argv[kar][0] == '-') {
            SUMA_S_Err("Prefix for -pc_proj should not start with '-'.\n"
                       "Could it be that %s is another option and \n"
                       "the prefix was forgtotten?", argv[kar]);
            exit(1);
         }
         PCprojpref = argv[kar];
			
         brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-node_depth") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need a prefix argument after -node_depth\n");
				exit (1);
			}
         Do_NodeDepth = 1;
         if (argv[kar][0] == '-') {
            SUMA_S_Err("Prefix for -node_depth should not start with '-'.\n"
                       "Could it be that %s is another option and \n"
                       "the prefix was forgtotten?", argv[kar]);
            exit(1);
         }
         NodeDepthpref = argv[kar];
         
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-make_consistent") == 0)) {
         Do_wind = YUP;
			brk = YUP;
		}

      if (!brk && (strcmp(argv[kar], "-flip_orient") == 0)) {
         Do_flip = YUP;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-xcenter") == 0)) {
         kar ++;
			if (kar+2>= argc)  {
		  		fprintf (SUMA_STDERR, "need 3 arguments after -xcenter\n");
				exit (1);
			}
			xcen[0] = atof(argv[kar]); ++kar;
			xcen[1] = atof(argv[kar]); ++kar;
			xcen[2] = atof(argv[kar]); 
         Docen = YUP;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-native") == 0)) {
         Do_native = YUP;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-orient_out") == 0)) {
         kar ++;
			if (kar>= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 argument after -orient_out\n");
				exit (1);
			}
			snprintf(orcode, 4*sizeof(char), "%s", argv[kar]);
         if (!SUMA_ok_orstring(orcode)) {
            fprintf (SUMA_STDERR, "%s is a bad orientation string\n", orcode);
				exit (1);
         } 
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-radial_to_sphere") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 argument after -radial_to_sphere\n");
				exit (1);
			}
         DoR2S = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-patch2surf") == 0)) {
         Do_p2s = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-xml_ascii") == 0)) {
         oFormat = SUMA_XML_ASCII_SURF;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-xml_b64") == 0)) {
         oFormat = SUMA_XML_B64_SURF;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-xml_b64gz") == 0)) {
         oFormat = SUMA_XML_B64GZ_SURF;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-tlrc") == 0)) {
         Do_tlrc = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-acpc") == 0)) {
         Do_acpc = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-mni_rai") == 0)) {
         Do_mni_RAI = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-mni_lpi") == 0)) {
         Do_mni_LPI = YUP;
         brk = YUP;
      }
      
      if (!brk && !ps->arg_checked[kar]) {
			fprintf (SUMA_STDERR,
                  "Error %s: Option %s not understood. Try -help for usage\n", 
                  FuncName, argv[kar]);
			suggest_best_prog_option(argv[0], argv[kar]);
         exit (1);
		} else {	
			brk = NOPE;
			kar ++;
		}
   }
   if (argc < 3) {
        SUMA_S_Err("Too few options");
        usage_SUMA_ConvertSurface (ps, 0);
        exit (1);
   }
   
   /* transfer info from ps structure (backward compat) */

   if (ps->o_N_surfnames) {
      of_name = ps->o_surfnames[0];
      of_name2 = ps->o_surftopo[0];
      oType = ps->o_FT[0];
      if (oFormat == SUMA_FF_NOT_SPECIFIED) {
         oFormat = ps->o_FF[0];
      }
   }
   if (ps->i_N_surfnames) {
      if_name = ps->i_surfnames[0];
      if_name2 = ps->i_surftopo[0];
      iType = ps->i_FT[0];
      iForm = ps->i_FF[0];
   }
   if (ps->ipar_N_surfnames) {
      ifpar_name = ps->ipar_surfnames[0];
      ifpar_name2 = ps->ipar_surftopo[0];
      iparType = ps->ipar_FT[0];
      iparForm = ps->ipar_FF[0];
   }
   
   if (ps->N_sv) sv_name = ps->sv[0];
   if (ps->N_vp) vp_name = ps->vp[0];
         
   /* sanity checks */
   if (Do_native && orcode[0] != '\0') {
      SUMA_S_Err("Options -native and -orient_out are mutually exclusive");
      exit(1);   
   }
   
   if (Do_mni_LPI && Do_mni_RAI) {
      SUMA_S_Err("\nCombining -MNI_lpi and -MNI_rai options.\nNot good.");
      exit(1);
   }
   
   if (!if_name) {
      SUMA_S_Err("input surface not specified.\n");
      exit(1);
   }
   if (!of_name && (Do_PCproj < 0 && !Do_NodeDepth) ) {
      SUMA_S_Err("output surface or projection PREFIX not specified.\n");
      exit(1);
   }
   if (iType == SUMA_FT_NOT_SPECIFIED) {
      SUMA_S_Err("input type not recognized.\n");
      exit(1);
   }
   if (oType == SUMA_FT_NOT_SPECIFIED && (Do_PCproj < 0 && !Do_NodeDepth) ) {
      SUMA_S_Err("output type not recognized.\n");
      exit(1);
   }
   if (  oType != SUMA_GIFTI && 
         oFormat >= SUMA_XML_SURF && 
         oFormat <= SUMA_XML_B64GZ_SURF &&
         (Do_PCproj < 0 && !Do_NodeDepth) ){
      SUMA_S_Err("XML output options only valid with -o_gii\n");
      exit(1);
   }
   if (iType == SUMA_SUREFIT) {
      if (!if_name2) {
         SUMA_S_Err("input SureFit surface incorrectly specified.\n");
         exit(1);
      }
      if (sv_name && !vp_name) {
         SUMA_S_Err("VolParent needs the -sv option for SureFit surfaces.");
         exit(1);
      }
   }
   if (iType == SUMA_VEC) {
      if (!if_name2) {
         SUMA_S_Err("Input vec surface incorrectly specified.\n");
         exit(1);
      }
   }

   if (( Do_mni_RAI || Do_mni_LPI) && !Do_tlrc) {
      SUMA_SL_Warn ( "I hope you know what you're doing.\n"
                     "The MNI transform should only be applied to a\n"
                     "Surface in the AFNI tlrc coordinate space.\n");
   }
   
   if (Do_acpc && Do_tlrc) {
      SUMA_S_Err("You can't do -tlrc and -acpc simultaneously.");
      exit(1);
   }
   
   if ((Doxmat || Docen) && (Do_acpc || Do_tlrc)) {
      SUMA_S_Err("You can't do -tlrc or -acpc with -xmat_1D and -xcenter.\n");
      exit(1);
   }
   
   if ((!Doxmat && Docen)) {
      SUMA_S_Err("You can't use -xcenter without -xmat_1D.\n");
      exit(1);
   }
   if (oType == SUMA_SUREFIT) {
      if (!of_name2) {
       SUMA_S_Err("output SureFit surface incorrectly specified. \n");
       exit(1);
      }
   }
   
   if (oType == SUMA_VEC) {
      if (!of_name2) {
       SUMA_S_Err("output vec surface incorrectly specified. \n");
       exit(1);
      }
   }
   
   if ( ps->i_N_surfnames > 1 && !Domergesurfs) {
      SUMA_S_Err("Multiple surfaces specified without -merge_surfs option\n"
                 "Nothing to do for such an input\n");
      exit(1);
   }
   
   
   /* test for existence of input files */
   
   if (!SUMA_is_predefined_SO_name(if_name, NULL, NULL, NULL, NULL) &&
       !SUMA_filexists(if_name)) {
      SUMA_S_Errv("if_name %s not found.\n", if_name);
      exit(1);
   }
   
   if (if_name2) {
      if (!SUMA_filexists(if_name2)) {
         SUMA_S_Errv("if_name2 %s not found.\n", if_name2);
         exit(1);
      }
   }

   if (ifpar_name2) {
      if (!SUMA_filexists(ifpar_name2)) {
         SUMA_S_Errv("ifpar_name2 %s not found.\n", ifpar_name2);
         exit(1);
      }
   }
   
   if (ifpar_name) {
      if (!SUMA_filexists(ifpar_name)) {
         SUMA_S_Errv("ifpar_name %s not found.\n", ifpar_name);
         exit(1);
      }
   }
   
   if (xmat_name) {
      if (!strstr(special_xmats,xmat_name) && !SUMA_filexists(xmat_name)) {
         SUMA_S_Errv("xmat file %s not found.\n", xmat_name);
         exit(1);
      }
   } else {
      if (Do_PolDec) {
         SUMA_S_Err("-polar_decomp is useless without -xmat_1D");
         exit(1);
      }
   }

   if (sv_name) {
      char *head = NULL, view[10];
      head = SUMA_AfniPrefix(sv_name, view, NULL, &volexists);
      if (!SUMA_AfniExistsView(volexists, view) && !SUMA_filexists(sv_name)) {
         fprintf (SUMA_STDERR,
                  "Error %s: volume %s not found.\n", FuncName, head);
         exit(1);
      }
      if (head) SUMA_free(head); head = NULL;
   }
   
  
   if ((Do_tlrc || Do_acpc) && (!sv_name)) {
      fprintf (SUMA_STDERR,
               "Error %s: -tlrc must be used with -sv option.\n", FuncName);
      exit(1);
   }
   
   if (vp_name) {
      if (!SUMA_filexists(vp_name)) {
         fprintf (SUMA_STDERR,
                  "Error %s: %s not found.\n", FuncName, vp_name);
         exit(1);
      }
   }

   /* check for existence of output files */
   if ((Do_PCproj < 0 && !Do_NodeDepth) ) {
      if (of_name2) {
         SUMA_SFname *SFname;

         SO_name = SUMA_2Prefix2SurfaceName (of_name, of_name2, NULL, 
                                             vp_name, oType, &exists);
         SFname = (SUMA_SFname *)SO_name;
         OF_name2 = SUMA_copy_string(SFname->name_topo);
         OF_name = SUMA_copy_string(SFname->name_coord);
      } else {
         SO_name = SUMA_Prefix2SurfaceName (of_name, NULL, vp_name, 
                                            oType, &exists);
         OF_name = SUMA_copy_string((char *) SO_name);
      }

      if (exists && !THD_ok_overwrite()) {
         if (OF_name2) 
            fprintf (SUMA_STDERR,
                     "Error %s: output file(s) %s and/or %s exist already.\n", 
                     FuncName, OF_name, OF_name2);
         else fprintf ( SUMA_STDERR,
                        "Error %s: output file %s exists already.\n", 
                        FuncName, OF_name);
         exit(1);
      }
   }   
   /* now for the real work */
   if (Doxmat) {
      MRI_IMAGE *im = NULL;
      double *far=NULL;
      int nrow, ncol;
      if (!strcmp(xmat_name,"RandRigid")) {
         SUMA_FillRandXform(xform, randseed, 2); 
      } else if (!strcmp(xmat_name,"RandAffine")) {
         SUMA_FillRandXform(xform, randseed, 3);
      } else if (!strcmp(xmat_name,"RandShift")) {
         SUMA_FillRandXform(xform, randseed, 1);
      } else if (!strcmp(xmat_name,"Scale")) {
         SUMA_FillScaleXform(xform, sc);
      } else if (!strcmp(xmat_name,"NegXY")) {
         SUMA_FillXYnegXform(xform);
      } else {
         im = mri_read_double_1D (xmat_name);

         if (!im) {
            SUMA_SLP_Err("Failed to read 1D file");
            exit(1);
         }
         far = MRI_DOUBLE_PTR(im);
         nrow = im->nx;
         ncol = im->ny;
         if (nrow == 1) {
            if (ncol != 12) { 
               SUMA_SL_Err("Mat file must have\n"
                           "one row of 12 columns.");
               mri_free(im); im = NULL;   /* done with that baby */
               exit(1);
            }
            i = 0;
            while (i < 12) {
               xform[i/4][0] = far[i]; ++i;
               xform[i/4][1] = far[i]; ++i;
               xform[i/4][2] = far[i]; ++i;
               xform[i/4][3] = far[i]; ++i;
            }
            xform[3][0] = 0.0;  
            xform[3][1] = 0.0;  
            xform[3][2] = 0.0;  
            xform[3][3] = 1.0;
         } else {
            if (ncol < 4 ) {
               SUMA_SL_Err("Mat file must have\n"
                           "at least 4 columns.");
               mri_free(im); im = NULL;   /* done with that baby */
               exit(1);
            }
            if (nrow < 3 ) {
               SUMA_SL_Err("Mat file must have\n"
                           "at least 3 rows.");
               mri_free(im); im = NULL;   /* done with that baby */
               exit(1);
            }
            if (ncol > 4) {
               SUMA_SL_Warn(  "Ignoring entries beyond 4th \n"
                              "column in transform file.");
            }
            if (nrow > 3) {
               SUMA_SL_Warn(  "Ignoring entries beyond 3rd\n"
                              "row in transform file.\n");
            }
            for (i=0; i < 3; ++i) {
               xform[i][0] = far[i];
               xform[i][1] = far[i+nrow];
               xform[i][2] = far[i+2*nrow];
               xform[i][3] = far[i+3*nrow];
            }
            xform[3][0] = 0.0;  
            xform[3][1] = 0.0;  
            xform[3][2] = 0.0;  
            xform[3][3] = 1.0;
         }
      }  
      
      if (LocalHead) {
         fprintf(SUMA_STDERR,"\n++ ConvertSurface xform:\n");
         for (i=0; i < 4; ++i) {
            fprintf(SUMA_STDERR," %+.5f\t%+.5f\t%+.5f\t%+.5f\n",
                   xform[i][0], xform[i][1], 
                   xform[i][2], xform[i][3]);  
         }
         fprintf(SUMA_STDERR,"\n");
      }
      
      mri_free(im); im = NULL;
      
      if (Doinv) {
         mat44 A, A0;
   
         LOAD_MAT44( A0, \
                  xform[0][0], xform[0][1], xform[0][2], xform[0][3],    \
                  xform[1][0], xform[1][1], xform[1][2], xform[1][3],    \
                  xform[2][0], xform[2][1], xform[2][2], xform[2][3]   );
         A = nifti_mat44_inverse(A0);
         UNLOAD_MAT44(A,   \
                  xform[0][0], xform[0][1], xform[0][2], xform[0][3],    \
                  xform[1][0], xform[1][1], xform[1][2], xform[1][3],    \
                  xform[2][0], xform[2][1], xform[2][2], xform[2][3]   );
      }            

      
      if (Do_PolDec) {
         #ifdef USE_DECOMPOSE_SHOEMAKE
            /* a little something to do a polar decomposition on M into M = Q*S*/
            {
               float det, m[4][4], q[4][4], s[4][4];
               char *stmp = SUMA_append_string("QS_",xmat_name);
               FILE *fout = fopen(stmp,"w"); SUMA_free(stmp); stmp = NULL;
               SUMA_S_Note("FixMe! #include above and if(1) here ...");
               det = polar_decomp(M, q,s);
               fprintf(fout,"#[M][D]: (D is the shift)\n");
               for (i=0;i<3; ++i)
                  fprintf(fout,  "#%.5f   %.5f  %.5f  %.5f\n", 
                                 M[i][0], M[i][1], M[i][2], M[i][3]); 
               fprintf(fout,"#Q:\n");
               for (i=0;i<3; ++i)
                  fprintf(fout,  "#%.5f   %.5f  %.5f  %.5f\n", 
                                 q[i][0], q[i][1], q[i][2], q[i][3]); 
               fprintf(fout,"#S:\n");
               for (i=0;i<3; ++i)
                  fprintf(fout,  "#%.5f   %.5f  %.5f  %.5f\n", 
                                 s[i][0], s[i][1], s[i][2], s[i][3]);
               fprintf(fout,"#det: %f\n", det);
               fprintf(fout,  "#[Q][D]: A close xform to [M][D], "
                              "without scaling.\n#M = Q*S\n");
               for (i=0;i<3; ++i)
                  fprintf(fout,  "%.5f   %.5f  %.5f  %.5f\n", 
                                 q[i][0], q[i][1], q[i][2], M[i][3]);
               fclose(fout); SUMA_free(stmp); stmp = NULL;
            }
            /* replace user's xform with orthogonal one: */
            fprintf(SUMA_STDOUT,"Replacing matrix:\n");
            for (i=0;i<3; ++i)
                  fprintf( SUMA_STDOUT,
                           " %.5f   %.5f  %.5f  %.5f\n", 
                           M[i][0], M[i][1], M[i][2], M[i][3]); 
            fprintf(SUMA_STDOUT,"     with matrix:\n");
            for (i=0;i<3; ++i)
                  fprintf(SUMA_STDOUT, 
                           " %.5f   %.5f  %.5f  %.5f\n", 
                           q[i][0], q[i][1], q[i][2], M[i][3]);
            for (i=0;i<3; ++i) { 
               M[i][0] = q[i][0]; M[i][1] = q[i][1]; M[i][2] = q[i][2]; 
            }
            
         #else
            {/* use the NIFTI polar decomposition function 
               (same results as above)*/
               mat33 Q, A;
               for (i=0;i<3;++i) { 
                  A.m[i][0] = xform[i][0]; 
                  A.m[i][1] = xform[i][1]; 
                  A.m[i][2] = xform[i][2]; 
               }
               Q = nifti_mat33_polar( A );
               /* replace user's xform with orthogonal one: */
               fprintf(SUMA_STDOUT,"Replacing matrix:\n");
               for (i=0;i<3; ++i)
                     fprintf( SUMA_STDOUT,
                              " %.5f   %.5f  %.5f  %.5f\n", 
                              xform[i][0], xform[i][1], 
                              xform[i][2], xform[i][3]); 
               fprintf(SUMA_STDOUT,"     with matrix:\n");
               for (i=0;i<3; ++i)
                     fprintf( SUMA_STDOUT,
                              " %.5f   %.5f  %.5f  %.5f\n", 
                              Q.m[i][0], Q.m[i][1], Q.m[i][2], xform[i][3]);
               for (i=0;i<3; ++i) { 
                  xform[i][0] = Q.m[i][0]; 
                  xform[i][1] = Q.m[i][1]; 
                  xform[i][2] = Q.m[i][2]; 
               }
                
            }
         #endif 
      }
   }
   
   if ( ps->i_N_surfnames ==  1) {
      /* load that one surface */
      SO = SUMA_Load_Surface_Object_Wrapper ( if_name, if_name2, vp_name, 
                                              iType, iForm, sv_name, 1);
      if (!SO) {
         SUMA_S_Err("Failed to read input surface.\n");
         exit (1);
      }
   } else if ( ps->i_N_surfnames > 1 && Domergesurfs) {
      SUMA_SurfaceObject **SOar=NULL;
      int ii;
      SUMA_S_Notev("Merging %d surfaces into 1\n", ps->i_N_surfnames);
      SOar = (SUMA_SurfaceObject **)
                  SUMA_calloc(ps->i_N_surfnames, sizeof(SUMA_SurfaceObject *));
      if (ps->N_sv > 1 || ps->N_vp > 1) {
         SUMA_S_Errv("Cannot handle multiple (%d) -sv or multiple (%d) -vp\n",
                     ps->N_sv, ps->N_vp);
         exit(1);
      }
      for (ii = 0; ii<ps->i_N_surfnames; ++ii) {
         SOar[ii] = SUMA_Load_Surface_Object_Wrapper(ps->i_surfnames[ii], 
                                                     ps->i_surftopo[ii],
                                                     vp_name, 
                                                     ps->i_FT[0], ps->i_FF[0], 
                                                     sv_name, 1);
      }
      if (!(SO = SUMA_MergeSurfs(SOar, ps->i_N_surfnames))) {
         SUMA_S_Err("Failed to merge");
         exit(1);
      }
      for (ii = 0; ii<ps->i_N_surfnames; ++ii) {
         SUMA_Free_Surface_Object(SOar[ii]);
         SOar[ii]=NULL;
      } SUMA_free(SOar); SOar=NULL;
   }
   
   if (DoR2S > 0.0000001) {
      if (!SUMA_ProjectSurfaceToSphere(SO, NULL , DoR2S , NULL)) {
         SUMA_S_Err("Failed to project to surface");
         exit(1);
      }
   }
   
   
   if (ifpar_name) {
      SOpar = SUMA_Load_Surface_Object_Wrapper ( ifpar_name, ifpar_name2,
                                 vp_name, iparType, iparForm, sv_name, 1);
      if (!SOpar) {
         SUMA_S_Err("Failed to read input parent surface.\n");
         exit (1);
      }
      /* need edge list */
      if (!SUMA_SurfaceMetrics_eng (SOpar,"EdgeList", NULL, 0, 
                                    SUMAg_CF->DsetList)) {
         SUMA_SL_Err("Failed to create edgelist for parent");
         exit(1);
      }
   }
   
   
   /* if Do_wind */
   if (Do_wind) {
      fprintf (SUMA_STDOUT,
         "Checking and repairing mesh's winding consistency...\n");
      /* check the winding, but that won't fix the normals, 
      you'll have to recalculate those things, if need be ... */
      if (!SUMA_SurfaceMetrics_eng (SO, "CheckWind", NULL, 0, 
                                    SUMAg_CF->DsetList)) {
         SUMA_S_Err("Failed in SUMA_SurfaceMetrics.\n");
         exit(1);
      }   
   }

   if (Do_flip) {
      fprintf (SUMA_STDOUT,
         "Flipping triangle winding...\n");
      SUMA_FlipSOTriangles(SO);   
   }
   
   if (Do_tlrc) {
      fprintf (SUMA_STDOUT,"Performing talairach transform...\n");

      /* form the tlrc version of the surface volume */
      tlrc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+
                                        strlen(SO->VolPar->prefix)+60, 
                                        sizeof(char));
      sprintf (tlrc_name, "%s%s+tlrc.HEAD", 
                           SO->VolPar->dirname, SO->VolPar->prefix);
      if (!SUMA_filexists(tlrc_name)) {
         fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, tlrc_name);
         exit(1);
      }
      
      /* read the tlrc header */
      aset = THD_open_dataset(tlrc_name) ;
      if( !ISVALID_DSET(aset) ){
         SUMA_S_Err("%s is not a valid data set.\n", tlrc_name) ;
         exit(1);
      }
      if( aset->warp == NULL ){
         SUMA_S_Err("tlrc_name does not contain a talairach transform.\n");
         exit(1);
      }
      
      warp = aset->warp ;
      
      /* now warp the coordinates, one node at a time */
      if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
         SUMA_S_Err("Failed in SUMA_AFNI_forward_warp_xyz.\n");
         exit(1);
      }

      
   }
   
   if (Do_acpc) {
      fprintf (SUMA_STDOUT,"Performing acpc transform...\n");

      /* form the acpc version of the surface volume */
      acpc_name = (char *) SUMA_calloc (strlen(SO->VolPar->dirname)+
                                        strlen(SO->VolPar->prefix)+60, 
                                        sizeof(char));
      sprintf (acpc_name, 
               "%s%s+acpc.HEAD", SO->VolPar->dirname, SO->VolPar->prefix);
      if (!SUMA_filexists(acpc_name)) {
         fprintf (SUMA_STDERR,"Error %s: %s not found.\n", FuncName, acpc_name);
         exit(1);
      }
      
      /* read the acpc header */
      aset = THD_open_dataset(acpc_name) ;
      if( !ISVALID_DSET(aset) ){
         fprintf (SUMA_STDERR,
                  "Error %s: %s is not a valid data set.\n", 
                  FuncName, acpc_name) ;
         exit(1);
      }
      if( aset->warp == NULL ){
         fprintf (SUMA_STDERR,
                  "Error %s: acpc_name does not contain an acpc transform.\n", 
                  FuncName);
         exit(1);
      }
      
      warp = aset->warp ;
      
      /* now warp the coordinates, one node at a time */
      if (!SUMA_AFNI_forward_warp_xyz(warp, SO->NodeList, SO->N_Node)) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed in SUMA_AFNI_forward_warp_xyz.\n", FuncName);
         exit(1);
      }

      
   }
   
   if (Do_mni_RAI) {
      fprintf (SUMA_STDOUT,"Performing MNI_RAI transform...\n");
      /* apply the mni warp */
      if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "RAI")) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName);
         exit(1);
      }
      sprintf(orsurf,"RAI");
   }
   
   if (Do_mni_LPI) {
      fprintf (SUMA_STDOUT,"Performing MNI_LPI transform...\n");
      /* apply the mni warp */
      if (!SUMA_AFNItlrc_toMNI(SO->NodeList, SO->N_Node, "LPI")) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed in SUMA_AFNItlrc_toMNI.\n", FuncName);
         exit(1);
      }
      sprintf(orsurf,"LPI");
   }
   
   if (Doxmat) {
      fprintf (SUMA_STDOUT,"Performing affine transform...\n");
      if (LocalHead) {
         for (i=0; i<3 ; ++i) {
            fprintf (SUMA_STDERR,
                     "M[%d][:] = %f %f %f %f\n", 
                     i, xform[i][0], xform[i][1], xform[i][2], xform[i][3]);
         }
         fprintf (SUMA_STDERR,"Cen[:] %f %f %f\n", xcen[0], xcen[1], xcen[2]);
      }
      if (Docen) {
         if (!SUMA_Apply_Coord_xform(  SO->NodeList, SO->N_Node, SO->NodeDim,
                                       xform, 0, xcen)) { 
            SUMA_SL_Err("Failed to xform coordinates"); exit(1); 
         }
      } else {
         if (!SUMA_Apply_Coord_xform(  SO->NodeList, SO->N_Node, SO->NodeDim,
                                       xform, 0, NULL)) { 
            SUMA_SL_Err("Failed to xform coordinates"); exit(1); 
         }
      }
      SUMA_Blank_AfniSO_Coord_System(SO->aSO);
   }
   
   if (orcode[0] != '\0') {
      SUMA_LHv("Changing coordinates from %s to %s\n", orsurf, orcode);
      if (!SUMA_CoordChange(orsurf, orcode, SO->NodeList, SO->N_Node)) {
         SUMA_S_Err("Failed to change coords.");
         exit(1);
      }
      SUMA_Blank_AfniSO_Coord_System(SO->aSO);
   }
   
   if (Do_p2s) {
      SUMA_SurfaceObject *SOold = SO;
      SUMA_LH("Changing patch to surface...");
      SO = SUMA_Patch2Surf(SOold->NodeList, SOold->N_Node, 
                           SO->FaceSetList, SO->N_FaceSet, 3);
      if (!SO) {
         SUMA_S_Err("Failed to change patch to surface.");
         exit(1);
      }
      
      /* get rid of old surface object */
      SUMA_Free_Surface_Object(SOold);
   }
   
   if (Do_native) {
      if (!SUMA_Delign_to_VolPar (SO, NULL)) {
         SUMA_S_Err("Failed to transform coordinates to native space");
         exit(1);  
      }
   }
   
   if (Do_NodeDepth) {
      float *dpth=NULL, mx=0.0;
      SUMA_PC_XYZ_PROJ *pcp=NULL;
      if (SUMA_NodeDepth(SO->NodeList, SO->N_Node, E1_DIR_PRJ, &dpth, 
                     0.0, NULL, &mx, &pcp) < 0) {
         SUMA_S_Err("Failed to compute node depth");
         exit(1);
      } else {
         if (!SUMA_WriteNodeDepth(NodeDepthpref,pcp,dpth, mx)) {
            SUMA_S_Err("Failed to write node depth");
            exit(1);
         } 
      }
      SUMA_ifree(dpth);
      pcp = SUMA_Free_PC_XYZ_Proj(pcp);
   }
   
   if (Do_PCproj > NO_PRJ) {
      SUMA_PC_XYZ_PROJ *pcp=NULL;
      pciref = 0; pcxyzref = NULL;
      if (!(pcp = SUMA_Project_Coords_PCA(SO->NodeList, SO->N_Node,
                                  pciref, pcxyzref, Do_PCproj, Do_PCrot, 1))) {
         SUMA_S_Err("Failed to project");
         exit(1);
      } else {
         if (!SUMA_Write_PC_XYZ_Proj(pcp, PCprojpref)) {
            SUMA_S_Err("Failed to write out projections");
            exit(1);
         } else {
           pcp = SUMA_Free_PC_XYZ_Proj(pcp);
         }  
         
         exit(0);
      }
   }

   
   
   /* write the surface object */
   if (SO_name) {
      if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
      fprintf (SUMA_STDOUT,"Writing surface...\n");
      if (!(SUMA_Save_Surface_Object ( SO_name,
                                    SO, oType, oFormat, SOpar))) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed to write surface object.\n", 
                  FuncName);
         exit (1);
      }
   } 
   
   
   
   if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip);
   if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip);
   if (OF_name) SUMA_free(OF_name);
   if (OF_name2) SUMA_free(OF_name2);
   if (SF_name) SUMA_free(SF_name);
   if (SO_name) SUMA_free(SO_name);
   if (SO) SUMA_Free_Surface_Object(SO);
   if (SOpar) SUMA_Free_Surface_Object(SOpar);
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   return (0);
}
Пример #9
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) ;
}
Пример #10
0
int main( int argc , char * argv[] )
{
   THD_3dim_dataset  *mask_dset=NULL, *iset=NULL, 
                     *sset=NULL, *xset=NULL, *vset=NULL;
   char *prefix="toy";
   int iarg=1 , mcount, udatum = MRI_float;
   byte *maskvox=NULL;
      
   mainENTRY("3dToyProg main"); machdep(); AFNI_logger("3dToyProg",argc,argv);
   
#ifdef USING_MCW_MALLOC
   enable_mcw_malloc() ;
#endif

   /*-- options --*/
   set_obliquity_report(0);   /* silence obliquity */

   while( iarg < argc && argv[iarg][0] == '-' ){
      CHECK_HELP(argv[iarg], help_3dToyProg);
      
      if( strncmp(argv[iarg],"-mask",5) == 0 ){
         if (iarg >= argc) ERROR_exit("Need dset after -mask");
         mask_dset = THD_open_dataset( argv[++iarg] ) ;
         if( mask_dset == NULL )
           ERROR_exit("Cannot open mask dataset!\n") ;
         if( DSET_BRICK_TYPE(mask_dset,0) == MRI_complex )
           ERROR_exit("Cannot deal with complex-valued mask dataset!\n");
         iarg++ ; continue ;
      }
      
      if( strcmp(argv[iarg],"-input") == 0) {
         if (iarg >= argc) ERROR_exit("Need dset after -mask");
         if (!(iset = THD_open_dataset( argv[++iarg]))) {
            ERROR_exit("Cannot open input dataset %s!\n", argv[iarg]) ;
         }
         DSET_mallocize(iset); DSET_load(iset);  /* load data part of dataset */
         iarg++ ; continue ;
      }
      
      if( strncmp(argv[iarg],"-prefix",6) == 0) {
         if (iarg >= argc) ERROR_exit("Need name after -prefix");
         prefix = argv[++iarg];
         iarg++ ; continue ;
         continue ;
      }

      if( strcmp(argv[iarg],"-datum") == 0) {
         if (iarg >= argc) ERROR_exit("Need datum type after -datum");
         ++iarg;
         if (!strcmp(argv[iarg],"float")) udatum = MRI_float;
         else if (!strcmp(argv[iarg],"short")) udatum = MRI_short;
         else {
            ERROR_exit(
               "For the purpose of this demo, only float and short are allowed");
         }
         iarg++ ; continue ;
         continue ;
      }

      ERROR_message("ILLEGAL option: %s\n",argv[iarg]) ;
		suggest_best_prog_option(argv[0], argv[iarg]);
      exit(1);
   }
   
   if( argc < 2 ){
     help_3dToyProg(TXT, 0);
     PRINT_COMPILE_DATE ; exit(0) ;
   }

   if( !iset )
     ERROR_exit("No dataset on command line!?") ;
   
   if (mask_dset) {
      if (THD_dataset_mismatch(mask_dset, iset)) 
         ERROR_exit("grid mismatch between input dset and mask dset");
      maskvox = THD_makemask( mask_dset , 0 , 1.0, -1.0 ) ; 
      mcount = THD_countmask( DSET_NVOX(mask_dset) , maskvox ) ;
      if( mcount <= 0 )  ERROR_exit("No voxels in the mask!\n") ;
      
      INFO_message("%d voxels in the mask dset %s\n",
                   mcount, DSET_PREFIX(mask_dset)) ;
      DSET_delete(mask_dset) ; mask_dset=NULL; /* Done with the mask dset */
   }
   
   /* An illustration of how volume navigation works */
   Dataset_Navigation(iset);
   
   /* Let us create a dataset from scratch */
   sset = New_Dataset_From_Scratch(prefix);
        /* Now for the output, add history, check for overwrite and write away */
   tross_Copy_History( iset , sset );/* Copy the old history (not mandatory). */
   tross_Make_History("3dToyProg", argc, argv ,sset) ; /* add the new */
   if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(sset)) ) {
      ERROR_message(
         "Output %s already exists, use -overwrite to do you know what",
         DSET_HEADNAME(sset));
   } else DSET_write(sset); 
   
   /* Now we'll do some voxelwise computations */
   xset = Voxelwise_Operations(sset, maskvox, prefix);
   tross_Copy_History( iset , xset ) ; /* Copy the old */
   tross_Make_History("3dToyProg", argc, argv ,xset) ; /* add the new */
   if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(xset)) ) {
      ERROR_message(
         "Output %s already exists, use -overwrite to do you know what",
         DSET_HEADNAME(xset));
   } else DSET_write(xset); 
   
   /* Or some volumewise operations */
   vset = Volumewise_Operations(sset, prefix, udatum);
   tross_Copy_History( iset , vset ) ; /* Copy the old */
   tross_Make_History("3dToyProg", argc, argv ,vset) ; /* add the new */
   if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(vset)) ) {
      ERROR_message(
         "Output %s already exists, use -overwrite to do you know what",
         DSET_HEADNAME(vset));
   } else DSET_write(vset); 
   
   
   
   
   /* cleanup */
   DSET_delete(xset); xset = NULL;
   DSET_delete(vset); vset = NULL;
   DSET_delete(sset); sset = NULL;
   exit(0) ;
}
Пример #11
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);
} 
Пример #12
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"quickspec"};
   int detail, kar, i, j, N_surf, N_name, idefstate;
   FILE *fid = NULL;
   char *spec_name, stmp[500], *Unique_st;
   SUMA_SO_File_Type TypeC[SUMA_MAX_N_SURFACE_SPEC];
   static char  
         *State[SUMA_MAX_N_SURFACE_SPEC],
         *Name_coord[SUMA_MAX_N_SURFACE_SPEC],
         *Name_topo[SUMA_MAX_N_SURFACE_SPEC],
         Anat[SUMA_MAX_N_SURFACE_SPEC],
         *LDP[SUMA_MAX_N_SURFACE_SPEC],
         *MARK[SUMA_MAX_N_SURFACE_SPEC],
         *LABEL[SUMA_MAX_N_SURFACE_SPEC];
   SUMA_GENERIC_ARGV_PARSE *ps;
   SUMA_Boolean brk;
   
   SUMA_mainENTRY;
   
	/* allocate space for CommonFields structure */
	SUMAg_CF = SUMA_Create_CommonFields ();
	if (SUMAg_CF == NULL) {
		fprintf( SUMA_STDERR,
               "Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
		exit(1);
	}
   
   ps = SUMA_Parse_IO_Args(argc, argv, "-t;");
   
   if (argc < 3)
       {
          usage_SUMA_quickspec (ps);
          exit (1);
       }
   
   kar = 1;
	brk = NOPE;
   detail = 1;
   N_surf = 0;
   N_name = 0;
   spec_name = NULL;
	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) {
			 usage_SUMA_quickspec(ps);
          exit (1);
		}
		if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -spec \n");
				exit (1);
			}
         spec_name = argv[kar];
			if (!THD_ok_overwrite() && SUMA_filexists(spec_name)) {
            fprintf (SUMA_STDERR, 
               "File %s exists, choose another one.\n", spec_name);
            exit(1);
         }
			brk = YUP;
		}
      if (!brk && (strcmp(argv[kar], "-tn") == 0)) {
         if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
            SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
            exit(1);   
         }
         /* get the type */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "Type argument must follow -tn \n");
				exit (1);
			}
         TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
         if (TypeC[N_surf] == SUMA_FT_ERROR || 
             TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
            fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]);
            exit(1);
         }
         /* get the name */
         if (TypeC[N_surf] == SUMA_SUREFIT || TypeC[N_surf] == SUMA_VEC) 
            N_name = 2;
         else N_name = 1;
         if (kar+N_name >= argc)  {
		  		fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
				exit (1);
			}
         kar ++; Name_coord[N_surf] = argv[kar];
         if (N_name == 2) {
            kar ++; Name_topo[N_surf] = argv[kar];
         } else { 
            Name_topo[N_surf] = NULL;
         }
         State[N_surf] = NULL;
         Anat[N_surf] = 'Y';
         LDP[N_surf] = NULL;
         ++N_surf; 
			brk = YUP;
		}
      if (!brk && (strcmp(argv[kar], "-tsn") == 0)) {
         if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
            SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
            exit(1);   
         }
         /* get the type */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "TYPE argument must follow -tsn \n");
				exit (1);
			}
         TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
         if (  TypeC[N_surf] == SUMA_FT_ERROR || 
               TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
            fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]);
            exit(1);
         }
         /* get the state */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "STATE argument must follow TYPE with -tsn \n");
				exit (1);
			}
         State[N_surf] = argv[kar];
         
         /* get the name */
         if (  TypeC[N_surf] == SUMA_SUREFIT || 
               TypeC[N_surf] == SUMA_VEC) N_name = 2;
         else N_name = 1;
         if (kar+N_name >= argc)  {
		  		fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
				exit (1);
			}
         kar ++; Name_coord[N_surf] = argv[kar];
         if (N_name == 2) {
            kar ++; Name_topo[N_surf] = argv[kar];
         } else { 
            Name_topo[N_surf] = NULL;
         }
         
         Anat[N_surf] = 'Y';
         LDP[N_surf] = NULL;
         ++N_surf; 
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-tsnad") == 0)) {
         if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
            SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
            exit(1);   
         }
         /* get the type */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n");
				exit (1);
			}
         TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
         if (  TypeC[N_surf] == SUMA_FT_ERROR || 
               TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
            fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]);
            exit(1);
         }
         /* get the state */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "STATE argument must follow TYPE with -tsnad \n");
				exit (1);
			}
         State[N_surf] = argv[kar];
         
         /* get the name */
         if (  TypeC[N_surf] == SUMA_SUREFIT || 
               TypeC[N_surf] == SUMA_VEC) N_name = 2;
         else N_name = 1;
         if (kar+N_name >= argc)  {
		  		fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
				exit (1);
			}
         kar ++; Name_coord[N_surf] = argv[kar];
         if (N_name == 2) {
            kar ++; Name_topo[N_surf] = argv[kar];
         } else { 
            Name_topo[N_surf] = NULL;
         }
         
         
         /* get the anatomical flag */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "Anatomical flag must follow NAME with -tsnad \n");
				exit (1);
			}
         Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]);
         if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') {
            SUMA_S_Err("Anatomical flag must be either 'y' or 'n'");
            exit (1);
         }
         /* get the LDP */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                 "LocalDomainParent must follow Anatomical flag with -tsnad \n");
				exit (1);
			}
         LDP[N_surf] = argv[kar];
         
         ++N_surf; 
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-tsnadm") == 0)) {
         if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
            SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
            exit(1);   
         }
         /* get the type */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n");
				exit (1);
			}
         TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
         if (  TypeC[N_surf] == SUMA_FT_ERROR || 
               TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
            fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]);
            exit(1);
         }
         /* get the state */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "STATE argument must follow TYPE with -tsnad \n");
				exit (1);
			}
         State[N_surf] = argv[kar];
         
         /* get the name */
         if (  TypeC[N_surf] == SUMA_SUREFIT || 
               TypeC[N_surf] == SUMA_VEC) N_name = 2;
         else N_name = 1;
         if (kar+N_name >= argc)  {
		  		fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
				exit (1);
			}
         kar ++; Name_coord[N_surf] = argv[kar];
         if (N_name == 2) {
            kar ++; Name_topo[N_surf] = argv[kar];
         } else { 
            Name_topo[N_surf] = NULL;
         }
         
         
         /* get the anatomical flag */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "Anatomical flag must follow NAME with -tsnad \n");
				exit (1);
			}
         Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]);
         if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') {
            SUMA_S_Err("Anatomical flag must be either 'y' or 'n'");
            exit (1);
         }
         /* get the LDP */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                 "LocalDomainParent must follow Anatomical flag with -tsnad \n");
				exit (1);
			}
         LDP[N_surf] = argv[kar];
         
         /* get the nodeMarker */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                 "LocalDomainParent must follow Anatomical flag with -tsnad \n");
				exit (1);
			}
         MARK[N_surf] = argv[kar];
         ++N_surf; 
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-tsnadl") == 0)) {
         if (N_surf >= SUMA_MAX_N_SURFACE_SPEC) {
            SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
            exit(1);   
         }
         /* get the type */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "TYPE argument must follow -tsnad \n");
				exit (1);
			}
         TypeC[N_surf] = SUMA_SurfaceTypeCode(argv[kar]);
         if (  TypeC[N_surf] == SUMA_FT_ERROR || 
               TypeC[N_surf] == SUMA_FT_NOT_SPECIFIED) {
            fprintf (SUMA_STDERR, "%s is a bad file TYPE.\n", argv[kar]);
            exit(1);
         }
         /* get the state */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "STATE argument must follow TYPE with -tsnad \n");
				exit (1);
			}
         State[N_surf] = argv[kar];
         
         /* get the name */
         if (  TypeC[N_surf] == SUMA_SUREFIT || 
               TypeC[N_surf] == SUMA_VEC) N_name = 2;
         else N_name = 1;
         if (kar+N_name >= argc)  {
		  		fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
				exit (1);
			}
         kar ++; Name_coord[N_surf] = argv[kar];
         if (N_name == 2) {
            kar ++; Name_topo[N_surf] = argv[kar];
         } else { 
            Name_topo[N_surf] = NULL;
         }
         
         
         /* get the anatomical flag */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                     "Anatomical flag must follow NAME with -tsnad \n");
				exit (1);
			}
         Anat[N_surf] = SUMA_TO_UPPER_C(argv[kar][0]);
         if (Anat[N_surf] != 'Y' && Anat[N_surf] != 'N') {
            SUMA_S_Err("Anatomical flag must be either 'y' or 'n'");
            exit (1);
         }
         /* get the LDP */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                 "LocalDomainParent must follow Anatomical flag with -tsnad \n");
				exit (1);
			}
         LDP[N_surf] = argv[kar];
         
         /* get the nodeMarker */
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, 
                 "LocalDomainParent must follow Anatomical flag with -tsnad \n");
				exit (1);
			}
         LABEL[N_surf] = argv[kar];
         ++N_surf; 
			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 ++;
		}
   }
   
   /* write out the comments */
   if (!spec_name) {
      fid = fopen("quick.spec", "w");
   } else {
      fid = fopen(spec_name,"w");
   }
   if (!fid){
      SUMA_SL_Err("Failed to open file for output");
      exit(1);
   }
   fprintf(fid,"# define the group\n");
   fprintf(fid,"\tGroup = QuickSpec\n");
   
   
   /* now create a list of unique states */
   idefstate = 0;
   if (!State[0]) {
      Unique_st = SUMA_copy_string ("\tStateDef = S_1\n");
      idefstate = 1;
   } else {
      sprintf(stmp, "\tStateDef = %s\n", State[0]);
      Unique_st = SUMA_copy_string (stmp);
   }
   for (i=1; i < N_surf; ++i) {
      if (!State[i]) { 
         ++idefstate;
         sprintf(stmp,"\tStateDef = S_%d\n", idefstate);
         Unique_st = SUMA_append_replace_string (Unique_st, stmp, "", 1);
      } else { 
         if (SUMA_iswordin(Unique_st, State[i]) != 1) {
            sprintf(stmp, "\tStateDef = %s\n", State[i]);
            Unique_st = SUMA_append_replace_string(Unique_st, stmp, "", 1);
         }
      }
   }
   fprintf (fid, "# define the various States\n");
   fprintf (fid, "%s\n", Unique_st);
   
   /* check on LDP correctness */
   for (i=0; i < N_surf; ++i) {
      if (LDP[i]) {
         if (!strcmp(LDP[i],"same") || !strcmp(LDP[i],"Same")) 
            SUMA_TO_UPPER(LDP[i]);
         if (strcmp(LDP[i],"SAME")) {
            j= 0;
            while (j<N_surf && strcmp(LDP[i], Name_coord[j])) ++j;
            if (j == N_surf) {
               SUMA_S_Errv("Could not find a surface named %s\n"
                           "to be the local domain parent of %s\n",
                           LDP[i], Name_coord[i]);
               exit(1);
            }
            if (!strcmp(LDP[i], Name_coord[i])) {/* reset to SAME*/
               LDP[i] = NULL; /* this results is SAME below */
            }
         }
      }
   } 
   /* now loop accross surfaces and write out the results */
   idefstate = 0;
   for (i=0; i < N_surf; ++i) {
      fprintf(fid, "\nNewSurface\n");
      fprintf(fid, "\tSurfaceType = %s\n", SUMA_SurfaceTypeString(TypeC[i]));
      if (!State[i]) { 
         ++idefstate;
         fprintf(fid, "\tSurfaceState = S_%d\n", idefstate);
      } else fprintf(fid, "\tSurfaceState = %s\n", State[i]);
      if (Name_topo[i]) {
         fprintf(fid, "\tCoordFile = %s\n", Name_coord[i]);
         fprintf(fid, "\tTopoFile = %s\n", Name_topo[i]);
      } else {
         fprintf(fid, "\tSurfaceName = %s\n", Name_coord[i]); 
      }
      /* add LocalDomainParent */
      if (LDP[i]) fprintf(fid, "\tLocalDomainParent = %s\n", LDP[i]);
      else fprintf(fid, "\tLocalDomainParent = SAME\n");
      /* add Anatomical */
      if (Anat[i]) fprintf(fid, "\tAnatomical = %c\n", Anat[i]);
      else fprintf(fid, "\tAnatomical = Y\n");
      /* add nodeMarker */
      if (MARK[i]) fprintf(fid, "\tNodeMarker = %s\n", MARK[i]);
      if (LABEL[i]) fprintf(fid, "\tLabelDset = %s\n", LABEL[i]);
      
      /* binary ? */
      switch (TypeC[i]) {
         case SUMA_FREE_SURFER:
            if (!SUMA_isExtension(Name_coord[i], ".asc")) {
               fprintf(fid, "\tSurfaceFormat = BINARY\n");
            }
            break;
         default:
            break;
      }
   }
   
   fclose(fid); fid = NULL;
   
   if (Unique_st) SUMA_free(Unique_st); Unique_st = NULL;
   
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   if (!SUMA_Free_CommonFields(SUMAg_CF)) {
      fprintf(SUMA_STDERR,"Error %s: SUMAg_CF Cleanup Failed!\n", FuncName);
      exit(1);
   }

   SUMA_RETURN(0);
   
}/* main quickspec */
Пример #13
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) ;
}
Пример #14
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);   
}
Пример #15
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"ConvexHull"}; 
	int i, i3, nspec = 0;
   void *SO_name=NULL;
   SUMA_SurfaceObject *SO = NULL;
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   char  stmp[200];
   SUMA_Boolean exists = NOPE;
   SUMA_Boolean LocalHead = NOPE;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;

   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, "-o;-i;-sv;");
   
   if (argc < 2) {
      usage_SUMA_ConvexHull(ps);
      exit (1);
   }
   
   Opt = SUMA_ConvexHull_ParseInput (argv, argc, ps);
      
   SO_name = SUMA_Prefix2SurfaceName(Opt->out_prefix, NULL, NULL, 
                                     Opt->SurfFileType, &exists);
   if (exists && !THD_ok_overwrite()) {
      SUMA_S_Err("Output file(s) %s* on disk.\nWill not overwrite.\n", 
                 Opt->out_prefix);
      exit(1);
   }
   
   if (Opt->obj_type < 0) {
      if (Opt->in_name) {
         if (Opt->debug) {
            SUMA_S_Note("Creating mask...");
         }
         if (!SUMA_Get_isosurface_datasets (Opt)) {
            SUMA_SL_Err("Failed to get data.");
            exit(1);
         }

         if (Opt->debug > 1) {
            if (Opt->debug == 2) {
               FILE *fout=fopen("inmaskvec.1D","w");
               SUMA_S_Note("Writing masked values...\n");
               if (!fout) {
                  SUMA_SL_Err("Failed to write maskvec");
                  exit(1);
               }
               fprintf(fout,  "#Col. 0 Voxel Index\n"
                              "#Col. 1 Is a mask (all values here should be 1)\n" );
               for (i=0; i<Opt->nvox; ++i) {
                  if (Opt->mcdatav[i]) {
                     fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]);
                  }
               }
               fclose(fout); fout = NULL;
            } else {
               FILE *fout=fopen("maskvec.1D","w");
               SUMA_S_Note("Writing all mask values...\n");
               if (!fout) {
                  SUMA_S_Err("Failed to write maskvec");
                  exit(1);
               }
               fprintf(fout,  "#Col. 0 Voxel Index\n"
                              "#Col. 1 Is in mask ?\n" );
               for (i=0; i<Opt->nvox; ++i) {
                  fprintf(fout,"%d %.2f\n", i, Opt->mcdatav[i]);
               }
               fclose(fout); fout = NULL;
            }
         }
      } else if (Opt->in_1D) {
            MRI_IMAGE *im = NULL;
            float *far=NULL;
            int nx2;
            
            /* load the 1D file */
            im = mri_read_1D (Opt->in_1D);
            if (!im) {
               SUMA_S_Err("Failed to read file");
               exit(1);
            }   

            far = MRI_FLOAT_PTR(im);
            if (im->nx == 0) {
               fprintf(SUMA_STDERR,"Error %s:\n Empty file %s.\n", FuncName, Opt->in_1D);
               exit(1);
            }
            if (im->ny != 3) {
               fprintf(SUMA_STDERR,"Error %s:\n Found %d columns in %s. Expecting 3\n", FuncName, im->ny, Opt->in_1D);
               exit(1);
            }
            
            /* copy the columns */
            Opt->N_XYZ = im->nx;
            Opt->XYZ = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float));
            if (!Opt->XYZ) {
               SUMA_S_Crit("Failed to allocate.");
               exit(1);
            }
            nx2 = 2*im->nx;
            for (i=0;i<Opt->N_XYZ; ++i) {
               i3 = 3*i;
               Opt->XYZ[i3  ] = far[i];
               Opt->XYZ[i3+1] = far[i+im->nx];
               Opt->XYZ[i3+2] = far[i+nx2];
            }
            
            /* done, clean up and out you go */
            if (im) mri_free(im); im = NULL; 
      } else if (ps->i_N_surfnames) {
         SUMA_SurfSpecFile *Spec=NULL;
         SUMA_SurfaceObject *SO=NULL;
         
         if (ps->i_N_surfnames > 1) {
            SUMA_S_Err("Only 1 input surface allowed!");
            exit(1);
         }
         Spec = SUMA_IO_args_2_spec(ps, &nspec);
         if (!Spec) {
            SUMA_S_Err("Failed to create spec!");
            exit(1);
         }
         if (nspec != 1) {
            SUMA_S_Warn("Expected one spec and nothing else");
         }
         /* load the surface object */
         SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], 0);
         if (!SO) {
            SUMA_S_Err("Failed to read surface.");
            exit(1);
         }
         /* transfer coords */
         if(SO->NodeDim != 3) {
            SUMA_S_Err("bad node coords.");
            exit(1);
         }
         
         Opt->N_XYZ = SO->N_Node;
         Opt->XYZ = (float *)SUMA_malloc(SO->N_Node * SO->NodeDim * sizeof(float));
         if (!Opt->XYZ) {
            SUMA_S_Crit("Failed to allocate.");
            exit(1);
         }
         for (i=0;i<SO->NodeDim*SO->N_Node; ++i) Opt->XYZ[i] = SO->NodeList[i];
         
         if (nspec) {
            int k=0; 
            for (k=0; k<nspec; ++k) {
               if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); } 
            }
            SUMA_free(Spec); Spec = NULL; nspec = 0;
         }

         if (SO) SUMA_Free_Surface_Object(SO); SO = NULL;
      } else {
         SUMA_S_Err("No input!");
         exit(1);
      }
   } else {
      SUMA_S_Err("Bad input!");
      exit(1);
   }
   
               
   /* Now call Marching Cube functions */
   if (!(SO = SUMA_ConvexHullSurface(Opt))) {
      SUMA_S_Err("Failed to create surface.\n");
      exit(1);
   }

   /* write the surface to disk */
   if (!SUMA_Save_Surface_Object (SO_name, SO, 
                        Opt->SurfFileType, Opt->SurfFileFormat, NULL)) {
      fprintf (SUMA_STDERR,
                  "Error %s: Failed to write surface object.\n", FuncName);
      exit (1);
   }
   
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   if (Opt->fvec) SUMA_free(Opt->fvec); Opt->fvec = NULL;
   if (Opt->mcdatav) {SUMA_free(Opt->mcdatav); Opt->mcdatav = NULL;} 
   if (Opt->in_vol) { DSET_delete( Opt->in_vol); Opt->in_vol = NULL;} 
   if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL;
   if (Opt->XYZ) SUMA_free(Opt->XYZ); Opt->XYZ = NULL;
   if (Opt) SUMA_free(Opt);
   if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
      SUMA_SL_Err("DO Cleanup Failed!");
   }
   if (SO_name) SUMA_free(SO_name); SO_name = NULL;
   if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
   exit(0);
}   
Пример #16
0
int main (int argc,char *argv[])
{/* Main */
   static char  FuncName[]={"MakeColorMap"};
   char  *fscolutname = NULL, *FidName = NULL, 
         *Prfx = NULL, h[9], *StdType=NULL, *dbfile=NULL, *MapName=NULL; 
   int Ncols = 0, N_Fid = 0, kar, i, ifact, *Nind = NULL, 
       imap = -1, MapSpecified = 0;
   int fsbl0, fsbl1, showfscolut, exists=0;
   float **Fid=NULL, **M=NULL;
   MRI_IMAGE *im = NULL;
   float *far=NULL;
   int AfniHex=0, freesm;
   int suc, idISi=0;
   char stmp[256], *s=NULL, *ooo=NULL, *sdset_prefix;
   SUMA_PARSED_NAME *sname=NULL;
   NI_group *ngr=NULL;   
   SUMA_Boolean   brk, SkipLast, PosMap, 
               Usage1, Usage2, Usage3, Usage4, flipud, fscolut,
               LocalHead = NOPE;
   SUMA_COLOR_MAP *SM=NULL;
   SUMA_DSET_FORMAT iform;
   SUMA_DSET *sdset=NULL;
      
   SUMA_STANDALONE_INIT;

   SUMA_mainENTRY;
   

   
   if (argc < 2) {
      SUMA_MakeColorMap_usage();
      exit (0);
   }
   
   kar = 1;
   freesm = 1;
   fscolutname = NULL;
   fsbl0 = -1;
   fsbl1 = -1;
   brk = NOPE;
   SkipLast = NOPE;
   AfniHex = 0;
   PosMap = NOPE;
   Usage1 = NOPE;
   Usage2 = NOPE;
   Usage3 = NOPE;
   Usage4 = NOPE;
   flipud = NOPE;
   fscolut = NOPE;
   showfscolut = 0;
   MapSpecified = NOPE;
   idISi=0;
   iform = SUMA_NO_DSET_FORMAT;
   sdset_prefix=NULL;
   while (kar < argc) { /* loop accross command ine options */
      if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
         SUMA_MakeColorMap_usage();
         exit (0);
      }
      
      SUMA_SKIP_COMMON_OPTIONS(brk, kar);
     
      if (!brk && (strcmp(argv[kar], "-v") == 0))
      {
         LocalHead = NOPE;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-flipud") == 0))
      {
         flipud = YUP;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-f") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -f ");
            exit (1);
         }
         FidName = argv[kar];
         Usage1 = YUP;
         brk = YUP;
      }      
      
      if (!brk && (strcmp(argv[kar], "-fscolutfile") == 0))
      {
         Usage4=YUP;
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need 1 argument after -fscolutfile ");
            exit (1);
         }
         fscolutname = argv[kar];
         if (fsbl0 < 0) {
            fsbl0 = 0;
            fsbl1 = 255;
         }
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-usercolutfile") == 0))
      {
         Usage4=YUP;
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need 1 argument after -fscolutfile ");
            exit (1);
         }
         fscolutname = argv[kar];
         if (fsbl0 < 0) {
            fsbl0 = 0;
            fsbl1 = -1;
         }  
         idISi=1;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-fscolut") == 0))
      {
         fscolut = YUP;
         Usage4=YUP;
         kar ++;
         if (kar+1 >= argc)  {
              fprintf (SUMA_STDERR, "need 2 arguments after -fscolut ");
            exit (1);
         }
         fsbl0 = atoi(argv[kar]); ++kar;
         fsbl1 = atoi(argv[kar]);
         if (fsbl0 > fsbl1 || fsbl0 < -1 || fsbl1 > 10000) {
            SUMA_S_Errv("-fscolut values of %d and %d either\n"
                        "do not make sense or exceed range 0 to 10000\n",
                        fsbl0, fsbl1);
            exit(1);
         }
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-show_fscolut") == 0))
      {
         showfscolut = 1;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-fn") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -fn ");
            exit (1);
         }
         FidName = argv[kar];
         Usage2 = YUP;
         brk = YUP;
      }      
      
      if (!brk && (strcmp(argv[kar], "-nc") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -nc ");
            exit (1);
         }
         Ncols = atoi(argv[kar]);
         Usage1 = YUP;
         brk = YUP;
      }      
   
      if (!brk && (strcmp(argv[kar], "-ah") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -ah ");
            exit (1);
         }
         Prfx = argv[kar];
         AfniHex = 1; 
         brk = YUP;
      }      
      
      if (!brk && (strcmp(argv[kar], "-ahc") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -ahc ");
            exit (1);
         }
         Prfx = argv[kar];
         AfniHex = 2; 
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-suma_cmap") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -suma_cmap");
            exit (1);
         }
         Prfx = argv[kar];
         AfniHex = 3; 
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-std") == 0))
      {
         kar ++;
         if (MapSpecified) {
            SUMA_S_Err( "Color map already specified.\n"
                        "-cmap and -std are mutually exclusive\n");
            exit (1);
         }
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -std ");
            exit (1);
         }
         MapSpecified = YUP;
         StdType = argv[kar];
         Usage3 = YUP; 
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-cmapdb") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -cmapdb ");
            exit (1);
         }
         SUMAg_CF->isGraphical = YUP; 
                        /* WILL NEED X DISPLAY TO RESOLVE COLOR NAMES */
         dbfile = argv[kar];
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-cmap") ==0)) {
         if (MapSpecified) {
            SUMA_S_Err( "Color map already specified.\n"
                        "-cmap and -std are mutually exclusive\n");
            exit (1);
         }
         MapSpecified = YUP;
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need 1 arguments after -cmap ");
            exit (1);
         }
         Usage3 = YUP; 
         MapName = argv[kar];
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-sl") == 0))
      {
         SkipLast = YUP;         
         brk = YUP;
      }      
      
      if (!brk && (strcmp(argv[kar], "-pos") == 0))
      {
         /* obsolete */
         PosMap = YUP;
         
         brk = YUP;
      }      
   
      if (!brk && (strcmp(argv[kar], "-sdset") == 0)) {
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need surface dataset after -sdset \n");
            exit (1);
         }
         iform = SUMA_NO_DSET_FORMAT;
         if (!(sdset = SUMA_LoadDset_s (argv[kar], &iform, 0))) {
            SUMA_S_Err("Failed to load surface dset");
            exit(1);
         }
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-sdset_prefix") == 0)) {
         kar ++;
         if (kar >= argc)  {
            fprintf (SUMA_STDERR, "need prefix dataset after -sdset_prefix \n");
            exit (1);
         }
         sdset_prefix = argv[kar];
         brk = YUP;
      }
      if (!brk) {
         SUMA_S_Errv("Option %s not understood. Try -help for usage\n", 
                     argv[kar]);
         suggest_best_prog_option(argv[0], argv[kar]);
         exit (1);
      } else {   
         brk = NOPE;
         kar ++;
      }
      
   }/* loop accross command ine options */
   
   /* check input */
   if (  (Usage1 && (Usage2 || Usage3 || Usage4)) || 
         (Usage2 && (Usage1 || Usage3 || Usage4)) || 
         (Usage3 && (Usage1 || Usage2 || Usage4)) || 
         (Usage4 && (Usage1 || Usage2 || Usage3)) ) {
      SUMA_S_Err("Mixing options from multiple usage modes.\n");
      exit(1);
   }
   
   if (!Usage1 && !Usage2 && !Usage3 && !Usage4) {
      SUMA_S_Err("One of these options must be used:\n"
                           "-f, -fn,  -std, or -fscolut.\n");
      exit(1);
   }
   
   /* are there database files to read */
   if (dbfile) {
      SUMA_LH("Now trying to read db file");
      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);
         }
      }
      if (SUMA_AFNI_Extract_Colors ( dbfile, SUMAg_CF->scm ) < 0) {
         SUMA_S_Errv("Failed to read %s colormap file.\n", dbfile);
         exit(1);
      }
   }
   
   if (Usage1 || Usage2) {
      if (!SUMA_filexists (FidName)) {
         SUMA_S_Errv("File %s could not be found.\n", FidName);
         exit(1);
      }
      
      /* read the fiducials file */
      im = mri_read_1D (FidName);
      if (!im) {
         SUMA_S_Err("Failed to read file");
         exit(1);
      }

      far = MRI_FLOAT_PTR(im);
      N_Fid = im->nx * im->ny;
   }

   if (PosMap) {
      fprintf (SUMA_STDERR,"\nWarning %s: -pos option is obsolete.\n", FuncName);
   }
   
   
   /* allocate for fiducials */
   if (Usage1) {
      if (N_Fid % 3) {
         fprintf (SUMA_STDERR,
                  "Error %s: Not all rows in %s appear to have RGB triplets.\n", 
                  FuncName, FidName);
         exit (1);
      }

      Fid = (float **) SUMA_allocate2D (N_Fid / 3, 3, sizeof(float));
      if (Fid == NULL) {
         fprintf (SUMA_STDERR,
                  "Error %s: Could not allocate for Fid.\n", FuncName);
         exit(1);
      }

      for (i=0; i < im->nx; ++i) {
         Fid[i][0] = far[i];
         Fid[i][1] = far[i+im->nx];
         Fid[i][2] = far[i+2*im->nx];
      }
      
      mri_free(im); im = NULL; 
      /* now create the color map */
      SM = SUMA_MakeColorMap (Fid, N_Fid/3, 0, Ncols, SkipLast, FuncName);
      if (SM == NULL) {
         fprintf (SUMA_STDERR,
                  "Error %s: Error in SUMA_MakeColorMap.\n", FuncName);
         exit(1);
      }
   } 
   if (Usage2) { /* second usage */
      if (N_Fid % 4) {
         fprintf (SUMA_STDERR,
                  "Error %s: Not all rows in %s appear to have "
                  "RGB N quadruplets.\n", FuncName, FidName);
         exit (1);
      }

      Fid = (float **) SUMA_allocate2D (N_Fid / 4, 3, sizeof(float));
      Nind = (int *) SUMA_calloc (N_Fid/4, sizeof(int));
      if (Fid == NULL || !Nind) {
         fprintf (SUMA_STDERR,
                  "Error %s: Could not allocate for Fid or Nind.\n", FuncName);
         exit(1);
      }
      
      for (i=0; i < im->nx; ++i) {
         Fid[i][0] = far[i];
         Fid[i][1] = far[i+im->nx];
         Fid[i][2] = far[i+2*im->nx];
         Nind[i] = (int)far[i+3*im->nx];
      }
      
      mri_free(im); im = NULL; 
      
      /* now create the color map */
      SM = SUMA_MakeColorMap_v2 (Fid, N_Fid/4, 0, Nind, SkipLast, FuncName); 
      if (SM == NULL) {
         fprintf (SUMA_STDERR,
                  "Error %s: Error in SUMA_MakeColorMap.\n", FuncName);
         exit(1);
      }
      Ncols = SM->N_M[0];
   }
   
   if (Usage3) { /* third usage */
      if (!MapName) {
         SM = SUMA_FindNamedColMap (StdType);
         freesm = 0;
         if (SM == NULL) {
            fprintf (SUMA_STDERR,
                     "Error %s: Error in SUMA_MakeColorMap.\n", FuncName);
            exit(1);
         }
         Ncols = SM->N_M[0];
      } else {
         imap = SUMA_Find_ColorMap ( MapName, SUMAg_CF->scm->CMv, 
                                     SUMAg_CF->scm->N_maps, -2);
         if (imap < 0) {
            fprintf (SUMA_STDERR,
                     "Error %s: Could not find colormap %s.\n", 
                     FuncName, MapName);
            exit (1); 
         }
         SM = SUMAg_CF->scm->CMv[imap]; 
         Ncols = SM->N_M[0];
      }
   }
   
   if (Usage4) { /* 4th usage */
      if (!(SM = SUMA_FScolutToColorMap(fscolutname, fsbl0, 
                                         fsbl1, showfscolut, idISi))) {
         SUMA_S_Err("Failed to get FreeSurfer colormap.");
         exit(1);
      }
      Ncols = SM->N_M[0];
   }
   
   if (flipud) {
      SUMA_Flip_Color_Map (SM);
   }
   
   M = SM->M;

   if (AfniHex && Ncols > 20) {
      if (!Usage4) {
         SUMA_S_Note("Writing colormap in colorscale format.\n");
      }  
   }
   
   
   
   if (!AfniHex) {
         SUMA_disp_mat (M, Ncols, 3, 1);
         /*SUMA_Show_ColorMapVec (&SM, 1, NULL, 2);*/
   } else {
         if (Usage4 || Ncols > 20) {
            if (AfniHex == 1) {
               fprintf (stdout, "%s \n", Prfx);
               for (i=0; i < Ncols; ++i) {
                  
                  /* Now create the hex form */
                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][0]*255)), 1, 0);
                  fprintf (stdout, "#%s", h); 

                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][1]*255)), 1, 0);
                  fprintf (stdout, "%s", h);

                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][2]*255)), 1, 0);
                  fprintf (stdout, "%s \n", h);
               }
                fprintf (stdout, "\n") ;
            } else if (AfniHex == 2){  /* to go in the C code 
                              (see pbardef.h and pbar.c)*/
               char *p2 = SUMA_copy_string(Prfx); 
               SUMA_TO_UPPER(p2);
               fprintf (stdout, "static char %s[] = {\n   \"%s \"\n   \"", 
                  p2, Prfx); SUMA_free(p2); p2 = NULL;
               for (i=0; i < Ncols; ++i) {
                  if (i) {
                     if (!(i % 4)) { fprintf (stdout, " \"\n   \""); }
                     else { fprintf (stdout, " "); }
                  }
                  /* Now create the hex form */
                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][0]*255)), 1, 0);
                  fprintf (stdout, "#%s", h); 

                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][1]*255)), 1, 0);
                  fprintf (stdout, "%s", h);

                  r_sprintf_long_to_hex (h, 
                        (unsigned long)rint((M[i][2]*255)), 1, 0);
                  fprintf (stdout, "%s", h);
               }
                fprintf (stdout, " \"\n};\n") ;
            } else if (AfniHex == 3){ 
               SUMA_LHv("Now turn %s to niml\n", SM->Name);
               sname = SUMA_ParseFname(Prfx, NULL);
               snprintf(stmp, 128*sizeof(char), 
                        "file:%s.niml.cmap", sname->FileName_NoExt); 
               if (SM->Name) SUMA_free(SM->Name); 
               SM->Name = SUMA_copy_string(sname->FileName_NoExt);
               ngr = SUMA_CmapToNICmap(SM);
               NEL_WRITE_TX(ngr, stmp, suc);
               if (!suc) {
                  SUMA_S_Errv("Failed to write %s\n", stmp);
               }
               SUMA_Free_Parsed_Name(sname); sname = NULL;
            } else {
               SUMA_S_Err("AfniHex should be 0, 1, or 2\n");
               exit(1);
            }
         } else {
            fprintf (stdout, "\n***COLORS\n");
            for (i=0; i < Ncols; ++i) {
               /* Now create the hex form */
               r_sprintf_long_to_hex (h, 
                     (unsigned long)rint((M[i][0]*255)), 1, 0);
               if (i<10) fprintf (stdout, "%s_0%d = #%s", Prfx, i, h);
                  else fprintf (stdout, "%s_%d = #%s", Prfx, i, h); 

               r_sprintf_long_to_hex (h, 
                     (unsigned long)rint((M[i][1]*255)), 1, 0);
               fprintf (stdout, "%s", h);

               r_sprintf_long_to_hex (h, 
                     (unsigned long)rint((M[i][2]*255)), 1, 0);
               fprintf (stdout, "%s\n", h);
            }

            /* color map */

            fprintf (stdout, "\n***PALETTES %s [%d]\n//1 to -1 range\n", 
                     Prfx, Ncols);
            ifact = 2;
            for (i=0; i < Ncols; ++i) {
               fprintf (stdout, "%f -> ", 1.0 - (float)(ifact*i)/Ncols);
               if (i<10) fprintf (stdout, "%s_0%d\n", Prfx, i);
                  else fprintf (stdout, "%s_%d\n", Prfx, i); 
            }
            fprintf (stdout, 
                     "\n***PALETTES %s [%d+]\n//1 to 0 range\n", Prfx, Ncols);
            ifact = 1;
            for (i=0; i < Ncols; ++i) {
               fprintf (stdout, "%f -> ", 1.0 - (float)(ifact*i)/Ncols);
               if (i<10) fprintf (stdout, "%s_0%d\n", Prfx, i);
                  else fprintf (stdout, "%s_%d\n", Prfx, i); 
            }
         }
   }
   
   /* free allocated space */
   if (Usage1)  {
      if (Fid) SUMA_free2D((char **)Fid, N_Fid / 3);
   } else {
      if (Fid) SUMA_free2D((char **)Fid, N_Fid / 4);
      if (Nind) SUMA_free(Nind);
   }
   
   /* add colormap to a surface dset ? */
   if (sdset) {
      SUMA_DSET *idset;
      if (!SUMA_is_AllConsistentCastType_dset(sdset, SUMA_int)) { 
         idset = SUMA_CoercedCopyofDset(sdset, SUMA_int, NULL);
      } else {
         idset = sdset;
      }
      if (!(SUMA_dset_to_Label_dset_cmap(idset, SM))) {
         SUMA_S_Err("Failed to make change");
         exit(1);
      }
      s = SUMA_OutputDsetFileStatus(
         sdset_prefix?sdset_prefix:SDSET_FILENAME(sdset),
                                 NULL, &iform, 
                                 NULL, ".lbl", &exists); 
      SUMA_AddNgrHist(sdset->ngr, FuncName, argc, argv);
      ooo = SUMA_WriteDset_s(s, idset, iform, 
                        THD_ok_overwrite(), 0);
      SUMA_free(ooo); ooo=NULL; SUMA_free(s); s = NULL;

      if (idset != sdset) SUMA_FreeDset(idset); 
      SUMA_FreeDset(sdset); sdset=NULL;
   }
   if (SM && !MapName && freesm) SUMA_Free_ColorMap(SM);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) { 
      SUMA_SL_Err("Failed to free commonfields."); 
   }
   
   SUMA_RETURN (0);
}   
Пример #17
0
/*!
   \brief parse the arguments for SurfSmooth program
   
   \param argv (char *)
   \param argc (int)
   \return Opt (SUMA_GETPATCH_OPTIONS *) options structure.
               To free it, use 
               SUMA_free(Opt->outfile);
               SUMA_free(Opt->histnote); 
               SUMA_free(Opt);
*/
SUMA_KUBATEST_OPTIONS *SUMA_SampBias_ParseInput(
      char *argv[], int argc, SUMA_KUBATEST_OPTIONS* Opt,
      SUMA_GENERIC_ARGV_PARSE *ps)
{
   static char FuncName[]={"SUMA_SampBias_ParseInput"}; 
   int kar, i, ind;
   char *outprefix;
   SUMA_Boolean brk = NOPE;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_ENTRY;


   kar = 1;
   brk = NOPE;
   Opt->debug = 0;
   Opt->plimit = 50;
   Opt->dlimit = 1000;
   Opt->outfile = NULL;
   Opt->prefix = NULL;
   Opt->segdo = NULL;
   Opt->ps=ps;
   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)
      {
         ps->hverb = strlen(argv[kar])>3?2:1;
         usage_SUMA_SampBias(ps);
         exit (0);
      }

      SUMA_SKIP_COMMON_OPTIONS(brk, kar);

      
      if (!brk && (strcmp(argv[kar], "-plimit") == 0)) 
      {
         kar++;
         if (kar >= argc)  
         {
            fprintf (SUMA_STDERR, "need argument after -plimit \n");
            exit (1);
         }
         Opt->plimit = atof(argv[kar]);
         brk = YUP;
      }
     
      if (!brk && (strcmp(argv[kar], "-dlimit") == 0)) 
      {
         kar++;
         if (kar >= argc)  
         {
            fprintf (SUMA_STDERR, "need argument after -dlimit \n");
            exit (1);
         }
         Opt->dlimit = atof(argv[kar]);
         brk = YUP;
      }
     
      if (!brk && (strcmp(argv[kar], "-out") == 0)) 
      {
         kar++;
         if (kar >= argc)  
         {
            fprintf (SUMA_STDERR, "need argument after -out \n");
            exit (1);
         }
         Opt->outfile = SUMA_copy_string(argv[kar]);
         brk = YUP;
      }
          
      if (!brk && (strcmp(argv[kar], "-segdo") == 0)) 
      {
         kar++;
         if (kar >= argc)  
         {
            fprintf (SUMA_STDERR, "need argument after -segdo \n");
            exit (1);
         }
         Opt->segdo = SUMA_Extension(argv[kar], ".1D.do", NOPE);
         brk = YUP;
      }
     
      if (!brk && (strcmp(argv[kar], "-prefix") == 0)) 
      {
         kar++;
         if (kar >= argc)  
         {
            fprintf (SUMA_STDERR, "need argument after -prefix \n");
            exit (1);
         }
         Opt->prefix = SUMA_copy_string(argv[kar]);
         brk = YUP;
      }
      
      
     if (!brk && !ps->arg_checked[kar]) 
      {
         SUMA_S_Errv("Option %s not understood. Try -help for usage\n", 
                     argv[kar]);
         suggest_best_prog_option(argv[0], argv[kar]);
         exit (1);
      } else 
      {
         brk = NOPE;
         kar ++;
      }
   }

   /* sanity checks */
   if (Opt->outfile == NULL && Opt->prefix == NULL) 
   {
      SUMA_SL_Err("No outfile, or prefix  specified.");
      exit(1);
   } 
   if (Opt->outfile) {
      if (!THD_ok_overwrite() && SUMA_filexists(Opt->outfile)) {
         SUMA_S_Errv("Outfile %s already exists\n", Opt->outfile);
         exit(1);
      }
   }
   if (Opt->prefix) {
      SUMA_DSET_NAME_CHECK(Opt->prefix); 
   }

   Opt->histnote = SUMA_HistString (NULL, argc, argv, NULL);
   
   SUMA_RETURN (Opt);
}
Пример #18
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;
}
Пример #19
0
int WB_netw_corr(int Do_r, 
                 int Do_Z,
                 int HAVE_ROIS, 
                 char *prefix, 
                 int NIFTI_OUT,
                 int *NROI_REF,
                 int *Dim,
                 double ***ROI_AVE_TS,
                 int **ROI_LABELS_REF,
                 THD_3dim_dataset *insetTIME,
                 byte *mskd2,
                 int Nmask,
                 int argc,
                 char *argv[])
{
   int i,j,k;
   float **AVE_TS_fl=NULL;    // not great, but another format of TS
   char OUT_indiv0[300];
   char OUT_indiv[300];
   char OUT_indivZ[300];
   MRI_IMAGE *mri=NULL;
   THD_3dim_dataset *OUT_CORR_MAP=NULL;
   THD_3dim_dataset *OUT_Z_MAP=NULL;
   float *zscores=NULL;
   int Nvox;


   Nvox = Dim[0]*Dim[1]*Dim[2];

   // make average time series per voxel
   AVE_TS_fl = calloc( 1,sizeof(AVE_TS_fl));  
   for(i=0 ; i<1 ; i++) 
      AVE_TS_fl[i] = calloc(Dim[3],sizeof(float)); 
   
   if( (AVE_TS_fl == NULL) ) {
      fprintf(stderr, "\n\n MemAlloc failure (time series out).\n\n");
      exit(123);
   }

   fprintf(stderr,"\nHAVE_ROIS=%d",HAVE_ROIS);
   for( k=0 ; k<HAVE_ROIS ; k++) { // each netw gets own file
      sprintf(OUT_indiv0,"%s_%03d_INDIV", prefix, k);
      mkdir(OUT_indiv0, 0777);
      for( i=0 ; i<NROI_REF[k] ; i++ ) {
         fprintf(stderr,"\nNROI_REF[%d]= %d",k,NROI_REF[k]);
         for( j=0 ; j<Dim[3] ; j++)
            AVE_TS_fl[0][j] = (float) ROI_AVE_TS[k][i][j];
         if( NIFTI_OUT )
            sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d.nii.gz",
                    OUT_indiv0,ROI_LABELS_REF[k][i+1]);
         else
            sprintf(OUT_indiv,"%s/WB_CORR_ROI_%03d",
                    OUT_indiv0,ROI_LABELS_REF[k][i+1]);
         mri = mri_float_arrays_to_image(AVE_TS_fl,Dim[3],1);
         OUT_CORR_MAP = THD_Tcorr1D(insetTIME, mskd2, Nmask,
                                    mri,
                                    "pearson", OUT_indiv);
         if(Do_r){
            THD_load_statistics(OUT_CORR_MAP);
            tross_Copy_History( insetTIME , OUT_CORR_MAP ) ;
            tross_Make_History( "3dNetcorr", argc, argv, OUT_CORR_MAP );
            if( !THD_ok_overwrite() && 
                THD_is_ondisk(DSET_HEADNAME(OUT_CORR_MAP)) )
               ERROR_exit("Can't overwrite existing dataset '%s'",
                          DSET_HEADNAME(OUT_CORR_MAP));
            THD_write_3dim_dataset(NULL, NULL, OUT_CORR_MAP, True);
            INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_CORR_MAP));

         }
         if(Do_Z){
          if( NIFTI_OUT )
             sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d.nii.gz",
                     OUT_indiv0,ROI_LABELS_REF[k][i+1]);
          else
             sprintf(OUT_indivZ,"%s/WB_Z_ROI_%03d",
                     OUT_indiv0,ROI_LABELS_REF[k][i+1]);

            OUT_Z_MAP = EDIT_empty_copy(OUT_CORR_MAP);
            EDIT_dset_items( OUT_Z_MAP,
                             ADN_nvals, 1,
                             ADN_datum_all , MRI_float , 
                             ADN_prefix    , OUT_indivZ,
                             ADN_none ) ;
            if( !THD_ok_overwrite() && 
                THD_is_ondisk(DSET_HEADNAME(OUT_Z_MAP)) )
               ERROR_exit("Can't overwrite existing dataset '%s'",
                          DSET_HEADNAME(OUT_Z_MAP));

            zscores = (float *)calloc(Nvox,sizeof(float)); 
            if( (zscores == NULL) ) {
               fprintf(stderr, "\n\n MemAlloc failure (zscores).\n\n");
               exit(123);
            }

            for( j=0 ; j<Nvox ; j++ )
              if( mskd2[j] ) // control for r ==1
                 BOBatanhf( THD_get_voxel(OUT_CORR_MAP, j, 0) );
                 /*
                 if( THD_get_voxel(OUT_CORR_MAP, j, 0) > MAX_R )
                   zscores[j] = (float) atanh(MAX_R);
                 else if ( THD_get_voxel(OUT_CORR_MAP, j, 0) < -MAX_R )
                   zscores[j] =  (float) atanh(-MAX_R);
                 else
                 zscores[j] = (float) atanh(THD_get_voxel(OUT_CORR_MAP, j, 0));*/
            
            EDIT_substitute_brick(OUT_Z_MAP, 0, MRI_float, zscores); 
            zscores=NULL;

            THD_load_statistics(OUT_Z_MAP);
            tross_Copy_History(insetTIME, OUT_Z_MAP);
            tross_Make_History("3dNetcorr", argc, argv, OUT_Z_MAP);
            THD_write_3dim_dataset(NULL, NULL, OUT_Z_MAP, True);
            INFO_message("Wrote dataset: %s\n",DSET_BRIKNAME(OUT_Z_MAP));

            DSET_delete(OUT_Z_MAP);
            free(OUT_Z_MAP);
            OUT_Z_MAP=NULL;
         }

         DSET_delete(OUT_CORR_MAP);
         free(OUT_CORR_MAP);
         OUT_CORR_MAP=NULL;
      }
   }
   
   free(zscores);
   mri_free(mri);
   for( i=0 ; i<1 ; i++) 
      free(AVE_TS_fl[i]);
   free(AVE_TS_fl);

   RETURN(1);
}
Пример #20
0
int main(int argc, char *argv[]) {
   int i,j,k,l,m,n,mm,ii;
   int idx;
   int iarg;
   THD_3dim_dataset *insetTIME = NULL;
   // THD_3dim_dataset *inset0 = NULL;
   THD_3dim_dataset *MASK=NULL;
   char *prefix="REHO" ;
   char in_name[300];
   char in_mask[300];
   
   THD_3dim_dataset *outset=NULL;
   char outname[300];

   int NIFTI_OUT=0;
   int DTYPE=0;

   int HAVE_MASK = 0;
   int ***mskd; // define mask of where time series are nonzero
   double temp_sum;

   // FILE *fout0, *fout1;
   int Nvox=-1;   // tot number vox
   int Dim[4]={0,0,0,0};
   
   float fbot = -1., ftop = -1;
   float delF = -1;
   float *allF=NULL;

   float **allPar=NULL;
   int Npar=NRSFC;   // currently... see list below
   char *namePar[NRSFC]={"ALFF", "MALFF", "FALFF",
                         "RSFA", "MRSFA", "FRSFA"};

   int MIN_full=0, MAX_full=-1; // indices of full spect
   int MIN_bp=0, MAX_bp = -1; // indices of lff/bp region

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

   // INFO_message("version: NU");
	
   /** scan args **/
   if (argc == 1) { usage_AmpToRSFC(1); exit(0); }
   iarg = 1; 
   while( iarg < argc && argv[iarg][0] == '-' ){
      if( strcmp(argv[iarg],"-help") == 0 || 
          strcmp(argv[iarg],"-h") == 0 ) {
         usage_AmpToRSFC(strlen(argv[iarg])>3 ? 2:1);
         exit(0);
      }
		
      if( strncmp(argv[iarg],"-band",5) == 0 ){
         if( ++iarg >= argc-1 ) ERROR_exit("need 2 arguments after -band!") ;

         fbot = strtod(argv[iarg++],NULL) ;
         ftop = strtod(argv[iarg++],NULL) ;
         continue ;
      }

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

         sprintf(in_mask,"%s", argv[iarg]); 
         MASK = THD_open_dataset(in_mask) ;
         if( (MASK == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_mask);

         DSET_load(MASK); CHECK_LOAD_ERROR(MASK);
			
         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],"-in_amp") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-in_amp'");

         sprintf(in_name,"%s", argv[iarg]); 
         DTYPE = 1; // for amps

         iarg++ ; continue ;
      }

      if( strcmp(argv[iarg],"-in_pow") == 0 ){
         iarg++ ; if( iarg >= argc ) 
                     ERROR_exit("Need argument after '-in_pow'");
         
         sprintf(in_name,"%s", argv[iarg]); 
         DTYPE = 2; // for pow
         
         iarg++ ; continue ;
      }

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

         sprintf(in_mask,"%s", argv[iarg]); 
         MASK = THD_open_dataset(in_mask) ;
         if( (MASK == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_mask);

         DSET_load(MASK); CHECK_LOAD_ERROR(MASK);
			
         iarg++ ; continue ;
      }

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

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

   // TEST BASIC INPUT PROPERTIES
   if (iarg < 3) {
      ERROR_message("Too few options. Try -help for details.\n");
      exit(1);
   }

   if( !DTYPE ) {
      ERROR_message("Think somebody forgot to specify an input file"
                    " using '-in_amp ...' or '-in_pow ...'.");
      exit(12);
   }
   else{
         insetTIME = THD_open_dataset(in_name) ;
         if( (insetTIME == NULL ))
            ERROR_exit("Can't open time series dataset '%s'.",in_name);
         
         DSET_load(insetTIME); CHECK_LOAD_ERROR(insetTIME);

         Nvox = DSET_NVOX(insetTIME) ;
         Dim[0] = DSET_NX(insetTIME); Dim[1] = DSET_NY(insetTIME); 
         Dim[2] = DSET_NZ(insetTIME); Dim[3]= DSET_NVALS(insetTIME); 
         delF = DSET_TR(insetTIME);
   }

   if( (fbot<0) || (ftop<0) ) {
      ERROR_message("Think somebody forgot to specify upper and lower"
                    " frequency bounds using '-band ... ...'.");
      exit(11);
   }
   if( fbot > ftop )
      ERROR_exit("Can't have ftop < fbot! Try entering frequency"
                    "band limits again");
   if( MASK ) 
      if ( Dim[0] != DSET_NX(MASK) || Dim[1] != DSET_NY(MASK) ||
           Dim[2] != DSET_NZ(MASK) ) {
         ERROR_message("Mask and inset don't appear to have the same "
                       "dimensions.\n");
         exit(1);
      }
  

	
   // ****************************************************************
   // ****************************************************************
   //                    pre-stuff, make storage
   // ****************************************************************
   // ****************************************************************

   // array of freqs-- starts at delta F, not zero, as the current
   // input data sets must!
   allF = (float *)calloc(Dim[3], sizeof(float));

   // will be the output
   allPar = calloc(Npar,sizeof(allPar)); 
   for(i=0 ; i<Npar ; i++) 
      allPar[i] = calloc(Nvox,sizeof(float)); 

   // MASK
   mskd = (int ***) calloc( Dim[0], sizeof(int **) );
   for ( i = 0 ; i < Dim[0] ; i++ ) 
      mskd[i] = (int **) calloc( Dim[1], sizeof(int *) );
   for ( i = 0 ; i < Dim[0] ; i++ ) 
      for ( j = 0 ; j < Dim[1] ; j++ ) 
         mskd[i][j] = (int *) calloc( Dim[2], sizeof(int) );

   if( (mskd == NULL) || (allF == NULL) || (allPar == NULL) ) {
      fprintf(stderr, "\n\n MemAlloc failure (mask).\n\n");
      exit(33);
   }


   // *************************************************************
   // *************************************************************
   //                    Beginning of main loops
   // *************************************************************
   // *************************************************************

   // Populate freq bands. For now, delF is constant.  Later.... who
   // knows, so make flexible
   allF[0] = DSET_TIMEORIGIN(insetTIME);
   if( allF[0] < EPS_V )
      ERROR_exit("The t-axis (here, frequency) origin is 0!"
                 "\n\t-> but you shouldn't have a baseline 0-frequency!");
   for( i=1 ; i<Dim[3] ; i++ )
      allF[i] = allF[i-1] + delF;

   // fill in rest of freq ranges; MIN_full=0 already
   MAX_full = Dim[3]-1;
   // these should be in order, so we can pass through like this.
   for( i=0 ; i<Dim[3] ; i++ ) {
      ii = Dim[3] - 1 - i;
      if( allF[ii] >= fbot )
         MIN_bp = ii;
      if( allF[i] <= ftop )
         MAX_bp = i;
   }
   if(MAX_bp < MIN_bp) // shouldn't happen...
      ERROR_exit("Something went horribly wrong with reading in the "
                 "bandpass limits! bot:%f, top:%f",MIN_bp, MAX_bp);

   INFO_message("Actual BP range: indices [%d, %d] -> "
                "freqs [%.4f, %.4f]", MIN_bp, MAX_bp, 
                allF[MIN_bp], allF[MAX_bp]);
   INFO_message("Full freq range: indices [%d, %d] -> "
                "freqs [%.4f, %.4f]", MIN_full, MAX_full, 
                allF[MIN_full], allF[MAX_full]);
   
   // go through once: define data vox
   idx = 0;
   for( k=0 ; k<Dim[2] ; k++ ) 
      for( j=0 ; j<Dim[1] ; j++ ) 
         for( i=0 ; i<Dim[0] ; i++ ) {
            if( HAVE_MASK ) {
               if( THD_get_voxel(MASK,idx,0)>0 )
                  mskd[i][j][k] = 1;
            }
            else {
               temp_sum = 0.;
               for ( l=0 ; l<Dim[3] ; l++ )
                  temp_sum+= abs(THD_get_voxel(insetTIME,idx,l));
               if ( temp_sum > EPS_V )
                  mskd[i][j][k] = 1;
            }
            idx++;
         }
   INFO_message("Done masking.");

   Spect_to_RSFC( insetTIME,
                  DTYPE,
                  Dim,
                  mskd,
                  MIN_bp, MAX_bp, 
                  MIN_full, MAX_full,
                  allPar,
                  Npar
                  );

   INFO_message("Done calculating parameters.");

   // **************************************************************
   // **************************************************************
   //                 Store and output
   // **************************************************************
   // **************************************************************

   for( m=0; m<Npar ; m++) {
      outset = EDIT_empty_copy(insetTIME) ;
      if(NIFTI_OUT)
         sprintf(outname,"%s_%s.nii.gz",prefix, namePar[m]);
      else
         sprintf(outname,"%s_%s",prefix, namePar[m]);
      
      INFO_message(" writing: %s %s", prefix, outname);
      
      EDIT_dset_items( outset,
                       ADN_nvals     , 1 ,
                       ADN_datum_all , MRI_float , 
                       ADN_prefix    , outname ,
                       ADN_none ) ;
      if( !THD_ok_overwrite() && THD_is_ondisk(DSET_HEADNAME(outset)) )
         ERROR_exit("Can't overwrite existing dataset '%s'",
                    DSET_HEADNAME(outset));
      EDIT_substitute_brick(outset, 0, MRI_float, allPar[m]); 
      allPar[m]=NULL;
      THD_load_statistics(outset);
      tross_Make_History("3dAmpToRSFC", argc, argv, outset);
      THD_write_3dim_dataset(NULL, NULL, outset, True);
      
      if(outset) {
         DSET_delete(outset);
         free(outset);
      }
   }



   // ************************************************************
   // ************************************************************
   //                    Freeing
   // ************************************************************
   // ************************************************************
	
   if(allF)
      free(allF);

   if(MASK) {
      DSET_delete(MASK);
      free(MASK);
   }
   if(insetTIME) {
      DSET_delete(insetTIME);
      free(insetTIME);
   }
  
   if(mskd) {
      for( i=0 ; i<Dim[0] ; i++) 
         for( j=0 ; j<Dim[1] ; j++) 
            free(mskd[i][j]);
      for( i=0 ; i<Dim[0] ; i++) 
         free(mskd[i]);
      free(mskd);
   }



   if(allPar) { // have freed other parts of this above
      free(allPar);
   }


   return 0;
}