int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"3dBRAIN_VOYAGERtoAFNI"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_OPEN_DX_STRUCT **dx = NULL;
   THD_3dim_dataset *dset=NULL;
   char *sto3d = NULL;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;

   /* Allocate space for DO structure */
	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   ps = SUMA_Parse_IO_Args(argc, argv, "");
   
   if (argc < 2) {
      usage_3dBRAIN_VOYAGERtoAFNI(ps);
      exit (1);
   }
   
   Opt = SUMA_3dBRAIN_VOYAGERtoAFNI_ParseInput (argv, argc, ps);

   if (Opt->debug > 2) LocalHead = YUP;
   
   dset = EDIT_empty_copy( NULL ) ;
   tross_Make_History( "3dBRAIN_VOYAGERtoAFNI" , argc,argv , dset) ;
   if (!(sto3d = SUMA_BrainVoyager_Read_vmr(Opt->in_name, dset, 1, Opt->b2, Opt->b1, Opt->Icold, Opt->out_prefix))) {
      if (Opt->debug) SUMA_SL_Err("Failed in SUMA_BrainVoyager_Read_vmr");
      exit(1);   
   }
   SUMA_LHv("Old command would be %s\n", sto3d);
   
   if (dset) {
      SUMA_LH("Writing Dset");
      DSET_write(dset) ;
      if (LocalHead) { 
         fprintf(SUMA_STDERR,"%s: Can use the following command to create dset with to3d:\n%s\n", FuncName,sto3d); 
      } 
   } else {
      /* the olde way */
      if (system(sto3d)) {
         fprintf(SUMA_STDERR, "Error %s: Failed while executing shell command:\n%s\n"
                              "Check to3d's error messages, and disk writing permissions.\n", FuncName, sto3d);
      }
   }
   
   
      
   if (sto3d) SUMA_free(sto3d); sto3d = NULL;
   if (dset) { DSET_delete(dset); dset = NULL; }
   if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
   exit(0);
   
} 
Exemplo n.º 2
0
SUMA_DSET *calcWithOffsets(SUMA_SurfaceObject *SO, SUMA_KUBATEST_OPTIONS* Opt)
{
   static char FuncName[]={"calcWithOffsets"};
   /* initialize OffS */
   SUMA_GET_OFFSET_STRUCT *OffS = SUMA_Initialize_getoffsets (SO->N_Node);
   struct timeval start_time, start_time_all;
   float etime_GetOffset, etime_GetOffset_all;
   float *gD=NULL, *pD=NULL, *rD=NULL;
   int *Pr=NULL, *Nd=NULL, *Lj=NULL;
   float pathD = 0;/*shortest distance along surface to node ii*/
   float geomD = 0;/*geometric distance to node ii*/
   float ratio = 1;
   int i = 0,  j = 0, ii = 0, lj =0;
   float x1, x2 , y1, y2, z1, z2, dx, dy, dz, d1, d2, r;
   FILE* outFile = NULL, *segDO=NULL;
   SUMA_DSET *dset=NULL;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;

   if (Opt->outfile) {
      if (!(outFile = fopen(Opt->outfile, "w"))) {
         SUMA_S_Errv("Failed to open %s for writing.\n",
                  Opt->outfile);
         SUMA_RETURN(NULL);
      }
      fprintf(outFile,  
         "#Col. 0 Node index\n"
         "#Col. 1 Node for which the ratio in 4 is the largest. "
         " (Companion of Node in Col.0)\n"
         "#Col. 2 distance in 3D\n"
         "#Col. 3 shortest surface path\n"
         "#Col. 4 Ratio of path/distance\n"
         "#Col. 5 Neighborhood layer of node in Col.1, "
         " i.e. Neighborhood layer of the companion of node in Col.0");
      if (Opt->histnote) {
         fprintf(outFile,  "#History:%s\n", Opt->histnote);
      }
   }
   
   if (Opt->segdo) {
      if (!(segDO = fopen(Opt->segdo, "w"))) {
         SUMA_S_Errv("Failed to open %s for writing.\n",
                  Opt->segdo);
         SUMA_RETURN(NULL);
      }
      fprintf(segDO,
         "#node-based_segments\n");
      if (Opt->histnote) {
         fprintf(segDO,  "#History:%s\n", Opt->histnote);
      }
   } 
    
   Nd=(int *)SUMA_calloc(SO->N_Node, sizeof(int));   
   Pr=(int *)SUMA_calloc(SO->N_Node, sizeof(int));   
   Lj=(int *)SUMA_calloc(SO->N_Node, sizeof(int));   
   gD=(float *)SUMA_calloc(SO->N_Node, sizeof(float));   
   pD=(float *)SUMA_calloc(SO->N_Node, sizeof(float));   
   rD=(float *)SUMA_calloc(SO->N_Node, sizeof(float)); 
   if (!Pr || !gD || !pD || !rD) {
      SUMA_S_Err("Failed to allocate");
      SUMA_RETURN(NOPE);
   }  
   
   SUMA_etime(&start_time_all,0);
   for (i=0; i < SO->N_Node; ++i)
   {
      pathD = 0;/*shortest distance along surface to node ii*/
      geomD = 0;/*geometric distance to node ii*/
      ratio = 1;
      j = 0;
      ii = 0;
      lj = -1;
      /* show me the offset from node 0 */
      SUMA_LHv("Calculating offsets from node %d\n", i);
      if (i == 0) {
         SUMA_etime(&start_time,0);
      }
      SUMA_getoffsets2 (i, SO, Opt->plimit, OffS, NULL, 0);
      if (i == 99) {
         etime_GetOffset = SUMA_etime(&start_time,1);
         SUMA_LHv("Search to %f mm took %f seconds for %d nodes.\n"
                  "Projected completion time: %f minutes\n",
                  Opt->plimit, etime_GetOffset, i+1,
                  etime_GetOffset * SO->N_Node / 60.0 / (i+1));
      }
      /*find smallest ratio*/
      for (j=0; j < OffS->N_Nodes; j++)
      {
         if( i!=j && OffS->LayerVect[j] >= 0)
         {
            x1 = SO->NodeList[i*3+0];
            x2 = SO->NodeList[j*3+0];
            y1 = SO->NodeList[i*3+1];
            y2 = SO->NodeList[j*3+1];
            z1 = SO->NodeList[i*3+2];
            z2 = SO->NodeList[j*3+2];
            dx = x1 - x2;
            dy = y1 - y2;
            dz = z1 - z2;
            d1 = OffS->OffVect[j];
            d2 = sqrt(dx*dx + dy*dy + dz*dz);
            r = d1 / d2;
            if ( d2 < Opt->dlimit && d1 < Opt->plimit && r > ratio )
            {
               if (r > 1000) {
                  SUMA_S_Notev("Extreme Ratio:\n"
                        "node=%d (%f %f %f), paired with node %d (%f %f %f)\n"
                        " geo_dist=%f Euc_dist=%f r=%f layer=%d\n", 
                     i, x1, y1, z1,
                     j, x2, y2, z2,
                     d1, d2, r, OffS->LayerVect[j]);
               }
               ratio = r;
               ii = j;
               lj = OffS->LayerVect[j];
               pathD = d1;
               geomD = d2;
            }
         }
      }
      Nd[i] = i;
      Pr[i] = ii;
      Lj[i] = lj;
      gD[i] = geomD;
      pD[i] = pathD;
      rD[i] = ratio;
      if (outFile)
         fprintf(outFile, "%i\t%i\t%f\t%f\t%f\t%d\n", 
                     i, ii, geomD, pathD, ratio, lj);
      if (segDO) {
         float r,g,b,a;
         SUMA_RAND_COL(i?-1:0,r,g,b,a);
         fprintf(segDO, "%i\t%i\t%f %f %f %f\n", i, ii, r,g,b,1.0);
      }
      
      if (LocalHead) 
         fprintf(SUMA_STDERR,"%s: Recycling OffS\n", FuncName);
      SUMA_Recycle_getoffsets (OffS);
      if (LocalHead)
         fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);
   }
   
   if (outFile) fclose(outFile);
   if (segDO) fclose(segDO);
   
   dset = SUMA_CreateDsetPointer(Opt->prefix, SUMA_NODE_BUCKET,
                                 NULL, SO->idcode_str,
                                 SO->N_Node);
   if (!SUMA_AddDsetNelCol(dset, "node index", SUMA_NODE_INDEX, Nd, NULL, 1)) {
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   if (!SUMA_AddDsetNelCol(dset, "PairingNode", SUMA_NODE_INT, Pr, NULL, 1)) {
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   if (!SUMA_AddDsetNelCol(dset, "LayerOfPairNode", SUMA_NODE_INT, Lj, NULL, 1)){
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   if (!SUMA_AddDsetNelCol(dset, "Eucl.Dist", SUMA_NODE_FLOAT, gD, NULL, 1)) {
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   if (!SUMA_AddDsetNelCol(dset, "Geo.Dist",SUMA_NODE_FLOAT,  pD, NULL, 1)) {
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   if (!SUMA_AddDsetNelCol(dset, "G/E.Dist",SUMA_NODE_FLOAT,  rD, NULL, 1)) {
      SUMA_S_Err("Failed to add new data");
      SUMA_FreeDset(dset); SUMA_RETURN(NULL);
   } 
   
   etime_GetOffset_all = SUMA_etime(&start_time_all,1);
   SUMA_S_Notev("Done.\nSearch to %f mm took %f minutes for %d nodes.\n" ,
                 Opt->plimit, etime_GetOffset_all / 60.0 , SO->N_Node);
   SUMA_Free_getoffsets(OffS);
   SUMA_free(Nd); Nd = NULL;
   SUMA_free(Pr); Pr = NULL;
   SUMA_free(Lj); Lj = NULL;
   SUMA_free(gD); gD = NULL;
   SUMA_free(pD); pD = NULL;
   SUMA_free(rD); rD = NULL;
   SUMA_RETURN(dset);
}
char * SUMA_BrainVoyager_Read_vmr(char *fnameorig, THD_3dim_dataset *dset, int LoadData, 
                                  byte Qxforce, byte bsforce, int viewforce, char *outname)
{
   static char FuncName[]={"SUMA_BrainVoyager_Read_vmr"};
   int  i = 0, nf, iop, dchunk, End, bs, doff, ex,
         data_type=SUMA_notypeset, view, endian, dblock;
   THD_ivec3 iv3;
   unsigned long len;
   short qxver;
   short nvox[3]; /* values are unsigned, so check for sign for bs... */
   THD_mat33 m33;
   THD_ivec3 orixyz , nxyz ;
   THD_fvec3 dxyz , orgxyz ;
   float ep[3], sp[3];
   char sview[10], *fname = NULL, *scom=NULL, form[10], swp[10], orstr[10], xfov[100], yfov[100], zfov[100], *prefix = NULL, *dsetheadname = NULL;
   FILE *fid = NULL;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;
   
   if (!dset || !fnameorig) {
      SUMA_SL_Err("NULL fname || NULL dset!");
      SUMA_RETURN(NOPE);
   }
   
   if (!SUMA_isExtension(fnameorig, ".vmr")) {
      SUMA_SL_Err("vmr dset is expected to have .vmr for an extension");
      SUMA_RETURN(NOPE);
   }
   
   if (!SUMA_filexists(fnameorig)) {
      SUMA_SL_Err("file does not exist");
      SUMA_RETURN(NOPE);
   }
   
   /* make fname be the new name without the extension*/
   if (!outname) {
      fname = SUMA_Extension(fnameorig,".vmr", YUP);
   } else {
      fname = SUMA_Extension(outname, ".vmr", YUP);
   }
   prefix = SUMA_AfniPrefix(fname, NULL, NULL, NULL);
   if( !THD_filename_ok(prefix) ) {
      SUMA_SL_Err("Bad prefix");
      goto CLEAN_EXIT;
   }
   
   /* someday, guess format on your own...*/
   qxver = 0;
   if (Qxforce) {
      SUMA_LH("Forcing qxver");
      qxver = 1;  /* set to 1 if qx format */
   } 
   
   /* view ? */
   SUMA_LHv("Viewforce = %d; [%d %d]\n", viewforce, VIEW_ORIGINAL_TYPE, VIEW_TALAIRACH_TYPE);
   if (viewforce >=  VIEW_ORIGINAL_TYPE && viewforce <= VIEW_TALAIRACH_TYPE) {
      view = viewforce;
   } else {
      view = VIEW_ORIGINAL_TYPE;
      if (SUMA_iswordin_ci(fnameorig, "_tal") == 1) { view = VIEW_TALAIRACH_TYPE; }
      else if (SUMA_iswordin_ci(fnameorig, "_acpc") == 1) { view = VIEW_ACPCALIGNED_TYPE; } 
      else { view = VIEW_ORIGINAL_TYPE;  } 
   }
   switch (view) {
      case VIEW_ORIGINAL_TYPE:
         sprintf(sview,"+orig"); break;
      case VIEW_ACPCALIGNED_TYPE:
         sprintf(sview,"+acpc"); break;
      case VIEW_TALAIRACH_TYPE: 
         sprintf(sview,"+tlrc"); break;
      default:
         SUMA_SL_Err("Bad view");
         goto CLEAN_EXIT; 
   }
   
   if (LocalHead) fprintf(SUMA_STDERR,"%s: View %s, %d\n", FuncName, sview, view);    
   
   dsetheadname = SUMA_append_replace_string(prefix,".HEAD", sview, 0);
   if (SUMA_filexists(dsetheadname)) {
      SUMA_S_Errv("Bad prefix, output dset %s exists\n", dsetheadname);
      goto CLEAN_EXIT;
   }
   SUMA_free(dsetheadname); dsetheadname = NULL;
   
   fid = fopen(fnameorig,"r"); 
   if (!fid) {
      SUMA_SL_Err("Could not open file for reading");
      goto CLEAN_EXIT;      
   }
   
   if (qxver) { 
      SUMA_LH("Reading dimensions, 2+ 1st 6 bytes and deciding on swap");
      doff = 4*sizeof(short);/* data offset 2 + 6 bytes */
   } else {
      SUMA_LH("Reading dimensions, 1st 6 bytes and deciding on swap");
      doff = 3*sizeof(short);/* data offset */
   }
   SUMA_WHAT_ENDIAN(endian);
   bs = 0;
   swp[0] = '\0';
   data_type = SUMA_byte; /* voxel data is bytes */
   dchunk = sizeof(byte); /* voxel data is bytes */
   sprintf(form,"3Db");
   if (qxver) { SUMA_READ_NUM(&(qxver), fid, ex, sizeof(short)); if (LocalHead) fprintf(SUMA_STDERR,"%s: QXver = %d\n", FuncName, qxver);}/* is this a QX format?*/
   SUMA_READ_NUM(&(nvox[2]), fid, ex, sizeof(short)); /* Z first */
   SUMA_READ_NUM(&(nvox[1]), fid, ex, sizeof(short));
   SUMA_READ_NUM(&(nvox[0]), fid, ex, sizeof(short));
   
   if ((nvox[0] < 0 || nvox[1] < 0 || nvox[2] < 0 )) {
      SUMA_LH("Byte swapping needed");
      bs = 1;
   }
   if (bsforce) {
      SUMA_LH("Byte swapping forced");
      bs = 1;
   }
   
   
   if (bs) {
      if (qxver) SUMA_swap_2(&(qxver));
      SUMA_swap_2(&(nvox[0]));
      SUMA_swap_2(&(nvox[1]));
      SUMA_swap_2(&(nvox[2]));
      sprintf(swp,"-2swap");
      SUMA_OTHER_ENDIAN(endian);
   }
   
   /* 1 1 1???? */
   if (nvox[0] == nvox[1]  && nvox[1] == nvox[2] && nvox[2] == 1) {
      if (LocalHead) { fprintf(SUMA_STDERR,"Warning %s: Voxel nums all 1. Trying from file size\n", FuncName); }
      len = THD_filesize( fnameorig ) ;
      len -= doff;
      len /= dchunk;
      nvox[0] = (int)pow((double)len, 1.0/3.0); 
      if (nvox[0] * nvox[0] * nvox[0] != len) {
         fprintf(SUMA_STDERR,"Error %s: Bad voxel numbers and could not infer number from filesize.\n"
                             "Size of file: %lld, data offset: %d, datum size: %d, data number: %ld\n"
                             "Inferred nvox:%d\n",
                             FuncName,
                             THD_filesize( fnameorig ), doff, dchunk, len, 
                             nvox[0]);
         goto CLEAN_EXIT;
      }
      nvox[2] = nvox[1] = nvox[0];
      if (LocalHead) { fprintf(SUMA_STDERR,"Warning %s: Using filesize inferred number of voxels: %d %d %d\n", 
                              FuncName, nvox[0], nvox[1], nvox[2]); }
   }
   
   if (LocalHead) fprintf(SUMA_STDERR,"Number of voxels: %d %d %d. qxver %d\n", nvox[0], nvox[1], nvox[2], qxver);
   

   /* check against filesize */
   
   len = THD_filesize( fnameorig ) ;
   dblock = nvox[0]*nvox[1]*nvox[2]*dchunk;
   if (len != (dblock + doff)) {
      if (!qxver) {
         fprintf(SUMA_STDERR, "Mismatch between file size    %ld\n"
                              "and expected size             %d = (%d*%d*%d*%d+%d) \n",
                              len, (dblock + doff), nvox[0], nvox[1], nvox[2], dchunk, doff);
         goto CLEAN_EXIT; 
      }else if (len < dblock + doff) {
         fprintf(SUMA_STDERR, "Mismatch between file size    %ld\n"
                              "and minimum expected size     %d = (%d*%d*%d*%d+%d) \n",
                              len, (dblock + doff), nvox[0], nvox[1], nvox[2], dchunk, doff);
         goto CLEAN_EXIT; 
      }else {
         SUMA_LH("Proceeding");
      }
   }
   if (LocalHead) fprintf(SUMA_STDERR,"File size passes test\n");

   /* orientation */
   
   orixyz.ijk[0] = ORI_A2P_TYPE;
   orixyz.ijk[1] = ORI_S2I_TYPE;
   orixyz.ijk[2] = ORI_R2L_TYPE;       
   
   /* load number of voxels */
   LOAD_IVEC3( nxyz   , nvox[0]    , nvox[1]    , nvox[2] ) ;
  
   /* form the command */
   SUMA_LH("Forming command");
   
   {  
      float delta[3]={1.0, 1.0, 1.0};
      float origin[3]={0.0, 0.0, 0.0}; 
      /* set origin of 0th voxel*/
      origin[0] = (float)((nvox[0]*delta[0]))/2.0;    /* ZSS: Changed from 0 0 0 Nov 1 07 */
      origin[1] = (float)((nvox[1]*delta[1]))/2.0;
      origin[2] = (float)((nvox[2]*delta[2]))/2.0;
       
      /* dimensions, same for vmr*/
      LOAD_FVEC3( dxyz , delta[0], delta[1], delta[2]   ) ;
      SUMA_sizeto3d_2_deltaHEAD(orixyz, &dxyz);
      /* origin */
      LOAD_FVEC3( orgxyz , origin[0], origin[1], origin[2]   ) ;
      SUMA_originto3d_2_originHEAD(orixyz, &orgxyz);
      
   }
    
   /* start point (edge of origin voxel) and end point (opposite to start ) */
   sp[0] = orgxyz.xyz[0] + SUMA_ABS(dxyz.xyz[0]) / 2.0;
   sp[1] = orgxyz.xyz[1] + SUMA_ABS(dxyz.xyz[1]) / 2.0;
   sp[2] = orgxyz.xyz[2] + SUMA_ABS(dxyz.xyz[2]) / 2.0;
   ep[0] = orgxyz.xyz[0] + (nxyz.ijk[0] - 0.5) * SUMA_ABS(dxyz.xyz[0]);
   ep[1] = orgxyz.xyz[1] + (nxyz.ijk[1] - 0.5) * SUMA_ABS(dxyz.xyz[1]);
   ep[2] = orgxyz.xyz[2] + (nxyz.ijk[2] - 0.5) * SUMA_ABS(dxyz.xyz[2]);
   SUMA_orcode_to_orstring (orixyz.ijk[0], orixyz.ijk[1], orixyz.ijk[2], orstr);
   sprintf(xfov," -xFOV %.2f%c-%.2f%c", sp[0], orstr[0], ep[0], orstr[3]);
   sprintf(yfov," -yFOV %.2f%c-%.2f%c", sp[1], orstr[1], ep[1], orstr[4]);
   sprintf(zfov," -zFOV %.2f%c-%.2f%c", sp[2], orstr[2], ep[2], orstr[5]);
  
   scom = (char *)SUMA_calloc((strlen(fnameorig)+500), sizeof(char));
   sprintf(scom,"to3d %s %s %s %s -prefix %s %s:%d:0:%d:%d:%d:%s ", 
            swp, xfov, yfov, zfov, prefix, form, doff, 
            nvox[0], nvox[1], nvox[0], fnameorig);
   
   SUMA_LH("HERE");
   
   if (dset) { /* form the dset header */
         int nvals_read = 0;
         SUMA_LH("Filling header");
         EDIT_dset_items( dset ,
                            ADN_prefix      , prefix ,
                            ADN_datum_all   , data_type ,
                            ADN_nxyz        , nxyz ,
                            ADN_xyzdel      , dxyz ,
                            ADN_xyzorg      , orgxyz ,
                            ADN_xyzorient   , orixyz ,
                            ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
                            ADN_view_type   , view ,
                            ADN_type        , HEAD_ANAT_TYPE ,
                            ADN_func_type   , ANAT_BUCK_TYPE ,
                          ADN_none ) ;

         if (LoadData) {
            void *vec=NULL;
            SUMA_LH("Loading data");
            if (!(vec = SUMA_BinarySuck(fnameorig, data_type, endian, 3*sizeof(short), -1, &nvals_read))) {
               SUMA_SL_Err("Failed to read data file"); goto CLEAN_EXIT;
            }
            if (qxver) {
               if (nvals_read < nvox[0]*nvox[1]*nvox[2]) {
                  SUMA_SL_Warn("Failed to read expected number of voxels\n proceeding...");
               }
            } else {
               if (nvals_read != nvox[0]*nvox[1]*nvox[2]) {
                  SUMA_SL_Warn("Failed to read the appropriate number of voxels\n proceeding...");
               }
            }  
            EDIT_substitute_brick( dset , 0 , data_type , vec) ;      
            if (LocalHead) fprintf(SUMA_STDERR,"%s: Read %d values from file.\n", FuncName, nvals_read);
            /* DSET_write(dset) ; */
         }
   }
   

   
   CLEAN_EXIT:
   if (prefix) SUMA_free(prefix); prefix = NULL;
   if (fname) SUMA_free(fname); fname = NULL;
   if (fid) fclose(fid); fid = NULL;
   SUMA_RETURN(scom);
}
Exemplo n.º 4
0
int main (int argc,char *argv[])
{/* Main */    
   static char FuncName[]={"SurfMatch"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt;  
   SUMA_GENERIC_ARGV_PARSE *ps=NULL;
   SUMA_SurfSpecFile *Spec = NULL;
   int N_Spec=0, N_inmask;
   byte *cmask=NULL;
   SUMA_SurfaceObject *SO = NULL, *SOr=NULL;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_STANDALONE_INIT;
	SUMA_mainENTRY;

   /* Allocate space for DO structure */
	SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS);
   ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;");
   
   if (argc < 2) {
      usage_SurfMatch(ps, 0);
      exit (1);
   }
   
   Opt = SUMA_SurfMatch_ParseInput (argv, argc, ps);

   if (Opt->debug > 2) LocalHead = YUP;
   
   /* check on inputs */
   if (ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames != 2) {
      SUMA_S_Err("Must have two surfaces");
      exit(1);
   }

   Spec = SUMA_IO_args_2_spec(ps, &N_Spec);
   if (N_Spec == 0) {
      SUMA_S_Err("No surfaces found.");
      exit(1);
   }
   if (N_Spec != 1) {
      SUMA_S_Err("Multiple spec at input.");
      exit(1);
   }

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

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

   if (SOr) SUMA_Free_Surface_Object(SOr); SOr = NULL;
   if (SO) SUMA_Free_Surface_Object(SO); SO = NULL;
   
   if (cmask) SUMA_free(cmask); cmask=NULL;                 
   if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL;
   if (N_Spec) {
      int k=0; 
      for (k=0; k<N_Spec; ++k) {
         if (!SUMA_FreeSpecFields(&(Spec[k]))) { 
            SUMA_S_Err("Failed to free spec fields"); 
         } 
      }
      SUMA_free(Spec); Spec = NULL; N_Spec = 0;
   }
   if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt);
   if (!SUMA_Free_CommonFields(SUMAg_CF)) 
      SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1);
   exit(0);
   
} 
Exemplo n.º 5
0
/*!
  contains code shamelessly stolen from Rick who stole it from Bob. 
*/
SUMA_Boolean SUMA_Get_isosurface_datasets (
                     SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt)
{
   static char FuncName[]={"SUMA_Get_isosurface_datasets"};
   int i;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;
   
   if (!Opt->in_vol && !Opt->in_name) {
      SUMA_S_Err("NULL input");
      SUMA_RETURN(NOPE);
   } 
   if (!Opt->in_vol) { /* open it */
     Opt->in_vol = THD_open_dataset( Opt->in_name );
   }
   if (!Opt->in_vol) {
      SUMA_S_Err("No volume could be had");
      SUMA_RETURN(NOPE);
   } 
   
   if (!ISVALID_DSET(Opt->in_vol)) {
      if (!Opt->in_name) {
         SUMA_SL_Err("NULL input volume.");
         SUMA_RETURN(NOPE);
      } else {
         SUMA_SL_Err("invalid volume.");
         SUMA_RETURN(NOPE);
      }
   } else if ( DSET_BRICK_TYPE(Opt->in_vol, 0) == MRI_complex) {
      SUMA_SL_Err("Can't do complex data.");
      SUMA_RETURN(NOPE);
   }
   
   Opt->nvox = DSET_NVOX( Opt->in_vol );
   if (DSET_NVALS( Opt->in_vol) != 1) {
      SUMA_SL_Err("Input volume can only have one sub-brick in it.\n"
                  "Use [.] selectors to choose sub-brick needed.");
      SUMA_RETURN(NOPE);
   }
   
   
   Opt->mcdatav = (double *)SUMA_malloc(sizeof(double)*Opt->nvox);
   if (!Opt->mcdatav) {
      SUMA_SL_Crit("Failed to allocate for maskv");
      SUMA_RETURN(NOPE);
   }
   if (Opt->xform == SUMA_ISO_XFORM_MASK) {
      SUMA_LH("SUMA_ISO_XFORM_MASK");
      switch (Opt->MaskMode) {
         case SUMA_ISO_CMASK:
            SUMA_LH("SUMA_ISO_CMASK");
            if (Opt->cmask) {
               /* here's the second order grand theft */
               int    clen = strlen( Opt->cmask );
	            char * cmd;
               byte *bmask;

	            cmd = (char *)malloc((clen + 1) * sizeof(char));
	            strcpy( cmd,  Opt->cmask);

	            bmask = EDT_calcmask( cmd, &Opt->ninmask, 0 );
               SUMA_LHv("Have %d\n", Opt->ninmask);
	            free( cmd );			   /* free EDT_calcmask() string */

	            if ( bmask == NULL ) {
	               SUMA_SL_Err("Failed to compute mask from -cmask option");
	               SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
                  SUMA_RETURN(NOPE);
	            } 
	            if ( Opt->ninmask != Opt->nvox ) {
	               SUMA_SL_Err("Input and cmask datasets do not have "
		                        "the same dimensions\n" );
	               SUMA_free(Opt->mcdatav); Opt->mcdatav=NULL;
	               SUMA_RETURN(NOPE);
	            }
	            Opt->ninmask = THD_countmask( Opt->ninmask, bmask );
               SUMA_LHv("Have %d\n", Opt->ninmask);
               for (i=0; i<Opt->nvox; ++i) 
                  if (bmask[i]) Opt->mcdatav[i] = (double)bmask[i]; 
                  else Opt->mcdatav[i] = -1;
               free(bmask);bmask=NULL;
            } else {
               SUMA_SL_Err("NULL cmask"); SUMA_RETURN(NOPE);
            }
            break;
         case SUMA_ISO_VAL:
         case SUMA_ISO_RANGE:
            SUMA_LH("SUMA_ISO_VAL, SUMA_ISO_RANGE");
            /* load the dset */
            DSET_load(Opt->in_vol);
            Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
            if (!Opt->dvec) {
               SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
               SUMA_RETURN(NOPE);
            }
            EDIT_coerce_scale_type( 
               Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
               DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , 
               MRI_double               , Opt->dvec  ) ;  
            /* no need for data in input volume anymore */
            PURGE_DSET(Opt->in_vol);

            Opt->ninmask = 0;
            if (Opt->MaskMode == SUMA_ISO_VAL) {
               for (i=0; i<Opt->nvox; ++i) {
                  if (Opt->dvec[i] == Opt->v0) { 
                     Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
                  }  else Opt->mcdatav[i] = -1;
               }
            } else if (Opt->MaskMode == SUMA_ISO_RANGE) {
               for (i=0; i<Opt->nvox; ++i) {
                  if (Opt->dvec[i] >= Opt->v0 && Opt->dvec[i] < Opt->v1) { 
                     Opt->mcdatav[i] = 1; ++ Opt->ninmask; 
                  }  else Opt->mcdatav[i] = -1;
               }
            } else {
               SUMA_SL_Err("Bad Miracle.");
               SUMA_RETURN(NOPE);
            }
            SUMA_free(Opt->dvec); Opt->dvec = NULL; 
                  /* this vector is not even created in SUMA_ISO_CMASK mode ...*/
            break;
         default:
            SUMA_SL_Err("Unexpected value of MaskMode");
            SUMA_RETURN(NOPE);
            break;   
      }
   } else if (Opt->xform == SUMA_ISO_XFORM_SHIFT) {
      /* load the dset */
      DSET_load(Opt->in_vol);
      Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
      if (!Opt->dvec) {
         SUMA_SL_Crit("Failed to allocate for dvec.\nOh misery.");
         SUMA_RETURN(NOPE);
      }
      EDIT_coerce_scale_type( 
         Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
         DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) ,      
         MRI_double               , Opt->dvec  ) ;   
      /* no need for data in input volume anymore */
      PURGE_DSET(Opt->in_vol);
      Opt->ninmask = Opt->nvox;
      for (i=0; i<Opt->nvox; ++i) { 
         Opt->mcdatav[i] = Opt->dvec[i] - Opt->v0;
      }
      SUMA_free(Opt->dvec); Opt->dvec = NULL; 
   } else if (Opt->xform == SUMA_ISO_XFORM_NONE) {
      /* load the dset */
      DSET_load(Opt->in_vol);
      Opt->dvec = (double *)SUMA_malloc(sizeof(double) * Opt->nvox);
      if (!Opt->dvec) {
         SUMA_SL_Crit("Faile to allocate for dvec.\nOh misery.");
         SUMA_RETURN(NOPE);
      }
      EDIT_coerce_scale_type( 
         Opt->nvox , DSET_BRICK_FACTOR(Opt->in_vol,0) ,
         DSET_BRICK_TYPE(Opt->in_vol,0), DSET_ARRAY(Opt->in_vol, 0) , 
         MRI_double               , Opt->dvec  ) ;   
      /* no need for data in input volume anymore */
      PURGE_DSET(Opt->in_vol);
      Opt->ninmask = Opt->nvox;
      for (i=0; i<Opt->nvox; ++i) { 
         Opt->mcdatav[i] = Opt->dvec[i];
      }
      SUMA_free(Opt->dvec); Opt->dvec = NULL; 
   } else {
      SUMA_SL_Err("Bad Opt->xform.");
      SUMA_RETURN(NOPE);
   }
   
   if ( Opt->ninmask  <= 0 ) {
	   if (Opt->ninmask == 0) {
         SUMA_SL_Err("A negative value!\nNothing to do." );
      } else {
         SUMA_SL_Err("An empty mask!\n Nothing to do." );
	   }
      SUMA_RETURN(NOPE);
	}
   
   if (Opt->debug > 0) {
      fprintf( SUMA_STDERR, 
               "%s:\nInput dset %s has nvox = %d, nvals = %d",
		         FuncName, SUMA_CHECK_NULL_STR(Opt->in_name), 
               Opt->nvox, DSET_NVALS(Opt->in_vol) );
	   fprintf( SUMA_STDERR, " (%d voxels in mask)\n", Opt->ninmask );
   }
   
   SUMA_RETURN(YUP);
}
Exemplo n.º 6
0
/*!
   A function to call SUMA_qhull_wrap or SUMA_qdelaunay_wrap
*/
SUMA_SurfaceObject *SUMA_ConvexHullSurface(
               SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt)
{
   static char FuncName[]={"SUMA_ConvexHullSurface"};
   SUMA_SurfaceObject *SO=NULL;
   float *xyz=NULL, *xyzp=NULL, *txyz=NULL;
   int npt, *ijk=NULL, nf=0, cnt, i, j, k, nxx, nyy, nzz,N_txyz=-1;
   FILE *fid=NULL;
   THD_fvec3 fv, iv;
   SUMA_Boolean LocalHead = NOPE;
   
   SUMA_ENTRY;
   
   npt = 0;
   N_txyz=-1;
   if (Opt->UseThisBrain) {
      MRI_IMAGE *im = NULL;
      float *far=NULL;
      int nx2, i3;

      /* load the 1D file */
      im = mri_read_1D (Opt->UseThisBrain);
      if (!im) {
         SUMA_S_Err("Failed to read file");
         SUMA_RETURN(NULL);
      }   

      far = MRI_FLOAT_PTR(im);
      if (im->nx == 0) {
         SUMA_S_Errv("Empty file %s.\n", Opt->UseThisBrain);
         SUMA_RETURN(NULL);
      }
      if (im->ny != 3) {
         SUMA_S_Errv("Found %d columns in %s. Expecting 3\n", 
                     im->ny, Opt->UseThisBrain);
         SUMA_RETURN(NULL);
      }

      /* copy the columns */
      N_txyz = im->nx;
      txyz = (float *)SUMA_malloc(im->nx*im->ny*sizeof(float));
      if (!txyz) {
         SUMA_S_Crit("Failed to allocate.");
         SUMA_RETURN(NULL);
      }
      nx2 = 2*im->nx;
      for (i=0; i<N_txyz; ++i) {
         i3 = 3*i;
         txyz[i3  ] = far[i];
         txyz[i3+1] = far[i+im->nx];
         txyz[i3+2] = far[i+nx2];
      }

      /* done, clean up and out you go */
      if (im) mri_free(im); im = NULL;       
   }
   
   if (Opt->in_vol) {
      cnt = 0; npt = 0;
      nxx = (DSET_NX(Opt->in_vol)); 
      nyy = (DSET_NY(Opt->in_vol));
      nzz = (DSET_NZ(Opt->in_vol));

      if (Opt->debug) fprintf(SUMA_STDERR,"%s:\nRunning qhull...\n", FuncName);
      xyz = (float *)SUMA_malloc(3*nxx*nyy*nzz*sizeof(float));
      if (!xyz) {
         SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL);
      }
      for(  k = 0 ; k < nzz ; k++ ) {
         for(  j = 0 ; j < nyy ; j++ ) {
            for(  i = 0 ; i < nxx ; i++ ) {
               if (Opt->mcdatav[cnt] == 1) {
                  fv.xyz[0] = DSET_XORG(Opt->in_vol) + i * DSET_DX(Opt->in_vol);
                  fv.xyz[1] = DSET_YORG(Opt->in_vol) + j * DSET_DY(Opt->in_vol);
                  fv.xyz[2] = DSET_ZORG(Opt->in_vol) + k * DSET_DZ(Opt->in_vol);
                  /* change mm to RAI coords */
		            iv = SUMA_THD_3dmm_to_dicomm( Opt->in_vol->daxes->xxorient, 
                                                Opt->in_vol->daxes->yyorient, 
                                                Opt->in_vol->daxes->zzorient, 
                                                fv );
                  xyz[3*npt] = iv.xyz[0]; 
                  xyz[3*npt+1] = iv.xyz[1]; xyz[3*npt+2] = iv.xyz[2]; 
                  npt++;
               }
               ++cnt;
            }
         }
      }
   } else if (Opt->XYZ) {
      xyz = (float *)SUMA_malloc(3*Opt->N_XYZ*sizeof(float));
      if (!xyz) {
         SUMA_S_Err("Failed to allocate"); SUMA_RETURN(NULL);
      }
      for(  k = 0 ; k < 3*Opt->N_XYZ ; k++ ) {  
         xyz[k] = Opt->XYZ[k]; npt = Opt->N_XYZ; 
      }   
   } else {
      SUMA_S_Err("No input");
      goto CLEANUP; 
   }
   
   if (Opt->corder) {
      SUMA_PC_XYZ_PROJ *pcp=NULL;
      if (Opt->geom==1) {
         SUMA_S_Warn("PCA projection makes no sense for usual convex hull");
      }
      if (!(pcp = SUMA_Project_Coords_PCA (xyz, npt, npt/2, NULL,
                                            E3_PLN_PRJ, ROT_2_Z,0))) {
         SUMA_S_Err("Failed to project");
         goto CLEANUP;   
      }
      xyzp = pcp->xyzp; pcp->xyzp = NULL;
      pcp = SUMA_Free_PC_XYZ_Proj(pcp);
   } else {
      xyzp = xyz;
   }

   if (N_txyz >= 0 && N_txyz != npt) {
      SUMA_S_Errv("Mismatch between number of coordinates for convex hull\n"
                  "and number of coordinates to adopt in the end.\n"
                  " %d, versus %d in -these_coords\n",
                  npt, N_txyz);
      goto CLEANUP;            
   }  
   
   if (Opt->geom == 1) { /* convex hull */
      if (! (nf = SUMA_qhull_wrap(npt, xyzp, &ijk, 1, Opt->s)) ) {
         fprintf(SUMA_STDERR,"%s:\nFailed in SUMA_qhull_wrap\n", FuncName);
         goto CLEANUP; 
      }
      
      /* Other than unif==0 make no sense here, but leave it to the user */
      switch (Opt->unif) {
         case 0:  /* coordinates as passed to qhull, 
                     could be projected ones*/
            SO = SUMA_Patch2Surf(xyzp, npt, ijk, nf, 3);
            break;
         case 1:  /* Original corrdinates passed to qhull
                     (pre-projections, if any) */
            SO = SUMA_Patch2Surf(xyz, npt, ijk, nf, 3);
            break;
         case 2: /* special coordinates passed by user, 
                    never passed in any form to qhull */
            SUMA_S_Warn("Makes no sense to mess with coords for convex hull...");
            SO = SUMA_Patch2Surf(txyz, npt, ijk, nf, 3);
            break;
         default:
            SUMA_S_Err("pit of despair");
            goto CLEANUP; 
      }
            
      if (Opt->debug) fprintf(SUMA_STDERR,"%s:\n%d triangles.\n", FuncName, nf);
   } else if (Opt->geom == 2) { /* triangulation */
      if (! (nf = SUMA_qdelaunay_wrap(npt, xyzp, &ijk, 1, Opt->s)) ) {
         fprintf(SUMA_STDERR,"%s:\nFailed in SUMA_qdelaunay_wrap\n", FuncName);
         goto CLEANUP;    
      }
      switch (Opt->unif) {
         case 0:  /* coordinates as passed to qdelaunay, 
                     could be projected ones*/
            if (xyz == xyzp) xyz=NULL; /* xyzp will be set to 
                                         null in next call, 
                                         so xyz is treated 
                                         the same here */
            SO = SUMA_NewSO(&xyzp, npt, &ijk, nf, NULL);
            SUMA_LHv("xyzp %p, ijk %p\n", txyz, ijk);
           break;
         case 1:  /* Original corrdinates passed to qdelaunay
                     (pre-projections, if any) */
            SO = SUMA_NewSO(&xyz, npt, &ijk, nf, NULL);
            SUMA_LHv("xyz %p, ijk %p\n", txyz, ijk);
            break;
         case 2:  /* special coordinates passed by user, 
                     never passed in any form to qdelaunay */
            SO = SUMA_NewSO(&txyz, npt, &ijk, nf, NULL);
            SUMA_LHv("txyz %p, ijk %p\n", txyz, ijk);
            break;
         default:
            SUMA_S_Err("pit of despair, again");
            goto CLEANUP; 
      }
   } else {
      SUMA_S_Errv("Opt->geom = %d not valid\n", Opt->geom);
      goto CLEANUP;      
   }  
   
   CLEANUP:
   if (ijk) SUMA_free(ijk); ijk=NULL;
   if(txyz) SUMA_free(txyz); txyz=NULL;
   if (xyzp != xyz && xyzp != NULL) SUMA_free(xyzp); xyzp = NULL;
   if (xyz) SUMA_free(xyz); xyz = NULL;

   SUMA_RETURN(SO);
}
Exemplo n.º 7
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);
}