changeset 2283:346e7a5bc5b9

Added -like option to list of arguments similar behaviour like mincresample.
author baghdadi <baghdadi>
date Fri, 28 Jul 2006 18:17:15 +0000
parents 3fa82d5737eb
children ef0c8ff5b5c0
files progs/rawtominc/rawtominc.c
diffstat 1 files changed, 400 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/progs/rawtominc/rawtominc.c
+++ b/progs/rawtominc/rawtominc.c
@@ -11,7 +11,10 @@
 @CREATED    : September 25, 1992 (Peter Neelin)
 @MODIFIED   : 
  * $Log: rawtominc.c,v $
- * Revision 6.20  2006-05-11 15:09:57  claude
+ * Revision 6.21  2006-07-28 18:17:15  baghdadi
+ * Added -like option to list of arguments similar behaviour like mincresample.
+ *
+ * Revision 6.20  2006/05/11 15:09:57  claude
  * added float and double to -swap_bytes
  *
  * Revision 6.13.2.2  2005/03/16 19:02:52  bert
@@ -149,7 +152,7 @@
 ---------------------------------------------------------------------------- */
 
 #ifndef lint
-static char rcsid[]="$Header: /private-cvsroot/minc/progs/rawtominc/rawtominc.c,v 6.20 2006-05-11 15:09:57 claude Exp $";
+static char rcsid[]="$Header: /private-cvsroot/minc/progs/rawtominc/rawtominc.c,v 6.21 2006-07-28 18:17:15 baghdadi Exp $";
 #endif
 
 #include "config.h"
@@ -198,9 +201,61 @@
 #define DEF_ORIGIN DBL_MAX
 #define ARG_SEPARATOR ','
 
+/* LB. needed for volume_def */
+#define VOL_NDIMS    3   /* Number of volume dimensions */
+#define WORLD_NDIMS  3   /* Number of world spatial dimensions */
+int Specified_like = FALSE;
+
 /* Macros */
 #define STR_EQ(s1,s2) (strcmp(s1,s2)==0)
 
+/* LB. For referring to world axes in arrays subscripted by WORLD_NDIMS */
+#define NO_AXIS -1
+#define XAXIS 0
+#define YAXIS 1
+#define ZAXIS 2
+typedef struct {
+   char *name;
+   int mincid;
+   int imgid;
+   int maxid;
+   int minid;
+   int ndims;
+   nc_type datatype;
+   int is_signed;
+   double vrange[2];                /* [0]=min, [1]=max */
+   long nelements[MAX_VAR_DIMS];    /* Size of each dimension */
+   int world_axes[MAX_VAR_DIMS];    /* Relates variable index to X, Y, Z 
+                                       or NO_AXIS */
+   int indices[VOL_NDIMS];        /* Indices of volume dimenions (subscripted
+                                       from slowest to fastest) */
+   int axes[WORLD_NDIMS];    /* Relates world X,Y,Z (index) to dimension 
+                                order (value=0,1,2; 0=slowest varying) */
+   int using_icv;            /* True if we are using an icv to read data */
+   int icvid;                /* Id of icv (if used) */
+   long slices_per_image;    /* Number of volume slices (row, column) per
+                                minc file image */
+   long images_per_file;     /* Number of minc file images in the file */
+   int do_slice_renormalization; /* Flag indicating that we need to 
+                                    loop through the data a second time, 
+                                    recomputing the slices to normalize
+                                    images properly */
+   int keep_real_range;      /* Flag indicating whether we should keep
+                                the real range of the input data or not */
+} File_Info;
+
+typedef struct {
+   int axes[WORLD_NDIMS];    /* Relates world X,Y,Z (index) to dimension 
+                                order (value=0,1,2; 0=slowest varying) */
+   long nelements[WORLD_NDIMS]; /* These are subscripted by X, Y and Z */
+   double step[WORLD_NDIMS];
+   double start[WORLD_NDIMS];
+   double dircos[WORLD_NDIMS][WORLD_NDIMS];
+   double *coords[WORLD_NDIMS];
+   char units[WORLD_NDIMS][MI_MAX_ATTSTR_LEN];
+   char spacetype[WORLD_NDIMS][MI_MAX_ATTSTR_LEN];
+} Volume_Definition;
+
 /* Function declarations */
 static void parse_args(int argc, char *argv[]);
 static void usage_error(char *pname);
@@ -208,6 +263,12 @@
 static int get_times(char *dst, char *key, char *nextarg);
 static int get_axis_order(char *dst, char *key, char *nextArg);
 
+/* LB. function prototypes */
+static void get_file_info(char *filename, int initialized_volume_def, 
+                          Volume_Definition *volume_def,
+                          File_Info *file_info);
+static int get_model_file(char *dst, char *key, char *nextArg);
+
 /* Array containing information about signs. It is subscripted by
    [signtype][type]. Note that the first row should never be used, since
    default_signs should be used instead. */
@@ -235,6 +296,8 @@
 char *dimname[MAX_VAR_DIMS];
 long dimlength[MAX_VAR_DIMS];
 int ndims;
+/* LB. */
+int NDims=0;
 int type = BYTE_TYPE;
 int signtype = DEF_SIGN;
 nc_type datatype;
@@ -275,6 +338,8 @@
 long skip_length;
 int swap_bytes = FALSE;
 char *axis_order[MAX_DIMS+1] = { MItime, MIzspace, MIyspace, MIxspace };
+/* LB. */
+static Volume_Definition volume_def;
 
 /* Argument table */
 ArgvInfo argTable[] = {
@@ -437,6 +502,8 @@
        "Specify the frame starting times (\"<t1>,<t2>,<t3>,...\")."},
    {"-frame_widths", ARGV_FUNC, (char *) get_times, NULL,
        "Specify the frame lengths (\"<w1>,<w2>,<w3>,...\")."},
+    {"-like", ARGV_FUNC, (char *) get_model_file, (char *) &volume_def,
+       "Specifies a model file."},
    {NULL, ARGV_END, NULL, NULL, NULL}
 };
 
@@ -975,32 +1042,50 @@
    if (ParseArgv(&argc, argv, argTable, 0)) {
       usage_error(pname);
    }
+    /* Get filename */
+   filename = argv[1];
 
    /* Check dimensions */
    ndims = argc - 2;
-   if ((ndims<MIN_DIMS)||(ndims>MAX_DIMS)) {
-      (void) fprintf(stderr, 
-         "\nWrong number of arguments.\n");
-      usage_error(pname);
-   }
-
-   /* Get filename */
-   filename = argv[1];
-
-   /* Get dimensions */
-   for (i=0; i<ndims; i++) {
-      dimlength[i] = strtol(argv[2+i], &ptr, 0);
-      if ((ptr==argv[2+i]) || (*ptr!=0)) {
-         if (ptr==argv[2+i]) {
-            (void) fprintf(stderr, "\nBad argument \"%s\".\n", ptr);
-         }
-         else {
-            (void) fprintf(stderr, 
-                           "\nDimension sizes must be integer values.\n");
-         }
-         usage_error(pname);
-      }
-      dimname[i]=axis_order[i+MAX_DIMS-ndims];
+   
+   /* LB. Modified to take -like with no dimension length provided */
+   if (ndims == 0)
+     {
+       if (!Specified_like) 
+	 {
+	   (void) fprintf(stderr, 
+			  "\nEither provide dimension lengths or use -like.\n");
+	   usage_error(pname);
+	 }
+       else {
+	 ndims = NDims;
+	 for (i=0; i<ndims; i++) {
+	   dimname[i]=axis_order[i+MAX_DIMS-ndims];
+	 }
+       }
+	   
+     }
+   else {
+     if ((ndims<MIN_DIMS)||(ndims>MAX_DIMS)) {
+       (void) fprintf(stderr, 
+		      "\nWrong number of arguments.\n");
+       usage_error(pname);
+     }
+     /* Get dimensions */
+     for (i=0; i<ndims; i++) {
+       dimlength[i] = strtol(argv[2+i], &ptr, 0);
+       if ((ptr==argv[2+i]) || (*ptr!=0)) {
+	 if (ptr==argv[2+i]) {
+	   (void) fprintf(stderr, "\nBad argument \"%s\".\n", ptr);
+	 }
+	 else {
+	   (void) fprintf(stderr, 
+			  "\nDimension sizes must be integer values.\n");
+	 }
+	 usage_error(pname);
+       }
+       dimname[i]=axis_order[i+MAX_DIMS-ndims];
+     }
    }
 
    /* Set types and signs */
@@ -1329,6 +1414,14 @@
         {MItime, MIzspace, MIxspace, MIyspace}, /* ZXY_ORIENTATION */
     };
 
+    /* LB. To avoid confusion for dimension order with -like*/
+    if (Specified_like) {
+      (void) fprintf(stderr, 
+		     "\"%s\" can not use this option with -like\n",
+		     key);
+      exit(EXIT_FAILURE);
+    }
+
     /* Get pointer to client data */
     dim_name_array = (char **) dst;
 
@@ -1431,3 +1524,285 @@
      */
     return (FALSE);
 }
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_file_info
+@INPUT      : filename - name of file to read
+              initialized_volume_def - if TRUE, then volume_def is taken 
+                 as being properly initialized and arrays are freed if
+                 non-NULL. Otherwise arrays are not freed.
+@OUTPUT     : volume_def - description of volume
+              file_info - description of file
+@RETURNS    : (nothing)
+@DESCRIPTION: Routine to get information about the volume definition of
+              a minc file. 
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : February 9, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+static void get_file_info(char *filename, int initialized_volume_def, 
+                          Volume_Definition *volume_def,
+                          File_Info *file_info)
+{
+   int dim[MAX_VAR_DIMS], dimid;
+   int axis_counter, idim, jdim, cur_axis;
+   int varndims, vardim[MAX_VAR_DIMS];
+   long varstart, varcount, dimlength1;
+   char attstr[MI_MAX_ATTSTR_LEN];
+   char dimname1[MAX_NC_NAME];
+   enum {UNKNOWN, REGULAR, IRREGULAR} coord_spacing;
+   
+   /* Open the minc file */
+   file_info->mincid = miopen(filename, NC_NOWRITE);
+   file_info->name = filename;
+
+   /* Get variable identifiers */
+   file_info->imgid = ncvarid(file_info->mincid, MIimage);
+   ncopts = 0;
+   file_info->maxid = ncvarid(file_info->mincid, MIimagemax);
+   file_info->minid = ncvarid(file_info->mincid, MIimagemin);
+   ncopts = NC_VERBOSE | NC_FATAL;
+
+   /* Get information about datatype dimensions of variable */
+   (void) miget_datatype(file_info->mincid, file_info->imgid, 
+                         &file_info->datatype, &file_info->is_signed);
+
+   /* Get valid max and min */
+   (void) miget_valid_range(file_info->mincid, file_info->imgid, 
+                            file_info->vrange);
+
+   /* Get information about dimensions */
+   (void) ncvarinq(file_info->mincid, file_info->imgid, NULL, NULL,
+                   &file_info->ndims, dim, NULL);
+
+   /* Set variables for keeping track of spatial dimensions */
+   axis_counter = 0;                   /* Keeps track of values for axes */
+
+   /* Initialize volume definition variables */
+   for (idim=0; idim < WORLD_NDIMS; idim++) {
+      volume_def->axes[idim] = NO_AXIS;
+      volume_def->step[idim] = 1.0;
+      volume_def->start[idim] = 0.0;
+      for (jdim=0; jdim < WORLD_NDIMS; jdim++) {
+         if (jdim==idim)
+            volume_def->dircos[idim][jdim] = 1.0;
+         else
+            volume_def->dircos[idim][jdim] = 0.0;
+      }
+      if (initialized_volume_def && (volume_def->coords[idim] != NULL)) {
+         free(volume_def->coords[idim]);
+      }
+      volume_def->coords[idim] = NULL;
+      (void) strcpy(volume_def->units[idim], "mm");
+      (void) strcpy(volume_def->spacetype[idim], MI_NATIVE);
+   }
+
+   /* Loop through dimensions, getting dimension information */
+
+   for (idim=0; idim < file_info->ndims; idim++) {
+
+      /* Get size of dimension */
+      (void) ncdiminq(file_info->mincid, dim[idim], dimname1, 
+                      &file_info->nelements[idim]);
+      
+      /* Check variable name */
+      /* LB. added minor modification to change axis_order
+	 for dimension order and name */
+      cur_axis = NO_AXIS;
+      if (strcmp(dimname1, MIxspace)==0)
+	{
+         cur_axis = XAXIS;
+	 axis_order[idim+1]= MIxspace;
+	}
+      else if (strcmp(dimname1, MIyspace)==0)
+	{
+         cur_axis = YAXIS;
+	 axis_order[idim+1]= MIyspace;
+	}
+      else if (strcmp(dimname1, MIzspace)==0)
+	{
+         cur_axis = ZAXIS;
+	 axis_order[idim+1]= MIzspace;
+	}
+      
+      /* Save world axis info */
+      file_info->world_axes[idim] = cur_axis;
+
+      /* Check for spatial dimension */
+      if (cur_axis == NO_AXIS) continue;
+
+      /* Set axis */
+      if (volume_def->axes[cur_axis] != NO_AXIS) {
+         (void) fprintf(stderr, "Repeated spatial dimension %s in file %s.\n",
+                 dimname1, filename);
+         exit(EXIT_FAILURE);
+      }
+      volume_def->axes[cur_axis] = axis_counter++;
+
+      /* Save spatial axis specific info */
+      file_info->axes[cur_axis] = volume_def->axes[cur_axis];
+      file_info->indices[volume_def->axes[cur_axis]] = idim;
+      volume_def->nelements[cur_axis] = file_info->nelements[idim];
+      
+      /* Check for existence of variable */
+      ncopts = 0;
+      dimid = ncvarid(file_info->mincid, dimname1);
+      ncopts = NC_VERBOSE | NC_FATAL;
+      if (dimid == MI_ERROR) continue;
+             
+      /* Get attributes from variable */
+      ncopts = 0;
+      (void) miattget1(file_info->mincid, dimid, MIstep, 
+                       NC_DOUBLE, &volume_def->step[cur_axis]);
+     
+      if (volume_def->step[cur_axis] == 0.0)
+         volume_def->step[cur_axis] = 1.0;
+       
+      (void) miattget1(file_info->mincid, dimid, MIstart, 
+                       NC_DOUBLE, &volume_def->start[cur_axis]);
+      
+      (void) miattget(file_info->mincid, dimid, MIdirection_cosines, 
+                      NC_DOUBLE, WORLD_NDIMS, 
+                      volume_def->dircos[cur_axis], NULL);
+
+      (void) miattgetstr(file_info->mincid, dimid, MIunits, 
+                         MI_MAX_ATTSTR_LEN, volume_def->units[cur_axis]);
+      (void) miattgetstr(file_info->mincid, dimid, MIspacetype, 
+                         MI_MAX_ATTSTR_LEN, volume_def->spacetype[cur_axis]);
+      ncopts = NC_VERBOSE | NC_FATAL;
+
+      /* Normalize the direction cosine */
+      // normalize_vector(volume_def->dircos[cur_axis]);
+
+      /* Look for irregular coordinates for dimension variable */
+      ncopts = 0;
+      coord_spacing = UNKNOWN;
+      dimlength1 = volume_def->nelements[cur_axis];
+      
+      if (miattgetstr(file_info->mincid, dimid, MIspacing, MI_MAX_ATTSTR_LEN,
+                       attstr) != NULL) {
+         if (strcmp(attstr, MI_IRREGULAR) == 0)
+            coord_spacing = IRREGULAR;
+         else if (strcmp(attstr, MI_REGULAR) == 0)
+            coord_spacing = REGULAR;
+      }
+      if (ncvarinq(file_info->mincid, dimid, NULL, NULL, 
+                   &varndims, vardim, NULL) == MI_ERROR) {
+         ncopts = NC_VERBOSE | NC_FATAL;
+         continue;
+      }
+      if ((coord_spacing != REGULAR) && 
+          (varndims == 1) && (vardim[0] == dim[idim])) {
+         coord_spacing = IRREGULAR;
+      }
+      if ((coord_spacing == UNKNOWN) || (dimlength1 <= 1)) {
+         coord_spacing = REGULAR;
+      }
+      if (coord_spacing == IRREGULAR) {
+         volume_def->coords[cur_axis] = malloc(sizeof(double) * dimlength1);
+         varstart = 0;
+         varcount = dimlength1;
+         if (mivarget(file_info->mincid, dimid, &varstart, &varcount,
+                      NC_DOUBLE, MI_SIGNED, volume_def->coords[cur_axis])
+                   == MI_ERROR) {
+            ncopts = NC_VERBOSE | NC_FATAL;
+            free(volume_def->coords[cur_axis]);
+            volume_def->coords[cur_axis] = NULL;
+            continue;
+         }
+         volume_def->start[cur_axis] = volume_def->coords[cur_axis][0];
+         if (dimlength1 > 1) {
+            volume_def->step[cur_axis] = 
+               (volume_def->coords[cur_axis][dimlength1-1] - 
+                            volume_def->coords[cur_axis][0]) /
+                               (dimlength1 - 1);
+            if (volume_def->step[cur_axis] == 0.0)
+               volume_def->step[cur_axis] = 1.0;
+         }
+      }
+      ncopts = NC_VERBOSE | NC_FATAL;
+     
+
+   }   /* End of loop over dimensions */
+
+   /* Check that we have the correct number of spatial dimensions */
+   if (axis_counter != WORLD_NDIMS) {
+      (void) fprintf(stderr, 
+                     "Incorrect number of spatial dimensions in file %s.\n",
+                     filename);
+         exit(EXIT_FAILURE);
+   }
+
+   return;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_model_file
+@INPUT      : dst - Pointer to client data from argument table
+              key - argument key
+              nextArg - argument following key
+@OUTPUT     : (nothing) 
+@RETURNS    : TRUE so that ParseArgv will discard nextArg unless there
+              is no following argument.
+@DESCRIPTION: Routine called by ParseArgv to read in a model file (-like)
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : February 15, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+static int get_model_file(char *dst, char *key, char *nextArg)
+     /* ARGSUSED */
+{
+  Volume_Definition *volume_def;
+  File_Info file;
+  int i;
+   /* Check for following argument */
+   if (nextArg == NULL) {
+      (void) fprintf(stderr, 
+                     "\"%s\" option requires an additional argument\n",
+                     key);
+      exit(EXIT_FAILURE);
+   }
+   /* set this flag so we know that -like is used */
+   Specified_like = TRUE;
+   /* Get pointer to volume definition structure */
+   volume_def = (Volume_Definition *) dst;
+   
+   /* Get file information */
+   get_file_info(nextArg, TRUE, volume_def, &file);
+   
+   /* LB. Set number of dimensions */
+   NDims = file.ndims;
+   /* LB. Set dimension lengths and other info */
+   dimlength[0] = volume_def->nelements[file.world_axes[0]];
+   dimlength[1] = volume_def->nelements[file.world_axes[1]];  
+   dimlength[2] = volume_def->nelements[file.world_axes[2]];
+   
+   /* start */
+   dimstart[0]=  volume_def->start[0];
+   dimstart[1]=  volume_def->start[1];
+   dimstart[2]=  volume_def->start[2];
+   /* step */
+   dimstep[0]=  volume_def->step[0];
+   dimstep[1]=  volume_def->step[1];
+   dimstep[2]=  volume_def->step[2];
+   /* modify dircos X */
+   dimdircos[0][0] = volume_def->dircos[0][0];
+   dimdircos[0][1] = volume_def->dircos[0][1];
+   dimdircos[0][2] = volume_def->dircos[0][2];
+   /* modify dircos Y */
+   dimdircos[1][0] = volume_def->dircos[1][0];
+   dimdircos[1][1] = volume_def->dircos[1][1];
+   dimdircos[1][2] = volume_def->dircos[1][2];
+   /* modify dircos Z */
+   dimdircos[2][0] = volume_def->dircos[2][0];
+   dimdircos[2][1] = volume_def->dircos[2][1];
+   dimdircos[2][2] = volume_def->dircos[2][2];  
+   
+   /* Close the file */
+   (void) miclose(file.mincid);
+   
+   return TRUE;
+}