int main(int argc, char *argv[])
{
   char **input_files;
   char *output_file;
   char *arg_string;
   int num_input_files;
   int inmincid;
   Loop_Options *loop_options;
   Program_Data program_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 3)) {
      (void) fprintf(stderr, 
                     "\nUsage: %s [options] <in1.mnc> [...] <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,
                     "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   input_files = &argv[1];
   num_input_files = argc - 2;
   output_file = argv[argc-1];

   /* Open the first input file and get the vector length */
   inmincid = miopen(input_files[0], NC_NOWRITE);
   if (get_vector_length(inmincid) > 1) {
      (void) fprintf(stderr, "Input file %s is not a scalar file\n",
                     input_files[0]);
      exit(EXIT_FAILURE);
   }

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, v2format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_output_vector_size(loop_options, num_input_files);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);
   set_loop_accumulate(loop_options, TRUE, 0, NULL, NULL);

   /* Do loop */
   voxel_loop(num_input_files, input_files, 1, &output_file, 
              arg_string, loop_options,
              do_makevector, (void *) &program_data);

   exit(EXIT_SUCCESS);
}
Example #2
0
/* Main program */
int main(int argc, char *argv[]){
   char **infiles, **outfiles;
   int nfiles, nout;
   char *arg_string;
   Loop_Options *loop_options;
   char *pname;
   int i;
   ident_t ident;
   scalar_t scalar;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   pname = argv[0];
   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 2)) {
      (void) fprintf(stderr, 
      "\nUsage: %s [options] [<in1.mnc> ...] <out.mnc>\n",
                     pname);
      (void) fprintf(stderr, 
        "       %s -help\n\n", pname);
      exit(EXIT_FAILURE);
   }

   /* Get output file names */
   nout = (Output_list == NULL ? 1 : Output_list_size);
   outfiles = malloc(nout * sizeof(*outfiles));
   if (Output_list == NULL) {
      outfiles[0] = argv[argc-1];
   }
   else {
      for (i=0; i < Output_list_size; i++) {
         outfiles[i] = Output_list[i].file;
      }
   }

   /* check for output files */
   for (i=0; i < nout; i++){
      if(access(outfiles[i], F_OK) == 0 && !clobber){
         fprintf(stderr, "%s: %s exists, use -clobber to overwrite\n\n",
                 argv[0], outfiles[i]);
         exit(EXIT_FAILURE);
      }
   }

   /* Get the list of input files either from the command line or
      from a file, or report an error if both are specified.
      Note that if -outfile is given then there is no output file name
      left on argv after option parsing. */
   nfiles = argc - 2;
   if (Output_list != NULL) nfiles++;
   if (filelist == NULL) {
      infiles = &argv[1];
   }
   else if (nfiles <= 0) {
      infiles = read_file_names(filelist, &nfiles);
      if (infiles == NULL) {
         (void) fprintf(stderr, 
                        "Error reading in file names from file \"%s\"\n",
                        filelist);
         exit(EXIT_FAILURE);
      }
   }
   else {
      (void) fprintf(stderr, 
                     "Do not specify both -filelist and input file names\n");
      exit(EXIT_FAILURE);
   }

   /* Make sure that we have something to process */
   if (nfiles == 0) {
      (void) fprintf(stderr, "No input files specified\n");
      exit(EXIT_FAILURE);
   }

   /* Get the expression from the file if needed */
   if ((expression == NULL) && (expr_file == NULL)) { 
      (void) fprintf(stderr, 
                     "An expression must be specified on the command line\n");
      exit(EXIT_FAILURE);
   }
   else if (expression == NULL) {
      expression = read_expression_file(expr_file);
   }

   /* Parse expression argument */
   if (debug) fprintf(stderr, "Feeding in expression %s\n", expression);
   lex_init(expression);
   if (debug) yydebug = 1; else yydebug = 0; 
   yyparse();
   lex_finalize();
   
   /* Optimize the expression tree */
   root = optimize(root);
   
   /* Setup the input vector from the input files */
   A = new_vector();
   for (i=0; i<nfiles; i++) {
      if (debug) fprintf(stderr,"Getting file[%d] %s\n", i, argv[i+1]);
      scalar = new_scalar(eval_width);
      vector_append(A, scalar);
      scalar_free(scalar);
   }
      
   /* Construct initial symbol table from the A vector. Since setting
      a symbol makes a copy, we have to get a handle to that copy. */
   rootsym = sym_enter_scope(NULL);
   ident = new_ident("A");
   sym_set_vector(eval_width, NULL, A, ident, rootsym);
   vector_free(A);
   A = sym_lookup_vector(ident, rootsym);
   if (A==NULL) {
      (void) fprintf(stderr, "Error initializing symbol table\n");
      exit(EXIT_FAILURE);
   }
   vector_incr_ref(A);

   /* Add output symbols to the table */
   if (Output_list == NULL) {
      Output_values = NULL;
   }
   else {
      Output_values = malloc(Output_list_size * sizeof(*Output_values));
      for (i=0; i < Output_list_size; i++) {
         ident = ident_lookup(Output_list[i].symbol);
         scalar = new_scalar(eval_width);
         sym_set_scalar(eval_width, NULL, scalar, ident, rootsym);
         scalar_free(scalar);
         Output_values[i] = sym_lookup_scalar(ident, rootsym);
      }
   }

   /* Set default copy_all_header according to number of input files */
   if (copy_all_header == DEFAULT_BOOL)
      copy_all_header = (nfiles == 1);

   if (value_for_illegal_operations == DEFAULT_DBL) {
      if (use_nan_for_illegal_values)
         value_for_illegal_operations = INVALID_DATA;
      else
         value_for_illegal_operations = 0.0;
   }

   /* Do math */
   loop_options = create_loop_options();
   set_loop_verbose(loop_options, verbose);
   set_loop_clobber(loop_options, clobber);
#if MINC2
   set_loop_v2format(loop_options, minc2_format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_copy_all_header(loop_options, copy_all_header);
   
   /* only set buffer size if specified */
   if(max_buffer_size_in_kb != 0){
      set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);
      }
   
   set_loop_check_dim_info(loop_options, check_dim_info);
   voxel_loop(nfiles, infiles, nout, outfiles, arg_string, loop_options,
              do_math, NULL);
   free_loop_options(loop_options);

   
   /* Clean up */
   vector_free(A);
   sym_leave_scope(rootsym);
   if (expr_file != NULL) free(expression);
   free(outfiles);
   if (Output_list != NULL) free(Output_list);
   if (Output_values != NULL) free(Output_values);
   exit(EXIT_SUCCESS);
}
Example #3
0
int main(int argc, char *argv[])
{
   char *infile, *outfile;
   char *arg_string;
   int inmincid;
   int input_vector_length;
   int ivalue;
   Loop_Options *loop_options;
   Program_Data program_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) {
      (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   infile = argv[1];
   outfile = argv[2];

   /* Check for conflicting options */
   if ((conversion_type != CONV_DEFAULT) && 
       (linear_coefficients.numvalues > 0)) {
      (void) fprintf(stderr, 
                     "Do not specify -linear with other conversion options\n");
      exit(EXIT_FAILURE);
   }

   /* Set up conversion information */
   if (conversion_type == CONV_DEFAULT) conversion_type = CONV_MAGNITUDE;
   program_data.conversion_type = conversion_type;
   program_data.num_coefficients = 0;
   program_data.linear_coefficients = NULL;

   /* Check for coefficients for linear combination */
   if (linear_coefficients.numvalues > 0) {
      conversion_type = CONV_LINEAR;
      program_data.conversion_type = conversion_type;
      program_data.num_coefficients = linear_coefficients.numvalues;
      program_data.linear_coefficients = 
         malloc(linear_coefficients.numvalues * 
                sizeof(*program_data.linear_coefficients));
      for (ivalue=0; ivalue < linear_coefficients.numvalues; ivalue++) {
         program_data.linear_coefficients[ivalue] =
            linear_coefficients.values[ivalue];
      }
   }

   /* Open the input file and get the vector length */
   inmincid = miopen(infile, NC_NOWRITE);
   input_vector_length = get_vector_length(inmincid);
   if (input_vector_length < 0) {
       fprintf(stderr, str_wrong_dimension_order);
       exit(EXIT_FAILURE);
   }
   if (input_vector_length < 1) input_vector_length = 1;

   /* Check that this length is okay */
   if ((conversion_type == CONV_GREY) && 
       (input_vector_length != 3) && (input_vector_length > 1)) {
      (void) fprintf(stderr, "Input file does not contain RGB data\n");
      exit(EXIT_FAILURE);
   }
   if ((conversion_type == CONV_LINEAR) && 
       (input_vector_length != program_data.num_coefficients) && 
       (input_vector_length > 1)) {
      (void) fprintf(stderr, 
         "Input vector length does not match number of linear coefficients\n");
      exit(EXIT_FAILURE);
   }

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, v2format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_output_vector_size(loop_options, 1);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);

   /* Do loop */
   voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options,
              do_makescalar, (void *) &program_data);

   /* Free stuff */
   if (program_data.linear_coefficients != NULL) {
      free(program_data.linear_coefficients);
   }
   if (linear_coefficients.values != NULL) {
      free(linear_coefficients.values);
   }

   exit(EXIT_SUCCESS);
}
Example #4
0
int main(int argc, char *argv[])
{
   char *infile, *outfile;
   char *arg_string;
   Loop_Options *loop_options;
   int inmincid;
   Lookup_Data lookup_data;

   /* Save time stamp and args */
   arg_string = time_stamp(argc, argv);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) {
      (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n",
                     argv[0]);
      exit(EXIT_FAILURE);
   }
   infile = argv[1];
   outfile = argv[2];

   /* Get the appropriate lookup table */
   if ((lookup_file != NULL) || (lookup_string != NULL)) {
      lookup_data.lookup_table = read_lookup_table(lookup_file, lookup_string);
   }
   else {
      switch (lookup_type) {
      case LU_GRAY:
         lookup_data.lookup_table = &gray_lookup;
         break;
      case LU_HOTMETAL:
         lookup_data.lookup_table = &hotmetal_lookup;
         break;
      case LU_SPECTRAL:
         lookup_data.lookup_table = &spectral_lookup;
         break;
      case LU_TABLE:
         break;
      default:
         fprintf(stderr, "Unknown lookup type: %d\n", lookup_type);
         break;
      }
   }

   /* Get the null value */
   lookup_data.null_value = 
      get_null_value(lookup_data.lookup_table->vector_length, 
                     null_value_string);

   /* Open the input file and get the range */
   inmincid = miopen(infile, NC_NOWRITE);
   if (!discrete_lookup && (lookup_range[0] == DEFAULT_RANGE)) {
      get_full_range(inmincid, lookup_range);
   }
   if (lookup_min != DEFAULT_RANGE)
      lookup_range[0] = lookup_min;
   if (lookup_max != DEFAULT_RANGE)
      lookup_range[1] = lookup_max;

   /* Set up lookup information */
   lookup_data.invert = invert_table;
   lookup_data.range[0] = lookup_range[0];
   lookup_data.range[1] = lookup_range[1];
   lookup_data.discrete = discrete_lookup;

   /* Set up looping options */
   loop_options = create_loop_options();
   set_loop_clobber(loop_options, clobber);
   set_loop_verbose(loop_options, verbose);
#if MINC2
   set_loop_v2format(loop_options, minc2_format);
#endif /* MINC2 */
   set_loop_datatype(loop_options, datatype, is_signed, 
                     valid_range[0], valid_range[1]);
   set_loop_convert_input_to_scalar(loop_options, TRUE);
   set_loop_output_vector_size(loop_options, 
                               lookup_data.lookup_table->vector_length);
   set_loop_buffer_size(loop_options, (long) buffer_size * 1024);
   set_loop_first_input_mincid(loop_options, inmincid);

   /* Do loop */
   voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options,
              do_lookup, (void *) &lookup_data);

   /* Free stuff */
   if (lookup_data.null_value != NULL) free(lookup_data.null_value);
   if (lookup_data.lookup_table->free_data) {
      free(lookup_data.lookup_table->table);
      free(lookup_data.lookup_table);
   }

   exit(EXIT_SUCCESS);
}
Example #5
0
int main(int argc, char *argv[])
{
   char **infiles, *outfiles[3];
   int nfiles, nout;
   char *arg_string;
   Norm_Data norm_data;
   Average_Data average_data;
   Loop_Options *loop_options;
   double *vol_mean, vol_total, nvols, global_mean, total_weight;
   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);

   /* Get arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 2)) {
      (void) fprintf(stderr, 
      "\nUsage: %s [options] [<in1.mnc> ...] <out.mnc>\n",
                     argv[0]);
      (void) fprintf(stderr, 
        "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
   }
   outfiles[0] = outfiles[1] = outfiles[2] = NULL;
   outfiles[0] = argv[argc-1];
   nout = 1;
   if( sdfile != NULL )
	   outfiles[nout++] = sdfile;
   if( weightfile != NULL )
	   outfiles[nout++] = weightfile;

   first_mincid = MI_ERROR;

   /* Get the list of input files either from the command line or
      from a file, or report an error if both are specified */
   nfiles = argc - 2;
   if (filelist == NULL) {
      infiles = &argv[1];
   }
   else if (nfiles <= 0) {
      infiles = read_file_names(filelist, &nfiles);
      if (infiles == NULL) {
         (void) fprintf(stderr, 
                        "Error reading in file names from file \"%s\"\n",
                        filelist);
         exit(EXIT_FAILURE);
      }
   }
   else {
      (void) fprintf(stderr, 
                     "Do not specify both -filelist and input file names\n");
      exit(EXIT_FAILURE);
   }

   /* Make sure that we have something to process */
   if (nfiles == 0) {
      (void) fprintf(stderr, "No input files specified\n");
      exit(EXIT_FAILURE);
   }

   /* 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 */
   if (weights_specified) {
      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: 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) {

         /* 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);
      }
   }

   /* If we don't have weights, each input will get a weight of 1 */
   if (average_data.num_weights == 0)
       total_weight = nfiles;

   /* Check the cumulative weight thresholding */
   if (weight_thresh > 0.0 && weight_thresh_fraction > 0.0){
      (void) fprintf(stderr, 
                     "Do not specify both -min_weight -min_weight_fraction\n");
      exit(EXIT_FAILURE);
   }
   else if( weight_thresh_fraction > 0.0 ){
       weight_thresh = weight_thresh_fraction * total_weight;
   }
   average_data.weight_thresh = weight_thresh;
   

   /* Check for binarization */
   if (binarize) {
      if (normalize == TRUE) {
         (void) fprintf(stderr, 
            "%s: Normalization and binarization cannot both be specified\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }
      normalize = FALSE;
      if (binvalue != -DBL_MAX) {
         binrange[0] = binvalue - 0.5;
         binrange[1] = binvalue + 0.5;
      }
      if (binrange[0] > binrange[1]) {
         (void) fprintf(stderr, 
         "%s: Please specify a binarization range with min less than max\n",
                        argv[0]);
         exit(EXIT_FAILURE);
      }
      average_data.binrange[0] = binrange[0];
      average_data.binrange[1] = binrange[1];
   }
   average_data.binarize = binarize;

   /* Store the ignore above/below values */
   average_data.ignore_below = ignore_below;
   average_data.ignore_above = ignore_above;

   /* Check for no specification of normalization */
#ifdef NO_DEFAULT_NORM
   if (normalize == -1) {
      (void) fprintf(stderr, "\n%s: %s\n\n%s\n%s\n%s\n%s\n%s\n\n", argv[0],
"Please specify either -norm or -nonorm.",
"The default setting for normalization is being changed from \"-norm\" to",
"\"-nonorm\". To prevent undetected problems with data, this program will ",
"not work unless one of these flags is explicitly given on the command-line",
"(ie. no default is permitted). The new default will come into effect some",
"time in the future."
                     );
      exit(EXIT_FAILURE);
   }
#endif

   /* Do normalization if needed */
   average_data.norm_factor = 
      malloc(sizeof(*average_data.norm_factor) * nfiles);
   if (normalize) {
      vol_mean = malloc(sizeof(*vol_mean) * nfiles);
      loop_options = create_loop_options();
      set_loop_verbose(loop_options, FALSE);
#if MINC2
      set_loop_v2format(loop_options, minc2_format);
#endif /* MINC2 */
      set_loop_accumulate(loop_options, TRUE, 0, NULL, NULL);
      set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);
      set_loop_check_dim_info(loop_options, check_dimensions);
      vol_total = 0.0;
      nvols = 0;
      if (verbose) {
         (void) fprintf(stderr, "Normalizing:");
         (void) fflush(stderr);
      }
      for (ifile=0; ifile < nfiles; ifile++) {
         norm_data.threshold_set = FALSE;
         norm_data.sum0 = 0.0;
         norm_data.sum1 = 0.0;
         if (verbose) {
            (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) {
            vol_mean[ifile] = norm_data.sum1 / norm_data.sum0;
            vol_total += vol_mean[ifile];
            nvols++;
         }
         else {
            vol_mean[ifile] = 0.0;
         }
         if (debug) {
            (void) fprintf(stderr, "Volume %d mean = %.15g\n",
                           ifile, vol_mean[ifile]);
         }
      }
      free_loop_options(loop_options);
      if (verbose) {
         (void) fprintf(stderr, "Done\n");
         (void) fflush(stderr);
      }
      if (nvols > 0)
         global_mean = vol_total / nvols;
      else
         global_mean = 0.0;
      for (ifile=0; ifile < nfiles; ifile++) {
         if (vol_mean[ifile] > 0.0)
            average_data.norm_factor[ifile] = global_mean / vol_mean[ifile];
         else
            average_data.norm_factor[ifile] = 0.0;
         if (debug) {
            (void) fprintf(stderr, "Volume %d norm factor = %.15g\n", 
                           ifile, average_data.norm_factor[ifile]);
         }
      }
      free(vol_mean);
   }
   else {
      for (ifile=0; ifile < nfiles; ifile++) {
         average_data.norm_factor[ifile] = 1.0;
      }
   }

   /* Do averaging */
   average_data.need_sd = (sdfile != NULL);
   average_data.need_weight = (weightfile != 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, 
                     valid_range[0], valid_range[1]);
   set_loop_accumulate(loop_options, TRUE, 1, start_average, finish_average);
   set_loop_copy_all_header(loop_options, copy_all_header);
   set_loop_dimension(loop_options, averaging_dimension);
   set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);
   set_loop_check_dim_info(loop_options, check_dimensions);
   voxel_loop(nfiles, infiles, nout, outfiles, arg_string, loop_options,
              do_average, (void *) &average_data);
   free_loop_options(loop_options);

   /* Free stuff */
   free(average_data.weights);
   free(average_data.norm_factor);

   exit(EXIT_SUCCESS);
}