changeset 995:26eb4481c907

Added -width_weighted option. Allow -weights with -avgdim option.
author neelin <neelin>
date Tue, 02 Apr 1996 20:16:09 +0000
parents 875912d658f7
children cb16b26212ea
files progs/mincaverage/mincaverage.c progs/mincaverage/mincaverage.man1
diffstat 2 files changed, 188 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/progs/mincaverage/mincaverage.c
+++ b/progs/mincaverage/mincaverage.c
@@ -9,9 +9,12 @@
 @CALLS      : 
 @CREATED    : April 28, 1995 (Peter Neelin)
 @MODIFIED   : $Log: mincaverage.c,v $
-@MODIFIED   : Revision 3.1  1995-11-20 14:24:47  neelin
-@MODIFIED   : Added -weights option.
+@MODIFIED   : Revision 3.2  1996-04-02 20:16:09  neelin
+@MODIFIED   : Added -width_weighted option. Allow -weights with -avgdim option.
 @MODIFIED   :
+ * Revision 3.1  1995/11/20  14:24:47  neelin
+ * Added -weights option.
+ *
  * Revision 3.0  1995/05/15  19:32:44  neelin
  * Release of minc version 0.3
  *
@@ -36,7 +39,7 @@
 ---------------------------------------------------------------------------- */
 
 #ifndef lint
-static char rcsid[]="$Header: /private-cvsroot/minc/progs/mincaverage/mincaverage.c,v 3.1 1995-11-20 14:24:47 neelin Exp $";
+static char rcsid[]="$Header: /private-cvsroot/minc/progs/mincaverage/mincaverage.c,v 3.2 1996-04-02 20:16:09 neelin Exp $";
 #endif
 
 #include <stdlib.h>
@@ -64,6 +67,10 @@
 
 #define THRESH_FRACTION (1/50.0)
 
+#define WIDTH_SUFFIX "-width"
+
+#define DEFAULT_BOOLEAN -1
+
 /* Double_Array structure */
 typedef struct {
    int numvalues;
@@ -76,6 +83,8 @@
    int need_sd;
    double binrange[2];
    double *norm_factor;
+   int averaging_over_dimension;
+   int num_weights;
    double *weights;
 } Average_Data;
 
@@ -115,7 +124,6 @@
 int verbose = TRUE;
 int debug = FALSE;
 int check_dimensions = TRUE;
-#define NO_DEFAULT_NORM
 #ifdef NO_DEFAULT_NORM
 int normalize = -1;
 #else
@@ -125,13 +133,14 @@
 nc_type datatype = NC_UNSPECIFIED;
 int is_signed = FALSE;
 double valid_range[2] = {0.0, 0.0};
-int copy_all_header = FALSE;
+int copy_all_header = DEFAULT_BOOLEAN;
 char *averaging_dimension = NULL;
 int max_buffer_size_in_kb = 4 * 1024;
 int binarize = FALSE;
 double binrange[2] = {DBL_MAX, -DBL_MAX};
 double binvalue = -DBL_MAX;
 Double_Array weights = {0, NULL};
+int width_weighted = FALSE;
 
 /* Argument table */
 ArgvInfo argTable[] = {
@@ -179,9 +188,9 @@
    {"-sdfile", ARGV_STRING, (char *) 1, (char *) &sdfile,
        "Specify an output sd file (default=none)."},
    {"-copy_header", ARGV_CONSTANT, (char *) TRUE, (char *) &copy_all_header,
-       "Copy all of the header from the first file."},
+       "Copy all of the header from the first file (default for one file)."},
    {"-nocopy_header", ARGV_CONSTANT, (char *) FALSE, (char *) &copy_all_header,
-       "Do not copy all of the header from the first file (default)."},
+       "Do not copy all of the header from the first file (default for many files))."},
    {"-avgdim", ARGV_STRING, (char *) 1, (char *) &averaging_dimension,
        "Specify a dimension along which we wish to average."},
    {"-binarize", ARGV_CONSTANT, (char *) TRUE, (char *) &binarize,
@@ -193,6 +202,8 @@
    {"-weights", ARGV_FUNC, (char *) get_double_list, 
        (char *) &weights,
        "Specify weights for averaging (\"<w1>,<w2>,...\")."},
+   {"-width_weighted", ARGV_CONSTANT, (char *) TRUE, (char *) &width_weighted,
+       "Weight by dimension widths when -avgdim is used."},
    {NULL, ARGV_END, NULL, NULL, NULL}
 };
 
@@ -207,8 +218,14 @@
    Average_Data average_data;
    Loop_Options *loop_options;
    double *vol_mean, vol_total, nvols, global_mean, total_weight;
-   int ifile;
+   int ifile, iweight;
    int weights_specified;
+   int first_mincid, dimid, varid, dim[MAX_VAR_DIMS];
+   int ndims;
+   long start, count;
+   int old_ncopts;
+   int strlength;
+   char dimname[MAX_NC_NAME];
 
    /* Save time stamp and args */
    arg_string = time_stamp(argc, argv);
@@ -227,38 +244,135 @@
    outfiles[0] = argv[argc-1];
    outfiles[1] = sdfile;
    nout = ((sdfile == NULL) ? 1 : 2);
+   first_mincid = MI_ERROR;
+
+   /* Set default value of copy_all_header */
+   if (copy_all_header == DEFAULT_BOOLEAN) {
+      copy_all_header = (nfiles <= 1);
+   }
+
+   /* Are we averaging over a dimension? */
+   average_data.averaging_over_dimension = (averaging_dimension != NULL);
+
+   /* Check for weights and width-weighting */
+   weights_specified = weights.numvalues > 0;
+   if (weights_specified && width_weighted) {
+      (void) fprintf(stderr, 
+         "%s: Please do not specify weights and width-weighting.\n",
+                     argv[0]);
+      exit(EXIT_FAILURE);
+   }
+
+   /* Default is no weighting */
+   average_data.num_weights = 0;
+   average_data.weights = NULL;
 
    /* Check for weights */
-   weights_specified = weights.numvalues > 0;
    if (weights_specified) {
-      if (averaging_dimension != NULL) {
+      if (averaging_dimension == NULL) {
+         if (weights.numvalues != nfiles) {
+            (void) fprintf(stderr, 
+               "%s: Number of weights does not match number of files.\n",
+                           argv[0]);
+            exit(EXIT_FAILURE);
+         }
+      }
+      else {
+         if (nfiles > 1) {
+            (void) fprintf(stderr,
+               "%s: Only one input file allowed with -weights and -avgdim.\n",
+                           argv[0]);
+            exit(EXIT_FAILURE);
+         }
+
+         /* Check that the dimension size matches the number of weights */
+         first_mincid = miopen(infiles[0], NC_NOWRITE);
+         dimid = ncdimid(first_mincid, averaging_dimension);
+         (void) ncdiminq(first_mincid, dimid, NULL, &count);
+         if (weights.numvalues != count) {
+            (void) fprintf(stderr,
+               "%s: Number of weights does not match size of dimension.\n",
+                           argv[0]);
+         }
+      }
+
+      /* Save the weights */
+      average_data.num_weights = weights.numvalues;
+      average_data.weights = 
+         MALLOC(sizeof(*average_data.weights) * average_data.num_weights);
+      for (iweight=0; iweight < average_data.num_weights; iweight++) {
+         average_data.weights[iweight] = weights.values[iweight];
+      }
+
+      FREE(weights.values);
+   }
+
+   /* Check for width weighting */
+   if (width_weighted) {
+
+      /* Check for errors */
+      if (averaging_dimension == NULL) {
          (void) fprintf(stderr, 
-            "%s: Sorry, you cannot use weights to average over a dimension.\n",
-                        argv[0]);
-         exit(EXIT_FAILURE);
-      }
-      if (weights.numvalues != nfiles) {
-         (void) fprintf(stderr, 
-            "%s: Number of weights does not match number of files.\n",
+                        "%s: Please specify -avgdim with -width_weighted.\n",
                         argv[0]);
          exit(EXIT_FAILURE);
       }
-   }
+      if (nfiles > 1) {
+         (void) fprintf(stderr,
+                        "%s: Use -width_weighted with only one input file.\n",
+                        argv[0]);
+         exit(EXIT_FAILURE);
+      }
+
+      /* Open the file */
+      first_mincid = miopen(infiles[0], NC_NOWRITE);
+
+      /* Get the dimension id */
+      dimid = ncdimid(first_mincid, averaging_dimension);
+
+      /* Look for the width variable */
+      strlength = MAX_NC_NAME - strlen(WIDTH_SUFFIX) - 1;
+      (void) strncpy(dimname, averaging_dimension, strlength);
+      dimname[strlength] = '\0';
+      (void) strcat(dimname, WIDTH_SUFFIX);
+      old_ncopts = ncopts; ncopts = 0;
+      varid = ncvarid(first_mincid, dimname);
+      (void) ncvarinq(first_mincid, varid, NULL, NULL, &ndims, dim, NULL);
+      ncopts = old_ncopts;
+      if (varid != MI_ERROR) {
 
-   /* Save weights */
-   average_data.weights = MALLOC(sizeof(*average_data.weights) * nfiles);
-   total_weight = 0.0;
-   for (ifile=0; ifile < nfiles; ifile++) {
-      average_data.weights[ifile] = 
-         (weights_specified ? weights.values[ifile] : 1.0);
-      total_weight += average_data.weights[ifile];
-   }
-   if (total_weight == 0.0) {
-      (void) fprintf(stderr, "%s: Weights sum to zero.\n", argv[0]);
-      exit(EXIT_FAILURE);
-   }
-   if (weights_specified) {
-      FREE(weights.values);
+         /* Check that things match up */
+         if ((ndims != 1) || (dim[0] != dimid)) {
+            (void) fprintf(stderr,
+                "%s: Dimension width variable does not match avgdim.\n",
+                           argv[0]);
+         }
+
+         /* Get the size of the dimension */
+         (void) ncdiminq(first_mincid, dim[0], NULL, &count);
+         average_data.num_weights = count;
+         average_data.weights = 
+            MALLOC(sizeof(*average_data.weights) * average_data.num_weights);
+
+         /* Read in the widths */
+         start = 0;
+         (void) mivarget(first_mincid, varid, &start, &count, NC_DOUBLE, NULL,
+                         average_data.weights);
+
+      }
+   }    /* If width_weighted */
+
+   /* Check that weights sum to non-zero. We don't need to normalize them,
+      since a running sum is done in the averaging. */
+   if (average_data.num_weights > 0) {
+      total_weight = 0.0;
+      for (iweight=0; iweight < average_data.num_weights; iweight++) {
+         total_weight += average_data.weights[iweight];
+      }
+      if (total_weight == 0.0) {
+         (void) fprintf(stderr, "%s: Weights sum to zero.\n", argv[0]);
+         exit(EXIT_FAILURE);
+      }
    }
 
    /* Check for binarization */
@@ -324,6 +438,10 @@
             (void) fprintf(stderr, ".");
             (void) fflush(stderr);
          }
+         if (first_mincid != MI_ERROR) {
+            set_loop_first_input_mincid(loop_options, first_mincid);
+            first_mincid = MI_ERROR;
+         }
          voxel_loop(1, &infiles[ifile], 0, NULL, NULL, loop_options,
                     do_normalization, (void *) &norm_data);
          if (norm_data.sum0 > 0.0) {
@@ -369,6 +487,10 @@
    /* Do averaging */
    average_data.need_sd = (sdfile != NULL);
    loop_options = create_loop_options();
+   if (first_mincid != MI_ERROR) {
+      set_loop_first_input_mincid(loop_options, first_mincid);
+      first_mincid = MI_ERROR;
+   }
    set_loop_verbose(loop_options, verbose);
    set_loop_clobber(loop_options, clobber);
    set_loop_datatype(loop_options, datatype, is_signed, 
@@ -542,7 +664,7 @@
    Average_Data *average_data;
    long ivox;
    double value;
-   int curfile;
+   int curfile, curindex;
    int num_out;
    double norm_factor, binmin, binmax, weight;
    int binarize;
@@ -560,8 +682,27 @@
 
    /* Get the normalization factor and binarization range */
    curfile = get_info_current_file(loop_info);
+   curindex = get_info_current_index(loop_info);
    norm_factor = average_data->norm_factor[curfile];
-   weight = average_data->weights[curfile];
+   if ((average_data->num_weights <= 0) || (average_data->weights == NULL)) {
+      weight = 1.0;
+   }
+   else {
+      if (average_data->averaging_over_dimension) {
+         if (curindex >= average_data->num_weights) {
+            (void) fprintf(stderr, "Internal error in index!\n");
+            exit(EXIT_FAILURE);
+         }
+         weight = average_data->weights[curindex];
+      }
+      else {
+         if (curfile >= average_data->num_weights) {
+            (void) fprintf(stderr, "Internal error in file number!\n");
+            exit(EXIT_FAILURE);
+         }
+         weight = average_data->weights[curfile];
+      }
+   }
    binarize = average_data->binarize;
    binmin = average_data->binrange[0];
    binmax = average_data->binrange[1];
--- a/progs/mincaverage/mincaverage.man1
+++ b/progs/mincaverage/mincaverage.man1
@@ -8,7 +8,7 @@
 .\" software for any purpose.  It is provided "as is" without
 .\" express or implied warranty.
 .\"
-.\" $Header: /private-cvsroot/minc/progs/mincaverage/mincaverage.man1,v 3.1 1995-11-20 14:24:47 neelin Exp $
+.\" $Header: /private-cvsroot/minc/progs/mincaverage/mincaverage.man1,v 3.2 1996-04-02 20:16:09 neelin Exp $
 .\"
 .TH MINCAVERAGE 1
 
@@ -104,10 +104,10 @@
 .P
 .I -copy_header:
 Copy all of the additional header information from the first input
-file.
+file (default for one input file).
 .P
 .I -nocopy_header:
-Do not copy additional header information (default).
+Do not copy additional header information (default for many input files).
 .P
 .I -avgdim
 <dimname>:
@@ -137,8 +137,16 @@
 Specify a series of weights for averaging. The number of weighting
 values must match the number of input files and the values must be
 provided as a single argument with commas or spaces as
-separators. The sum of the weights must be non-zero and weights cannot
-be used with an averaging dimension.
+separators. The sum of the weights must be non-zero. If weights are
+used with an averaging dimension, then only one input file can be
+specified.
+.P
+.I -width_weighted:
+This option can only be used when averaging across a dimension
+(-avgdim option). It specifies that weighting should be done using the
+width variable that corresponds to the averaging dimension. For
+example, using -width_weighted with -avgdim time will use the
+time-width variable to weight the values.
 
 .SH Generic options for all commands:
 .P