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);
}
Ejemplo n.º 2
0
SUMA_GENERIC_PROG_OPTIONS_STRUCT *SUMA_SurfToSurf_ParseInput(
   char *argv[], int argc, SUMA_GENERIC_ARGV_PARSE *ps)
{
   static char FuncName[]={"SUMA_BrainWrap_ParseInput"}; 
   SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt=NULL;
   int kar;
   SUMA_Boolean brk, accepting_out;
   
   SUMA_Boolean LocalHead = NOPE;

   SUMA_ENTRY;
   
   Opt = SUMA_Alloc_Generic_Prog_Options_Struct();
   kar = 1;
   brk = NOPE;
   Opt->in_1D = NULL;
   Opt->NodeDbg = -1;
   Opt->debug = 0;
   Opt->NearestNode = 0;
   Opt->NearestTriangle = 0;
   Opt->DistanceToMesh = 0;
   Opt->ProjectionOnMesh = 0;
   Opt->NearestNodeCoords = 0;
   Opt->Data = 0;
   Opt->in_name = NULL;
   Opt->out_prefix = NULL;
   Opt->fix_winding = 0;
   Opt->iopt = 0;
   Opt->oform = SUMA_NO_DSET_FORMAT;
   accepting_out = NOPE;
   while (kar < argc) { /* loop accross command ine options */
		/*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
      
      if (!brk && accepting_out) { 
         /* make sure you have not begun with new options */
         if (*(argv[kar]) == '-') accepting_out = NOPE;
      }
		
      if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0) {
			 usage_SurfToSurf(ps, strlen(argv[kar]) > 3 ? 2:1);
          exit (0);
		}
		
		SUMA_SKIP_COMMON_OPTIONS(brk, kar);
      
      if (!brk && (strcmp(argv[kar], "-debug") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a number after -debug \n");
            exit (1);
         }
         
         Opt->debug = atoi(argv[++kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-node_debug") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a number after -node_debug \n");
            exit (1);
         }
         
         Opt->NodeDbg = atoi(argv[++kar]);
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-node_indices") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a parameter after -node_indices \n");
            exit (1);
         }
         
         Opt->in_nodeindices = argv[++kar];
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-closest_possible") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a number after -closest_possible \n");
            exit (1);
         }
         
         Opt->iopt = atoi(argv[++kar]);
         if (Opt->iopt != 0 && Opt->iopt != 1 && Opt->iopt != 2 && 
             Opt->iopt != 3) {
            SUMA_S_Errv("Must choose from 0, 1, 2, or 3 for -closest_possible."
                        " Have %d\n",
                         Opt->iopt);
            exit (1);
         } 
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-output_params") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, 
                     "need at least one parameter after output_params \n");
            exit (1);
         }
         
         accepting_out = YUP;
         brk = YUP;
      }
      
      if (!brk && accepting_out && (strcmp(argv[kar], "NearestNode") == 0)) {
         if (Opt->NearestNode < 1) Opt->NearestNode = 1;
         brk = YUP;
      }
      
      if (!brk && accepting_out && 
            (strcmp(argv[kar], "NearestTriangleNodes") == 0)) {
         if (Opt->NearestNode < 3) Opt->NearestNode = 3;
         brk = YUP;
      }
      
      if (!brk && accepting_out && (strcmp(argv[kar], "NearestTriangle") == 0)) {
         if (Opt->NearestTriangle < 1) Opt->NearestTriangle = 1;
         brk = YUP;
      }
      
      if (!brk && accepting_out && (strcmp(argv[kar], "DistanceToSurf") == 0)) {
         Opt->DistanceToMesh = 1;
         brk = YUP;
      }
      
      if (!brk && accepting_out && 
            (strcmp(argv[kar], "ProjectionOnSurf") == 0)) {
         Opt->ProjectionOnMesh = 1;
         brk = YUP;
      }
      
      if (!brk && accepting_out && 
            (strcmp(argv[kar], "NearestNodeCoords") == 0)) {
         Opt->NearestNodeCoords = 1;
         brk = YUP;
      }
      
      if (!brk && accepting_out && 
            (strcmp(argv[kar], "Data") == 0)) {
         if (Opt->Data < 0) {
            fprintf (SUMA_STDERR, 
                     "Cannot mix parameter Data with -dset option \n");
            exit (1);   
         }
         Opt->Data = 1;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-data") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a name after -data \n");
            exit (1);
         }
         ++kar;
         if (strcmp(argv[kar],"_XYZ_") == 0) { 
            /* default Opt->in_name = NULL*/
            if (Opt->in_name) {
               SUMA_SL_Err("Input already specified."
                           "Do not mix -data and -dset");
               exit (1);
            }
         } else {
            Opt->in_name = SUMA_copy_string(argv[kar]);
         }
         Opt->Data = 1;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-dset") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a name after -dset \n");
            exit (1);
         }
         ++kar;
         if (strcmp(argv[kar],"_XYZ_") == 0 || Opt->Data > 0) { 
            /* default Opt->in_name = NULL*/
            if (Opt->in_name || Opt->Data > 0) {
               SUMA_SL_Err("Input already specified."
                           "Do not mix -data and -dset."
                           "Or use parameter DATA with -dset");
               exit (1);
            }
         } else {
            Opt->in_name = SUMA_copy_string(argv[kar]);
         }
         Opt->Data = -1;
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-prefix") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a name after -prefix \n");
            exit (1);
         }
         
         Opt->out_prefix = SUMA_RemoveDsetExtension_eng(argv[++kar],
                                                      &(Opt->oform));
         brk = YUP;
      }

      if (!brk && (strcmp(argv[kar], "-mapfile") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a name after -mapfile \n");
            exit (1);
         }
         
         Opt->s = SUMA_Extension(argv[++kar],".niml.M2M", NOPE);
         if (!SUMA_filexists(Opt->s)) {
            SUMA_S_Errv("File %s not found\n"
                         , Opt->s);
            exit(1);
         }
         brk = YUP;
      }
      
      if (!brk && (strcmp(argv[kar], "-proj_dir") == 0))
      {
         if (kar+1 >= argc)
         {
            fprintf (SUMA_STDERR, "need a name after -proj_dir \n");
            exit (1);
         }
         
         Opt->in_1D = argv[++kar];
         brk = YUP;
      }
      if (!brk && (strcmp(argv[kar], "-make_consistent") == 0))
      {
         Opt->fix_winding = 1;
         brk = YUP;
      }
      if (!brk && !ps->arg_checked[kar]) {
			fprintf (SUMA_STDERR,
                  "Error %s:\n"
                  "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 ++;
		}
   }
   
   /* set default for NearestNode if nothing has been set */
   if (Opt->NearestNode < 1) Opt->NearestNode = 3;
   
   if (!Opt->out_prefix) Opt->out_prefix = SUMA_copy_string("SurfToSurf"); 
   if (Opt->in_1D && Opt->s) {
      SUMA_S_Err("Cannot use -proj_dir along with -mapfile");
      exit(1);
   }
   SUMA_RETURN(Opt);
}
Ejemplo n.º 3
0
/*!
   \brief parse the arguments for SurfSmooth program
   
   \param argv (char *)
   \param argc (int)
   \return Opt (SUMA_GETPATCH_OPTIONS *) options structure.
               To free it, use 
               SUMA_free(Opt->outfile);
               SUMA_free(Opt->histnote); 
               SUMA_free(Opt);
*/
SUMA_KUBATEST_OPTIONS *SUMA_SampBias_ParseInput(
      char *argv[], int argc, SUMA_KUBATEST_OPTIONS* Opt,
      SUMA_GENERIC_ARGV_PARSE *ps)
{
   static char FuncName[]={"SUMA_SampBias_ParseInput"}; 
   int kar, i, ind;
   char *outprefix;
   SUMA_Boolean brk = NOPE;
   SUMA_Boolean LocalHead = NOPE;

   SUMA_ENTRY;


   kar = 1;
   brk = NOPE;
   Opt->debug = 0;
   Opt->plimit = 50;
   Opt->dlimit = 1000;
   Opt->outfile = NULL;
   Opt->prefix = NULL;
   Opt->segdo = NULL;
   Opt->ps=ps;
   while (kar < argc) 
   { /* loop accross command ine options */
      /*fprintf(stdout, "%s verbose: Parsing command line...\n", FuncName);*/
      if (strcmp(argv[kar], "-h") == 0 || strcmp(argv[kar], "-help") == 0)
      {
         ps->hverb = strlen(argv[kar])>3?2:1;
         usage_SUMA_SampBias(ps);
         exit (0);
      }

      SUMA_SKIP_COMMON_OPTIONS(brk, kar);

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

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

   Opt->histnote = SUMA_HistString (NULL, argc, argv, NULL);
   
   SUMA_RETURN (Opt);
}
Ejemplo n.º 4
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);
}