Exemple #1
0
/*!
   a function to test debugging 
*/
int * SUMA_disaster(void)
{
   static char FuncName[]={"SUMA_disaster"};
   int *iv1=NULL, *iv2 = NULL, *iv3 = NULL;
   int N_iv1, N_iv2;
   int i;
   double v[7] = {-1.6, -1.5, -1.4, 0, 1.4, 1.5, 1.6};
   
   SUMA_ENTRY;
   
   
   
   for (i=0; i<7; ++i) {
      fprintf (stderr,"%f  : r %d, c %d\n", 
               v[i], SUMA_ROUND(v[i]), SUMA_CEIL(v[i]));
   }
   
   SUMA_S_Notev("Domemtrace %d\n", get_Domemtrace());
   N_iv1 = 5;
   N_iv2 = 5;
   iv1 = (int*) SUMA_calloc(N_iv1, sizeof(int));
   iv2 = (int*) SUMA_calloc(N_iv2, sizeof(int));
   
   /* overwrite iv1 */
   iv1[N_iv1] = 3;
   
   /* overwrite iv2 */
   iv2[N_iv2] = 7;
   
   /* MEMCHECK should give a warning */
   SUMA_S_Note("Memcheck output");
   MCHECK ; fflush(stdout) ; /* ZSS */

   /* free iv1 (that should give a warning)*/
   SUMA_S_Note("Now freeing iv1");
   SUMA_free(iv1); /* without the -trace option, 
                      you'll get a warning of this corruption here */

   /* try to free iv3 although it was not allocated for */
   /* AFNI's functions do not check for this ...*/
   /* SUMA_free(iv3);*/
         
   /* don't free iv2, that should only give a warning when you
      exit with -trace option turned on */
   SUMA_S_Note("Now dumping malloc table");
   mcw_malloc_dump();
   
   /* if you use -trace, you'll get a warning at the return for iv2 
   All allocated memory will be checked, at the return, not just iv2*/   
   SUMA_S_Note("Now returning");
   SUMA_RETURN(iv2); 
}
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"SUMA_TestDsetIO"}; 
   int *NodeDef=NULL;
   byte *maskrow, *maskcol;
   int i, i3, N_NodeDef, N_Alloc, flg;
   float *r=NULL, *g=NULL, *b=NULL, *rgb=NULL;
   char stmp[500], idcode[50], **s, *si, *OutName = NULL;
   NI_element *nel=NULL;
   NI_stream ns;
   int found = 0, NoStride = 0;
   byte *bt=NULL;
   SUMA_DSET * dset = NULL, *ndset=NULL;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_STANDALONE_INIT;
   SUMA_mainENTRY;
   
	
   LocalHead = YUP; /* turn on debugging */
   SUMA_LH("Creating Data ...");
   /* Create some sample data*/
      /* let us create some colors to go on each node */
      N_Alloc = 50;
      NodeDef = (int *)SUMA_malloc(N_Alloc * sizeof(int));
      r = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      g = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      b = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      bt = (byte *)SUMA_malloc(N_Alloc * sizeof(byte));
      s = (char **)SUMA_malloc(N_Alloc * sizeof(char *));
      maskrow = (byte *)SUMA_malloc(N_Alloc * sizeof(byte));
      maskcol = (byte *)SUMA_malloc(10*sizeof(byte)); 
      for (i=0; i<10; ++i) { 
         if (i==1 || i == 3) maskcol[i]=0; 
         else maskcol[i] = 1; 
      }
      N_NodeDef = N_Alloc;
      for (i=0; i<N_NodeDef; ++i) {
         NodeDef[i] = i;
         r[i] = sin((float)i/N_NodeDef*5);
         g[i] = sin((float)i/N_NodeDef*10);
         b[i] = cos((float)i/N_NodeDef*7);
         bt[i] = (byte)(4*b[i]);
         sprintf(stmp,"teststr_%d", i);
         s[i] = SUMA_copy_string(stmp);
         if (i==3 || i== 7 || i==33) maskrow[i] = 1; else maskrow[i]=0;
      }
      /* what if you had a vector of say, triplets */
      rgb = (float *)SUMA_malloc(3 * N_Alloc * sizeof(float));
      for (i=0; i<N_NodeDef; ++i) {
         i3 = 3*i;
         rgb[i3] = r[i];
         rgb[i3+1] = g[i];
         rgb[i3+2] = b[i];
      }
      
  {
      float *xc, *de, *amp;
      int dof;
      float par[3];
      /* store some statistics */
      xc = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      de = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      amp = (float *)SUMA_malloc(N_Alloc * sizeof(float));
      for (i=0; i<N_NodeDef; ++i) {
         xc[i] = rand()%1000/1000.0 * 1.0;
         de[i] = rand()%1000/1000.0 * 30;
         amp[i] = rand()%1000/1000.0 * 5.0;
      }
     
      SUMA_LH("Creating dset pointer");
      dset = SUMA_CreateDsetPointer(
                                    "ExpandingRing_ResponseDelay",         /* some label */
                                    SUMA_NODE_BUCKET,                /* mix and match */
                                    NULL,    /* no idcode, let the function create one from the filename*/
                                    NULL,       /* no domain str specified */
                                    N_Alloc    /* Number of nodes allocated for */
                                    ); /* DO NOT free dset, if it is stored in DsetList */
      #ifdef SUMA_COMPILED
      SUMA_LH("inserting dset pointer into list");
      if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList,0)) {
         SUMA_SL_Err("Failed to insert dset into list");
         exit(1);
      }  
      #endif
      	/* form the dataset */
   SUMA_LH("Adding stat NodeDef column ...");
   if (!SUMA_AddDsetNelCol (   dset, /* the famed nel */ 
                           "Node Indices", 
                           SUMA_NODE_INDEX, /* the column's type (description),
                                               one of SUMA_COL_TYPE */
                           (void *)NodeDef, /* column pointer p, here it is
                                             the list of node indices */
                           NULL  /* that's an optional structure containing 
                                    attributes of the added column. 
                                    Not used at the moment */
                           ,1 /* stride, useful when you need to copy a column
                                 from a multiplexed vector. Say you have in p 
                                 [rgb rgb rgb rgb], to set the g column you 
                                 send in p+1 for the column pointer and a stride
                                 of 3 */
                           )) {
         fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
         exit(1);                    
      }
      
      SUMA_LH("Adding stat other columns...");
         par[0] = 120; par[1] = 2; par[2] = 2;
         if (!SUMA_AddDsetNelCol (dset, "XcorrCoef", 
                                  SUMA_NODE_XCORR, (void *)xc, (void *)par ,1)) {
            fprintf (stderr,
                     "Error  %s:\nFailed in SUMA_AddDsetNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Delay", 
                                  SUMA_NODE_FLOAT, (void *)de, NULL ,1)) {
            fprintf (stderr,
                     "Error  %s:\nFailed in SUMA_AddDsetNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Amplitude", SUMA_NODE_FLOAT, (void *)amp, NULL ,1)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddDsetNelCol", FuncName);
            exit(1);
         }
      SUMA_LH("History note");
      if (!SUMA_AddNgrHist(dset->ngr, FuncName, argc, argv)) {
         SUMA_SL_Err("History addition failed.");
         exit(1);
      }
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("SampleDset", dset, SUMA_ASCII_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("SampleDset", dset, SUMA_ASCII_NIML, 1, 1); 
      #endif
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }

      #ifdef SUMA_COMPILED
      /* Now create a new dataset nel 
      no need to worry about loosing previous dset because it is in 
      SUMAg_CF->DsetList*/
      #else
      /* free dset by hand */
      SUMA_LH("Freeing datasets ...");
      if (dset) SUMA_FreeDset((void *)dset);
      dset = NULL;
      #endif
      
   }
   SUMA_LH("Creating dset pointer");
   dset = SUMA_CreateDsetPointer(
                                 "SomethingLikeFileName",         /* usually the filename */
                                 SUMA_NODE_BUCKET,                /* mix and match */
                                 NULL,    /* no idcode, let the function create one from the filename*/
                                 NULL,       /* no domain str specified */
                                 N_Alloc    /* Number of nodes allocated for */
                                 ); /* DO NOT free dset, it is store in DsetList */
   #ifdef SUMA_COMPILED
   SUMA_LH("inserting dset pointer into list");
   if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList,0)) {
      SUMA_SL_Err("Failed to insert dset into list");
      exit(1);
   }  
   #endif
                           
	/* form the dataset */
   SUMA_LH("Adding NodeDef column ...");
   if (!SUMA_AddDsetNelCol (   dset, /* the famed nel */ 
                           "le Node Def", 
                           SUMA_NODE_INDEX, /* the column's type (description),
                                               one of SUMA_COL_TYPE */
                           (void *)NodeDef, /* column pointer p, here it is
                                             the list of node indices */
                           NULL  /* that's an optional structure containing 
                                    attributes of the added column. 
                                    Not used at the moment */
                           ,1 /* stride, useful when you need to copy a column
                                 from a multiplexed vector. Say you have in p 
                                 [rgb rgb rgb rgb], to set the g column you 
                                 send in p+1 for the column pointer and a stride
                                 of 3 */
                           )) {
         fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
         exit(1);                    
      }
      
      SUMA_LH("Adding other columns...");
      NoStride = 0;
      if (NoStride) {
         /* insert separate r, g and b column */
         if (!SUMA_AddDsetNelCol (dset, "Le R", SUMA_NODE_R, (void *)r, NULL ,1)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Le G", SUMA_NODE_G, (void *)g, NULL ,1)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Le B", SUMA_NODE_B, (void *)b, NULL ,1)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }
      } else {
         /* insert from multiplexed rgb vector */
         if (!SUMA_AddDsetNelCol (dset, "le R", SUMA_NODE_R, (void *)rgb, NULL ,3 )) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Le G", SUMA_NODE_G, (void *)(rgb+1), NULL ,3)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }

         if (!SUMA_AddDsetNelCol (dset, "Le B", SUMA_NODE_B, (void *)(rgb+2), NULL ,3)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }
         #if 0
         SUMA_LH("Testing insert column ...");
         /* Test NI_inset_column_stride here please */
         if (!SUMA_InsertDsetNelCol (dset, "Le G2", SUMA_NODE_G, (void *)(rgb+1), NULL ,3, 0)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
         }
         #endif
      }
      { int suc; SUMA_LH("Where are the attributes?"); NEL_WRITE_TX(dset->ngr,"fd:1",suc); }
      /* add the byte column, just to check multi type nightmares */
      if (!SUMA_AddDsetNelCol (dset, "Le byte moi", SUMA_NODE_BYTE, (void *)bt, NULL ,1)) {
            fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
            exit(1);
      }
      
      
      SUMA_LH("Testing write ops before adding string columns ...");
      /* before adding a string column ... */
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_write_all_num", dset, SUMA_1D, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_write_all_num", dset, SUMA_1D, 1, 1); 
      #endif

      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }
      
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_writebi_all_num", dset, SUMA_BINARY_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_writebi_all_num", dset, SUMA_BINARY_NIML, 1, 1); 
      #endif
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL; 
      }
	   
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_writeas_all_num", dset, SUMA_ASCII_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_writeas_all_num", dset, SUMA_ASCII_NIML, 1, 1); 
      #endif
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }
      
      /* Now shuffle some columns (then put them back) */
      SUMA_S_Note("NOTE THAT SHUFFLING here does not take care of attributes inside dset, but only dnel");
      NI_move_column(dset->dnel, -1, 2);
      SUMA_ShowNel(dset->dnel);
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_writeas_all_shuff_num", dset, SUMA_ASCII_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_writeas_all_shuff_num", dset, SUMA_ASCII_NIML, 1, 1); 
      #endif
      NI_move_column(dset->dnel, 2, -1);
      SUMA_ShowNel(dset->dnel);
     
      /* zero out some columns and test operations */
      SUMA_LH("Trying masking operations");
      ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); 
      SUMA_LH("Done");
      /* try also:
         ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 0, 1);
         ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 0, 0);
         ndset = SUMA_MaskedCopyofDset(dset, maskrow, NULL, 1, 0); 
         ndset = SUMA_MaskedCopyofDset(dset, NULL, NULL, 1, 0); 
         ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); 
      */
      if (!ndset) {
         SUMA_SL_Err("Failed in SUMA_MaskedCopyofDset");
      } else {
         #ifdef SUMA_COMPILED
         OutName = SUMA_WriteDset_s ("Test_writeas_MaskedCopy_num", ndset, SUMA_ASCII_NIML, 1, 1); 
         #else
         OutName = SUMA_WriteDset_ns ("Test_writeas_MaskedCopy_num", ndset, SUMA_ASCII_NIML, 1, 1); 
         #endif
         if (!OutName) {
            SUMA_SL_Err("Write Failed.");
         } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
            SUMA_free(OutName); OutName = NULL;
         }
         SUMA_free(ndset); ndset = NULL;
      }
      
      SUMA_LH("Adding a string column");
      /* add a string column, just for kicks ..*/
      if (!SUMA_AddDsetNelCol (dset, "la string", SUMA_NODE_STRING, (void *)s, NULL, 1)) {
         fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
         exit(1);  
      }
      
      /* now try to create a masked copy, this should fail */
      fprintf (stderr,"%s: Attempting to mask a not all numeric dset, this should fail\n", FuncName);
      ndset = SUMA_MaskedCopyofDset(dset, maskrow, maskcol, 1, 0); 
      if (ndset) {
         fprintf (stderr,"Error  %s:\nWhat the hell? This should not be supported.", FuncName);
         exit(1);
      }else{
         fprintf (stderr,"%s: Good, failed.\n", FuncName);
      }  
      /* after adding a string column ... */
      SUMA_LH("Writing datasets ...");
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_writeas", dset, SUMA_ASCII_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_writeas", dset, SUMA_ASCII_NIML, 1, 1); 
      #endif
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }
      
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_writebi", dset, SUMA_BINARY_NIML, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_writebi", dset, SUMA_BINARY_NIML, 1, 1); 
      #endif
      
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }
	   
      SUMA_LH("Writing to 1D a dataset that is not all numbers.\nThis should fail.\n");
      #ifdef SUMA_COMPILED
      OutName = SUMA_WriteDset_s ("Test_write", dset, SUMA_1D, 1, 1); 
      #else
      OutName = SUMA_WriteDset_ns ("Test_write", dset, SUMA_1D, 1, 1); 
      #endif
      if (!OutName) {
         SUMA_SL_Err("Write Failed.");
      } else { fprintf (stderr,"%s:\nDset written to %s\n", FuncName, OutName); 
         SUMA_free(OutName); OutName = NULL;
      }
      
     
      
        
      /* How about loading some data */
      #ifdef SUMA_COMPILED
      /* Now create a new dataset nel 
      no need to worry about loosing previous dset because it is in 
      SUMAg_CF->DsetList*/
      #else
      /* free dset by hand */
      SUMA_LH("Freeing datasets ...");
      if (dset) SUMA_FreeDset((void *)dset);
      dset = NULL;
      #endif
      
      SUMA_LH("Fresh dataset ...");
      dset = SUMA_NewDsetPointer();
      SUMA_LH("Reading dataset ...");
      DSET_READ(dset, "file:Test_writebi.niml.dset"); if (!dset->ngr) exit(1);
      /* insert the baby into the list */
      
      #ifdef SUMA_COMPILED
      SUMA_LH("Inserting newly read element into list\n");
      if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList, 0)) {
         char *newid = NULL;
         SUMA_SL_Err("Failed to insert dset into list");
         /* Now change the idcode of that baby */
         newid = UNIQ_hashcode(SDSET_ID(dset));
         NI_set_attribute(dset->dnel, "self_idcode", newid); SUMA_free(newid);
         SUMA_LH("Trying to insert dset with a new id ");
         if (!SUMA_InsertDsetPointer(&dset, SUMAg_CF->DsetList, 0)) {
            SUMA_SL_Err("Failed to insert dset into list\nI failed to succeed, snif.");
            exit(1);
         }
         SUMA_LH("Lovely, that worked...");
      }
      #endif
           
      /* show me the whole thing. Don't do this for an enormous nel */
         /* SUMA_ShowNel((void*)dset->nel); */
         
      
      /* I want the pointer to the green column but do not know its index */
         {   
            int j, *iv, N_i;
            float *fp;
            fprintf (stderr,"---Looking for green column ---\n");
            iv = SUMA_GetDsetColIndex (dset, SUMA_NODE_G, &N_i);
            if (!iv) {
               fprintf (stderr,"Error %s: Failed to find column.\n"
                           , FuncName);
            } else {
               fprintf (stderr,"\t%d columns of type SUMA_NODE_G found.\n",
                           N_i);
               if (N_i) {
                  fprintf (stderr,"\tReporting values at index %d\n", iv[0]);
                  fp = (float *)dset->dnel->vec[iv[0]]; /* I know we only have one 
                                                   such col. here */
                  for (j=0; j < SDSET_VECLEN(dset); ++j) {
                     fprintf (stderr,"%f, ", fp[j]);
                  }
                  SUMA_free(iv); iv = NULL;
               }
            }
            
                  
         }
          
   
   /* Now show me that baby,*/
   SUMA_LH("I wanna Show You Some Info");
   si = SUMA_DsetInfo (dset, 0);
   fprintf (SUMA_STDERR,"Output of DsetInfo:\n%s\n", si); SUMA_free(si); si=NULL; 
   
   if (LocalHead) fprintf(stderr," %s:-\nFrenching ...\n", FuncName);

   /* free other stuff */
   if (r) SUMA_free(r); r = NULL;
   if (g) SUMA_free(g); g = NULL;
   if (b) SUMA_free(b); b = NULL;
   if (rgb) SUMA_free(rgb); rgb = NULL;
   if (maskrow) SUMA_free(maskrow); maskrow = NULL;
   if (maskcol) SUMA_free(maskcol); maskcol = NULL;
   if (NodeDef) SUMA_free(NodeDef); NodeDef = NULL;  
   if (s) {
      for (i=0; i<N_NodeDef; ++i) {
         if (s[i]) SUMA_free(s[i]);
      }
      SUMA_free(s);
   }

   #ifdef SUMA_COMPILED
   /* dset and its contents are freed in SUMA_Free_CommonFields */
   if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
   #else
   /* free dset by hand */
   if (dset) SUMA_FreeDset((void *)dset);
   #endif
   
	SUMA_RETURN (0);
}/* Main */
Exemple #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);
   
} 
Exemple #4
0
/*!\**
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 */ 
Exemple #5
0
/*!
   \brief parse the arguments for SurfSmooth program
   
   \param argv (char *)
   \param argc (int)
   \return Opt (SUMA_SURFCLUST_OPTIONS *) options structure.
               To free it, use 
               SUMA_free(Opt->out_name); 
               SUMA_free(Opt);
*/
SUMA_SURFCLUST_OPTIONS *SUMA_SurfClust_ParseInput (char *argv[], int argc,
                              SUMA_GENERIC_ARGV_PARSE *ps)
{
   static char FuncName[]={"SUMA_SurfClust_ParseInput"}; 
   SUMA_SURFCLUST_OPTIONS *Opt=NULL;
   int kar, i, ind;
   char *outname;
   SUMA_Boolean brk = NOPE;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_ENTRY;
   
   Opt = SUMA_create_SurfClust_Opt("SurfClust");
   kar = 1;
   
   outname = NULL;
   BuildMethod = SUMA_OFFSETS2_NO_REC;
	brk = NOPE;
	while (kar < argc) { /* loop accross command ine options */
		/*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
		if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
			 usage_SUMA_SurfClust(strlen(argv[kar]) > 3 ? 2:1);
          exit (0);
		}
		
		SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      if (!brk && (strcmp(argv[kar], "-no_cent") == 0)) {
         Opt->DoCentrality = 0;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-cent") == 0)) {
         Opt->DoCentrality = 1;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-O2") == 0)) {
         BuildMethod = SUMA_OFFSETS2;
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-O2_NR") == 0)) {
         BuildMethod = SUMA_OFFSETS2_NO_REC;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-Oll") == 0)) {
         BuildMethod = SUMA_OFFSETS_LL;
         brk = YUP;
      }
      
       
      if (!brk && (strcmp(argv[kar], "-update") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -update \n");
				exit (1);
			}
			Opt->update = atof(argv[kar]);
         if (Opt->update < 1 || Opt->update > 100) {
            fprintf (SUMA_STDERR, 
                     "-update needs a parameter between "
                     "1 and 50 (I have %.1f)\n", Opt->update);
         }
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-prefix") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -prefix \n");
				exit (1);
			}
         Opt->oform = SUMA_GuessFormatFromExtension(argv[kar], NULL);		
         if (Opt->oform == SUMA_NO_DSET_FORMAT) Opt->oform = SUMA_ASCII_NIML;
         Opt->out_prefix = SUMA_RemoveDsetExtension_s(argv[kar], Opt->oform);	
         Opt->WriteFile = YUP;
         brk = YUP;
		}
            
#if 0
      if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -spec \n");
				exit (1);
			}
			Opt->spec_file = argv[kar];
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -sv \n");
				exit (1);
			}
			Opt->sv_name = argv[kar];
			brk = YUP;
		}
      
      if (!brk && (strncmp(argv[kar], "-surf_", 6) == 0)) {
			if (kar + 1>= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -surf_X SURF_NAME \n");
				exit (1);
			}
			ind = argv[kar][6] - 'A';
         if (ind < 0 || ind >= SURFCLUST_MAX_SURF) {
            fprintf (SUMA_STDERR, 
                     "-surf_X SURF_NAME option is out of range.\n"
                     "Only %d surfaces are allowed. \n"
                     "Must start with surf_A for first surface.\n", 
                     SURFCLUST_MAX_SURF);
				exit (1);
         }
         kar ++;
         Opt->surf_names[ind] = argv[kar];
         Opt->N_surf = ind+1;
         brk = YUP;
		}
#endif
      
      if (!brk && (strcmp(argv[kar], "-input") == 0)) {
         kar ++;
			if (kar+1 >= argc)  {
		  		fprintf (SUMA_STDERR, "need 2 arguments after -input \n");
				exit (1);
			}
			Opt->in_name = argv[kar]; kar ++;
         /* no need for that one Opt->nodecol = atoi(argv[kar]); kar ++; */
         Opt->labelcol = atoi(argv[kar]); 
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-rmm") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -rmm \n");
				exit (1);
			}
			Opt->DistLim = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-in_range") == 0)) {
         kar ++;
			if (kar+1 >= argc)  {
		  		fprintf (SUMA_STDERR, "need two arguments after -in_range \n");
				exit (1);
			}
			Opt->DoThreshold = SUMA_THRESH_INSIDE_RANGE;
         Opt->ThreshR[0] = atof(argv[kar]); ++kar;
         Opt->ThreshR[1] = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-ex_range") == 0)) {
         kar ++;
			if (kar+1 >= argc)  {
		  		fprintf (SUMA_STDERR, "need two arguments after -ex_range \n");
				exit (1);
			}
			Opt->DoThreshold = SUMA_THRESH_OUTSIDE_RANGE;
         Opt->ThreshR[0] = atof(argv[kar]); ++kar;
         Opt->ThreshR[1] = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-thresh") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -thresh \n");
				exit (1);
			}
			Opt->DoThreshold = SUMA_LESS_THAN;
         Opt->ThreshR[0] = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-athresh") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -athresh \n");
				exit (1);
			}
			Opt->DoThreshold = SUMA_ABS_LESS_THAN;
         Opt->ThreshR[0] = atof(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-thresh_col") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -thresh_col \n");
				exit (1);
			}
         Opt->tind = atoi(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-amm2") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -amm2 \n");
				exit (1);
			}
			Opt->AreaLim = atof(argv[kar]);
			brk = YUP;
		}

      if (!brk && (strcmp(argv[kar], "-n") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -n \n");
				exit (1);
			}
			Opt->NodeLim = atoi(argv[kar]);
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-out_roidset") == 0)) {
         Opt->OutROI = YUP;
			brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-prepend_node_index") == 0)) {
         Opt->prepend_node_index = YUP;
			brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-out_clusterdset") == 0)) {
         Opt->OutClustDset = YUP;
			brk = YUP;
      }

      if (!brk && (strcmp(argv[kar], "-out_fulllist") == 0)) {
         Opt->FullROIList = YUP;
			brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-sort_none") == 0)) {
         Opt->SortMode = SUMA_SORT_CLUST_NO_SORT;
			brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-sort_n_nodes") == 0)) {
         Opt->SortMode = SUMA_SORT_CLUST_BY_NUMBER_NODES;
			brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-sort_area") == 0)) {
         Opt->SortMode = SUMA_SORT_CLUST_BY_AREA;
			brk = YUP;
      }
      
      if (!brk && !ps->arg_checked[kar]) {
			SUMA_S_Errv("Option %s not understood.\n"
                  "Try -help for usage\n", argv[kar]);
			suggest_best_prog_option(argv[0], argv[kar]);
         exit (1);
		} else {	
			brk = NOPE;
			kar ++;
		}
   }

   /* sanitorium */
   if (Opt->DistLim == -1.5f) {
      fprintf (SUMA_STDERR, "must use option -rmm  \n");
      exit(1);
   }
   if (!Opt->out_prefix) {
      Opt->out_prefix = 
         SUMA_RemoveDsetExtension_s(Opt->in_name, SUMA_NO_DSET_FORMAT);
   }
   
   if (Opt->SortMode == SUMA_SORT_CLUST_NOT_SET) { 
      Opt->SortMode = SUMA_SORT_CLUST_BY_AREA; }

   if (BuildMethod == SUMA_OFFSETS2) { SUMA_S_Note("Using Offsets2"); }
   else if (BuildMethod == SUMA_OFFSETS_LL) { SUMA_S_Note("Using Offsets_ll"); } 
   else if (BuildMethod == SUMA_OFFSETS2_NO_REC) { 
      if (LocalHead) SUMA_S_Note("Using no recursion"); }
   else {
      SUMA_SL_Err("Bad BuildMethod");
      exit(1);
   } 
   
   SUMA_SurfClust_Set_Method(BuildMethod);
   
   if (Opt->FullROIList && !(Opt->OutROI || Opt->OutClustDset)) {
      SUMA_SL_Err("-out_fulllist must be used in conjunction "
                  "with -out_ROIdset or -out_clusterdset");
      exit(1);
   }   
   SUMA_RETURN(Opt);
}
Exemple #6
0
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"FSread_annot"};
   int kar, Showct, testmode;
   char *fname = NULL, *fcmap = NULL, *fdset = NULL, 
         *froi = NULL, *fcol = NULL, *ctfile=NULL, sbuf[1024]={""};
   SUMA_Boolean SkipCoords = NOPE, brk;
   SUMA_DSET *dset=NULL;
   int lbl1,lbl2, ver, hemi, FSdefault;
   SUMA_Boolean LocalHead = NOPE;	
   
   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;
   
	/* allocate space for CommonFields structure */
	SUMAg_CF = SUMA_Create_CommonFields ();
	if (SUMAg_CF == NULL) {
		fprintf( SUMA_STDERR,
               "Error %s: Failed in SUMA_Create_CommonFields\n", FuncName);
		exit(1);
	}

   /* parse command line */
   kar = 1;
   fname = NULL;
   froi = NULL;
   fcmap = NULL;
   fcol = NULL;
	brk = NOPE;
   ctfile = NULL;
   Showct = 0;
   testmode = 0;
   lbl1 = -1;
   lbl2 = -1;
   ver = -1;
   FSdefault = 0;
   hemi=0;
	while (kar < argc) { /* loop accross command ine options */
		/*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
		if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
			 usage_SUMA_FSread_annot_Main();
          exit (0);
		}
      
      if (!brk && (strcmp(argv[kar], "-show_FScmap") == 0)) {
         Showct = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-testmode") == 0)) {
         testmode = 1;
			brk = YUP;
		}
      
      if (!brk && (strcmp(argv[kar], "-input") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need argument after -input\n");
				exit (1);
			}
         fname = argv[kar];
			brk = YUP;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      
      if (Opt->debug || Opt->gold || Opt->gold_bias) {
         double bad_bias_thresh, bias_bad_count;
         char *sbig=NULL;
         sprintf(sinf, "Class Stat iter %d:\n", iter+1);
         if (iter == Opt->N_main-1 || Opt->debug) {
            SUMA_show_Class_Stat(Opt->cs, sinf, NULL);
            if (Opt->proot) sprintf(sreport, 
                     "%s/ClassStat.i%02d%s.txt", Opt->proot, 
                                  iter+1, (iter==Opt->N_main-1) ? ".FINAL":"");
            else snprintf(sreport, 500, 
                     "%s.ClassStat.i%02d%s.txt",  
                     Opt->prefix, iter+1, (iter==Opt->N_main-1) ? ".FINAL":"");
            sbig = SUMA_append_replace_string(Opt->hist, sinf,"\n",0);
            SUMA_show_Class_Stat(Opt->cs, sbig, sreport);
            SUMA_ifree(sbig);
         }
         
         /* Report on bias correction */
         bad_bias_thresh = 0.06;
         if ((Opt->gold_bias && Opt->Bset) && 
             (iter == Opt->N_main-1 || Opt->debug)) {
            FILE *fout = fopen(sreport,"a");
            bias_bad_count = SUMA_CompareBiasDsets(Opt->gold_bias, Opt->Bset, 
                                 Opt->cmask, Opt->cmask_count, 
                                 bad_bias_thresh, NULL);
            SUMA_S_Notev("bad_count at thresh %f = %f%% of mask.\n",
                  bad_bias_thresh, bias_bad_count);
            if (fout) {
               fprintf(fout, "bad_count at thresh %f = %f%% of mask.\n",
                  bad_bias_thresh, bias_bad_count);
               fclose(fout); fout = NULL;
            }
         }
      }
      
   }
   
   if (Opt->Split) {
      THD_3dim_dataset *Gcset=NULL;
      THD_3dim_dataset *GpstCgALL=NULL;
      /* need to put things back */
      if (!SUMA_Regroup_classes(Opt, 
                        Opt->cs->label, Opt->cs->N_label, Opt->cs->keys,
                        Opt->Gcs->label, Opt->Gcs->N_label, Opt->Gcs->keys,
                        Opt->cmask, Opt->pstCgALL, Opt->cset,
                        &GpstCgALL, &Gcset)) {
      }
      /* switch dsets */
      DSET_delete(Opt->pstCgALL); Opt->pstCgALL = GpstCgALL; GpstCgALL = NULL;
      DSET_delete(Opt->cset); Opt->cset = Gcset; Gcset = NULL;
   }
   
   SUMA_RETURN(1);
}
int main(int argc, char **argv)
{
   static char FuncName[]={"3dSeg"};
   SEG_OPTS *Opt=NULL;
   char *atr=NULL;
   float *mixfrac= NULL;
   int i=0;
   double ff;
   SUMA_SEND_2AFNI SS2A;
   SUMA_Boolean LocalHead = NOPE;

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

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

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

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

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

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

   

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

   
   /* Now call the workhorse */
   if (!SUMA_SegEngine(Opt)) {
      SUMA_S_Err("Failed in SUMA_SegEngine");
      exit(1);
   }
   
   /* write output */
   if (Opt->Bset && !Opt->this_fset_name) {
      tross_Append_History(Opt->Bset, Opt->hist);
      SUMA_Seg_Write_Dset(Opt->proot, "BiasField", /* DSET_PREFIX(Opt->Bset) */
                              Opt->Bset, -1, Opt->hist);
   }
   if (Opt->xset && !Opt->this_xset_name) {
      AFNI_FEED(Opt->ps->cs, "BiasCorrect", -1, Opt->xset);
      SUMA_Seg_Write_Dset(Opt->proot, "AnatUB", /* DSET_PREFIX(Opt->xset)*/
                              Opt->xset, -1, Opt->hist);
   }
   if (Opt->cset) {
      SUMA_Seg_Write_Dset(Opt->proot, "Classes", /* Opt->crefix */ 
                          Opt->cset, -1, Opt->hist);
      AFNI_FEED(Opt->ps->cs, "FinalClasses", -1, Opt->cset);
   }
   if (Opt->pstCgALL) {
      SUMA_Seg_Write_Dset(Opt->proot, "Posterior",  /* Opt->prefix */
                          Opt->pstCgALL, -1, Opt->hist);
      AFNI_FEED(Opt->ps->cs, "pstCgALL-final", -1, Opt->pstCgALL);
   }
   if (Opt->aset) {
      SUMA_Seg_Write_Dset(Opt->proot, "Anat",  
                          Opt->aset, -1, Opt->hist);
   }
   if (Opt->debug) SUMA_S_Note("Writing Unmodulated output");
   if (!(SUMA_pst_C_giv_ALL(Opt->xset, 
                               Opt->cmask, Opt->cmask_count,
                               Opt->cs,  
                               NULL, NULL,
                               Opt->B, Opt->T, 0,
                               &Opt->pstCgALL))) {
         SUMA_S_Err("Failed in SUMA_pst_C_giv_ALL unmodulated");
         SUMA_RETURN(1);
   }
   SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.p", 
                        Opt->pstCgALL, -1, Opt->hist);
   
   if (!(SUMA_assign_classes( Opt->pstCgALL, Opt->cs, 
                              Opt->cmask, &Opt->cset))) { 
      SUMA_S_Err("Failed in assign_classes");
      SUMA_RETURN(1);
   }
   SUMA_Seg_Write_Dset(Opt->proot, "Unmodulated.c", 
                       Opt->cset, -1, Opt->hist);
                       
   /* all done, free */
   Opt = free_SegOpts(Opt);
  
   PRINT_COMPILE_DATE ; 
   SUMA_RETURN(0);
}
Exemple #9
0
int GenFeatureDist_CheckOpts(SEG_OPTS *Opt) 
{
   static char FuncName[]={"GenFeatureDist_CheckOpts"};
   int i=0, kk=0, nmatch;
   
   SUMA_ENTRY;
   
   if (!Opt->clss) {
      SUMA_S_Err("Need -classes option");
      SUMA_RETURN(1);
   } 
   if (!Opt->sig_names) {
      SUMA_S_Err("Need -sig option");
      SUMA_RETURN(1);
   }
   if (!Opt->samp_names) {
      SUMA_S_Err("Need -samp option");
      SUMA_RETURN(1);
   }
   if (Opt->samp_names->num != Opt->sig_names->num) {
      SUMA_S_Errv("Need as many -samp options (%d) as -sig options (%d)\n",
            Opt->samp_names->num, Opt->sig_names->num);
      SUMA_RETURN(1);
   }
   
   /* labeltable? */
   if (Opt->labeltable_name) {
      Dtable *vl_dtable=NULL;
      char *labeltable_str=NULL;
      
      /* read the table */
      if (!(labeltable_str = AFNI_suck_file( Opt->labeltable_name))) {
         ERROR_exit("Failed to read %s", Opt->labeltable_name);
      }
      if (!(vl_dtable = Dtable_from_nimlstring(labeltable_str))) {
         ERROR_exit("Could not parse labeltable");
      }
      /* make sure all classes are in the labeltable */
      for (i=0; i<Opt->clss->num; ++i) {
         if ((kk = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[i]))<0){
               ERROR_exit("Key not found in %s for %s ", 
                        Opt->labeltable_name, Opt->clss->str[i]);
         }
         if (Opt->keys) {
            if (Opt->keys[i]!=kk) {
               ERROR_exit("Key mismatch %d %d", Opt->keys[i], kk);
            }
         }   
      }   
      if (!Opt->keys) { /* get them from table */
         Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int));
         for (i=0; i<Opt->clss->num; ++i) {
            if ((kk = SUMA_KeyofLabel_Dtable(vl_dtable, Opt->clss->str[i]))<0){
                  ERROR_exit("(should noy happen) Key not found in %s for %s ", 
                           Opt->labeltable_name, Opt->clss->str[i]);
            }
            Opt->keys[i] = kk;
         }
      }
      destroy_Dtable(vl_dtable); vl_dtable=NULL;
   } 
   
   
   /* Make sure any histogram specs are for a class in use */
   for (kk=0; kk<Opt->N_hspec; ++kk) {
      if ( (nmatch = SUMA_is_wild_hspec_label(Opt->hspec[kk]->label)) >= 0) {
         if (!nmatch) break;
         for (i=0; i<Opt->feats->num; ++i) {
            if (!strncmp(Opt->feats->str[i], 
                         Opt->hspec[kk]->label, nmatch)) break;
         }
      } else {
         for (i=0; i<Opt->feats->num; ++i) {
            if (!strcmp(Opt->feats->str[i], Opt->hspec[kk]->label)) break;
         }
      }
      if (i==Opt->feats->num) {
         SUMA_S_Warn("Feature %s in -hspec not found under -features and will have no impact on the output\n",
                    Opt->hspec[kk]->label);
      }
   }
   
   if (!Opt->keys) {
      /* add default keys */
      if (Opt->debug) SUMA_S_Note("Keys not available, assuming defaults");
      Opt->keys = (int *)calloc(Opt->clss->num, sizeof(int));
      for (i=0; i<Opt->clss->num; ++i) {
         Opt->keys[i] = i+1;
      }
   }
   
   /* Show the match between keys and classes */
   if (Opt->debug > 1) {
      SUMA_S_Note("Class-->key map");
      SUMA_ShowClssKeys(Opt->clss->str, Opt->clss->num, Opt->keys);
   }
   
   if( ! THD_is_directory(Opt->proot) ){
      if( mkdir( Opt->proot , THD_MKDIR_MODE ) != 0 ){
         SUMA_S_Errv("Failed to create %s\n", Opt->proot);
         SUMA_RETURN(0);
      }
   }
   

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

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

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

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

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

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

   SUMA_S_Note("Computing histograms of features per class");
   for (cc=0; cc<Opt->clss->num; ++cc) {
      if (N_FCset[0][cc] < 10) {
         SUMA_S_Errv("Requested class %s (%d) has just %d samples.\n"
                     "Not enough to grease your pan.\n",
                     Opt->clss->str[cc], Opt->keys[cc], N_FCset[0][cc]);
         exit(1);
      }
      for (aa=0; aa<Opt->feats->num; ++aa) {
         sprintf(sbuf, "h(%s|%s)",Opt->feats->str[aa], Opt->clss->str[cc]);
         hrange[0] = hf[aa]->min; hrange[1] = hf[aa]->max; 
         /* Do not optimize hist range and binwidth anymore, 
            but allow smoothing. This is needed when a particular 
            class has very few samples */
         if (!(hh[aa][cc] = SUMA_hist_opt(FCset[aa][cc], N_FCset[aa][cc], 
                                    hf[aa]->K, hf[aa]->W, 
                                    hrange, sbuf, 1,
                                    0.1, "OsciSmooth"))) {
            SUMA_S_Errv("Failed to generate histogram for %s|%s. \n"
                        "This will cause trouble at classification.\n",
                        Opt->feats->str[aa], Opt->clss->str[cc])
         } else {
            if (Opt->debug > 1) SUMA_Show_hist(hh[aa][cc], 1, NULL);
            /* save the histogram */
            if (!SUMA_write_hist(hh[aa][cc],
                     SUMA_hist_fname(Opt->proot, 
                              Opt->feats->str[aa], Opt->clss->str[cc], 0))) {
               SUMA_S_Errv("Failed to write histog to %s\n", sbuf);
            } 
         }
      }
   }
   
   SUMA_S_Note("Computing Correlation matrices");
   /* L2 normalize all of FCset */
   for (cc=0; cc<Opt->clss->num; ++cc) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         THD_normalize(N_FCset[aa][cc], FCset[aa][cc]);
      }
   }
   
   {
      NI_element **CC=NULL;
      float *fm=NULL, *fn=NULL;
      NI_element *nel = NULL;
      int suc;
      
   /* Compute the correlation matrices for each class */
   CC = (NI_element **) SUMA_calloc(Opt->clss->num, sizeof(NI_element *));
   
   for(cc=0; cc<Opt->clss->num; ++cc) {
      sprintf(sbuf, "CorrMat(%s)", Opt->clss->str[cc]);
      CC[cc] = NI_new_data_element(sbuf, Opt->feats->num);
      NI_set_attribute(CC[cc],"Measure","correlation");
      atr = SUMA_NI_str_ar_2_comp_str(Opt->feats, " ; ");
      NI_set_attribute(CC[cc],"ColumnLabels", atr);SUMA_free(atr); atr = NULL;
      atr = SUMA_HistString (FuncName, argc, argv, NULL);
      NI_set_attribute(CC[cc],"CommandLine", atr);SUMA_free(atr); atr = NULL;
      for (aa=0; aa<Opt->feats->num; ++aa) {
         NI_add_column_stride ( CC[cc], NI_FLOAT, NULL, 1 );
      }
      for (aa=0; aa<Opt->feats->num; ++aa) {
         fm = (float*)CC[cc]->vec[aa];
         for (iii=0; iii<aa; ++iii) fm[iii] = 0.0; /* will fill later */
         fm[aa]=1.0;
         for (iii=aa+1; iii<Opt->feats->num; ++iii) {
            if (N_FCset[aa][cc]!=N_FCset[iii][cc]) {
               SUMA_S_Errv("Sanity check failed, %d != %d\n",
                              N_FCset[aa][cc], N_FCset[iii][cc]);
            }
            SUMA_DOTP_VEC(FCset[aa][cc], FCset[iii][cc], 
                          fm[iii], N_FCset[aa][cc], 
                          float, float);
         }
      }
      /* Now fill the remainder */
      for (aa=0; aa<Opt->feats->num; ++aa) {
         fm = (float*)CC[cc]->vec[aa];
         for (iii=0; iii<aa; ++iii) {
            fn = (float*)CC[cc]->vec[iii];
            fm[iii] = fn[aa];
         }
      }
      snprintf(sbuf, 510, "file:%s.niml.cormat", 
               SUMA_corrmat_fname(Opt->proot, Opt->clss->str[cc], 0));
      NEL_WRITE_TXH(CC[cc], sbuf, suc);
   }
   
   }
   /* free everything */
   if (FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         for (cc=0; cc<Opt->clss->num; ++cc) {
            if (FCset[aa][cc]) SUMA_free(FCset[aa][cc]);
         }
         SUMA_free(FCset[aa]); 
      }
      SUMA_free(FCset); FCset=NULL;
   }
   if (N_FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         SUMA_free(N_FCset[aa]);
      }
      SUMA_free(N_FCset); N_FCset=NULL;
   }
   if (N_alloc_FCset) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         SUMA_free(N_alloc_FCset[aa]);
      }
      SUMA_free(N_alloc_FCset); N_alloc_FCset=NULL;
   }
   if (ifeat) SUMA_free(ifeat); ifeat=NULL;
   
   if (hh) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         for (cc=0; cc<Opt->clss->num; ++cc) {
            if (hh[aa][cc]) hh[aa][cc] = SUMA_Free_hist(hh[aa][cc]);
         }
         SUMA_free(hh[aa]);
      }
      SUMA_free(hh); hh=NULL;
   }
   
   if (hf) {
      for (aa=0; aa<Opt->feats->num; ++aa) {
         if (hf[aa]) hf[aa] = SUMA_Free_hist(hf[aa]);
      }
      SUMA_free(hf); hf=NULL;
   }
   
   if (masks) {
      for (ss=0; ss<Opt->sig_names->num; ++ss) {
         if (masks[ss]) SUMA_free(masks[ss]);
      }
      masks[ss]=NULL;
   }
   
   SUMA_S_Notev("\n"
                "Consider running this script to examine the distributions:\n"
                "   @ExamineGenFeatDists -fdir %s -odir %s\n",
                Opt->proot, Opt->proot);
   
   /* all done, free */
   Opt = free_SegOpts(Opt);
   
   PRINT_COMPILE_DATE ; exit(0);
}
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);
} 
Exemple #12
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);
}   
Exemple #13
0
byte *MaskSetup(SEG_OPTS *Opt, THD_3dim_dataset *aset, int mask_zero_aset,
                THD_3dim_dataset **msetp, byte **cmaskp, int dimcmask, 
                float mask_bot, float mask_top, int *mcount) 
{ 
   static char FuncName[]={"MaskSetup"};
   byte *mmm=NULL;
   int ii=0, kk=0, Fixit=0;
   byte *cmask = NULL;
   THD_3dim_dataset *mset = NULL;
   float *fa=NULL;
   MRI_IMAGE *imin=NULL;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;
   /* ------------- Mask business -----------------*/
   if (!aset) {
      SUMA_S_Err("Null aset?");
      SUMA_RETURN(NULL);
   }
   if (cmaskp) cmask = *cmaskp;
   if (msetp) mset = *msetp;
   
   if (Opt->mset_name && !strcmp(Opt->mset_name,"VOX_DEBUG")) {
      /* Just the debugging voxel man! */
      if (Opt->VoxDbg >= 0) {
         if (Opt->VoxDbg < DSET_NVOX(aset)) {
            SUMA_S_Note("Mask consists of voxel %d only", Opt->VoxDbg);
            mmm = (byte *)calloc( DSET_NVOX(aset), sizeof(byte));
            mmm[Opt->VoxDbg]=1;
            *mcount = 1;
         } else {
            SUMA_S_Err("VoxDbg (%d) > #voxels (%d) in dset", 
                       Opt->VoxDbg, DSET_NVOX(aset));
            ERROR_exit("No reason to proceed");
         }
      } else {
         SUMA_S_Err("Used VOX_DEBUG for -mask but no -vox_debug entry.\n"
                     "Ignoring masking, all %d voxels in the dataset will\n"
                     "be used.", DSET_NVOX(aset)) ;
         ERROR_exit("Goodbye cruel world");
      }
   } else {
      if( mset == NULL ){
         mmm = NULL ;
         if( Opt->debug ) 
            INFO_message("%d voxels in the entire dataset (no mask)\n",
                        DSET_NVOX(aset)) ;
         *mcount = DSET_NVOX(aset);
      } else {
         if( DSET_NVOX(mset) != DSET_NVOX(aset) )
           ERROR_exit("Input and mask datasets are not same dimensions!\n");
         mmm = THD_makemask( mset , 0 , mask_bot, mask_top ) ;
         *mcount = THD_countmask( DSET_NVOX(mset) , mmm ) ;
         if( *mcount <= 0 ) {
            ERROR_message("No voxels in the mask!\n") ;
            SUMA_RETURN(NULL);
         }
         if( Opt->debug ) INFO_message("%d voxels in the mask\n",*mcount) ;
         DSET_delete(mset); *msetp=NULL;
      }
   }

   if( cmask != NULL ){
      SUMA_LH("Merging with cmask");
      if( dimcmask != DSET_NVOX(aset) )
        ERROR_exit("Input and cmask datasets are not same dimensions!\n");
      if( mmm != NULL ){
         for( ii=0 ; ii < DSET_NVOX(aset) ; ii++ ) 
            mmm[ii] = (mmm[ii] && cmask[ii]) ;
         free(cmask) ; *cmaskp=NULL;
         *mcount = THD_countmask( DSET_NVOX(aset) , mmm ) ;
         if( *mcount <= 0 ) {
            ERROR_message("No voxels in the mask+cmask!\n") ;
            SUMA_RETURN(NULL);
         }
         if( Opt->debug ) 
            INFO_message("%d voxels in the mask+cmask\n",*mcount) ;
      } else {
         mmm = cmask ;
         *mcount = THD_countmask( DSET_NVOX(aset) , mmm ) ;
         if( *mcount <= 0 ) {
            ERROR_message("No voxels in the cmask!\n") ;
            SUMA_RETURN(NULL);
         }
         if( Opt->debug ) INFO_message("%d voxels in the cmask\n",*mcount) ;
      }
   }
   
   /* Make sure that aset has no exact 0s that are in the mask 
      Unless had VOX_DEBUG for mask */
   if (mask_zero_aset) {
      if (Opt->mset_name && strcmp(Opt->mset_name,"VOX_DEBUG")) {
         imin = THD_extract_float_brick(0,aset) ;
         fa = MRI_FLOAT_PTR(imin);
         Fixit = 0;
         for( ii=0 ; ii < DSET_NVOX(aset) && !Fixit; ii++ ) {
            if (IN_MASK(mmm, ii) && fa[ii] == 0.0) {
               Fixit = 1; 
            }
         }
      }
      if (Fixit) {
         SUMA_LH("Have to merge mask with anat");
         if (!mmm) {
            mmm = (byte *)malloc(DSET_NVOX(aset)*sizeof(byte));
            memset(mmm, 1, sizeof(byte)*DSET_NVOX(aset));
            *mcount = DSET_NVOX(aset);
         }
         for( ii=0 ; ii < DSET_NVOX(aset); ii++ ) {
            if (IN_MASK(mmm, ii) && fa[ii] == 0.0) {
               mmm[ii] = 0; *mcount = *mcount - 1;
            }
         }
      }
      if (imin) mri_free(imin); imin = NULL; fa = NULL;
   }
   
   SUMA_RETURN(mmm);         
}
Exemple #14
0
int main (int argc,char *argv[])
{/* Main */
   static char  FuncName[]={"MakeColorMap"};
   char  *fscolutname = NULL, *FidName = NULL, 
         *Prfx = NULL, h[9], *StdType=NULL, *dbfile=NULL, *MapName=NULL; 
   int Ncols = 0, N_Fid = 0, kar, i, ifact, *Nind = NULL, 
       imap = -1, MapSpecified = 0;
   int fsbl0, fsbl1, showfscolut, exists=0;
   float **Fid=NULL, **M=NULL;
   MRI_IMAGE *im = NULL;
   float *far=NULL;
   int AfniHex=0, freesm;
   int suc, idISi=0;
   char stmp[256], *s=NULL, *ooo=NULL, *sdset_prefix;
   SUMA_PARSED_NAME *sname=NULL;
   NI_group *ngr=NULL;   
   SUMA_Boolean   brk, SkipLast, PosMap, 
               Usage1, Usage2, Usage3, Usage4, flipud, fscolut,
               LocalHead = NOPE;
   SUMA_COLOR_MAP *SM=NULL;
   SUMA_DSET_FORMAT iform;
   SUMA_DSET *sdset=NULL;
      
   SUMA_STANDALONE_INIT;

   SUMA_mainENTRY;
   

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

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

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

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

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

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

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

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

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

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

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

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

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

            /* color map */

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

      if (idset != sdset) SUMA_FreeDset(idset); 
      SUMA_FreeDset(sdset); sdset=NULL;
   }
   if (SM && !MapName && freesm) SUMA_Free_ColorMap(SM);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) { 
      SUMA_SL_Err("Failed to free commonfields."); 
   }
   
   SUMA_RETURN (0);
}   
int main (int argc,char *argv[])
{/* Main */
   static char FuncName[]={"ConvertSurface"}; 
	int kar, volexists, i, j, Doinv, randseed, Domergesurfs=0, pciref;
   float DoR2S, fv[3], *pcxyzref;
   double xcen[3], sc[3];
   double xform[4][4];
   char  *if_name = NULL, *of_name = NULL, *if_name2 = NULL, 
         *of_name2 = NULL, *sv_name = NULL, *vp_name = NULL,
         *OF_name = NULL, *OF_name2 = NULL, *tlrc_name = NULL,
         *acpc_name=NULL, *xmat_name = NULL, *ifpar_name = NULL, 
         *ifpar_name2 = NULL;
   SUMA_SO_File_Type iType = SUMA_FT_NOT_SPECIFIED, 
                     iparType = SUMA_FT_NOT_SPECIFIED,
                     oType = SUMA_FT_NOT_SPECIFIED;
   SUMA_SO_File_Format iForm = SUMA_FF_NOT_SPECIFIED, 
                        iparForm = SUMA_FF_NOT_SPECIFIED, 
                        oFormat = SUMA_FF_NOT_SPECIFIED;
   SUMA_SurfaceObject *SO = NULL, *SOpar = NULL, *SOsurf = NULL;
   SUMA_PARSED_NAME *of_name_strip = NULL, *of_name2_strip = NULL;
   SUMA_SFname *SF_name = NULL;
   void *SO_name = NULL;
   char orsurf[6], orcode[6], *PCprojpref=NULL, *NodeDepthpref=NULL;
   THD_warp *warp=NULL ;
   THD_3dim_dataset *aset=NULL;
   SUMA_Boolean brk, Do_tlrc, Do_mni_RAI, Do_mni_LPI, Do_acpc, Docen, Do_flip;
   SUMA_Boolean Doxmat, Do_wind, Do_p2s, onemore, Do_native, Do_PolDec;
   int Do_PCproj, Do_PCrot, Do_NodeDepth;
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_Boolean exists;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;
	
   /* Allocate space for DO structure */
	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   ps = SUMA_Parse_IO_Args(argc, argv, "-o;-i;-sv;-ipar;");
   
   
   kar = 1;
   xmat_name = NULL;
   xcen[0] = 0.0; xcen[1] = 0.0; xcen[2] = 0.0;
	brk = NOPE;
   orcode[0] = '\0'; 
   randseed = 1234;
   sprintf(orsurf,"RAI");
   Docen = NOPE;
   Doxmat = NOPE;
   Do_tlrc = NOPE;
   Do_mni_RAI = NOPE;
   Do_mni_LPI = NOPE;
   Do_acpc = NOPE;
   Do_wind = NOPE;
   Do_flip = NOPE;
   Do_p2s = NOPE;
   Do_native = NOPE;
   DoR2S = 0.0;
   Do_PolDec = NOPE;
   Do_PCproj = NO_PRJ;
   Do_PCrot = NO_ROT;
   pciref = -1;
   pcxyzref = NULL;
   PCprojpref = NULL;
   NodeDepthpref = NULL;
   Do_NodeDepth = 0;
   Doinv = 0;
   Domergesurfs = 0;
   onemore = NOPE;
	while (kar < argc) { /* loop accross command ine options */
		/*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
		if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
			 usage_SUMA_ConvertSurface(ps, strlen(argv[kar]) > 3 ? 2:1);
          exit (0);
		}
		
      SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      SUMA_TO_LOWER(argv[kar]);
		      
      if (!brk && (strcmp(argv[kar], "-seed") == 0)) {
         kar ++;
			if (kar >= argc)  {
		  		fprintf (SUMA_STDERR, "need 1 integer after -seed\n");
				exit (1);
			}
			randseed = atoi(argv[kar]); 
			brk = YUP;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   
   
   /* write the surface object */
   if (SO_name) {
      if (LocalHead) SUMA_Print_Surface_Object (SO, stderr);
      fprintf (SUMA_STDOUT,"Writing surface...\n");
      if (!(SUMA_Save_Surface_Object ( SO_name,
                                    SO, oType, oFormat, SOpar))) {
         fprintf (SUMA_STDERR,
                  "Error %s: Failed to write surface object.\n", 
                  FuncName);
         exit (1);
      }
   } 
   
   
   
   if (of_name_strip) of_name_strip = SUMA_Free_Parsed_Name (of_name_strip);
   if (of_name2_strip) of_name2_strip = SUMA_Free_Parsed_Name (of_name2_strip);
   if (OF_name) SUMA_free(OF_name);
   if (OF_name2) SUMA_free(OF_name2);
   if (SF_name) SUMA_free(SF_name);
   if (SO_name) SUMA_free(SO_name);
   if (SO) SUMA_Free_Surface_Object(SO);
   if (SOpar) SUMA_Free_Surface_Object(SOpar);
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   return (0);
}