예제 #1
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SampBias"};
   int N_Spec = -1;
   int i;
   SUMA_SurfaceObject *SO = NULL;
   SUMA_SurfSpecFile *Spec;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   void *SO_name = NULL;
   SUMA_DSET *dset=NULL;
   SUMA_Boolean LocalHead = NOPE;
   SUMA_KUBATEST_OPTIONS Opt;
   
   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;-sv;-s;-o;");
   
   SUMA_SampBias_ParseInput (argv, argc, &Opt, ps);
   if (argc < 4)
   {
      SUMA_S_Err("Too few arguments");
      exit (0);
   }
   
   
   /* read surface */
   Spec = SUMA_IO_args_2_spec(ps, &N_Spec);
   if (N_Spec == 0) {
      SUMA_S_Err("No surfaces found.");
      exit(1);
   }

   SUMA_LH("Loading surface...");
   SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], Opt.debug);
   if (!SO) {
         fprintf (SUMA_STDERR,"Error %s:\n"
                              "Failed to find surface\n"
                              "in spec file. \n",
                              FuncName );
         exit(1);
      
   }
   
   
   if (!(dset = calcWithOffsets(SO, &Opt))) {
      SUMA_S_Err("Failed to calc ratios");
      exit(1);
   }
      
   if (!SUMA_AddNgrHist(dset->ngr, "SampBias", argc, argv)) {
      SUMA_S_Err("Failed to add history");
   }

   if (Opt.prefix) {
      char *cc = SUMA_WriteDset_s(Opt.prefix, dset, 
                                  SUMA_NO_DSET_FORMAT, 1,1);
      if (cc) SUMA_free(cc);
   }   
      
   SUMA_LH("clean up");
   if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) {
      SUMA_SL_Err("DO Cleanup Failed!");
   }

   if (Opt.outfile) SUMA_free(Opt.outfile);
   if (Opt.histnote) SUMA_free(Opt.histnote);
   if (Opt.prefix) SUMA_free(Opt.prefix);
   if (Opt.segdo) SUMA_free(Opt.segdo);
   
   if (!SUMA_FreeSpecFields(Spec)) {
      SUMA_S_Err("Failed to free SpecFields");
   } SUMA_free(Spec); Spec = NULL;
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   
   if (!SUMA_Free_CommonFields(SUMAg_CF)) {
      SUMA_SL_Err("SUMAg_CF Cleanup Failed!");}
   
   
   SUMA_RETURN(0);
}
예제 #2
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfMatch"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_SurfSpecFile *Spec = NULL;
   int N_Spec=0, N_inmask;
   byte *cmask=NULL;
   SUMA_SurfaceObject *SO = NULL, *SOr=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;");
   
   if (argc < 2) {
      usage_SurfMatch(ps, 0);
      exit (1);
   }
   
   Opt = SUMA_SurfMatch_ParseInput (argv, argc, ps);

   if (Opt->debug > 2) LocalHead = YUP;
   
   /* check on inputs */
   if (ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames != 2) {
      SUMA_S_Err("Must have two surfaces");
      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);
   }

   SOr = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 1);
   if (!SOr) {
         fprintf (SUMA_STDERR,"Error %s:\n"
                              "Failed to find surface\n"
                              "in spec file. \n",
                              FuncName );
         exit(1);
      
   }   
   
   if (Opt->efrac>0.0) {
      SUMA_SurfaceObject *SOrr=NULL;
      if (!(SOrr = SUMA_Mesh_Resample_nodes(SOr, Opt->efrac))) {
         SUMA_S_Errv("Failed to resample initial mesh at %f\n",Opt->efrac);
         exit(1);
      }
      SUMA_Free_Surface_Object(SOr); SOr=SOrr; SOrr=NULL;
      SUMA_SurfaceMetrics_eng(SOr, "EdgeList|MemberFace", NULL, 0, 
                                          SUMAg_CF->DsetList);
      if (!SOr->Label && !(SUMA_SurfaceFileName(SOr, NOPE))) {
         SOr->Label = SUMA_copy_string("Le_Remaille");
      }
   }
   
   SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 1);

   if (Opt->flt1 != 1.0) {
      SUMA_LHv("Masking out nodes deeper than %f mm", Opt->flt1);
      N_inmask = SUMA_NodeDepth(SO->NodeList, SO->N_Node, prjdir,  NULL, 
                                Opt->flt1, &cmask, NULL);
   } else {
      N_inmask = SO->N_Node;
   }
   
   SUMA_S_Notev("Have Reference %s %d nodes, input %s, %d nodes (%d in mask)\n",
                  SOr->Label, SOr->N_Node, SO->Label, SO->N_Node, N_inmask);
   if (Opt->b1) {
      Opt->s = SUMA_append_replace_string(Opt->s,"City", " ; ", 1);
   }
   SUMA_AlignCoords(SO->NodeList, SO->N_Node, cmask, 1, SOr, Opt->s);
   
   /* write surface */
   if (!SUMA_Save_Surface_Object_Wrap (Opt->out_prefix, NULL, SO, 
                                  SUMA_FT_NOT_SPECIFIED, SUMA_FF_NOT_SPECIFIED, 
                                  NULL)) {
      SUMA_S_Err("Failed to write surface of whole head");
      exit (1);
   }

   if (SOr) SUMA_Free_Surface_Object(SOr); SOr = NULL;
   if (SO) SUMA_Free_Surface_Object(SO); SO = NULL;
   
   if (cmask) SUMA_free(cmask); cmask=NULL;                 
   if (ps) SUMA_FreeGenericArgParse(ps); ps = 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 (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);
   
} 
예제 #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[])
{/* 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);
   
} 
예제 #5
0
파일: SUMA_suma.c 프로젝트: pmolfese/afni
/*!\**
File : SUMA.c
\author : Ziad Saad
Date : Thu Dec 27 16:21:01 EST 2001
   
Purpose : 
   
   
   
Input paramters : 
\param   
\param   
   
Usage : 
      SUMA ( )
   
   
Returns : 
\return   
\return   
   
Support : 
\sa   OpenGL prog. Guide 3rd edition
\sa   varray.c from book's sample code
   
Side effects : 
   
   
   
***/
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"suma"}; 
   int kar, i;
   SUMA_SFname *SF_name;
   SUMA_Boolean brk, SurfIn;
   char  *NameParam, *AfniHostName = NULL, *s = NULL, *pdspec=NULL, *pdsv=NULL;
   char *specfilename[SUMA_MAX_N_GROUPS], *VolParName[SUMA_MAX_N_GROUPS];
   byte InMem[SUMA_MAX_N_GROUPS];
   SUMA_SurfSpecFile *Specp[SUMA_MAX_N_GROUPS];   
   SUMA_Axis *EyeAxis;    
   SUMA_EngineData *ED= NULL;
   DList *list = NULL;
   DListElmt *Element= NULL;
   int iv15[15], N_iv15, ispec, nspec;
   struct stat stbuf;
   float fff=0.0;
   int Start_niml = 0;
   SUMA_Boolean  Domemtrace = YUP;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_Boolean LocalHead = NOPE;
   
    
   SUMA_STANDALONE_INIT;
   SUMA_mainENTRY;
   
   
   SUMAg_CF->isGraphical = YUP;
   
   ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-dset;-do;");

   /* initialize Volume Parent and AfniHostName to nothing */
   for (ispec=0; ispec < SUMA_MAX_N_GROUPS; ++ispec) {
      specfilename[ispec] = NULL;
      VolParName[ispec] = NULL;
      Specp[ispec] = NULL;
      InMem[ispec] = 0;
   }
   AfniHostName = NULL; 
   
      
   /* Allocate space for DO structure */
   SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   
   /* call the function to parse the other surface mode inputs */
   ispec = 0;
   if (LocalHead) SUMA_Show_IO_args(ps);
   if (ps->i_N_surfnames || ps->t_N_surfnames || ps->N_DO) {
      SUMA_LH("-i and/or -t surfaces on command line!");
      Specp[ispec] = SUMA_IO_args_2_spec (ps, &nspec); 
      if (Specp[ispec]) {
         ++ispec;
         if (nspec != 1) {
            SUMA_S_Errv("-spec is being parsed separately here, "
                        "expecting one spec only from SUMA_IO_args_2_spec, \n"
                        "got %d\n", nspec);
            exit (1);
         }
      } else {
         SUMA_S_Err("Failed to load -i/-t surfaces");
         exit(1);
      }
      
   }
   /* Work the options */
   kar = 1;
   brk = NOPE;
   SurfIn = NOPE;
   Domemtrace = YUP; 
   while (kar < argc) { /* loop accross command ine options */
      /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
      
      if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
         SUMA_usage (ps, strlen(argv[kar]) > 3 ? 2:1);
          exit (0); /* return a good status on -help   12 Jul 2013 [rickr] */
      }
      
      /* -list_ports list and quit */
      if( strncmp(argv[kar],"-list_ports", 8) == 0) {
         show_ports_list(); exit(0);
      }
      
      /* -port_number and quit */
      if( strncmp(argv[kar],"-port_number", 8) == 0) {
         int pp = 0;
         if( ++kar >= argc ) 
            ERROR_exit("need an argument after -port_number!"); 
         pp = get_port_named(argv[kar]);
         if (strcmp(argv[kar-1], "-port_number_quiet")) { 
            fprintf(stdout, "\nPort %s: %d\n", argv[kar], pp); 
         } else {
            fprintf(stdout, "%d\n", pp); 
         }
         if (pp < 1) exit(1);
         else exit(0);
      }
      
      if (strcmp(argv[kar], "-visuals") == 0) {
          SUMA_ShowAllVisuals ();
          exit (0);
      }
      
      if (strcmp(argv[kar], "-brethren_windows") == 0) {
          Display *dd=NULL; Window ww;
          if (!(dd = XOpenDisplay(NULL))) {
            SUMA_S_Err("No display "); exit(1);
          }
          ww = XDefaultRootWindow(dd);
          
          SUMA_WindowsOnRootDisplay(dd, ww , 0);
          exit (0);
      }
      
      if (strcmp(argv[kar], "-version") == 0) {
          s = SUMA_New_Additions (0.0, 1);
          fprintf (SUMA_STDOUT,"%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-sources") == 0) {
          s = SUMA_sources_Info();
          fprintf (SUMA_STDOUT,"%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-help_nido") == 0) {
         s = SUMA_NIDO_Info();
         fprintf (SUMA_STDOUT,"%s\n", s); 
         SUMA_free(s); s = NULL;
         exit (0);
      }
      
      if (strcmp(argv[kar], "-all_latest_news") == 0) {
          s = SUMA_New_Additions (-1.0, 0);
          fprintf (SUMA_STDOUT,"%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-help_sphinx_interactive") == 0) {
         FILE *fout = NULL;
         if( ++kar >= argc ) 
            ERROR_exit("need a file name after -help_sphinx_interactive!");       
          fout = fopen(argv[kar],"w");
          if (!fout) {
            SUMA_S_Err("Failed to open %s for writing", argv[kar]);
            exit(1);
          }
          SUMA_help_message(fout,SPX);
          fclose(fout); fout = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-help_interactive") == 0) {
          FILE *fout = fopen("Mouse_Keyboard_Controls.txt","w");
          if (!fout) {
            SUMA_S_Err("Failed to open Mouse_Keyboard_Controls.txt for writing");
            exit(1);
          }
          SUMA_help_message(fout,TXT);
          fclose(fout); fout = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-test_help_string_edit") == 0) {
         SUMA_Sphinx_String_Edit_Help(SUMA_STDOUT, 0);
         exit(0);
      }
      if (strcmp(argv[kar], "-test_help_string_edit_web") == 0) {
         SUMA_Sphinx_String_Edit_Help(SUMA_STDOUT, 1);
         exit(0);
      }
      
      if (strcmp(argv[kar], "-environment") == 0) {
          s = SUMA_env_list_help (0, TXT);
          fprintf (SUMA_STDOUT,  
            "#SUMA ENVIRONMENT \n"
            "# If you do not have a ~/.sumarc file, cannot find a SUMA\n"
            "# environment variable that's been mentioned in documentation,\n"
            "# or fervently desire to update your current ~/.sumarc with  \n"
            "# all the latest variables that SUMA uses, you should run: \n"
            "# \n"
            "#    suma -update_env\n"
            "# \n"
            "# Unless you have setup SUMA environment variables outside of\n"
            "# your ~/.sumarc file, updating your ~/.sumarc file with \n"
            "# 'suma -update_env' WILL NOT ALTER changes you have already\n"
            "# made to the variables in your current ~/.sumarc. \n"
            "# For this reason consider running the update command after each \n"
            "# upgrade of your AFNI/SUMA binaries.\n" 
            "***ENVIRONMENT\n"
                  "%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-default_env") == 0) {
          s = SUMA_env_list_help (1, NO_FORMAT);
          fprintf (SUMA_STDOUT,  
                  "#SUMA DEFAULT ENVIRONMENT (user settings ignored)\n"
                  "# see also suma -udate_env or suma -environment\n"
                  "# \n"
                  "***ENVIRONMENT\n"
                  "%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-update_env") == 0) {
          if (system("suma -environment > ___sumarc")) {
            SUMA_S_Err("Failed to create env file.");
            exit(1);
          }
          if (SUMA_filexists("~/.sumarc")) {
            if (system("\\cp -f ~/.sumarc ~/.sumarc-bak")) {
               SUMA_S_Err("Failed to backup ~/.sumarc to ~/.sumarc-bak.");
               exit(1);
            }
          }
          if (system("\\mv ___sumarc ~/.sumarc")) {
            SUMA_S_Err("Failed to copy newrc (___sumarc) to ~/.sumarc");
            exit(1); 
          }
          SUMA_S_Note("Environment update done.");
          exit(0);
      }
      
      if (strcmp(argv[kar], "-latest_news") == 0) {
          s = SUMA_New_Additions (0.0, 0);
          fprintf (SUMA_STDOUT,"%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-progs") == 0) {
          s = SUMA_All_Programs();
          fprintf (SUMA_STDOUT,"%s\n", s); 
          SUMA_free(s); s = NULL;
          exit (0);
      }
      
      if (strcmp(argv[kar], "-motif_ver") == 0) {  /* 9 Mar 2009 [rickr] */
         show_motif_version_string();
         exit (0);
      }
      
      if (!brk && (strcmp(argv[kar], "-iodbg") == 0)) {
         fprintf(SUMA_STDERR,"Error %s: Obsolete, use -trace\n", FuncName);
         exit (0);
         /*
         fprintf(SUMA_STDOUT,
                 "Warning %s: SUMA running in in/out debug mode.\n", FuncName);
         SUMA_INOUT_NOTIFY_ON; 
         brk = YUP;
         */
      }
      
      
      
      SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      #if SUMA_MEMTRACE_FLAG
         if (!brk && (strcmp(argv[kar], "-memdbg") == 0)) {
            fprintf(SUMA_STDOUT,"Error %s: -memdbg is obsolete, use -trace\n", 
                                FuncName);
            exit (0);
            fprintf( SUMA_STDOUT,
                     "Warning %s: SUMA running in memory trace mode.\n", 
                     FuncName);
            SUMAg_CF->MemTrace = YUP;
            #ifdef USING_MCW_MALLOC
            #endif
            brk = YUP;
         }
      #endif
      
      if (!brk && (strcmp(argv[kar], "-dev") == 0)) {
         fprintf(SUMA_STDOUT,
                  "Warning %s: SUMA running in developer mode, "
                  "some options may malfunction.\n", FuncName);
         SUMAg_CF->Dev = YUP;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-fake_cmap") == 0)) {
         SUMA_S_Warn("-fake_cmap is for automatic selfies of the widgets.\n"
                     "You should not use this option for any other reason\n");
         SUMAg_CF->Fake_Cmap = YUP;
         brk = YUP;
      }
      
      if (!brk && SUMAg_CF->Dev && (strcmp(argv[kar], "-truth_table") == 0)) {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need expression after -truth_table \n");
            exit (1);
         }
         SUMA_bool_eval_truth_table(argv[kar], 0);  exit(0);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-niml") == 0)) {
         Start_niml = 1;
         brk = YUP;
      }

      if (!brk && (strcmp(argv[kar], "-noniml") == 0)) {
         Start_niml = -1;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-vp") == 0 || 
                   strcmp(argv[kar], "-sa") == 0 || 
                   strcmp(argv[kar], "-sv") == 0))
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -vp|-sa|-sv \n");
            exit (1);
         }
         if (ispec < 1) {
            fprintf (SUMA_STDERR, 
                     "a -spec option must precede the first -sv option\n");
            exit (1);
         }
         if (!specfilename[ispec-1] && !Specp[ispec-1]) {
            fprintf (SUMA_STDERR, 
                     "a -spec option must precede each -sv option\n");
            exit (1);
         }
         VolParName[ispec-1] = argv[kar]; 
         if (LocalHead) {
            fprintf(SUMA_STDOUT, "Found: %s\n", VolParName[ispec]);
         }
         
         brk = YUP;
      }      
      
      if (!brk && strcmp(argv[kar], "-drive_com") == 0)
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -drive_com\n");
            exit (1);
         }
         SUMAg_CF->dcom = (char **)SUMA_realloc(SUMAg_CF->dcom,
                                          (SUMAg_CF->N_dcom+1)*sizeof(char *));
         SUMAg_CF->dcom[SUMAg_CF->N_dcom] = SUMA_copy_string(argv[kar]);
         ++SUMAg_CF->N_dcom;
         brk = YUP;
      }
      
      if (!brk && strcmp(argv[kar], "-ah") == 0)
      {
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -ah\n");
            exit (1);
         }
         if (strcmp(argv[kar],"localhost") != 0) {
            AfniHostName = argv[kar];
         }else {
           fprintf (SUMA_STDERR, 
                    "localhost is the default for -ah\n"
                    "No need to specify it.\n");
         }
         /*fprintf(SUMA_STDOUT, "Found: %s\n", AfniHostName);*/

         brk = YUP;
      }   
      
      if (!brk && strcmp(argv[kar], "-spec") == 0)
      { 
         kar ++;
         if (kar >= argc)  {
              fprintf (SUMA_STDERR, "need argument after -spec \n");
            exit (1);
         }
         
         if (ispec >= SUMA_MAX_N_GROUPS) {
            fprintf (SUMA_STDERR, 
                     "Cannot accept more than %d spec files.\n",     
                     SUMA_MAX_N_GROUPS);
            exit(1);
         }
         
         if (SUMA_is_predefined_SO_name(argv[kar], NULL, 
                                        &pdspec, &pdsv, NULL) == 3) {
            specfilename[ispec] = pdspec; pdspec = NULL; /* Memory leak! */
            VolParName[ispec] = pdsv; pdsv = NULL; /* Memory leak! */
         } else {
            specfilename[ispec] = argv[kar]; 
         }
         if (LocalHead) {
            fprintf(SUMA_STDOUT, "Found: %s\n", specfilename[ispec]);
         }
         ++ispec;
         brk = YUP;
      } 
      
      
      if (!brk && !ps->arg_checked[kar]) {
         if (  !strcmp(argv[kar], "-i") ||
               !strncmp(argv[kar], "-i_",3) ) {
            fprintf (SUMA_STDERR,
      "Error %s: Option %s not understood. \n"
      "  Make sure parameter after -i or -i_ is the full name of a surface.\n"
      "%s",
      FuncName, argv[kar], 
      strlen(argv[kar])==2 ? 
         "For -i to work, SUMA needs to guess at the surface type from\n"
         "  the filename extensions. If SUMA fails try the full -i_* option"
         " instead.\n" : ""
      );
         } else {
            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 ++;
      }
      
   }/* loop accross command ine options */
   /* -ah option now checked for in ps */
   if (ps->cs->afni_host_name && !AfniHostName) {
      AfniHostName = SUMA_copy_string(ps->cs->afni_host_name);
   }
   
   #if 0
   SUMA_S_Note("KILL ME");
   { 
      int i,j, nl; 
      SUMA_TextBoxSize("Hello", &i,&j,&nl,NULL); 
      SUMA_TextBoxSize("", 
                        &i,&j,&nl,GLUT_BITMAP_8_BY_13); 
      SUMA_TextBoxSize("O", 
                        &i,&j,&nl,GLUT_BITMAP_8_BY_13); 
                        SUMA_TextBoxSize(NULL, 
                        &i,&j,&nl,GLUT_BITMAP_8_BY_13); 
   }
   SUMA_ReadNIDO("/Users/ziad/SUMA_test_dirs/DO/TextDO/sample.niml.do", NULL);   
   exit(1);
      
   #endif
      
   /* Make surface loading pacifying */
   SetLoadPacify(1);
   
   #if 0
   if (ps->N_DO) { /* Have DOs on command line */
      if (Specp[0]) { /* Add to Specp[0] */
         if (ps->N_DO + Specp[0]->N_DO > SUMA_MAX_DO_SPEC) {
            SUMA_S_Warn("Too many DOs, increase static limit..");
                                       /* ignore extras for now */
            ps->N_DO = SUMA_MAX_DO_SPEC - Specp[0]->N_DO;
         }
         for (i=0; i<ps->N_DO; ++i) {
            strcpy(Specp[0]->DO_name[Specp[0]->N_DO], ps->DO_name[i]);
            Specp[0]->DO_type[Specp[0]->N_DO] = ps->DO_type[i];
            ++Specp[0]->N_DO;
         }
      } else {
         Specp[0]
      }
   }
   #endif
      
   /* any Specp to be found ?*/
   if (specfilename[0] == NULL && Specp[0] == NULL) {
      SUMA_SurfaceObject **SOv=NULL;
      int N_SOv = 0;
      fprintf (SUMA_STDERR,
               "\n"
               "%s: \n"
               "     No input specified, loading some toy surfaces...\n"
               "     Use '.' and ',' to cycle between them.\n"
               "     See suma -help for assistance.\n"
               "\n", FuncName);
      /* create your own surface and put it in a spec file */
      SOv = SUMA_GimmeSomeSOs(&N_SOv);
      Specp[ispec] = SUMA_SOGroup_2_Spec (SOv, N_SOv);
      SUMA_free(SOv); SOv = NULL;
      InMem[ispec] = 1;
      ++ispec;
   }

   if(!SUMA_Assign_HostName (SUMAg_CF, AfniHostName, -1)) {
      fprintf (SUMA_STDERR, 
         "Error %s: Failed in SUMA_Assign_HostName\n", FuncName);
      exit (1);
   }
   
   #ifdef SUMA_DISASTER
   /* a function to test Memtracing */
   {
      int *jnk;
      jnk = SUMA_disaster();
      SUMA_free(jnk); /* without the -trace, you'll get a 
                           warning here if jnk is corrupted */
   }
   #endif
   
   /* create an Eye Axis DO */
   EyeAxis = SUMA_Alloc_Axis ("Eye Axis", AO_type);
   if (EyeAxis == NULL) {
      SUMA_error_message (FuncName,"Error Creating Eye Axis",1);
      exit(1);
   }

   /* Store it into SUMAg_DOv */
   if (!SUMA_AddDO(  SUMAg_DOv, &SUMAg_N_DOv, 
                     (void *)EyeAxis,  AO_type, SUMA_SCREEN)) {
      SUMA_error_message (FuncName,"Error Adding DO", 1);
      exit(1);
   }
   /*fprintf (SUMA_STDERR, "SUMAg_N_DOv = %d created\n", SUMAg_N_DOv);
   SUMA_Show_DOv(SUMAg_DOv, SUMAg_N_DOv, NULL);*/

   /* Allocate space (and initialize) Surface Viewer Structure */
   SUMAg_SVv = SUMA_Alloc_SurfaceViewer_Struct (SUMA_MAX_SURF_VIEWERS);
   
   /* SUMAg_N_SVv gets updated in SUMA_X_SurfaceViewer_Create
   and reflects not the number of elements in SUMAg_SVv which is
   SUMA_MAX_SURF_VIEWERS, but the number of viewers that were realized
   by X */
   
   /* Check on initialization */
   /*SUMA_Show_SurfaceViewer_Struct (SUMAg_cSV, stdout);*/

   /* Create the Surface Viewer Window */
   if (!SUMA_X_SurfaceViewer_Create ()) {
      fprintf(stderr,"Error in SUMA_X_SurfaceViewer_Create. Exiting\n");
      return 1;
   }
   
   for (i=0; i<ispec; ++i) {
      if (!list) list = SUMA_CreateList();
      ED = SUMA_InitializeEngineListData (SE_Load_Group);
      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_cp, (void *)specfilename[i], 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_Head, NULL ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }
      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_ip, (void *)Specp[i], 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_In, Element ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }
      fff = (float) InMem[i];
      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_f, (void *)&fff, 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_In, Element ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }
      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_vp, (void *)VolParName[i], 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_In, Element ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }

      N_iv15 = SUMA_MAX_SURF_VIEWERS;
      if (N_iv15 > 15) {
         fprintf( SUMA_STDERR,
                  "Error %s: trying to register more than 15 viewers!\n", 
                  FuncName);
         exit(1);
      }
      for (kar=0; kar<N_iv15; ++kar) iv15[kar] = kar;
      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_iv15, (void *)iv15, 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_In, Element ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }

      if (!( Element = SUMA_RegisterEngineListCommand (  list, ED, 
                                             SEF_i, (void *)&N_iv15, 
                                             SES_Suma, NULL, NOPE, 
                                             SEI_In, Element ))) {
         fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
         exit (1);
      }
   }
   
   if (ispec > 0 && !SUMA_Engine (&list)) {
      fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_Engine\n", FuncName);
      exit (1);
   }
   
   /* For some reason, I had to add the glLightfv line below
   to force the lightflipping done in SUMA_SetupSVforDOs to take place
   in the A viewer when first opened. I don't know why that is, especially
   since other controllers would show up lit correctly without this 
   glLightfv line below.
      To make matters worse, the A controller's light0_position is correctly 
   flipped.
      It is just that the shading is done as if the position was never flipped. 
   Actually, without the line below, the first time you hit the F key (to 
   manually flip the light), nothing changes, that's because the light's position    is unflipped, which is supposed to show the incorrect lighting. 
   You'll have to hit F again to have the lighting correctly flipped 
   and the shading reflecting it.... ZSS, Aug. 05 04 */
   glLightfv(GL_LIGHT0, GL_POSITION, SUMAg_SVv[0].light0_position); 

   if (Start_niml != -1 && (Start_niml == 1|| AFNI_yesenv("SUMA_START_NIML"))) {
      if (!list) list = SUMA_CreateList();
      SUMA_REGISTER_HEAD_COMMAND_NO_DATA( list, SE_StartListening, 
                                          SES_Suma, NULL);

      if (!SUMA_Engine (&list)) {
         fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName);
         exit (1);   
      }
   }
   
   /* load the datasets onto the first SO, if any, else hope that dset 
      is some form of DO  */
   if (ps->N_dsetname>0) {
      SUMA_SurfaceObject *SO = SUMA_findanySOp_inDOv(SUMAg_DOv, 
                                                     SUMAg_N_DOv, NULL);
      if (!SO) {
         SUMA_LH("Could not find any SO, here is hoping dset is a DO");
      }
      for (i=0; i<ps->N_dsetname; ++i) {
         if (!(SUMA_LoadDsetOntoSO_eng(ps->dsetname[i], SO, 1, 1, 1, NULL))) {
            SUMA_S_Errv("Failed to load %s onto %s\n", 
                        ps->dsetname[i], SO?SO->Label:"NULL");
         }
      }
   }

   SUMA_FreeGenericArgParse(ps); ps = NULL;
 
   /* A Warning about no sumarc */
   if (NoSumaRcFound()) { 
         SUMA_S_Warn(
"\n"
" No sumarc file found. You should create one by running the following:\n"
"\n"
"              suma -update_env\n"
"\n"
" I also recommend you run 'suma -update_env' whenever you update AFNI.\n" 
"\n"
" See details for -environment and -update_env options in suma -help's output.\n"
"\n");
   }
   
   /*Main loop */
   XtAppMainLoop(SUMAg_CF->X->App);

   
   /* Done, clean up time */
   if (ispec) {
      int k=0; 
      for (k=0; k<ispec; ++k) {
         if (!SUMA_FreeSpecFields((Specp[k]))) { 
            SUMA_S_Err("Failed to free spec fields"); 
         } 
         Specp[k] = NULL;
      }
   } ispec = 0;
  
   if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) 
      SUMA_error_message(FuncName,"DO Cleanup Failed!",1);
   if (!SUMA_Free_SurfaceViewer_Struct_Vect (SUMAg_SVv, SUMA_MAX_SURF_VIEWERS)) 
      SUMA_error_message(FuncName,"SUMAg_SVv Cleanup Failed!",1);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) 
      SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
  SUMA_RETURN(0);             /* ANSI C requires main to return int. */
}/* Main */ 
예제 #6
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[]= {"SurfQual"};
    char *OutName = NULL, ext[5], *prefix = NULL, *shist=NULL;
    SUMA_SURFQUAL_OPTIONS *Opt;
    int SO_read = -1;
    int i, cnt, trouble, consistent = -1, eu = -1, nsi = -1, N_Spec=0;
    SUMA_SurfaceObject *SO = NULL;
    SUMA_SurfSpecFile *Spec=NULL;
    void *SO_name = NULL;
    SUMA_Boolean DoConv = NOPE, DoSphQ = NOPE, DoSelfInt = NOPE;
    int N_bad_nodes, N_bad_facesets;
    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_SurfQual_ParseInput (argv, argc, ps);
    if (argc < 2)
    {
        SUMA_S_Err("Too few options");
        usage_SUMA_SurfQual(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->self_intersect) DoSelfInt = YUP;

    DoConv = NOPE;
    DoSphQ = NOPE;
    if (Opt->surftype) {
        if (!strcmp(Opt->surftype, "-sphere")) {
            DoSphQ = YUP;
        } else {
            /* Don't complain anymore, maybe winding checking is all users need */
        }
    }

    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);
        }
        fprintf(SUMA_STDERR,"\nReport for Surface %s\n", SO->Label);
        /* do the quality thing based on the Opt->surftype */
        if (!Opt->out_prefix) prefix = SUMA_copy_string(SO->Label);
        else prefix = SUMA_copy_string (Opt->out_prefix);

        /* check the winding */
        if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet,
                                  SO->EL, 0, &trouble)) {
            SUMA_S_Warn(
                "Failed to make sure surface's mesh is consistently wound.\n"
                "You should fix the mesh.\n");
            consistent = 0;
        }

        {
            int iii=0, isbad=0, ht0;
            int *badedge=(int*)SUMA_calloc(SO->N_Node, sizeof(int));
            /* check on troubled edges */
            while (iii < SO->EL->N_EL) {
                ht0 = SO->EL->ELps[iii][1];
                /* make sure edge is not part of three triangles, if it is,skip it*/
                if (SO->EL->ELps[iii][2] > 2) {
                    ++iii;
                    fprintf( SUMA_STDERR,
                             "%s: Bad edge (#%d: %d--%d), \n"
                             " part of more than 2 triangles, skip it\n",
                             FuncName, i, SO->EL->EL[iii][0], SO->EL->EL[iii][1]);
                    ++badedge[SO->EL->EL[iii][0]];
                    ++badedge[SO->EL->EL[iii][1]];
                    isbad = 1;
                    continue;
                }
                ++iii;
            }
            if (isbad) {
                if (Spec->N_Surfs > 1) {
                    sprintf(ext,"_%c", 65+i);
                    OutName = SUMA_append_replace_string (
                                  prefix,
                                  "_BadEdgeNodes.1D.dset",
                                  ext, 0);
                } else {
                    OutName = SUMA_append_string (prefix, "_BadEdgeNodes.1D.dset");
                }
                SUMA_WRITE_ARRAY_1D(badedge,SO->N_Node,1,OutName);
                if (OutName) SUMA_free(OutName);
                OutName = NULL;
            }
            SUMA_free(badedge);
            badedge = NULL;
        }

        if (DoConv) {
            float *Cx = NULL;
            if (Spec->N_Surfs > 1) {
                sprintf(ext,"_%c", 65+i);
                OutName = SUMA_append_replace_string
                          (prefix, "_Conv_detail.1D.dset", ext, 0);
            } else {
                OutName = SUMA_append_string (prefix, "_Conv_detail.1D.dset");
            }
            Cx = SUMA_Convexity_Engine ( SO->NodeList, SO->N_Node,
                                         SO->NodeNormList, SO->FN, OutName, NULL);
            if (Cx) SUMA_free(Cx);
            Cx = NULL;
            if (OutName) SUMA_free(OutName);
            OutName = NULL;
        }

        if (DoSphQ) {
            if (Spec->N_Surfs > 1) {
                sprintf(ext,"_%c", 65+i);
                OutName = SUMA_append_string (prefix, ext);
            } else {
                OutName = SUMA_copy_string (prefix);
            }
            shist = SUMA_HistString (NULL, argc, argv, NULL);
            SUMA_SphereQuality (SO, OutName, shist, &N_bad_nodes, &N_bad_facesets);
            if (shist) SUMA_free(shist);
            shist = NULL;
            if (OutName) SUMA_free(OutName);
            OutName = NULL;
        }

        if (trouble) { /* put winding problem here to make it visible */
            fprintf (SUMA_STDERR,"\n");
            SUMA_S_Warn(
                "Mesh is not consistent, use ConvertSurface's -make_consistent \n"
                "option to fix the problem before proceeding further.\n"
                "Other results reported by this and other programs\n"
                "may be incorrect if mesh is not consistently wound.\n" );
            consistent = 0;
        } else {
            consistent = 1;
            fprintf (SUMA_STDERR,"\n");
            fprintf (SUMA_STDERR,"Surface is consistently wound\n");
        }
        {
            SUMA_EULER_SO(SO, eu);
            fprintf (SUMA_STDERR,"\n");
            fprintf(SUMA_STDERR,"Surface Euler Characteristic is: %d\n", eu);
        }
        if ((SO->EL->min_N_Hosts == 1 || SO->EL->max_N_Hosts == 1)) {
            fprintf (SUMA_STDERR,"\n");
            fprintf(SUMA_STDERR,
                    "Warning %s:\n"
                    " Min/Max number of edge hosting triangles: [%d/%d] \n",
                    FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts);
            fprintf( SUMA_STDERR,
                     " You have edges that form a border in the surface.\n");
        }
        if (SO->EL->min_N_Hosts == 2 && SO->EL->max_N_Hosts == 2) {
            fprintf (SUMA_STDERR,"\n");
            fprintf(SUMA_STDERR,"Surface is closed and is a 2-manifold.");
        }
        if (SO->EL->min_N_Hosts > 2 || SO->EL->max_N_Hosts > 2) {
            fprintf (SUMA_STDERR,"\n");
            fprintf( SUMA_STDERR,
                     "Warning %s:\n"
                     "Min/Max number of edge hosting triangles: [%d/%d] \n",
                     FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts);
            fprintf(SUMA_STDERR,
                    "Warning %s:\n"
                    " You have edges that belong to more than two triangles.\n"
                    " Bad for analysis assuming surface is a 2-manifold.\n",
                    FuncName);
            if (1) {
                int iii=0;
                fprintf( SUMA_STDERR,
                         " These edges are formed by the following nodes:\n");
                for (iii = 0; iii < SO->EL->N_EL; ++iii) {
                    if (SO->EL->ELps[iii][2] > 2)
                        fprintf (SUMA_STDERR,
                                 " %d: Edge [%d %d] shared by %d triangles.\n",
                                 iii+1, SO->EL->EL[iii][0], SO->EL->EL[iii][1] ,
                                 SO->EL->ELps[iii][2] );
                }
            }
        }

        if (DoSelfInt) {
            int iii;
            FILE *fout=NULL;
            byte *report = (byte *)SUMA_calloc(SO->N_Node, sizeof(byte));
            if (!report) {
                SUMA_SL_Crit("Failed to allocate for report");
                report = NULL;
            }
            fprintf( SUMA_STDERR, "\n\nChecking for intersections...:\n");
            nsi = SUMA_isSelfIntersect(SO, 500, report);
            if (nsi) {
                fprintf( SUMA_STDERR,
                         " Surface is self intersecting.\n"
                         "%d segments were found to intersect the surface.\n", nsi);
                if (nsi >= 500) {
                    fprintf( SUMA_STDERR,
                             " It is possible that you have additional segments"
                             " intersecting the surface.\n");
                }
                if (report) {
                    if (Spec->N_Surfs > 1) {
                        sprintf(ext,"_%c", 65+i);
                        OutName = SUMA_append_replace_string ( prefix,
                                                               "_IntersNodes.1D.dset",
                                                               ext, 0);
                    } else {
                        OutName = SUMA_append_string (prefix, "_IntersNodes.1D.dset");
                    }
                    fout = fopen(OutName, "w");
                    if (fout) {
                        fprintf(fout,
                                "#List of nodes that are part of segments which intersect "
                                "the surface\n"
                                "#%s\n"
                                "#A total of %d segments (search limit is 500) were found to "
                                "intersect the surface.\n"
                                "#Col.1 : Node index\n"
                                "#Col.2 : Dummy flag, always 1\n",
                                SUMA_CHECK_NULL_STR(SO->Label), nsi );
                        for (iii=0; iii<SO->N_Node; ++iii)
                            if (report[iii]) fprintf(fout, "%d\t1\n", iii);
                        fclose(fout);
                        fout = NULL;
                    } else {
                        SUMA_SL_Err("Failed to open file for output.");
                    }
                    if (OutName) SUMA_free(OutName);
                }
            } else {
                fprintf(SUMA_STDERR, " Surface is not self intersecting.\n");
            }
            if (report) SUMA_free(report);
            report = NULL;
        }

        fprintf (SUMA_STDERR,"\n");

        if (Opt->DoSum) {   /* do not change syntax, scripts depend on this */
            fprintf(stdout,"Summary for %s:\n", SO->Label);
            fprintf(stdout,"Euler_Charac. %d\n", eu);
            fprintf(stdout,"Consistent_Winding %d\n", consistent);
            if (DoSphQ) {
                fprintf(stdout,"Folding_Triangles %d\n", N_bad_facesets);
                fprintf(stdout,"Sketchy_nodes %d\n", N_bad_nodes);
            }
            if (DoSelfInt)
                fprintf(stdout,"Self_Intersections %d\n", nsi);
            fprintf(stdout,"\n");
        }

    }



    SUMA_LH("clean up");
    if (!SUMA_FreeSpecFields(Spec)) {
        SUMA_S_Err("Failed to free spec fields");
    }
    SUMA_free(Spec);
    Spec = NULL;
    if (prefix) SUMA_free(prefix);
    prefix = NULL;
    if (Opt->out_prefix) SUMA_free(Opt->out_prefix);
    Opt->out_prefix = 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_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);

    SUMA_RETURN(0);
}
예제 #8
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);
} 
예제 #9
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);
}   
예제 #10
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfInfo"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_SurfSpecFile *Spec = NULL;
   int i, N_Spec;
   char *s = NULL;
   SUMA_SurfaceObject *SO=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;");
   
   if (argc < 2) {
      usage_SurfInfo(ps);
      exit (1);
   }
   
   Opt = SUMA_SurfInfo_ParseInput (argv, argc, ps);

   if (Opt->debug > 2) LocalHead = YUP;
   
   if (ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames != 1) {
      SUMA_S_Err("Multiple surface specifications used. "
                 "Only one surface allowed.");
      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);
   }

   SUMA_LH("Loading surface...");
   SO = SUMA_Load_Spec_Surf(Spec, 0, ps->sv[0], Opt->debug);
   if (!SO) {
         fprintf (SUMA_STDERR,"Error %s:\n"
                              "Failed to find surface\n"
                              "in spec file. \n",
                              FuncName );
         exit(1);
      
   }   
   if (Opt->b1) {
      SUMA_LH("Calculating all metrics, be patient...");
      /* calc trimmings */
      if (!SUMA_SurfaceMetrics_eng(SO, "Convexity|EdgeList|PolyArea|Curvature|"
                                       "EdgeList|MemberFace|CheckWind", 
                                       NULL, Opt->debug, SUMAg_CF->DsetList)) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
      }
   }
   if (!Opt->s) { /* the whole thing */
      SUMA_Print_Surface_Object(SO, stdout);
   } else { /* just the specifics */
      char *s=NULL;
      i = 0;
      while ( (s=SUMA_NI_get_ith_string(Opt->s,"|",i) ) ) {
         if (!strcmp(s,"N_Node")) {   
            if (Opt->b2) {
               if (i) fprintf(SUMA_STDOUT, "%s%d", Opt->in_1D, SO->N_Node);
               else fprintf(SUMA_STDOUT, "%d", SO->N_Node);
            } else {
               if (i) fprintf(SUMA_STDOUT, "%s%s=%d", Opt->in_1D, s, SO->N_Node);
               else fprintf(SUMA_STDOUT, "%s=%d", s, SO->N_Node);
            }         
         } else if (!strcmp(s,"N_Tri") || !strcmp(s,"N_FaceSet")) {   
            if (Opt->b2) {
               if (i) fprintf(SUMA_STDOUT, "%s%d", Opt->in_1D, SO->N_FaceSet);
               else fprintf(SUMA_STDOUT, "%d", SO->N_FaceSet);
            } else {
               if (i) fprintf(SUMA_STDOUT, "%s%s=%d", 
                                          Opt->in_1D, s, SO->N_FaceSet);
               else fprintf(SUMA_STDOUT, "%s=%d", s, SO->N_FaceSet);
            }
         } else if (!strcmp(s,"COM")) {
            if (Opt->b2) {
               if (i) fprintf(SUMA_STDOUT, "%s%f %f %f", 
                              Opt->in_1D, 
                              SO->Center[0], SO->Center[1],SO->Center[2]);
               else fprintf(SUMA_STDOUT, "%f %f %f", 
                              SO->Center[0], SO->Center[1],SO->Center[2]);
            } else {
               if (i) fprintf(SUMA_STDOUT, "%s%s=%f %f %f", 
                              Opt->in_1D, s, 
                              SO->Center[0], SO->Center[1],SO->Center[2]);
               else fprintf(SUMA_STDOUT, "%s=%f %f %f", s, 
                              SO->Center[0], SO->Center[1],SO->Center[2]);
            }
         } else {
            SUMA_S_Errv("Don't know about parameter >>%s<<\n", s);
            exit(1);
         }
         SUMA_free(s);
         ++i;
      }
      fprintf(SUMA_STDOUT,"\n");
   }
   if (SO) SUMA_Free_Surface_Object(SO); SO = 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);
   
}