Esempio n. 1
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_vector_length
@INPUT      : mincid - minc file id
@OUTPUT     : (none)
@RETURNS    : Length of vector dimension or zero if no such dimension.
@DESCRIPTION: Routine to get the length of the vector dimension in a minc file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : November 30, 1994 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static long get_vector_length(int mincid)
{
   int imgid;
   int ndims;
   int dim[MAX_VAR_DIMS];
   char dimname[MAX_NC_NAME];
   long vector_length;
   int i;

   /* Get image variable id */
   imgid = ncvarid(mincid, MIimage);

   /* Get the image dimension info */
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dim, NULL);

   /* Check for vector dimension */
   (void) ncdiminq(mincid, dim[ndims-1], dimname, &vector_length);
   if ((strcmp(dimname, MIvector_dimension) != 0) || (ndims <= 2)) {
      vector_length = 0;

      /* New deal - check for an actual vector_dimension anywhere in the
       * file.
       */
      for (i = 0; i < ndims; i++) {
          ncdiminq(mincid, dim[i], dimname, NULL);
          if (!strcmp(dimname, MIvector_dimension)) {
              vector_length = -1;
              break;
          }
      }
   }

   return vector_length;
}
Esempio n. 2
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_full_range
@INPUT      : mincid - id of the input minc file
@OUTPUT     : range - 2-value array giving real range of input values
@RETURNS    : (nothing)
@DESCRIPTION: Routine to get the full real range of an input file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : December 8, 1994 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static void get_full_range(int mincid, double range[2])
{
   char *string;
   int varid;
   int ivar, idim, ndims;
   int dim[MAX_VAR_DIMS];
   double sign, *extreme, *values;
   long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS], num_values;
   long ivalue, length;

   /* Loop over image-min and image-max variables */
   range[0] = 0.0;
   range[1] = 1.0;
   for (ivar=0; ivar < 2; ivar++) {
      if (ivar==0) {
         string = MIimagemin;
         sign = -1.0;
         extreme = &range[0];
      }
      else {
         string = MIimagemax;
         sign = +1.0;
         extreme = &range[1];
      }
      ncopts = 0;
      varid = ncvarid(mincid, string);
      ncopts = NCOPTS_DEFAULT;
      if (varid != MI_ERROR) {
         (void) ncvarinq(mincid, varid, NULL, NULL, &ndims, dim, NULL);
         num_values = 1;
         for (idim=0; idim < ndims; idim++) {
            (void) ncdiminq(mincid, dim[idim], NULL, &length);
            start[idim] = 0;
            count[idim] = length;
            num_values *= length;
         }
         if (num_values > 0) {
            values = malloc(num_values * sizeof(*values));
            (void) mivarget(mincid, varid, start, count, 
                            NC_DOUBLE, NULL, values);
            *extreme = values[0];
            for (ivalue=0; ivalue < num_values; ivalue++) {
               if ((values[ivalue] * sign) > (*extreme * sign))
                  *extreme = values[ivalue];
            }
            free(values);
         }

      }          /* If variable is found */

   }          /* Loop over image-min/max */
   

   return;
}
Esempio n. 3
0
MNCAPI int
MI2varinq(int fd, int varid, char *varnm_ptr, nc_type *type_ptr,
          int *ndims_ptr, int *dims_ptr, int *natts_ptr)
{
    if (MI2_ISH5OBJ(fd)) {
        return (hdf_varinq(fd, varid, varnm_ptr, type_ptr, ndims_ptr, 
                           dims_ptr, natts_ptr));
    }
    else {
        return (ncvarinq(fd, varid, varnm_ptr, type_ptr, ndims_ptr, 
                         dims_ptr, natts_ptr));
    }
}
Esempio n. 4
0
/*
 * Return information about a netCDF variable, given its ID.
 */
static void
c_ncvinq (
    int ncid,		/* netCDF ID */
    int varid,		/* variable ID */
    char* varname,	/* returned variable name */
    nc_type* datatype,	/* returned variable type */
    int* indims,	/* returned number of dimensions */
    int* dimarray,	/* returned array of ndims dimension IDs */
    int* inatts,	/* returned number of attributes */
    int* rcode		/* returned error code */
)
{
    *rcode = ncvarinq(ncid, varid, varname, datatype, indims,
		      dimarray, inatts) == -1
		? ncerr
		: 0;
}
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_vector_length
@INPUT      : mincid - minc file id
@OUTPUT     : (none)
@RETURNS    : Length of vector dimension or zero if no such dimension.
@DESCRIPTION: Routine to get the length of the vector dimension in a minc file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : November 30, 1994 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static long get_vector_length(int mincid)
{
   int imgid;
   int ndims;
   int dim[MAX_VAR_DIMS];
   char dimname[MAX_NC_NAME];
   long vector_length;

   /* Get image variable id */
   imgid = ncvarid(mincid, MIimage);

   /* Get the image dimension info */
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dim, NULL);

   /* Check for vector dimension */
   (void) ncdiminq(mincid, dim[ndims-1], dimname, &vector_length);
   if ((strcmp(dimname, MIvector_dimension) != 0) || (ndims <= 2)) {
      vector_length = 0;
   }

   return vector_length;
}
Esempio n. 6
0
int
cpy_att(int in_id,int out_id,int var_in_id,int var_out_id)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int var_in_id: input netCDF input-variable ID
   int var_out_id: input netCDF output-variable ID
 */
{
  /* Routine to copy all the attributes from the input netCDF
     file to the output netCDF file. If var_in_id == NC_GLOBAL,
     then the global attributes are copied. Otherwise the variable's
     attributes are copied. */

  int idx;
  int nbr_att;

  if(var_in_id == NC_GLOBAL){
    ncinquire(in_id,(int *)NULL,(int *)NULL,&nbr_att,(int *)NULL);

  }else{
    ncvarinq(in_id,var_in_id,(char *)NULL,(nc_type *)NULL,
                   (int *)NULL,(int*)NULL,&nbr_att);
  } /* end else */

  /* Get the attributes names, types, lengths, and values */
  for(idx=0;idx<nbr_att;idx++){
    char att_nm[MAX_STR_LENGTH];

    ncattname(in_id,var_in_id,idx,att_nm);

    ncattcopy(in_id,var_in_id,att_nm,out_id,var_out_id);
  } /* end loop over attributes */

  return(EX_NOERR);

} /* end cpy_att() */
Esempio n. 7
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : DumpInfo
@INPUT      : CDF - a NetCDF file handle
@OUTPUT     : Info to stdout.
@RETURNS    : (void)
@DESCRIPTION: Prints to stdout a bunch of handy information about a NetCDF 
              file.  Includes number of dimensions, variables, and global
	      attributes; dimension lengths; variable types and dimensions.
@METHOD     : 
@GLOBALS    : 
@CALLS      : NetCDF library
@CREATED    : November 1993, Greg Ward.
@MODIFIED   : 
---------------------------------------------------------------------------- */
void DumpInfo (int CDF)
{
   int     NumDims;
   int     NumVars;
   int     NumAtts;
   int     i, j;
   char    Name [MAX_NC_NAME];
   long    Len;
   nc_type Type;
   int	   DimList [MAX_NC_DIMS];

   if (CDF < 0) return;

   ncinquire (CDF, &NumDims, &NumVars, &NumAtts, NULL);
   printf ("%d dimensions, %d variables, %d global attributes\n",
           NumDims, NumVars, NumAtts);

   for (i = 0; i < NumDims; i++)
   {
      ncdiminq (CDF, i, Name, &Len);
      printf ("Dim %d: %s (length %ld)\n", i, Name, Len);
   }

   for (i = 0; i < NumVars; i++)
   {
      ncvarinq (CDF, i, Name, &Type, &NumDims, DimList, &NumAtts);
      printf ("Var %d: %s (%s) (%d dimensions:", 
	      i, Name, type_names[Type], NumDims);
      for (j = 0; j < NumDims; j++)
      {
	 ncdiminq (CDF, DimList[j], Name, NULL);
	 printf (" %s", Name);
      }
      printf (")\n");
   }	
}
Esempio n. 8
0
MNCAPI int
minc_file_size(char *path,
               long *ct, long *cz, long *cy, long *cx,
               long *cvoxels, long *cbytes)
{
    int fd;
    nc_type nctype;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i;
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    long voxel_count;
    long byte_count;
    int old_ncopts;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }
    
    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    if (ct != NULL) {
        *ct = dim_len[MI_S_T];
    }
    if (cz != NULL) {
        *cz = dim_len[MI_S_Z];
    }
    if (cy != NULL) {
        *cy = dim_len[MI_S_Y];
    }
    if (cx != NULL) {
        *cx = dim_len[MI_S_X];
    }

    var_id = ncvarid(fd, MIimage);

    if (cvoxels != NULL || cbytes != NULL) {
        ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

        voxel_count = 1;

        for (i = 0; i < var_ndims; i++) {
            long length;
            ncdiminq(fd, var_dims[i], NULL, &length);
            voxel_count *= length;
        }

        byte_count = voxel_count * nctypelen(nctype);

        if (cvoxels != NULL) {
            *cvoxels = voxel_count;
        }
        if (cbytes != NULL) {
            *cbytes = byte_count;
        }
    }
    return (MINC_STATUS_OK);
}
Esempio n. 9
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);
}
Esempio n. 10
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : find_mincfile_range
@INPUT      : mincid - id of minc file
@OUTPUT     : minimum - minimum for file
              maximum - maximum for file
@RETURNS    : (nothing)
@DESCRIPTION: Routine to find the min and max in a minc file
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : April 25, 1995 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static void find_mincfile_range(int mincid, double *minimum, double *maximum)
{
   int varid;
   char *varname;
   double sign, value;
   double *extreme;
   long index[MAX_VAR_DIMS], count[MAX_VAR_DIMS];
   int ndims, dim[MAX_VAR_DIMS];
   int idim, imm;
   int old_ncopts;

   *minimum = 0.0;
   *maximum = 1.0;
   for (imm=0; imm < 2; imm++) {

      /* Set up for max or min */
      if (imm == 0) {
         varname = MIimagemin;
         sign = -1.0;
         extreme = minimum;
      }
      else {
         varname = MIimagemax;
         sign = 1.0;
         extreme = maximum;
      }

      /* Get the variable id */
      old_ncopts = ncopts; ncopts = 0;
      varid = ncvarid(mincid, varname);
      ncopts = old_ncopts;
      if (varid == MI_ERROR) continue;

      /* Get the dimension info */
      (void) ncvarinq(mincid, varid, NULL, NULL, &ndims, dim, NULL);
      for (idim=0; idim < ndims; idim++) {
         (void) ncdiminq(mincid, dim[idim], NULL, &count[idim]);
      }
      if (ndims <= 0) {
         ndims = 1;
         count[0] = 1;
      }

      /* Loop through values, getting extrema */
      (void) miset_coords(ndims, (long) 0, index);
      *extreme = sign * (-DBL_MAX);
      while (index[0] < count[0]) {
         (void) mivarget1(mincid, varid, index, NC_DOUBLE, NULL, &value);
         if ((value * sign) > (*extreme * sign)) {
            *extreme = value;
         }
         idim = ndims-1;
         index[idim]++;
         while ((index[idim] > count[idim]) && (idim > 0)) {
            idim--;
            index[idim]++;
         }
      }
   }

}
Esempio n. 11
0
void
mexFunction	(
	INT			nlhs,
	Matrix	*	plhs[],
	INT			nrhs,
	const Matrix	*	prhs[]
	)

{
	char		*	opname;
	OPCODE			opcode;
	
	Matrix		*	mat;
	
	int				status;
	char		*	path;
	int				cmode;
	int				mode;
	int				cdfid;
	int				ndims;
	int				nvars;
	int				natts;
	int				recdim;
	char		*	name;
	long			length;
	int				dimid;
	nc_type			datatype;
	int			*	dim;
	int				varid;
	long		*	coords;
	VOIDP			value;
	long		*	start;
	long		*	count;
	int			*	intcount;
	long		*	stride;
	long		*	imap;
	long			recnum;
	int				nrecvars;
	int			*	recvarids;
	long		*	recsizes;
	VOIDPP			datap;		/*	pointers for record access.	*/
	int				len;
	int				incdf;
	int				invar;
	int				outcdf;
	int				outvar;
	int				attnum;
	char		*	attname;
	char		*	newname;
	int				fillmode;
	
	int				i;
	int				m;
	int				n;
	char		*	p;
	char			buffer[MAX_BUFFER];
	
	DOUBLE		*	pr;
	DOUBLE			addoffset;
	DOUBLE			scalefactor;
	int				autoscale;		/*	do auto-scaling if this flag is non-zero.	*/
	
	/*	Disable the NC_FATAL option from ncopts.	*/
	
	if (ncopts & NC_FATAL)	{
		ncopts -= NC_FATAL;
	}
	
	/*	Display usage if less than one input argument.	*/
	
	if (nrhs < 1)	{
	
		Usage();
		
		return;
	}
	
	/*	Convert the operation name to its opcode.	*/
	
	opname = Mat2Str(prhs[0]);
	for (i = 0; i < strlen(opname); i++)	{
		opname[i] = (char) tolower((int) opname[i]);
	}
	p = opname;
	if (strncmp(p, "nc", 2) == 0)	{	/*	Trim away "nc".	*/
		p += 2;
	}
	
	i = 0;
	opcode = NONE;
	while (ops[i].opcode != NONE)	{
		if (!strcmp(p, ops[i].opname))	{
			opcode = ops[i].opcode;
			if (ops[i].nrhs > nrhs)	{
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few input arguments.\n");
			}
			else if (0 && ops[i].nlhs > nlhs)	{	/*	Disabled.	*/
				mexPrintf("MEXCDF: opname = %s\n", opname);
				mexErrMsgTxt("MEXCDF: Too few output arguments.\n");
			}
			break;
		}
		else	{
			i++;
		}
	}
	
	if (opcode == NONE)	{
		mexPrintf("MEXCDF: opname = %s\n", opname);
		mexErrMsgTxt("MEXCDF: No such operation.\n");
	}
	
	Free((VOIDPP) & opname);
	
	/*	Extract the cdfid by number.	*/
	
	switch (opcode)	{
	
	case USAGE:
	case CREATE:
	case OPEN:
	case TYPELEN:
	case SETOPTS:
	case ERR:
	case PARAMETER:
	
		break;
	
	default:

		cdfid = Scalar2Int(prhs[1]);
	
		break;
	}
	
	/*	Extract the dimid by number or name.	*/
	
	switch (opcode)	{

	case DIMINQ:
	case DIMRENAME:
	
		if (mxIsNumeric(prhs[2]))	{
			dimid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			dimid = ncdimid(cdfid, name);
			Free((VOIDPP) & name);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the varid by number or name.	*/
	
	switch (opcode)	{

	case VARINQ:
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:
	case VARRENAME:
	case VARCOPY:
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTNAME:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[2]))	{
			varid = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[2]);
			varid = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
			if (varid == -1)	{
				varid = Parameter(prhs[2]);
			}
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the attname by name or number.	*/
	
	switch (opcode)	{
	
	case ATTPUT:
	case ATTINQ:
	case ATTGET:
	case ATTCOPY:
	case ATTRENAME:
	case ATTDEL:
	
		if (mxIsNumeric(prhs[3]))	{
			attnum = Scalar2Int(prhs[3]);
			attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
			status = ncattname(cdfid, varid, attnum, attname);
		}
		else	{
			attname = Mat2Str(prhs[3]);
		}
		break;
	
	default:
	
		break;
	}
	
	/*	Extract the "add_offset" and "scale_factor" attributes.	*/
	
	switch (opcode)	{
	
	case VARPUT1:
	case VARGET1:
	case VARPUT:
	case VARGET:
	case VARPUTG:
	case VARGETG:

		addoffset = Add_Offset(cdfid, varid);
		scalefactor = Scale_Factor(cdfid, varid);
		if (scalefactor == 0.0)	{
			scalefactor = 1.0;
		}
		
		break;
	
	default:
	
		break;
	}
	
	/*	Perform the NetCDF operation.	*/
	
	switch (opcode)	{
		
	case USAGE:
	
		Usage();
		
		break;
	
	case CREATE:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			cmode = Parameter(prhs[2]);
		}
		else	{
			cmode = NC_NOCLOBBER;	/*	Default.	*/
		}
		
		cdfid = nccreate(path, cmode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case OPEN:
		
		path = Mat2Str(prhs[1]);
		
		if (nrhs > 2)	{
			mode = Parameter(prhs[2]);
		}
		else	{
			mode = NC_NOWRITE;	/*	Default.	*/
		}
		
		cdfid = ncopen(path, mode);
		
		plhs[0] = Int2Scalar(cdfid);
		plhs[1] = Int2Scalar((cdfid >= 0) ? 0 : -1);
		
		Free((VOIDPP) & path);
		
		break;
		
	case REDEF:
		
		status = ncredef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ENDEF:
		
		status = ncendef(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case CLOSE:
		
		status = ncclose(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case INQUIRE:
	
		status = ncinquire(cdfid, & ndims, & nvars, & natts, & recdim);
		
		if (nlhs > 1)	{
			plhs[0] = Int2Scalar(ndims);
			plhs[1] = Int2Scalar(nvars);
			plhs[2] = Int2Scalar(natts);
			plhs[3] = Int2Scalar(recdim);
			plhs[4] = Int2Scalar(status);
		}
		else	{	/*	Default to 1 x 5 row vector.	*/
			plhs[0] = mxCreateFull(1, 5, REAL);
			pr = mxGetPr(plhs[0]);
			if (status == 0)	{
				pr[0] = (DOUBLE) ndims;
				pr[1] = (DOUBLE) nvars;
				pr[2] = (DOUBLE) natts;
				pr[3] = (DOUBLE) recdim;
			}
			pr[4] = (DOUBLE) status;
		}
		
		break;
		
	case SYNC:
	
		status = ncsync(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case ABORT:
	
		status = ncabort(cdfid);
		
		plhs[0] = Int2Scalar(status);
		
		break;
		
	case DIMDEF:
	
		name = Mat2Str(prhs[2]);
		length = Parameter(prhs[3]);
		
		dimid = ncdimdef(cdfid, name, length);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMID:
	
		name = Mat2Str(prhs[2]);
		
		dimid = ncdimid(cdfid, name);
		
		plhs[0] = Int2Scalar(dimid);
		plhs[1] = Int2Scalar((dimid >= 0) ? 0 : dimid);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMINQ:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncdiminq(cdfid, dimid, name, & length);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Long2Scalar(length);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case DIMRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncdimrename(cdfid, dimid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARDEF:
	
		name = Mat2Str(prhs[2]);
		datatype = (nc_type) Parameter(prhs[3]);
		ndims = Scalar2Int(prhs[4]);
		if (ndims == -1)	{
			ndims = Count(prhs[5]);
		}
		dim = Mat2Int(prhs[5]);
		
		varid = ncvardef(cdfid, name, datatype, ndims, dim);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARID:
	
		name = Mat2Str(prhs[2]);
		
		varid = ncvarid(cdfid, name);
		
		Free((VOIDPP) & name);
		
		plhs[0] = Int2Scalar(varid);
		plhs[1] = Int2Scalar((varid >= 0) ? 0 : varid);
		
		break;
		
	case VARINQ:
	
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Str2Mat(name);
		plhs[1] = Int2Scalar(datatype);
		plhs[2] = Int2Scalar(ndims);
		plhs[3] = Int2Mat(dim, 1, ndims);
		plhs[4] = Int2Scalar(natts);
		plhs[5] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		break;
		
	case VARPUT1:
		
		coords = Mat2Long(prhs[3]);
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[4]);
		}
		else	{
			mat = prhs[4];
		}
		if (mat == NULL)	{
			mat = prhs[4];
		}
		
		pr = mxGetPr(mat);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		status = ncvarput1(cdfid, varid, coords, buffer);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARGET1:
		
		coords = Mat2Long(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		mat = Int2Scalar(0);
		
		pr = mxGetPr(mat);
		
		status = ncvarget1(cdfid, varid, coords, buffer);
		status = Convert(opcode, datatype, 1, buffer, scalefactor, addoffset, pr);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & coords);
		
		break;
		
	case VARPUT:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		
		autoscale = (nrhs > 6 && Scalar2Int(prhs[6]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[5]);
		}
		else	{
			mat = prhs[5];
		}
		if (mat == NULL)	{
			mat = prhs[5];
		}
		
		pr = mxGetPr(mat);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarput(cdfid, varid, start, count, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & start);
		Free((VOIDPP) & count);
		
		break;
		
	case VARGET:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		
		autoscale = (nrhs > 5 && Scalar2Int(prhs[5]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvarget(cdfid, varid, start, count, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
			plhs[0] = mat;
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARPUTG:
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		if (nrhs > 7)	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[7]);
			}
			else	{
				mat = prhs[7];
			}
			if (mat == NULL)	{
				mat = prhs[7];
			}
		}
		else	{
			if (datatype == NC_CHAR)	{
				mat = SetStr(prhs[6]);
			}
			else	{
				mat = prhs[6];
			}
			if (mat == NULL)	{
				mat = prhs[6];
			}
		}
		pr = mxGetPr(mat);
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		len = 0;
		if (ndims > 0)	{
			len = 1;
			for (i = 0; i < ndims; i++)	{
				len *= count[i];
			}
		}
		
		autoscale = (nrhs > 8 && Scalar2Int(prhs[8]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		status = ncvarputg(cdfid, varid, start, count, stride, imap, value);
		Free((VOIDPP) & value);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;
		
	case VARGETG:
		
		start = Mat2Long(prhs[3]);
		count = Mat2Long(prhs[4]);
        intcount = Mat2Int(prhs[4]);
		stride = Mat2Long(prhs[5]);
		imap = NULL;
		
		autoscale = (nrhs > 7 && Scalar2Int(prhs[7]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		name = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		dim = (int *) mxCalloc(MAX_NC_DIMS, sizeof(int));
		
		status = ncvarinq(cdfid, varid, name, & datatype, & ndims, dim, & natts);
		
		datatype = RepairBadDataType(datatype);
		
		for (i = 0; i < ndims; i++)	{
			if (count[i] == -1)	{
				status = ncdiminq(cdfid, dim[i], name, & count[i]);
				count[i] -= start[i];
			}
		}
		
		Free((VOIDPP) & name);
		Free((VOIDPP) & dim);
		
		m = 0;
		n = 0;
		if (ndims > 0)	{
			m = count[0];
			n = count[0];
			for (i = 1; i < ndims; i++)	{
				n *= count[i];
				if (count[i] > 1)	{
					m = count[i];
				}
			}
			n /= m;
		}
		len = m * n;
		if (ndims < 2)	{
			m = 1;
			n = len;
		}
		
		for (i = 0; i < ndims; i++)	{
			intcount[i] = count[ndims-i-1];   /*	Reverse order.	*/
		}
		
		if (MEXCDF_4 || ndims < 2)	{
			mat = mxCreateFull(m, n, mxREAL);	/*	mxCreateDoubleMatrix	*/
		}
# if MEXCDF_5
		else	{
			mat = mxCreateNumericArray(ndims, intcount, mxDOUBLE_CLASS, mxREAL);
		}
# endif
		
		pr = mxGetPr(mat);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncvargetg(cdfid, varid, start, count, stride, imap, value);
		status = Convert(opcode, datatype, len, value, scalefactor, addoffset, pr);
		Free((VOIDPP) & value);
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[0] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & stride);
		Free((VOIDPP) & intcount);
		Free((VOIDPP) & count);
		Free((VOIDPP) & start);
		
		break;

	case VARRENAME:
		
		name = Mat2Str(prhs[3]);
		
		status = ncvarrename(cdfid, varid, name);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & name);
		
		break;
		
	case VARCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[3]);
	
		outvar = -1;
/*		outvar = ncvarcopy(incdf, invar, outcdf);	*/
		
		plhs[0] = Int2Scalar(outvar);
		plhs[1] = Int2Scalar((outvar >= 0) ? 0 : outvar);
		
		break;
		
	case ATTPUT:
		
		datatype = (nc_type) Parameter(prhs[4]);
		
		datatype = RepairBadDataType(datatype);
		
		if (datatype == NC_CHAR)	{
			mat = SetNum(prhs[6]);
		}
		else	{
			mat = prhs[6];
		}
		if (mat == NULL)	{
			mat = prhs[6];
		}
		
		len = Scalar2Int(prhs[5]);
		if (len == -1)	{
			len = Count(mat);
		}
		
		pr = mxGetPr(mat);
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		status = ncattput(cdfid, varid, attname, datatype, len, value);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTINQ:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		plhs[0] = Int2Scalar((int) datatype);
		plhs[1] = Int2Scalar(len);
		plhs[2] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTGET:
		
		status = ncattinq(cdfid, varid, attname, & datatype, & len);
		
		datatype = RepairBadDataType(datatype);
		
		value = (VOIDP) mxCalloc(len, nctypelen(datatype));
		status = ncattget(cdfid, varid, attname, value);
		
		mat = mxCreateDoubleMatrix(1, len, mxREAL);
		
		pr = mxGetPr(mat);
		
		status = Convert(opcode, datatype, len, value, (DOUBLE) 1.0, (DOUBLE) 0.0, pr);
		
		if (value != NULL)	{
			Free((VOIDPP) & value);
		}
		
		if (datatype == NC_CHAR)	{
			plhs[0] = SetStr(mat);
		}
		else	{
			plhs[0] = mat;
		}
		if (plhs[0] == NULL)	{
/*			prhs[4] = mat;		*/
			plhs[0] = mat;		/*	ZYDECO 24Jan2000	*/
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTCOPY:
	
		incdf = cdfid;
		
		invar = varid;
		
		outcdf = Scalar2Int(prhs[4]);
	
		if (mxIsNumeric(prhs[5]))	{
			outvar = Scalar2Int(prhs[2]);
		}
		else	{
			name = Mat2Str(prhs[5]);
			outvar = ncvarid(cdfid, name);
			Free((VOIDPP) & name);
		}
	
		status = ncattcopy(incdf, invar, attname, outcdf, outvar);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTNAME:
		
		attnum = Scalar2Int(prhs[3]);
		attname = (char *) mxCalloc(MAX_NC_NAME, sizeof(char));
		
		status = ncattname(cdfid, varid, attnum, attname);
		
		plhs[0] = Str2Mat(attname);
		plhs[1] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case ATTRENAME:
	
		newname = Mat2Str(prhs[4]);
		
		status = ncattrename(cdfid, varid, attname, newname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		Free((VOIDPP) & newname);
		
		break;
		
	case ATTDEL:
		
		status = ncattdel(cdfid, varid, attname);
		
		plhs[0] = Int2Scalar(status);
		
		Free((VOIDPP) & attname);
		
		break;
		
	case RECPUT:
		
		recnum = Scalar2Long(prhs[2]);
		pr = mxGetPr(prhs[3]);
		
		autoscale = (nrhs > 4 && Scalar2Int(prhs[4]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if (Count(prhs[3]) < n)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[0] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		p = (char *) value;
		pr = mxGetPr(prhs[3]);
		
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
		
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		status = ncrecput(cdfid, recnum, datap);
		
		plhs[0] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case RECGET:
		
		recnum = Scalar2Long(prhs[2]);
		
		autoscale = (nrhs > 3 && Scalar2Int(prhs[3]) != 0);
		
		if (!autoscale)	{
			scalefactor = 1.0;
			addoffset = 0.0;
		}
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		datap = (VOIDPP) mxCalloc(MAX_VAR_DIMS, sizeof(VOIDP));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status == -1)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (nrecvars == 0)	{
			Free ((VOIDPP) & recsizes);
			Free ((VOIDPP) & recvarids);
			plhs[0] = mxCreateFull(0, 0, REAL);
			break;
		}
		
		length = 0;
		n = 0;
		for (i = 0; i < nrecvars; i++)	{
			ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			length += recsizes[i];
			n += (recsizes[i] / nctypelen(datatype));
		}
		
		if ((value = (VOIDP) mxCalloc((int) length, sizeof(char))) == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		if (value == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		length = 0;
		p = value;
		for (i = 0; i < nrecvars; i++)	{
			datap[i] = p;
			p += recsizes[i];
		}
		
		if ((status = ncrecget(cdfid, recnum, datap)) == -1)	{
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		m = 1;
		
		plhs[0] = mxCreateFull(m, n, REAL);
		
		if (plhs[0] == NULL)	{
			status = -1;
			plhs[1] = Int2Scalar(status);
			break;
		}
		
		pr = mxGetPr(plhs[0]);
		p = (char *) value;
		
		for (i = 0; i < nrecvars; i++)	{
			status = ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
			datatype = RepairBadDataType(datatype);
			
			if (status == -1)	{
				plhs[1] = Int2Scalar(status);
				break;
			}
			length = recsizes[i] / nctypelen(datatype);
			if (autoscale)	{
				addoffset = Add_Offset(cdfid, recvarids[i]);
				scalefactor = Scale_Factor(cdfid, recvarids[i]);
				if (scalefactor == 0.0)	{
					scalefactor = 1.0;
				}
			}
			Convert(opcode, datatype, length, (VOIDP) p,  scalefactor, addoffset, pr);
			pr += length;
			p += recsizes[i];
		}
		
		plhs[1] = Int2Scalar(status);
		
		Free ((VOIDPP) & value);
		Free ((VOIDPP) & datap);
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;

	case RECINQ:
		
		recvarids = (int *) mxCalloc(MAX_VAR_DIMS, sizeof(int));
		recsizes = (long *) mxCalloc(MAX_VAR_DIMS, sizeof(long));
		
		status = ncrecinq(cdfid, & nrecvars, recvarids, recsizes);
		
		if (status != -1)	{
			for (i = 0; i < nrecvars; i++)	{
				ncvarinq(cdfid, recvarids[i], NULL, & datatype, NULL, NULL, NULL);
		
				datatype = RepairBadDataType(datatype);
			
				recsizes[i] /= nctypelen(datatype);
			}
			m = 1;
			n = nrecvars;
			plhs[0] = Int2Mat(recvarids, m, n);
			plhs[1] = Long2Mat(recsizes, m, n);
		}
		
		plhs[2] = Int2Scalar(status);
		
		Free ((VOIDPP) & recsizes);
		Free ((VOIDPP) & recvarids);
		
		break;
		
	case TYPELEN:
	
		datatype = (nc_type) Parameter(prhs[1]);
		
		len = nctypelen(datatype);
		
		plhs[0] = Int2Scalar(len);
		plhs[1] = Int2Scalar((len >= 0) ? 0 : 1);
		
		break;
		
	case SETFILL:
	
		fillmode = Scalar2Int(prhs[1]);
		
		status = ncsetfill(cdfid, fillmode);
		
		plhs[0] = Int2Scalar(status);
		plhs[1] = Int2Scalar(0);
		
		break;

	case SETOPTS:
		
		plhs[0] = Int2Scalar(ncopts);
		plhs[1] = Int2Scalar(0);
		ncopts = Scalar2Int(prhs[1]);
		
		break;
		
	case ERR:
	
		plhs[0] = Int2Scalar(ncerr);
		ncerr = 0;
		plhs[1] = Int2Scalar(0);
		
		break;
		
	case PARAMETER:
	
		if (nrhs > 1)	{
			plhs[0] = Int2Scalar(Parameter(prhs[1]));
			plhs[1] = Int2Scalar(0);
		}
		else	{
			i = 0;
			while (strcmp(parms[i].name, "NONE") != 0)	{
				mexPrintf("%12d %s\n", parms[i].code, parms[i].name);
				i++;
			}
			plhs[0] = Int2Scalar(0);
			plhs[1] = Int2Scalar(-1);
		}
		
		break;
		
	default:
	
		break;
	}
	
	return;
}
Esempio n. 12
0
int ex_copy (int in_exoid, int out_exoid)
{
   int ndims;                   /* number of dimensions */
   int nvars;                   /* number of variables */
   int ngatts;                  /* number of global attributes */
   int recdimid;                /* id of unlimited dimension */
   int dimid;                   /* dimension id */
   int dim_out_id;              /* dimension id */
   int varid;                   /* variable id */
   int var_out_id;              /* variable id */
   struct ncvar var;            /* variable */
   struct ncatt att;            /* attribute */
   int i, temp;
   long numrec;
   long dim_sz;
   char dim_nm[MAX_NC_NAME];
   int in_large, out_large;
   
   extern int ncopts;

   exerrval = 0; /* clear error code */

   /*
    * Get exodus_large_model setting on both input and output
    * databases so know how to handle coordinates.
    */
   in_large  = ex_large_model(in_exoid);
   out_large = ex_large_model(out_exoid);
   
   /*
    * get number of dimensions, number of variables, number of global
    * atts, and dimension id of unlimited dimension, if any
    */

   ncinquire(in_exoid, &ndims, &nvars, &ngatts, &recdimid);
   ncdiminq (in_exoid, recdimid, (char *) 0, &numrec);

   /* put output file into define mode */

   ncredef(out_exoid);

   /* copy global attributes */

   for (i = 0; i < ngatts; i++) {

      ncattname(in_exoid, NC_GLOBAL, i, att.name);
        
      ncattinq(in_exoid, NC_GLOBAL, att.name, &att.type, &att.len);

      /* if attribute exists in output file, don't overwrite it; compute 
       * word size, I/O word size etc. are global attributes stored when
       * file is created with ex_create;  we don't want to overwrite those
       */

      if (ncattinq (out_exoid, NC_GLOBAL, att.name, &att.type, &att.len) == -1){

        /* The "last_written_time" attribute is a special attribute
           used by the Sierra IO system to determine whether a
           timestep has been fully written to the database in order to
           try to detect a database crash that happens in the middle
           of a database output step. Don't want to copy that attribute.
        */
        if (strcmp(att.name,"last_written_time") != 0) {
          /* attribute doesn't exist in new file so OK to create it */
          ncattcopy (in_exoid,NC_GLOBAL,att.name,out_exoid,NC_GLOBAL);
        }
      }
   }

   /* copy dimensions */

   /* Get the dimension sizes and names */

   for(dimid = 0; dimid < ndims; dimid++){

      ncdiminq(in_exoid,dimid,dim_nm,&dim_sz);

      /* See if the dimension has already been defined */

      temp = ncopts;
      ncopts = 0;
      dim_out_id = ncdimid(out_exoid,dim_nm);
      ncopts = temp;

      /* If the dimension isn't one we specifically don't want 
       * to copy (ie, number of QA or INFO records) and it 
       * hasn't been defined, copy it */

      if ( ( strcmp(dim_nm,DIM_NUM_QA)        != 0) &&
           ( strcmp(dim_nm,DIM_NUM_INFO)      != 0) &&
           ( strcmp(dim_nm,DIM_NUM_NOD_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_EDG_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_FAC_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ELE_VAR)   != 0) &&
           ( strcmp(dim_nm,DIM_NUM_NSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ESET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_FSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_SSET_VAR)  != 0) &&
           ( strcmp(dim_nm,DIM_NUM_ELSET_VAR) != 0) &&
           ( strcmp(dim_nm,DIM_NUM_GLO_VAR)   != 0) ) {

         if(dim_out_id == -1){
            if(dimid != recdimid){
               dim_out_id=ncdimdef(out_exoid,dim_nm,dim_sz);
            }else{
               dim_out_id=ncdimdef(out_exoid,dim_nm,NC_UNLIMITED);
            } /* end else */
         } /* end if */
      } /* end if */
   } /* end loop over dim */

   /* copy variable definitions and variable attributes */

   for (varid = 0; varid < nvars; varid++) {

      ncvarinq(in_exoid, varid, var.name, &var.type, &var.ndims, 
                      var.dims, &var.natts);

      /* we don't want to copy some variables because there is not a
       * simple way to add to them;
       * QA records, info records and all results variables (nodal
       * element, and global results) are examples
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)     &&
           ( strcmp(var.name,VAR_INFO) != 0)         &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)     &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)     &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0) &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)      &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0) &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)      &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0) &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0) &&
           ( strncmp(var.name,"vals_sset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_fset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_eset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nset_var",  13) != 0) &&
           ( strncmp(var.name,"vals_nod_var",   12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",  13) != 0) &&
           ( strncmp(var.name,"vals_face_var",  13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",  13) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          var_out_id = cpy_coord_def (in_exoid, out_exoid, recdimid, var.name,
                                      in_large, out_large);
        } else {
          var_out_id = cpy_var_def (in_exoid, out_exoid, recdimid, var.name);
        }

         /* copy the variable's attributes */
         (void) cpy_att (in_exoid, out_exoid, varid, var_out_id);

      }
   }

   /* take the output file out of define mode */
   ncendef (out_exoid);

   /* output variable data */

   for (varid = 0; varid < nvars; varid++) {
      ncvarinq(in_exoid, varid, var.name, &var.type, &var.ndims,
                    var.dims, &var.natts);

      /* we don't want to copy some variable values;
       * QA records and info records shouldn't be copied because there
       * isn't an easy way to add to them;
       * the time value array ("time_whole") and any results variables
       * (nodal, elemental, or global) shouldn't be copied 
       */

      if ( ( strcmp(var.name,VAR_QA_TITLE) != 0)        &&
           ( strcmp(var.name,VAR_INFO) != 0)            &&
           ( strcmp(var.name,VAR_EBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FBLK_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELEM_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ELSET_TAB) != 0)       &&
           ( strcmp(var.name,VAR_SSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_FSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_ESET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NSET_TAB) != 0)        &&
           ( strcmp(var.name,VAR_NAME_GLO_VAR) != 0)    &&
           ( strcmp(var.name,VAR_GLO_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_NOD_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NOD_VAR) != 0)         &&
           ( strcmp(var.name,VAR_NAME_EDG_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_FAC_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_ELE_VAR) != 0)    &&
           ( strcmp(var.name,VAR_NAME_NSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ESET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_FSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_SSET_VAR) != 0)   &&
           ( strcmp(var.name,VAR_NAME_ELSET_VAR) != 0)  &&
           ( strncmp(var.name,"vals_elset_var", 14) != 0)&&
           ( strncmp(var.name,"vals_sset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_fset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_eset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nset_var", 13) != 0)&&
           ( strncmp(var.name,"vals_nod_var", 12) != 0) &&
           ( strncmp(var.name,"vals_edge_var",13) != 0) &&
           ( strncmp(var.name,"vals_face_var",13) != 0) &&
           ( strncmp(var.name,"vals_elem_var",13) != 0) &&
           ( strcmp(var.name,VAR_WHOLE_TIME) != 0) ) {

        if (strncmp(var.name,VAR_COORD,5) == 0) {
          (void) cpy_coord_val (in_exoid, out_exoid, var.name,
                                in_large, out_large);
        } else {
          (void) cpy_var_val (in_exoid, out_exoid, var.name);
        }

      }
   }

   /* ensure internal data structures are updated */

   /* if number of blocks > 0 */
   update_internal_structs( out_exoid, EX_INQ_EDGE_BLK, &ed_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_BLK, &fa_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_BLK, &eb_ctr_list );

   /* if number of sets > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_SETS, &ns_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_EDGE_SETS, &es_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_SETS, &fs_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_SIDE_SETS, &ss_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_SETS, &els_ctr_list );

   /* if number of maps > 0 */
   update_internal_structs( out_exoid, EX_INQ_NODE_MAP, &nm_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_EDGE_MAP, &edm_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_FACE_MAP, &fam_ctr_list );
   update_internal_structs( out_exoid, EX_INQ_ELEM_MAP, &em_ctr_list );

   return(EX_NOERR);
}
Esempio n. 13
0
int
cpy_var_val(int in_id,int out_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the variable data from an input netCDF file
   * to an output netCDF file. 
   */

  int *dim_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;
  long *dim_cnt;
  long *dim_sz;
  long *dim_srt;
  long var_sz=1L;

  nc_type var_type_in, var_type_out;

  void *void_ptr;

  /* Get the var_id for the requested variable from both files. */
  var_in_id=ncvarid(in_id,var_nm);

  var_out_id=ncvarid(out_id,var_nm);
 
  /* Get the number of dimensions for the variable. */

  ncvarinq(out_id,var_out_id,(char *)NULL,&var_type_out,&nbr_dim,
                (int *)NULL,(int *)NULL);

  ncvarinq(in_id,var_in_id,(char *)NULL,&var_type_in,&nbr_dim,
                (int *)NULL,(int *)NULL);
 
  /* Allocate space to hold the dimension IDs */
  dim_cnt = malloc(nbr_dim*sizeof(long));

  dim_id=malloc(nbr_dim*sizeof(int));

  dim_sz=malloc(nbr_dim*sizeof(long));

  dim_srt=malloc(nbr_dim*sizeof(long));
 
  /* Get the dimension IDs from the input file */
  ncvarinq(in_id,var_in_id,(char *)NULL,(nc_type *)NULL,
                (int *)NULL,dim_id,(int *)NULL);
 
  /* Get the dimension sizes and names from the input file */
  for(idx=0;idx<nbr_dim;idx++){
  /* NB: For the unlimited dimension, ncdiminq() returns the maximum
     value used so far in writing data for that dimension.
     Thus if you read the dimension sizes from the output file, then
     the ncdiminq() returns dim_sz=0 for the unlimited dimension
     until a variable has been written with that dimension. This is
     the reason for always reading the input file for the dimension
     sizes. */

    ncdiminq(in_id,dim_id[idx],(char *)NULL,dim_cnt+idx);

    /* Initialize the indicial offset and stride arrays */
    dim_srt[idx]=0L;
    var_sz*=dim_cnt[idx];
  } /* end loop over dim */

  /* Allocate enough space to hold the variable */
  void_ptr=malloc(var_sz*nctypelen(var_type_in));

  /* Get the variable */

  /* if variable is float or double, convert if necessary */

  if(nbr_dim==0){  /* variable is a scalar */

    ncvarget1(in_id,var_in_id,0L,void_ptr);

    if ( ( (var_type_in == NC_FLOAT) && (var_type_out == NC_FLOAT) ) ||
         ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_DOUBLE) ) ) {
      /* no conversion necessary */

      ncvarput1(out_id,var_out_id,0L,void_ptr);

    } else if ( (var_type_in == NC_FLOAT) && (var_type_out == NC_DOUBLE) ) {
      /* convert up */

      ncvarput1(out_id,var_out_id,0L,
                ex_conv_array (out_id, WRITE_CONVERT_UP, void_ptr, 1));

    } else if ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_FLOAT) ) {
      /* convert down */

      ncvarput1(out_id,var_out_id,0L,
                ex_conv_array (out_id, WRITE_CONVERT_DOWN, void_ptr, 1));

    } else {  /* variable isn't float or double */

      /* no conversion necessary */

      ncvarput1(out_id,var_out_id,0L,void_ptr);

    }

  } else { /* variable is a vector */

    ncvarget(in_id,var_in_id,dim_srt,dim_cnt,void_ptr);

    if ( ( (var_type_in == NC_FLOAT) && (var_type_out == NC_FLOAT) ) ||
         ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_DOUBLE) ) ) {
      /* no conversion necessary */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,void_ptr);

    } else if ( (var_type_in == NC_FLOAT) && (var_type_out == NC_DOUBLE) ) {
      /* convert up */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,
               ex_conv_array (out_id,WRITE_CONVERT_UP,void_ptr,var_sz));

    } else if ( (var_type_in == NC_DOUBLE) && (var_type_out == NC_FLOAT) ) {
      /* convert down */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,
               ex_conv_array (out_id,WRITE_CONVERT_DOWN,void_ptr,var_sz));

    } else {  /* variable isn't float or double */

      /* no conversion necessary */

      ncvarput(out_id,var_out_id,dim_srt,dim_cnt,void_ptr);

    }

  } /* end if variable is an array */

  /* Free the space that held the dimension IDs */
  (void)free(dim_cnt);
  (void)free(dim_id);
  (void)free(dim_sz);
  (void)free(dim_srt);

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_var_val() */
Esempio n. 14
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : PutMaxMin
@INPUT      : ImInfo - pointer to struct describing the image variable
              ImVals - pointer to array of doubles containing the image data
              SliceNum, FrameNum - needed to correctly place the max and min
                values into the MIimagemax and MIimagemin variables
              DoFrames - whether or not there is a time dimension in this file
@OUTPUT     : (none)
@RETURNS    : (void)
@DESCRIPTION: Finds the max and min values of an image, and puts them
              into the MIimagemax and MIimagemin variables associated
              with the specified image variable.  Note: the caller must
              make sure that MIimagemax and MIimagemin exist in the
              file, and ensure that ImInfo->MaxID and ImInfo->MinID contain
              their variable ID's.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : 93-6-3, Greg Ward
@MODIFIED   : 
---------------------------------------------------------------------------- */
void PutMaxMin (ImageInfoRec *ImInfo, double *ImVals, 
                long SliceNum, long FrameNum, 
                Boolean DoSlices, Boolean DoFrames)
{
   int      i;
   double   Max, Min;
   long     Coord [2];          /* might use 0, 1 or 2 elements */
   int      old_ncopts;
   int      ret;
   nc_type  range_type;
   int      range_len;
   int      update_vr;
   double   valid_range[2];
   double   vr_max;

#ifdef DEBUG
   int      NumDims;            /* number of dimensions in imagemax/imagemin */
   int      Dims [4];           /* dimension ID's of imagemax/imagemin */

   printf ("Slice dimension is %d\n", ImInfo->SliceDim);
   printf ("Frame dimension is %d\n", ImInfo->FrameDim);

   ncvarinq (ImInfo->CDF, ImInfo->MaxID, NULL, NULL, &NumDims, Dims, NULL);
   printf ("MIimagemax has %d dimensions: ", NumDims);
   for (i = 0; i < NumDims; i++)
   {
      printf ("%5d", Dims [i]);
   }
   putchar ('\n');

   ncvarinq (ImInfo->CDF, ImInfo->MinID, NULL, NULL, &NumDims, Dims, NULL);
   printf ("MIimagemin has %d dimensions: ", NumDims);
   for (i = 0; i < NumDims; i++)
   {
      printf ("%5d", Dims [i]);
   }
   putchar ('\n');
#endif

   Max = - DBL_MAX;
   Min = DBL_MAX;

   /*
    * Find the actual max and min values in the buffer
    */

   for (i = 0; i < ImInfo->ImageSize; i++)
   {
      if (ImVals [i] > Max)
      {
         Max = ImVals [i];
      }

      if (ImVals [i] < Min)
      {
         Min = ImVals [i];
      }
   }     /* for i */

   /*
    * Now figure out the Coord vector (where to put the max and min
    * within the MIimagemax and MIimagemin variables), and put 'em there
    */

   if (DoFrames)        /* i.e. some frame was specified */
   { 
      Coord [ImInfo->FrameDim] = FrameNum;
   }

   if (DoSlices)
   {
      Coord [ImInfo->SliceDim] = SliceNum;
   }

#ifdef DEBUG
   printf ("Slice %ld, frame %ld: max is %lg, min is %lg\n", 
           (DoSlices) ? (SliceNum) : -1,
           (DoFrames) ? (FrameNum) : -1,
           Max, Min);
   if (DoSlices && DoFrames)
      printf ("Coord vector is: %ld %ld\n", Coord [0], Coord [1]);
   
#endif

   mivarput1 (ImInfo->CDF, ImInfo->MaxID, Coord, NC_DOUBLE, MI_SIGNED, &Max);
   mivarput1 (ImInfo->CDF, ImInfo->MinID, Coord, NC_DOUBLE, MI_SIGNED, &Min);

   /*
    * Update the image valid_range attribute for floating-point volumes
    */
   if ((ImInfo->DataType == NC_FLOAT) || (ImInfo->DataType == NC_DOUBLE)) {

      /* Get type and length of valid_range attribute */
      old_ncopts = ncopts; ncopts = 0;
      ret = ncattinq(ImInfo->CDF, ImInfo->ID, MIvalid_range, 
                     &range_type, &range_len);
      ncopts = old_ncopts;

      /* If type and length are okay, then read in old value and update */
      if ((ret != MI_ERROR) && 
          (range_type == NC_DOUBLE) && (range_len == 2)) {

         (void) ncattget(ImInfo->CDF, ImInfo->ID, MIvalid_range, valid_range);

         /* Test for first write of valid range */
         vr_max = (ImInfo->DataType == NC_DOUBLE ? 
                   1.79769313e+308 : 3.402e+38);
         update_vr = ((valid_range[0] < -vr_max) && (valid_range[1] > vr_max));

         /* Check the range */
         if ((Min < valid_range[0]) || update_vr)
            valid_range[0] = Min;
         if ((Max > valid_range[1]) || update_vr)
            valid_range[1] = Max;

         /* Check for whether float rounding is needed */
         if (ImInfo->DataType == NC_FLOAT) {
            valid_range[0] = (float) valid_range[0];
            valid_range[1] = (float) valid_range[1];
         }

         /* Write it out */
         (void) ncattput(ImInfo->CDF, ImInfo->ID, MIvalid_range, 
                         NC_DOUBLE, 2, valid_range);

      }

   }     /* if DataType is floating-point */

}     /* PutMaxMin */
Esempio n. 15
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_dimension_info
@INPUT      : infile - name of input file
              icvid - id of the image conversion variable
@OUTPUT     : volume - input volume data
@RETURNS    : (nothing)
@DESCRIPTION: Routine to get dimension information from an input file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : August 26, 1993 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
static void get_dimension_info(char *infile, int icvid, 
                               Volume_Info *volume_info)
{
   int mincid, imgid, varid;
   int idim, ndims;
   int dim[MAX_VAR_DIMS];
   long *dimlength;
   char *dimname;
   int offset;
   int missing_one_dimension;

   /* Get the minc file id and the image variable id */
   (void) miicv_inqint(icvid, MI_ICV_CDFID, &mincid);
   (void) miicv_inqint(icvid, MI_ICV_VARID, &imgid);
   if ((mincid == MI_ERROR) || (imgid == MI_ERROR)) {
      (void) fprintf(stderr, "File %s is not attached to an icv!\n",
                     infile);
      exit(EXIT_FAILURE);
   }

   /* Get the list of dimensions subscripting the image variable */
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dim, NULL);
   (void) miicv_inqint(icvid, MI_ICV_NUM_DIMS, &ndims);

   /* Check that we have two or three dimensions */
   if ((ndims != NUMBER_OF_DIMENSIONS) &&
       (ndims != NUMBER_OF_DIMENSIONS-1)) {
      (void) fprintf(stderr, 
                     "File %s does not have %d or %d dimensions\n",
                     infile, NUMBER_OF_DIMENSIONS,
                     NUMBER_OF_DIMENSIONS-1);
      exit(EXIT_FAILURE);
   }

   /* Pretend that we have three dimensions */
   offset = ndims - NUMBER_OF_DIMENSIONS;
   missing_one_dimension = (offset < 0);
   ndims = NUMBER_OF_DIMENSIONS;

   /* Loop through dimensions, checking them and getting their sizes */
   for (idim=0; idim<ndims; idim++) {

      /* Get pointers to the appropriate dimension size and name */
      switch (idim) {
      case 0: dimlength = &(volume_info->nslices) ; break;
      case 1: dimlength = &(volume_info->nrows) ; break;
      case 2: dimlength = &(volume_info->ncolumns) ; break;
      }
      dimname = volume_info->dimension_names[idim];

      /* Get dimension name and size */
      if (missing_one_dimension && (idim==0)) {
         (void) strcpy(dimname, "unknown");
         *dimlength = 1;
      }
      else {
         (void) ncdiminq(mincid, dim[idim+offset], dimname, dimlength);
      }

   }

   /* Get dimension step and start (defaults = 1 and 0). For slices,
      we read straight from the variable, but for image dimensions, we
      get the step and start from the icv. If we didn't have 
      MI_ICV_DO_DIM_CONV set to TRUE, then we would have to get the image 
      dimension step and start straight from the variables. */
   for (idim=0; idim<ndims; idim++) {
      volume_info->step[idim] = 1.0;
      volume_info->start[idim] = 0.0;
   }
   ncopts = 0;
   (void) miicv_inqdbl(icvid, MI_ICV_ADIM_STEP, &volume_info->step[COLUMN]);
   (void) miicv_inqdbl(icvid, MI_ICV_ADIM_START, &volume_info->start[COLUMN]);
   (void) miicv_inqdbl(icvid, MI_ICV_BDIM_STEP, &volume_info->step[ROW]);
   (void) miicv_inqdbl(icvid, MI_ICV_BDIM_START, &volume_info->start[ROW]);
   if ((varid=ncvarid(mincid, volume_info->dimension_names[SLICE])) 
                                != MI_ERROR) {
      (void) miattget1(mincid, varid, MIstep, NC_DOUBLE, 
                       &volume_info->step[SLICE]);
      (void) miattget1(mincid, varid, MIstart, NC_DOUBLE,
                       &volume_info->start[SLICE]);
   }
   ncopts = NC_OPTS_VAL;

}
Esempio n. 16
0
File: minc.c Progetto: BIC-MNI/xdisp
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_dimension_info
@INPUT      : infile - name of input file
              icvid - id of the image conversion variable
@OUTPUT     : volume - input volume data
@RETURNS    : (nothing)
@DESCRIPTION: Routine to get dimension information from an input file.
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : August 26, 1993 (Peter Neelin)
@MODIFIED   : 
---------------------------------------------------------------------------- */
void get_dimension_info(char *infile, int icvid, 
                               Volume_Info *volume_info)
{
   int mincid, imgid, varid;
   int idim, ndims;
   int dim[MAX_VAR_DIMS];
   long *dimlength;
   char *dimname;

   /* Get the minc file id and the image variable id */
   (void) miicv_inqint(icvid, MI_ICV_CDFID, &mincid);
   (void) miicv_inqint(icvid, MI_ICV_VARID, &imgid);
   if ((mincid == MI_ERROR) || (imgid == MI_ERROR)) {
      (void) fprintf(stderr, "File %s is not attached to an icv!\n",
                     infile);
      exit_xdisp(EXIT_FAILURE);
   }

   /* Get the list of dimensions subscripting the image variable */
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dim, NULL);
   (void) miicv_inqint(icvid, MI_ICV_NUM_DIMS, &ndims);
   volume_info->number_of_dimensions = ndims;

   /* Check that there are at least two dimensions */
   if (ndims < 2 || ndims > MAX_VAR_DIMS) {
      (void) fprintf(stderr, "File %s requires at least two and at most %d dimensions\n",
                     infile, MAX_VAR_DIMS);
      exit_xdisp(EXIT_FAILURE);
   }

   /* Initialize step and start to unknown values */
   for (idim=0; idim<ndims; idim++){
      volume_info->step[idim] = 0;
      volume_info->start[idim] = 0;
   }

   ncopts = 0;

   /* Loop through dimensions, checking them and getting their sizes */
   for (idim=0; idim<ndims; idim++){
      /* Get pointers to the appropriate dimension size and name */
      dimname = volume_info->dimension_names[idim];
      (void)ncdiminq(mincid,dim[idim],dimname,&(volume_info->length[idim]));

      /* Get step and start directly from the variables */
      /* GBP: add direction_cosines and units */
      if ((varid = ncvarid(mincid, volume_info->dimension_names[idim]))
          != MI_ERROR){

         (void)miattget1(mincid, varid, MIstep, NC_DOUBLE,
                         &(volume_info->step[idim]));
         (void)miattget1(mincid, varid, MIstart, NC_DOUBLE,
                         &(volume_info->start[idim]));
         (void)miattget(mincid, varid, MIdirection_cosines, NC_DOUBLE, 3,
                         &(volume_info->direction_cosines[idim]), NULL);
         (void)miattgetstr(mincid, varid, MIunits, 20,
                         volume_info->dimension_units[idim]);

      }
   }

   /* get image plane start and step values */
   /* A is fastest dimension (screen x) and B is next fastest (screen y) */
   (void)miicv_inqdbl(icvid, MI_ICV_ADIM_START, &(volume_info->a_start));
   (void)miicv_inqdbl(icvid, MI_ICV_ADIM_STEP, &(volume_info->a_step));
   (void)miicv_inqdbl(icvid, MI_ICV_BDIM_START, &(volume_info->b_start));
   (void)miicv_inqdbl(icvid, MI_ICV_BDIM_STEP, &(volume_info->b_step));

   ncopts = NC_OPTS_VAL;
}
Esempio n. 17
0
/*
 * TODO, lots of declared, but unused variables here
 */
static void do_netcdfquery_proc(Widget, XtPointer, XtPointer)
{
    int setno, src;
    char xvar[256], yvar[256];
    char buf[256], fname[512];
    XmString xms;
    XmString *s, cs;
    int *pos_list;
    int i, j, pos_cnt, cnt;
    char *cstr;

    int cdfid; /* netCDF id */
    int ndims, nvars, ngatts, recdim;
    int var_id;
    long start[2];
    long count[2];
    char varname[256];
    nc_type datatype = 0;
    int dim[100], natts;
    long dimlen[100];
    long len;

    int x_id, y_id;
    nc_type xdatatype = 0;
    nc_type ydatatype = 0;
    int xndims, xdim[10], xnatts;
    int yndims, ydim[10], ynatts;
    long nx, ny;

    int atlen;
    char attname[256];
    char atcharval[256];

    extern int ncopts;

    ncopts = 0; /* no crash on error */

    set_wait_cursor();

    strcpy(fname, xv_getstr(netcdf_file_item));

    if ((cdfid = ncopen(fname, NC_NOWRITE)) == -1)
    {
        errwin("Can't open file.");
        goto out2;
    }
    if (XmListGetSelectedPos(netcdf_listx_item, &pos_list, &pos_cnt))
    {
        XtVaGetValues(netcdf_listx_item,
                      XmNselectedItemCount, &cnt,
                      XmNselectedItems, &s,
                      NULL);
        cs = XmStringCopy(*s);
        if (XmStringGetLtoR(cs, charset, &cstr))
        {
            strcpy(xvar, cstr);
            XtFree(cstr);
        }
        XmStringFree(cs);
    }
    else
    {
        errwin("Need to select X, either variable name or INDEX");
        goto out1;
    }
    if (XmListGetSelectedPos(netcdf_listy_item, &pos_list, &pos_cnt))
    {
        XtVaGetValues(netcdf_listy_item,
                      XmNselectedItemCount, &cnt,
                      XmNselectedItems, &s,
                      NULL);
        cs = XmStringCopy(*s);
        if (XmStringGetLtoR(cs, charset, &cstr))
        {
            strcpy(yvar, cstr);
            XtFree(cstr);
        }
        XmStringFree(cs);
    }
    else
    {
        errwin("Need to select Y");
        goto out1;
    }
    if (strcmp(xvar, "INDEX") == 0)
    {
        stufftext("X is the index of the Y variable\n", STUFF_START);
    }
    else
    {
        if ((x_id = ncvarid(cdfid, xvar)) == -1)
        {
            char ebuf[256];
            sprintf(ebuf, "do_query(): No such variable %s for X", xvar);
            errwin(ebuf);
            goto out1;
        }
        ncvarinq(cdfid, x_id, NULL, &xdatatype, &xndims, xdim, &xnatts);
        ncdiminq(cdfid, xdim[0], NULL, &nx);
        sprintf(buf, "X is %s, data type %s \t length [%d]\n", xvar, getcdf_type(xdatatype), nx);
        stufftext(buf, STUFF_TEXT);
        sprintf(buf, "\t%d Attributes:\n", xnatts);
        stufftext(buf, STUFF_TEXT);
        for (i = 0; i < xnatts; i++)
        {
            atcharval[0] = 0;
            ncattname(cdfid, x_id, i, attname);
            ncattinq(cdfid, x_id, attname, &datatype, &atlen);
            switch (datatype)
            {
            case NC_CHAR:
                ncattget(cdfid, x_id, attname, (void *)atcharval);
                break;
            }
            sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
            stufftext(buf, STUFF_TEXT);
        }
    }
    if ((y_id = ncvarid(cdfid, yvar)) == -1)
    {
        char ebuf[256];
        sprintf(ebuf, "do_query(): No such variable %s for Y", yvar);
        errwin(ebuf);
        goto out1;
    }
    ncvarinq(cdfid, y_id, NULL, &ydatatype, &yndims, ydim, &ynatts);
    ncdiminq(cdfid, ydim[0], NULL, &ny);
    sprintf(buf, "Y is %s, data type %s \t length [%d]\n", yvar, getcdf_type(ydatatype), ny);
    stufftext(buf, STUFF_TEXT);
    sprintf(buf, "\t%d Attributes:\n", ynatts);
    stufftext(buf, STUFF_TEXT);
    for (i = 0; i < ynatts; i++)
    {
        atcharval[0] = 0;
        ncattname(cdfid, y_id, i, attname);
        ncattinq(cdfid, y_id, attname, &datatype, &atlen);
        switch (datatype)
        {
        case NC_CHAR:
            ncattget(cdfid, y_id, attname, (void *)atcharval);
            break;
        }
        sprintf(buf, "\t\t%s: %s\n", attname, atcharval);
        stufftext(buf, STUFF_TEXT);
    }

out1:
    ;
    ncclose(cdfid);

out2:
    ;
    stufftext("\n", STUFF_STOP);
    unset_wait_cursor();
}
Esempio n. 18
0
void update_netcdfs(void)
{
    int i, j;
    char buf[256], fname[512];
    XmString xms;
    int cdfid; /* netCDF id */
    int ndims, nvars, ngatts, recdim;
    int var_id;
    long start[2];
    long count[2];
    char varname[256];
    nc_type datatype = 0;
    int dim[100], natts;
    long dimlen[100];
    long len;
    extern int ncopts;

    ncopts = 0; /* no crash on error */

    if (netcdf_frame != NULL)
    {
        strcpy(fname, xv_getstr(netcdf_file_item));
        set_wait_cursor();
        XmListDeleteAllItems(netcdf_listx_item);
        XmListDeleteAllItems(netcdf_listy_item);
        xms = XmStringCreateLtoR("INDEX", charset);
        XmListAddItemUnselected(netcdf_listx_item, xms, 0);
        XmStringFree(xms);

        if (strlen(fname) < 2)
        {
            unset_wait_cursor();
            return;
        }
        if ((cdfid = ncopen(fname, NC_NOWRITE)) == -1)
        {
            errwin("Can't open file.");
            unset_wait_cursor();
            return;
        }
        ncinquire(cdfid, &ndims, &nvars, &ngatts, &recdim);
        /*
          printf("%d %d %d %d\n", ndims, nvars, ngatts, recdim);
      */
        for (i = 0; i < ndims; i++)
        {
            ncdiminq(cdfid, i, NULL, &dimlen[i]);
        }
        for (i = 0; i < nvars; i++)
        {
            ncvarinq(cdfid, i, varname, &datatype, &ndims, dim, &natts);
            if ((var_id = ncvarid(cdfid, varname)) == -1)
            {
                char ebuf[256];
                sprintf(ebuf, "update_netcdfs(): No such variable %s", varname);
                errwin(ebuf);
                continue;
            }
            if (ndims != 1)
            {
                continue;
            }
            ncdiminq(cdfid, dim[0], (char *)NULL, &len);
            sprintf(buf, "%s", varname);
            xms = XmStringCreateLtoR(buf, charset);
            XmListAddItemUnselected(netcdf_listx_item, xms, 0);
            XmListAddItemUnselected(netcdf_listy_item, xms, 0);
            XmStringFree(xms);
        }
        ncclose(cdfid);
        unset_wait_cursor();
    }
}
Esempio n. 19
0
MNCAPI int
minc_load_data(char *path, void *dataptr, int datatype,
               long *ct, long *cz, long *cy, long *cx,
               double *dt, double *dz, double *dy, double *dx,
               void **infoptr)
{
    int fd;                     /* MINC file descriptor */
    nc_type nctype;             /* netCDF type */
    char *signstr;              /* MI_SIGNED or MI_UNSIGNED */
    int length;
    int dim_id[MI_S_NDIMS];
    long dim_len[MI_S_NDIMS];
    int i, j;                   /* Generic loop counters */
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;                    /* MINC image conversion variable */
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    size_t ucount[MI_S_NDIMS];
    int dir[MI_S_NDIMS];        /* Dimension "directions" */
    int map[MI_S_NDIMS];        /* Dimension mapping */
    int old_ncopts;             /* For storing the old state of ncopts */
    double *p_dtmp;
    long *p_ltmp;
    struct file_info *p_file;
    struct att_info *p_att;
    int r;                      /* Generic return code */
    
    *infoptr = NULL;

    fd = miopen(path, NC_NOWRITE);
    if (fd < 0) {
        return (MINC_STATUS_ERROR);
    }

    old_ncopts =get_ncopts();
    set_ncopts(0);

    for (i = 0; i < MI_S_NDIMS; i++) {
        dim_id[i] = ncdimid(fd, minc_dimnames[i]);
        if (dim_id[i] >= 0) {
            ncdiminq(fd, dim_id[i], NULL, &dim_len[i]);
            var_id = ncvarid(fd, minc_dimnames[i]);
            ncattinq(fd, var_id, MIstep, &nctype, &length);

            switch (i) {
            case MI_S_T:
                p_ltmp = ct;
                p_dtmp = dt;
                break;
            case MI_S_X:
                p_ltmp = cx;
                p_dtmp = dx;
                break;
            case MI_S_Y:
                p_ltmp = cy;
                p_dtmp = dy;
                break;
            case MI_S_Z:
                p_ltmp = cz;
                p_dtmp = dz;
                break;
            default:
                return (MINC_STATUS_ERROR);
            }
                
            if (nctype == NC_DOUBLE && length == 1) {
                ncattget(fd, var_id, MIstep, p_dtmp);
            }
            else {
                *p_dtmp = 0;    /* Unknown/not set */
            }
            *p_ltmp = dim_len[i];
        }
        else {
            dim_len[i] = 0;
        }
    }

    set_ncopts(old_ncopts);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, &nctype, &var_ndims, var_dims, NULL);

    if (var_ndims != 3 && var_ndims != 4) {
        return (MINC_STATUS_ERROR);
    }

    /* We want the data to wind up in t, x, y, z order. */

    for (i = 0; i < MI_S_NDIMS; i++) {
        map[i] = -1;
    }

    for (i = 0; i < var_ndims; i++) {
        if (var_dims[i] == dim_id[MI_S_T]) {
            map[MI_S_T] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_X]) {
            map[MI_S_X] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Y]) {
            map[MI_S_Y] = i;
        }
        else if (var_dims[i] == dim_id[MI_S_Z]) {
            map[MI_S_Z] = i;
        }
    }

    icv = miicv_create();

    minc_simple_to_nc_type(datatype, &nctype, &signstr);
    miicv_setint(icv, MI_ICV_TYPE, nctype);
    miicv_setstr(icv, MI_ICV_SIGN, signstr);
    miicv_attach(icv, fd, var_id);

    for (i = 0; i < var_ndims; i++) {
        start[i] = 0;
    }

    for (i = 0; i < MI_S_NDIMS; i++) {
        if (map[i] >= 0) {
            count[map[i]] = dim_len[i];
        }
    }

    r = miicv_get(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    if (map[MI_S_T] >= 0) {
        if (*dt < 0) {
            dir[MI_S_T] = -1;
            *dt = -*dt;
        }
        else {
            dir[MI_S_T] = 1;
        }
    }

    if (map[MI_S_X] >= 0) {
        if (*dx < 0) {
            dir[MI_S_X] = -1;
            *dx = -*dx;
        }
        else {
            dir[MI_S_X] = 1;
        }
    }

    if (map[MI_S_Y] >= 0) {
        if (*dy < 0) {
            dir[MI_S_Y] = -1;
            *dy = -*dy;
        }
        else {
            dir[MI_S_Y] = 1;
        }
    }

    if (map[MI_S_Z] >= 0) {
        if (*dz < 0) {
            dir[MI_S_Z] = -1;
            *dz = -*dz;
        }
        else {
            dir[MI_S_Z] = 1;
        }
    }

    if (var_ndims == 3) {
        for (i = 1; i < MI_S_NDIMS; i++) {
            map[i-1] = map[i];
            dir[i-1] = dir[i];
        }
    }

    j = 0;
    for (i = 0; i < MI_S_NDIMS; i++) {
        if (dim_len[i] > 0) {
            ucount[j++] = dim_len[i];
        }
    }

    restructure_array(var_ndims, dataptr, ucount, nctypelen(nctype),
                      map, dir);

    miicv_detach(icv);
    miicv_free(icv);

    old_ncopts =get_ncopts();
    set_ncopts(0);

    /* Generate the complete infoptr array.
     * This is essentially an in-memory copy of the variables and attributes
     * in the file.
     */

    p_file = (struct file_info *) malloc(sizeof (struct file_info));

    ncinquire(fd, &p_file->file_ndims, &p_file->file_nvars,
              &p_file->file_natts, NULL);

    p_file->file_atts = (struct att_info *) malloc(sizeof (struct att_info) * 
                                                   p_file->file_natts);

    p_file->file_vars = (struct var_info *) malloc(sizeof (struct var_info) *
                                                   p_file->file_nvars);

    for (i = 0; i < p_file->file_natts; i++) {
        p_att = &p_file->file_atts[i];

        ncattname(fd, NC_GLOBAL, i, p_att->att_name);
        ncattinq(fd, NC_GLOBAL, 
                 p_att->att_name, 
                 &p_att->att_type, 
                 &p_att->att_len);

        p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));

        ncattget(fd, NC_GLOBAL, p_att->att_name, p_att->att_val);
    }

    for (i = 0; i < p_file->file_nvars; i++) {
        struct var_info *p_var = &p_file->file_vars[i];

        ncvarinq(fd, i, 
                 p_var->var_name, 
                 &p_var->var_type, 
                 &p_var->var_ndims, 
                 p_var->var_dims,
                 &p_var->var_natts);

        p_var->var_atts = malloc(p_var->var_natts *
                                 sizeof (struct att_info));

        if (ncdimid(fd, p_var->var_name) >= 0) {
            /* It's a dimension variable, have to treat it specially... */
        }

        for (j = 0; j < p_var->var_natts; j++) {
            p_att = &p_var->var_atts[j];

            ncattname(fd, i, j, p_att->att_name);
            ncattinq(fd, i, 
                     p_att->att_name, 
                     &p_att->att_type, 
                     &p_att->att_len);

            p_att->att_val = malloc(p_att->att_len * nctypelen(p_att->att_type));
            ncattget(fd, i, p_att->att_name, p_att->att_val);
        }
    }

    *infoptr = p_file;

    set_ncopts(old_ncopts);

    miclose(fd);

    return (MINC_STATUS_OK);
}
Esempio n. 20
0
MNCAPI int
minc_save_data(int fd, void *dataptr, int datatype,
               long st, long sz, long sy, long sx,
               long ct, long cz, long cy, long cx)
{
    nc_type nctype;
    char *signstr;
    int i;
    int var_id;
    int var_ndims;
    int var_dims[MAX_NC_DIMS];
    int icv;
    long start[MI_S_NDIMS];
    long count[MI_S_NDIMS];
    int old_ncopts;
    int r;
    double min, max;
    long slice_size;
    long index;
    int dtbytes;                /* Length of datatype in bytes */

    old_ncopts =get_ncopts();
    set_ncopts(0);

    var_id = ncvarid(fd, MIimage);

    ncvarinq(fd, var_id, NULL, NULL, &var_ndims, var_dims, NULL);

    set_ncopts(old_ncopts);
    
    if (var_ndims < 2 || var_ndims > 4) {
        return (MINC_STATUS_ERROR);
    }
    
    r = minc_simple_to_nc_type(datatype, &nctype, &signstr);
    if (r == MINC_STATUS_ERROR) {
        return (MINC_STATUS_ERROR);
    }

    dtbytes = nctypelen(nctype);

    /* Update the image-min and image-max values */
    if (ct > 0) {
        slice_size = cz * cy * cx;
        index = st;

        for (i = 0; i < ct; i++) {
            find_minmax((char *) dataptr + (dtbytes * slice_size * i), 
                        slice_size, datatype, &min, &max);
        
            mivarput1(fd, ncvarid(fd, MIimagemin), &index, 
                      NC_DOUBLE, MI_SIGNED, &min);
            mivarput1(fd, ncvarid(fd, MIimagemax), &index, 
                      NC_DOUBLE, MI_SIGNED, &max);
            index++;
        }
    }
    else {
        slice_size = cy * cx;
        index = sz;

        for (i = 0; i < cz; i++) {
            find_minmax((char *) dataptr + (dtbytes * slice_size * i), 
                        slice_size, datatype, &min, &max);
            mivarput1(fd, ncvarid(fd, MIimagemin), &index, 
                      NC_DOUBLE, MI_SIGNED, &min);
            mivarput1(fd, ncvarid(fd, MIimagemax), &index, 
                      NC_DOUBLE, MI_SIGNED, &max);
            index++;
        }
    }

    /* We want the data to wind up in t, x, y, z order. */

    icv = miicv_create();
    if (icv < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_TYPE, nctype);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setstr(icv, MI_ICV_SIGN, signstr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_DO_NORM, 1);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_setint(icv, MI_ICV_DO_FILLVALUE, 1);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    r = miicv_attach(icv, fd, var_id);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    i = 0;
    switch (var_ndims) {
    case 4:
        count[i] = ct;
        start[i] = st;
        i++;
        /* fall through */
    case 3:
        count[i] = cz;
        start[i] = sz;
        i++;
        /* fall through */
    case 2:
        count[i] = cy;
        start[i] = sy;
        i++;
        
        count[i] = cx;
        start[i] = sx;
        i++;
        break;
    }

    r = miicv_put(icv, start, count, dataptr);
    if (r < 0) {
        return (MINC_STATUS_ERROR);
    }

    miicv_detach(icv);
    miicv_free(icv);
    return (MINC_STATUS_OK);
}
Esempio n. 21
0
int
cpy_var_def(int in_id,int out_id,int rec_dim_id,char *var_nm)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   int rec_dim_id: input input-file record dimension ID
   char *var_nm: input variable name
   int cpy_var_def(): output output-file variable ID
 */
{
  /* Routine to copy the variable metadata from an input netCDF file
   * to an output netCDF file. 
   */

  int *dim_in_id;
  int *dim_out_id;
  int idx;
  int nbr_dim;
  int var_in_id;
  int var_out_id;
  int temp;

  extern int ncopts;

  nc_type var_type;

  /* See if the requested variable is already in the output file. */
  temp = ncopts;
  ncopts=0;
  var_out_id=ncvarid(out_id,var_nm);
  ncopts = temp;
  if(var_out_id != -1) return var_out_id;

  /* See if the requested variable is in the input file. */
  var_in_id=ncvarid(in_id,var_nm);

  /* Get the type of the variable and the number of dimensions. */
  ncvarinq(in_id,var_in_id,(char *)NULL,&var_type,&nbr_dim,
        (int *)NULL,(int *)NULL);

  /* Recall:
     1. The dimensions must be defined before the variable.
     2. The variable must be defined before the attributes. */

  /* Allocate space to hold the dimension IDs */
  dim_in_id=malloc(nbr_dim*sizeof(int)); 
  dim_out_id=malloc(nbr_dim*sizeof(int));

  /* Get the dimension IDs */
  ncvarinq(in_id,var_in_id,(char *)NULL,(nc_type *)NULL,
                (int *)NULL,dim_in_id,(int *)NULL);

  /* Get the dimension sizes and names */
  for(idx=0;idx<nbr_dim;idx++){
    char dim_nm[MAX_NC_NAME];
    long dim_sz;

    ncdiminq(in_id,dim_in_id[idx],dim_nm,&dim_sz);

    /* See if the dimension has already been defined */
    temp = ncopts;
    ncopts = 0;
    dim_out_id[idx]=ncdimid(out_id,dim_nm);
    ncopts = temp;

    /* If the dimension hasn't been defined, copy it */
    if(dim_out_id[idx] == -1){
      if(dim_in_id[idx] != rec_dim_id){
        dim_out_id[idx]=ncdimdef(out_id,dim_nm,dim_sz);
      }else{
        dim_out_id[idx]=ncdimdef(out_id,dim_nm,NC_UNLIMITED);
      } /* end else */
    } /* end if */
  } /* end loop over dim */

  /* Define the variable in the output file */

  /* If variable is float or double, define it according to the EXODUS
     file's IO_word_size */

  if ((var_type == NC_FLOAT) || (var_type == NC_DOUBLE)) {
     var_out_id=ncvardef(out_id,var_nm,nc_flt_code(out_id),
                             nbr_dim,dim_out_id);
  } else {
     var_out_id=ncvardef(out_id,var_nm,var_type,nbr_dim,dim_out_id);
  }

  /* Free the space holding the dimension IDs */
  (void)free(dim_in_id);
  (void)free(dim_out_id);

  return var_out_id;
} /* end cpy_var_def() */
Esempio n. 22
0
int
test_icv_read(char *filename, int xsize, int ysize, double image_min,
              double image_max, nc_type datatype, char *signtype)
{
   int icv, cdfid, img, ndims;
   static long coord[MAX_VAR_DIMS];
   static long count[MAX_VAR_DIMS];
   int dim[MAX_VAR_DIMS];
   long dim_size;
   unsigned char *image;
   int i;
   double min, max;
   int n;

   min = DBL_MAX;
   max = -DBL_MAX;

   image = malloc(xsize * ysize * nctypelen(datatype));
   if (image == NULL) {
       return (ERROR_STATUS);
   }

   /* Create the icv */
   icv=miicv_create();
   (void) miicv_setint(icv, MI_ICV_XDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_YDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ZDIM_DIR, MI_ICV_POSITIVE);
   (void) miicv_setint(icv, MI_ICV_ADIM_SIZE, xsize);
   (void) miicv_setint(icv, MI_ICV_BDIM_SIZE, ysize);
   (void) miicv_setint(icv, MI_ICV_KEEP_ASPECT, FALSE);
   (void) miicv_setint(icv, MI_ICV_DO_DIM_CONV, TRUE);
   (void) miicv_setint(icv, MI_ICV_TYPE, datatype);
   (void) miicv_setstr(icv, MI_ICV_SIGN, signtype);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, image_max);
   (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, image_min);

   /* Open the file, attach the image variable */
   cdfid=miopen(filename, NC_NOWRITE);

   /* Attach image variable */
   img=ncvarid(cdfid, MIimage);
   (void) miicv_attach(icv, cdfid, img);

   /* Get the number of dimensions and modify count and coord */
   (void) ncvarinq(cdfid, img, NULL, NULL, &ndims, dim, NULL);
   if (ndims!=3) {
      (void) fprintf(stderr, "File must have 3 dimensions\n");
      return ERROR_STATUS;
   }
   (void) ncdiminq(cdfid, dim[0], NULL, &dim_size);
   count[0]=1;
   count[1]=ysize;
   count[2]=xsize;
   coord[1]=0;
   coord[2]=0;

   /* Get the data */
   for (i=0; i<dim_size; i++) {
      coord[0]=i;
      (void) miicv_get(icv, coord, count, image);

      switch (datatype) {
      case NC_BYTE:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned char uc = *(((unsigned char *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed char sc = *(((signed char *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_SHORT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned short uc = *(((unsigned short *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed short sc = *(((signed short *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_INT:
          if (!strcmp(signtype, MI_UNSIGNED)) {
              for (n = 0; n < xsize*ysize; n++) {
                  unsigned int uc = *(((unsigned int *)image) + n);
                  if (uc > max) {
                      max = uc;
                  }
                  if (uc < min) {
                      min = uc;
                  }
              }
          }
          else {
              for (n = 0; n < xsize*ysize; n++) {
                  signed int sc = *(((signed int *)image) + n);
                  if (sc > max) {
                      max = sc;
                  }
                  if (sc < min) {
                      min = sc;
                  }
              }
          }
          break;
      case NC_FLOAT:
          for (n = 0; n < xsize*ysize; n++) {
              float sc = *(((float *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      case NC_DOUBLE:
          for (n = 0; n < xsize*ysize; n++) {
              double sc = *(((double *)image) + n);
              if (sc > max) {
                  max = sc;
              }
              if (sc < min) {
                  min = sc;
              }
          }
          break;
      }
      printf("%d %s %s %f %f\n", i, signtype, nctypename(datatype), min, max);
   }

   /* Close the file and free the icv */
   (void) miclose(cdfid);
   (void) miicv_free(icv);

   free(image);
   return (NORMAL_STATUS);
}
Esempio n. 23
0
int
cpy_coord_val(int in_id,int out_id,char *var_nm,
              int in_large, int out_large)
/*
   int in_id: input netCDF input-file ID
   int out_id: input netCDF output-file ID
   char *var_nm: input variable name
 */
{
  /* Routine to copy the coordinate data from an input netCDF file
   * to an output netCDF file. 
   */

  const char *routine = NULL;
  int i;
  long spatial_dim, num_nodes;
  long start[2], count[2];
  nc_type var_type_in, var_type_out;

  void *void_ptr;

  /* Handle easiest situation first: in_large matches out_large */
  if (in_large == out_large)
    return cpy_var_val(in_id, out_id, var_nm);
  
  /* At this point, know that in_large != out_large, so will need to
     either copy a vector to multiple scalars or vice-versa.  Also
     will a couple dimensions, so get them now.*/
  ex_get_dimension(in_id, DIM_NUM_DIM, "dimension", &spatial_dim, routine);
  ex_get_dimension(in_id, DIM_NUM_NODES, "nodes",   &num_nodes, routine);

  if (in_large == 0 && out_large == 1) {
    /* output file will have coordx, coordy, coordz (if 3d). */
    /* Get the var_id for the requested variable from both files. */
    int var_in_id, var_out_id[3];
    var_in_id = ncvarid(in_id, VAR_COORD);
    var_out_id[0] = ncvarid(out_id,VAR_COORD_X);
    var_out_id[1] = ncvarid(out_id,VAR_COORD_Y);
    var_out_id[2] = ncvarid(out_id,VAR_COORD_Z);

    ncvarinq(in_id,var_in_id,(char *)NULL,&var_type_in,(int*)NULL,
                (int *)NULL,(int *)NULL);
    ncvarinq(out_id,var_out_id[0],(char *)NULL,&var_type_out,(int *)NULL,
                (int *)NULL,(int *)NULL);

    void_ptr=malloc(num_nodes * nctypelen(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;
      ncvarget(in_id, var_in_id, start, count, void_ptr);
      
      if (var_type_in == var_type_out) {
        if (var_type_out == NC_FLOAT) {
          nc_put_var_float(out_id, var_out_id[i], void_ptr);
        } else {
          nc_put_var_double(out_id, var_out_id[i], void_ptr);
        }
      } else if (var_type_in == NC_FLOAT && var_type_out == NC_DOUBLE) {
        nc_put_var_double(out_id, var_out_id[i],
                          ex_conv_array(out_id, WRITE_CONVERT_UP, void_ptr, num_nodes));
      } else if (var_type_in == NC_DOUBLE && var_type_out == NC_FLOAT) {
        nc_put_var_float(out_id, var_out_id[i],
                          ex_conv_array(out_id, WRITE_CONVERT_DOWN, void_ptr, num_nodes));
      }
    }
  }

  if (in_large == 1 && out_large == 0) {
    /* input file will have coordx, coordy, coordz (if 3d); output has
       only "coord" */
    int var_in_id[3], var_out_id;
    var_in_id[0] = ncvarid(in_id,  VAR_COORD_X);
    var_in_id[1] = ncvarid(in_id,  VAR_COORD_Y);
    var_in_id[2] = ncvarid(in_id,  VAR_COORD_Z);
    var_out_id   = ncvarid(out_id, VAR_COORD);
    
    ncvarinq(in_id,var_in_id[0],(char *)NULL,&var_type_in,(int *)NULL,
                (int *)NULL,(int *)NULL);

    ncvarinq(out_id,var_out_id,(char *)NULL,&var_type_out,(int*)NULL,
                (int *)NULL,(int *)NULL);

    void_ptr=malloc(num_nodes * nctypelen(var_type_in));

    /* Copy each component of the variable... */
    for (i=0; i < spatial_dim; i++) {
      if (var_type_in == NC_FLOAT) {
        nc_get_var_float(in_id, var_in_id[i], void_ptr);
      } else {
        nc_get_var_double(in_id, var_in_id[i], void_ptr);
      }

      start[0] = i; start[1] = 0;
      count[0] = 1; count[1] = num_nodes;
      if (var_type_in == var_type_out) {
        ncvarput(out_id, var_out_id, start, count, void_ptr);
      } else if (var_type_in == NC_FLOAT && var_type_out == NC_DOUBLE) {
        ncvarput(out_id, var_out_id, start, count,
                 ex_conv_array(out_id, WRITE_CONVERT_UP, void_ptr, num_nodes));
      } else if (var_type_in == NC_DOUBLE && var_type_out == NC_FLOAT) {
        ncvarput(out_id, var_out_id, start, count,
                 ex_conv_array(out_id, WRITE_CONVERT_DOWN, void_ptr, num_nodes));
      }
    }
  }

  /* Free the space that held the variable */
  (void)free(void_ptr);

  return(EX_NOERR);

} /* end cpy_coord_val() */
Esempio n. 24
0
/* Open an input netCDF file and get some information about it */
int process_ncinfile(char *ncname, unsigned char appendnc, int outncfid,
                     char *outncname, int *nfiles, unsigned char verbose)
{
    struct fileinfo ncinfile;  /* Information about an input netCDF file */
    int nfiles2;  /* Number of files in the decomposed domain */
    int d, v, n;  /* Loop variables */
    int dimid;  /* ID of a dimension */
    int decomp[4];  /* "domain_decomposition" information */
    char attname[MAX_NC_NAME];  /* Name of a global or variable attribute */
    unsigned char ncinfileerror=0;  /* Were there any file errors? */

    /* Open an input netCDF file; return if not openable - possibly IEEE */
    if ((ncinfile.ncfid=ncopen(ncname,NC_NOWRITE))==(-1)) return(2);

    /* Determine the number of files in the decomposed domain */
    if (ncattget(ncinfile.ncfid,NC_GLOBAL,"NumFilesInSet",
                 (void *)&nfiles2)==(-1))
    {
        if (*nfiles==1)
        {
            fprintf(stderr,"Error: missing the \"NumFilesInSet\" global attribute!\n");
            return(1);
        }
        else if (*nfiles==(-1))
        {
            fprintf(stderr,"Warning: missing the \"NumFilesInSet\" global attribute.\n");
        }
    }
    *nfiles=nfiles2;

    /* Get some general information about the input netCDF file */
    if (ncinquire(ncinfile.ncfid,&(ncinfile.ndims),&(ncinfile.nvars),
                  &(ncinfile.ngatts),&(ncinfile.recdim))==(-1))
    {
        fprintf(stderr,"Error: cannot read the file's metadata!\n");
        ncclose(ncinfile.ncfid);
        return(1);
    }

    /* Get some information about the dimensions */
    for (d=0; d < ncinfile.ndims; d++)
    {
        if ((ncdiminq(ncinfile.ncfid,d,ncinfile.dimname[d],
                      &(ncinfile.dimsize[d])))==(-1))
        {
            fprintf(stderr,"Error: cannot read dimension #%d's metadata!\n",d);
            ncclose(ncinfile.ncfid);
            return(1);
        }
        ncinfile.dimfullsize[d]=ncinfile.dimsize[d];
        ncinfile.dimstart[d]=1;
        ncinfile.dimend[d]=(-1);
    }

    /* Get some information about the variables */
    for (v=0; v < ncinfile.nvars; v++)
    {
        if ((ncvarinq(ncinfile.ncfid,v,ncinfile.varname[v],
                      &(ncinfile.datatype[v]),&(ncinfile.varndims[v]),
                      ncinfile.vardim[v],&(ncinfile.natts[v])))==(-1))
        {
            fprintf(stderr,"Error: cannot read variable #%d's metadata!\n",v);
            ncclose(ncinfile.ncfid);
            return(1);
        }

        /* If the variable is also a dimension then get decomposition info */
        if ((dimid=ncdimid(ncinfile.ncfid,ncinfile.varname[v]))!=(-1))
        {
            if (ncattget(ncinfile.ncfid,v,"domain_decomposition",
                         (void *)decomp)!=(-1))
            {
                ncinfile.dimfullsize[dimid]=decomp[1]-decomp[0]+1;
                ncinfile.dimstart[dimid]=decomp[2]-(decomp[0]-1);
                ncinfile.dimend[dimid]=decomp[3]-(decomp[0]-1);
            }
            else
            {
                ncinfile.dimfullsize[dimid]=ncinfile.dimsize[dimid];
                ncinfile.dimstart[dimid]=1;
                ncinfile.dimend[dimid]=(-1);
            }
        }
    }

#if DEBUG==1
    print_debug(&ncinfile,verbose);
#endif

    /* If the output netCDF file was just created then define its structure */
    if (!appendnc)
    {
#if DEBUG==1
        printf("Creating output netCDF file... \"%s\"\n",outncname);
#endif
        /* Define the dimensions */
        for (d=0; d < ncinfile.ndims; d++)
        {
            if (d==ncinfile.recdim)
                ncdimdef(outncfid,ncinfile.dimname[d],NC_UNLIMITED);
            else ncdimdef(outncfid,ncinfile.dimname[d],ncinfile.dimfullsize[d]);
        }

        /* Define the variables and copy their attributes */
        for (v=0; v < ncinfile.nvars; v++)
        {
            ncvardef(outncfid,ncinfile.varname[v],ncinfile.datatype[v],
                     ncinfile.varndims[v],ncinfile.vardim[v]);
            for (n=0; n < ncinfile.natts[v]; n++)
            {
                ncattname(ncinfile.ncfid,v,n,attname);
                if (!strcmp(attname,"domain_decomposition")) continue;
                else
                {
                    if (ncattcopy(ncinfile.ncfid,v,attname,outncfid,v)==(-1))
                    {
                        fprintf(stderr,"Error: cannot copy variable \"%s\"'s attributes!\n",
                                ncinfile.varname[v]);
                        return(1);
                    }
                }
            }
        }

        /* Copy the global attributes */
        for (n=0; n < ncinfile.ngatts; n++)
        {
            ncattname(ncinfile.ncfid,NC_GLOBAL,n,attname);
            if (!strcmp(attname,"NumFilesInSet")) continue;
            else if (!strcmp(attname,"filename"))
                ncattput(outncfid,NC_GLOBAL,attname,NC_CHAR,strlen(outncname),
                         (void *)outncname);
            else
            {
                if (ncattcopy(ncinfile.ncfid,NC_GLOBAL,attname,outncfid,
                              NC_GLOBAL)==(-1))
                {
                    fprintf(stderr,"Error: cannot copy the file's global attributes!\n");
                    return(1);
                }
            }
        }

        /* Definitions done */
        ncendef(outncfid);
    }

    /* Copy all the data values of the dimensions and variables */
    ncinfileerror=copy_nc_data(&ncinfile,outncfid,appendnc,verbose);

    /* Done */
    ncclose(ncinfile.ncfid);
    return(ncinfileerror);
}
Esempio n. 25
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : get_num_minmax_values
@INPUT      : reshape_info - information for reshaping volume
              block_start - start for a block (or NULL)
              block_count - count for a block
@OUTPUT     : num_min_values - number of image-min values to be read
              num_max_values - number of image-max values to be read
@RETURNS    : (nothing)
@DESCRIPTION: Gets the number of image-min and image-max values that
              correspond to a block. If block_start is NULL, then
              it is assumed to translate to an input start of [0,0,...]. 
              Note that only the true number of values for the specified 
              block is computed (specifying a hyperslab that goes beyond 
              file extents does not give a bigger number of values).
@METHOD     :
@GLOBALS    :
@CALLS      :
@CREATED    : October 25, 1994 (Peter Neelin)
@MODIFIED   :
---------------------------------------------------------------------------- */
static void get_num_minmax_values(Reshape_info *reshape_info,
                                  long *block_start, long *block_count,
                                  long *num_min_values, long *num_max_values)
{
   int iloop, idim, ndims;
   int varid, inimgid;
   long size;
   long minmax_count[MAX_VAR_DIMS];
   long input_block_start[MAX_VAR_DIMS];
   long input_block_count[MAX_VAR_DIMS];
   long *num_values;

   /* Check for icv normalization */
   if (reshape_info->do_icv_normalization) {
      *num_min_values = 0;
      *num_max_values = 0;
      return;
   }

   /* Translate output block count to input count */
   translate_output_to_input(reshape_info, block_start, block_count, 
                             input_block_start, input_block_count);
   if (block_start != NULL) {
      truncate_input_vectors(reshape_info, input_block_start, 
                             input_block_count);
   }
   inimgid = ncvarid(reshape_info->inmincid, MIimage);

   /* Loop over image-min and image-max */

   for (iloop=0; iloop < 2; iloop++) {

      /* Get varid and pointer to return value */
      ncopts = 0;
      switch (iloop) {
      case 0: 
         varid = ncvarid(reshape_info->inmincid, MIimagemin); 
         num_values = num_min_values;        /* Pointer to long */
         break;
      case 1: 
         varid = ncvarid(reshape_info->inmincid, MIimagemax);
         num_values = num_max_values;        /* Pointer to long */
         break;
      }
      ncopts = NCOPTS_DEFAULT;

      /* Translate block count to min or max count and work out the
         total number of values. */
      size = 0;
      if (varid != MI_ERROR) {
         (void) ncvarinq(reshape_info->inmincid, varid, NULL, NULL, 
                         &ndims, NULL, NULL);
         (void) mitranslate_coords(reshape_info->inmincid,
                                   inimgid, input_block_count,
                                   varid, minmax_count);
         size = 1;
         for (idim=0; idim < ndims; idim++) {
            size *= minmax_count[idim];
         }
      }
      *num_values = size;
   }

}
Esempio n. 26
0
int
main(int argc, char **argv)
{
    /* NIFTI stuff */
    nifti_image *nii_ptr;
    nifti_image nii_rec;
    int nii_dimids[MAX_NII_DIMS];
    int nii_dir[MAX_NII_DIMS];
    int nii_map[MAX_NII_DIMS];
    unsigned long nii_lens[MAX_NII_DIMS];
    int nii_ndims;
    static int nifti_filetype;
    static int nifti_datatype;
    static int nifti_signed = 1;

    /* MINC stuff */
    int mnc_fd;                 /* MINC file descriptor */
    nc_type mnc_type;           /* MINC data type as read */
    int mnc_ndims;              /* MINC image dimension count */
    int mnc_dimids[MAX_VAR_DIMS]; /* MINC image dimension identifiers */
    long mnc_dlen;              /* MINC dimension length value */
    double mnc_dstep;           /* MINC dimension step value */
    int mnc_icv;                /* MINC image conversion variable */
    int mnc_vid;                /* MINC Image variable ID */
    long mnc_start[MAX_VAR_DIMS]; /* MINC data starts */
    long mnc_count[MAX_VAR_DIMS]; /* MINC data counts */
    int mnc_signed;             /* MINC if output voxels are signed */
    double real_range[2];       /* MINC real range (min, max) */
    double input_valid_range[2]; /* MINC valid range (min, max) */
    double output_valid_range[2]; /* Valid range of output data. */
    double nifti_slope;         /* Slope to be applied to output voxels. */
    double nifti_inter;         /* Intercept to be applied to output voxels. */
    double total_valid_range;   /* Overall valid range (max - min). */
    double total_real_range;    /* Overall real range (max - min). */

    /* Other stuff */
    char out_str[1024];         /* Big string for filename */
    char att_str[1024];         /* Big string for attribute values */
    int i;                      /* Generic loop counter the first */
    int j;                      /* Generic loop counter the second */
    char *str_ptr;              /* Generic ASCIZ string pointer */
    int r;                      /* Result code. */
    static int vflag = 0;       /* Verbose flag (default is quiet) */

    static ArgvInfo argTable[] = {
        {NULL, ARGV_HELP, NULL, NULL,
         "Output voxel data type specification"},
        {"-byte", ARGV_CONSTANT, (char *)DT_INT8, (char *)&nifti_datatype,
         "Write voxel data in 8-bit signed integer format."},
        {"-short", ARGV_CONSTANT, (char *)DT_INT16, (char *)&nifti_datatype,
         "Write voxel data in 16-bit signed integer format."},
        {"-int", ARGV_CONSTANT, (char *)DT_INT32, (char *)&nifti_datatype,
         "Write voxel data in 32-bit signed integer format."},
        {"-float", ARGV_CONSTANT, (char *)DT_FLOAT32, (char *)&nifti_datatype,
         "Write voxel data in 32-bit floating point format."},
        {"-double", ARGV_CONSTANT, (char *)DT_FLOAT64, (char *)&nifti_datatype,
         "Write voxel data in 64-bit floating point format."},
        {"-signed", ARGV_CONSTANT, (char *)1, (char *)&nifti_signed,
         "Write integer voxel data in signed format."},
        {"-unsigned", ARGV_CONSTANT, (char *)0, (char *)&nifti_signed,
         "Write integer voxel data in unsigned format."},
        {NULL, ARGV_HELP, NULL, NULL,
         "Output file format specification"},
        {"-dual", ARGV_CONSTANT, (char *)FT_NIFTI_DUAL, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 two-file format (.img and .hdr)"},
        {"-ASCII", ARGV_CONSTANT, (char *)FT_NIFTI_ASCII, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 ASCII header format (.nia)"},
        {"-nii", ARGV_CONSTANT, (char *)FT_NIFTI_SINGLE, 
         (char *)&nifti_filetype,
         "Write NIfTI-1 one-file format (.nii)"},
        {"-analyze", ARGV_CONSTANT, (char *)FT_ANALYZE, 
         (char *)&nifti_filetype,
         "Write an Analyze two-file format file (.img and .hdr)"},
        {NULL, ARGV_HELP, NULL, NULL,
         "Other options"},
        {"-quiet", ARGV_CONSTANT, (char *)0, 
         (char *)&vflag,
         "Quiet operation"},
        {"-verbose", ARGV_CONSTANT, (char *)1, 
         (char *)&vflag,
         "Quiet operation"},
        {NULL, ARGV_END, NULL, NULL, NULL}
    };

    ncopts = 0;                 /* Clear global netCDF error reporting flag */

    /* Default NIfTI file type is "NII", single binary file
     */
    nifti_filetype = FT_UNSPECIFIED;
    nifti_datatype = DT_UNKNOWN;

    if (ParseArgv(&argc, argv, argTable, 0) || (argc < 2)) {
        fprintf(stderr, "Too few arguments\n");
        return usage();
    }

    if (!nifti_signed) {
        switch (nifti_datatype) {
        case DT_INT8:
            nifti_datatype = DT_UINT8;
            break;
        case DT_INT16:
            nifti_datatype = DT_UINT16;
            break;
        case DT_INT32:
            nifti_datatype = DT_UINT32;
            break;
        }
    }
    switch (nifti_datatype){
    case DT_INT8:
    case DT_UINT8:
        mnc_type = NC_BYTE;
        break;
    case DT_INT16:
    case DT_UINT16:
        mnc_type = NC_SHORT;
        break;
    case DT_INT32:
    case DT_UINT32:
        mnc_type = NC_INT;
        break;
    case DT_FLOAT32:
        mnc_type = NC_FLOAT;
        break;
    case DT_FLOAT64:
        mnc_type = NC_DOUBLE;
        break;
    }

    if (argc == 2) {
        strcpy(out_str, argv[1]);
        str_ptr = strrchr(out_str, '.');
        if (str_ptr != NULL && !strcmp(str_ptr, ".mnc")) {
            *str_ptr = '\0';
        }
    }
    else if (argc == 3) {
        strcpy(out_str, argv[2]);
        str_ptr = strrchr(out_str, '.');
        if (str_ptr != NULL) {
            /* See if a recognized file extension was specified.  If so,
             * we trim it off and set the output file type if none was
             * specified.  If the extension is not recognized, assume
             * that we will form the filename by just adding the right
             * extension for the selected output format.
             */
            if (!strcmp(str_ptr, ".nii")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_SINGLE;
                }
                *str_ptr = '\0';
            }
            else if (!strcmp(str_ptr, ".img") || 
                     !strcmp(str_ptr, ".hdr")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_DUAL;
                }
                *str_ptr = '\0';
            }
            else if (!strcmp(str_ptr, ".nia")) {
                if (nifti_filetype == FT_UNSPECIFIED) {
                    nifti_filetype = FT_NIFTI_ASCII;
                }
                *str_ptr = '\0';
            }
        }
    }
    else {
        fprintf(stderr, "Filename argument required\n");
        return usage();
    }

    /* Open the MINC file.  It needs to exist.
     */
    mnc_fd = miopen(argv[1], NC_NOWRITE);
    if (mnc_fd < 0) {
        fprintf(stderr, "Can't find input file '%s'\n", argv[1]);
        return (-1);
    }

    /* Find the MINC image variable.  If we can't find it, there is no
     * further processing possible...
     */
    mnc_vid = ncvarid(mnc_fd, MIimage);
    if (mnc_vid < 0) {
        fprintf(stderr, "Can't locate the image variable (mnc_vid=%d)\n", mnc_vid);
        return (-1);
    }

    /* Find out about the MINC image variable - specifically, how many
     * dimensions, and which dimensions.
     */
    r = ncvarinq(mnc_fd, mnc_vid, NULL, NULL, &mnc_ndims, mnc_dimids, NULL);
    if (r < 0) {
        fprintf(stderr, "Can't read information from image variable\n");
        return (-1);
    }
    if (mnc_ndims > MAX_NII_DIMS) {
        fprintf(stderr, "NIfTI-1 files may contain at most %d dimensions\n", 
                MAX_NII_DIMS);
        return (-1);
    }

    /* Initialize the NIfTI structure 
     */
    nii_ptr = &nii_rec;

    init_nifti_header(nii_ptr);

    /* For now we just use the mnc2nii command line as the description
     * field.  Probably we should use something better, perhaps a
     * combination of some other standard MINC fields that might
     * provide more information.
     */
    str_ptr = nii_ptr->descrip;
    for (i = 0; i < argc; i++) {
        char *arg_ptr = argv[i];

        if ((str_ptr - nii_ptr->descrip) >= MAX_NII_DESCRIP) {
            break;
        }

        if (i != 0) {
            *str_ptr++ = ' ';
        }

        while (*arg_ptr != '\0' && 
               (str_ptr - nii_ptr->descrip) < MAX_NII_DESCRIP) {
            *str_ptr++ = *arg_ptr++;
        }
        *str_ptr = '\0';
    }

    nii_ptr->fname = malloc(strlen(out_str) + 4 + 1);
    nii_ptr->iname = malloc(strlen(out_str) + 4 + 1);
    strcpy(nii_ptr->fname, out_str);
    strcpy(nii_ptr->iname, out_str);

    switch (nifti_filetype) {
    case FT_ANALYZE:
        strcat(nii_ptr->fname, ".hdr");
        strcat(nii_ptr->iname, ".img");
        break;
    case FT_NIFTI_SINGLE:
        strcat(nii_ptr->fname, ".nii");
        strcat(nii_ptr->iname, ".nii");
        break;
    case FT_NIFTI_DUAL:
        strcat(nii_ptr->fname, ".hdr");
        strcat(nii_ptr->iname, ".img");
        break;
    case FT_NIFTI_ASCII:
        strcat(nii_ptr->fname, ".nia");
        strcat(nii_ptr->iname, ".nia");
        break;
    default:
        fprintf(stderr, "Unknown output file type %d\n", nifti_filetype);
        return (-1);
    }

    /* Get real voxel range for the input file.
     */
    miget_image_range(mnc_fd, real_range);

    /* Get the actual valid voxel value range.
     */
    miget_valid_range(mnc_fd, mnc_vid, input_valid_range);

    /* Find the default range for the output type. Our output file
     * will use the full legal range of the output type if it is
     * an integer.
     */

    if (nifti_datatype == DT_UNKNOWN) {
        nii_ptr->datatype = DT_FLOAT32; /* Default */
        mnc_type = NC_FLOAT;
        mnc_signed = 1;
    }
    else {
        nii_ptr->datatype = nifti_datatype;
        mnc_signed = nifti_signed;
    }

    if (vflag) {
        fprintf(stderr, "MINC type %d signed %d\n", mnc_type, mnc_signed);
    }

    miget_default_range(mnc_type, mnc_signed, output_valid_range);

    total_valid_range = input_valid_range[1] - input_valid_range[0];
    total_real_range = real_range[1] - real_range[0];

    if ((output_valid_range[1] - output_valid_range[0]) > total_valid_range) {
        /* Empirically, forcing the valid range to be the nearest power
         * of two greater than the existing valid range seems to improve
         * the behavior of the conversion. This is at least in part because
         * of the limited precision of the NIfTI-1 voxel scaling fields.
         */
        double new_range = nearest_power_of_two(total_valid_range);
        if (new_range - 1.0 >= total_valid_range) {
            new_range -= 1.0;
        }

        if (output_valid_range[1] > total_valid_range) {
            output_valid_range[0] = 0;
            output_valid_range[1] = new_range;
        }
        else {
            output_valid_range[1] = output_valid_range[0] + new_range;
        }
    }
    else {
        /* The new range can't fully represent the input range. Use the 
         * full available range, and warn the user that they may have a
         * problem.
         */
        printf("WARNING: Range of input exceeds range of output format.\n");
    }

    if (vflag) {
        printf("Real range: %f %f Input valid range: %f %f Output valid range: %f %f\n",
               real_range[0], real_range[1],
               input_valid_range[0], input_valid_range[1],
               output_valid_range[0], output_valid_range[1]);
    }

    /* If the output type is not floating point, we may need to scale the
     * voxel values.
     */

    if (mnc_type != NC_FLOAT && mnc_type != NC_DOUBLE) {

        /* Figure out how to map pixel values into the range of the 
         * output datatype.
         */
        nifti_slope = ((real_range[1] - real_range[0]) / 
                       (output_valid_range[1] - output_valid_range[0]));

        if (nifti_slope == 0.0) {
            nifti_slope = 1.0;
        }
        nifti_inter = real_range[0] - (output_valid_range[0] * nifti_slope);

        /* One problem with NIfTI-1 is the limited precision of the 
         * scl_slope and scl_inter fields (they are just 32-bits). So
         * we look for possible issues and warn about that here.
         */
        if (nifti_inter != (float) nifti_inter || 
            nifti_slope != (float) nifti_slope) {
            double epsilon_i = nifti_inter - (float) nifti_inter;
            double epsilon_s = nifti_slope - (float) nifti_slope;

            /* If the loss in precision is more than one part per thousand
             * of the real range, flag this as a problem!
             */
            if ((epsilon_i > total_real_range / 1.0e3) ||
                (epsilon_s > total_real_range / 1.0e3)) {
                fprintf(stderr, "ERROR: Slope and intercept cannot be represented in the NIfTI-1 header.\n");
                fprintf(stderr, "      slope %f (%f), intercept %f (%f)\n", 
                        nifti_slope, (float) nifti_slope,
                        nifti_inter, (float) nifti_inter);
                return (-1);
            }
        }
    }
    else {
        nifti_slope = 0.0;
    }

    nii_ptr->scl_slope = nifti_slope;
    nii_ptr->scl_inter = nifti_inter;

    nii_ptr->nvox = 1;          /* Initial value for voxel count */

    /* Find all of the dimensions of the MINC file, in the order they 
     * will be listed in the NIfTI-1/Analyze file.  We use this to build
     * a map for restructuring the data according to the normal rules
     * of NIfTI-1.
     */
    nii_ndims = 0;
    for (i = 0; i < MAX_NII_DIMS; i++) {
        if (dimnames[i] == NULL) {
            nii_dimids[nii_ndims] = -1;
            continue;
        }

        nii_dimids[nii_ndims] = ncdimid(mnc_fd, dimnames[i]);
        if (nii_dimids[nii_ndims] == -1) {
            continue;
        }

        /* Make sure the dimension is actually used to define the image.
         */
        for (j = 0; j < mnc_ndims; j++) {
            if (nii_dimids[nii_ndims] == mnc_dimids[j]) {
                nii_map[nii_ndims] = j;
                break;
            }
        }

        if (j < mnc_ndims) {
            mnc_dlen = 1;
            mnc_dstep = 0;

            ncdiminq(mnc_fd, nii_dimids[nii_ndims], NULL, &mnc_dlen);
            ncattget(mnc_fd, ncvarid(mnc_fd, dimnames[i]), MIstep, &mnc_dstep);

            if (mnc_dstep < 0) {
                nii_dir[nii_ndims] = -1;
                mnc_dstep = -mnc_dstep;
            }
            else {
                nii_dir[nii_ndims] = 1;
            }

            nii_lens[nii_ndims] = mnc_dlen;
            nii_ndims++;
        }

        nii_ptr->dim[dimmap[i]] = (int) mnc_dlen;
        nii_ptr->nvox *= mnc_dlen;

        nii_ptr->pixdim[dimmap[i]] = (float) mnc_dstep;
    }

    /* Here we do some "post-processing" of the results. Make certain that
     * the nt value is never zero, and make certain that ndim is set to
     * 4 if there is a time dimension and 5 if there is a vector dimension
     */

    if (nii_ptr->dim[3] > 1 && nii_ndims < 4) {
        nii_ndims = 4;
    }

    if (nii_ptr->dim[4] > 1) {
        nii_ptr->intent_code = NIFTI_INTENT_VECTOR;
        nii_ndims = 5;
    }

    nii_ptr->ndim = nii_ndims; /* Total number of dimensions in file */
    nii_ptr->nx = nii_ptr->dim[0];
    nii_ptr->ny = nii_ptr->dim[1];
    nii_ptr->nz = nii_ptr->dim[2];
    nii_ptr->nt = nii_ptr->dim[3];
    nii_ptr->nu = nii_ptr->dim[4];

    nii_ptr->dx = nii_ptr->pixdim[0];
    nii_ptr->dy = nii_ptr->pixdim[1];
    nii_ptr->dz = nii_ptr->pixdim[2];
    nii_ptr->dt = nii_ptr->pixdim[3];
    nii_ptr->du = 1; /* MINC files don't define a sample size for a vector_dimension */

    nii_ptr->nifti_type = nifti_filetype;

    /* Load the direction_cosines and start values into the NIfTI-1 
     * sform structure.
     *
     */
    for (i = 0; i < MAX_SPACE_DIMS; i++) {
        int id = ncvarid(mnc_fd, mnc_spatial_names[i]);
        double start;
        double step;
        double dircos[MAX_SPACE_DIMS];
        int tmp;

        if (id < 0) {
            continue;
        }

        /* Set default values */
        start = 0.0;
        step = 1.0;
        dircos[DIM_X] = dircos[DIM_Y] = dircos[DIM_Z] = 0.0;
        dircos[i] = 1.0;

        miattget(mnc_fd, id, MIstart, NC_DOUBLE, 1, &start, &tmp);
        miattget(mnc_fd, id, MIstep, NC_DOUBLE, 1, &step, &tmp);
        miattget(mnc_fd, id, MIdirection_cosines, NC_DOUBLE, MAX_SPACE_DIMS, 
                 dircos, &tmp);
        ncdiminq(mnc_fd, ncdimid(mnc_fd, mnc_spatial_names[i]), NULL, 
                 &mnc_dlen);

        if (step < 0) {
            step = -step;
            start = start - step * (mnc_dlen - 1);
        }

        nii_ptr->sto_xyz.m[0][i] = step * dircos[0];
        nii_ptr->sto_xyz.m[1][i] = step * dircos[1];
        nii_ptr->sto_xyz.m[2][i] = step * dircos[2];

        nii_ptr->sto_xyz.m[0][3] += start * dircos[0];
        nii_ptr->sto_xyz.m[1][3] += start * dircos[1];
        nii_ptr->sto_xyz.m[2][3] += start * dircos[2];

        miattgetstr(mnc_fd, id, MIspacetype, sizeof(att_str), att_str);

        /* Try to set the S-transform code correctly.
         */
        if (!strcmp(att_str, MI_TALAIRACH)) {
            nii_ptr->sform_code = NIFTI_XFORM_TALAIRACH;
        }
        else if (!strcmp(att_str, MI_CALLOSAL)) {
            /* TODO: Not clear what do do here... */
            nii_ptr->sform_code = NIFTI_XFORM_SCANNER_ANAT;
        }
        else {                  /* MI_NATIVE or unknown */
            nii_ptr->sform_code = NIFTI_XFORM_SCANNER_ANAT;
        }
    }

    /* So the last row is right... */
    nii_ptr->sto_xyz.m[3][0] = 0.0;
    nii_ptr->sto_xyz.m[3][1] = 0.0;
    nii_ptr->sto_xyz.m[3][2] = 0.0;
    nii_ptr->sto_xyz.m[3][3] = 1.0;

    nii_ptr->sto_ijk = nifti_mat44_inverse(nii_ptr->sto_xyz);

    nifti_datatype_sizes(nii_ptr->datatype, 
                         &nii_ptr->nbyper, &nii_ptr->swapsize);


    if (vflag) {
        nifti_image_infodump(nii_ptr);
    }

    /* Now load the actual MINC data. */

    nii_ptr->data = malloc(nii_ptr->nbyper * nii_ptr->nvox);
    if (nii_ptr->data == NULL) {
        fprintf(stderr, "Out of memory.\n");
        return (-1);
    }

    mnc_icv = miicv_create();
    miicv_setint(mnc_icv, MI_ICV_TYPE, mnc_type);
    miicv_setstr(mnc_icv, MI_ICV_SIGN, (mnc_signed) ? MI_SIGNED : MI_UNSIGNED);
    miicv_setdbl(mnc_icv, MI_ICV_VALID_MAX, output_valid_range[1]);
    miicv_setdbl(mnc_icv, MI_ICV_VALID_MIN, output_valid_range[0]);
    miicv_setdbl(mnc_icv, MI_ICV_IMAGE_MAX, real_range[1]);
    miicv_setdbl(mnc_icv, MI_ICV_IMAGE_MIN, real_range[0]);
    miicv_setdbl(mnc_icv, MI_ICV_DO_NORM, TRUE);
    miicv_setdbl(mnc_icv, MI_ICV_USER_NORM, TRUE);

    miicv_attach(mnc_icv, mnc_fd, mnc_vid);

    /* Read in the entire hyperslab from the file.
     */
    for (i = 0; i < mnc_ndims; i++) {
        ncdiminq(mnc_fd, mnc_dimids[i], NULL, &mnc_count[i]);
        mnc_start[i] = 0;
    }

    r = miicv_get(mnc_icv, mnc_start, mnc_count, nii_ptr->data);
    if (r < 0) {
        fprintf(stderr, "Read error\n");
        return (-1);
    }

    /* Shut down the MINC stuff now that it has done its work. 
     */
    miicv_detach(mnc_icv);
    miicv_free(mnc_icv);
    miclose(mnc_fd);

    if (vflag) {
        /* Debugging stuff - just to check the contents of these arrays.
         */
        for (i = 0; i < nii_ndims; i++) {
            printf("%d: %ld %d %d\n", 
                   i, nii_lens[i], nii_map[i], nii_dir[i]);
        }
        printf("bytes per voxel %d\n", nii_ptr->nbyper);
        printf("# of voxels %ld\n", nii_ptr->nvox);
    }

    /* Rearrange the data to correspond to the NIfTI dimension ordering.
     */
    restructure_array(nii_ndims,
                      nii_ptr->data,
                      nii_lens,
                      nii_ptr->nbyper,
                      nii_map,
                      nii_dir);

    if (vflag) {
        /* More debugging stuff - check coordinate transform.
         */
        test_xform(nii_ptr->sto_xyz, 0, 0, 0);
        test_xform(nii_ptr->sto_xyz, 10, 0, 0);
        test_xform(nii_ptr->sto_xyz, 0, 10, 0);
        test_xform(nii_ptr->sto_xyz, 0, 0, 10);
        test_xform(nii_ptr->sto_xyz, 10, 10, 10);
    }

    if (vflag) {
        fprintf(stdout, "Writing NIfTI-1 file...");
    }
    nifti_image_write(nii_ptr);
    if (vflag) {
        fprintf(stdout, "done.\n");
    }

    return (0);
}
Esempio n. 27
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : FinishExclusionLists
@INPUT      : ParentCDF
              NumChildDims
              ChildDimNames
@OUTPUT     : NumExclude
              Exclude
@RETURNS    : 
@DESCRIPTION: Finishes off the list of variables to exclude from mass
              copying from parent to child file.  This includes
              dimension and dimension-width variables associated with
              dimensions in the parent file that don't exist in the
              child file; and the obvious ones not to copy:
              MIrootvariable, MIimage, MIimagemax, MIimagemin.
@METHOD     : 
@GLOBALS    : 
@CALLS      : MINC/NetCDF stuff
@CREATED    : fall 1993, Greg Ward
@MODIFIED   : 
---------------------------------------------------------------------------- */
void FinishExclusionLists (int ParentCDF,
			   int NumChildDims, char *ChildDimNames[],
			   int *NumExclude, int Exclude[])
{
   int	NumParentDims;
   int	CurParentDim;
   char ParentDimName [MAX_NC_NAME];
   char ParentVarName [MAX_NC_NAME];
   int	ParentVar;
   int	WidthVar;
   int	CurChildDim;
   int	DimMatch;

#ifdef DEBUG
   int  i;

   printf ("FinishExclusionLists\n");
   printf (" Initial list of variables to exclude from copying:\n");
   for (i = 0; i < *NumExclude; i++)
   {
      ParentVar = Exclude [i];
      ncvarinq (ParentCDF, ParentVar, ParentVarName, NULL, NULL, NULL, NULL);
      printf ("  %s (ID %d)\n", ParentVarName, ParentVar);
   }
   putchar ('\n');
#endif

   /* 
    * Find all dimensions in the parent file, and for any that do not
    * have a corresponding dimension in the child file (using 
    * ChildDimNames[] to match), add that parent dimension to both
    * exclusion lists.
    */

#ifdef DEBUG
   printf (" Looking for unmatched parent dimensions...\n");
#endif

   ncinquire (ParentCDF, &NumParentDims, NULL, NULL, NULL);
   for (CurParentDim = 0; CurParentDim < NumParentDims; CurParentDim++)
   {
      ncdiminq (ParentCDF, CurParentDim, ParentDimName, NULL);

#ifdef DEBUG
      printf ("  Checking parent dimension %d (%s)\n", 
	      CurParentDim, ParentDimName);
#endif

      /* 
       * Get the ID's of the variables with the same name as this
       * dimension, and with the dimension name + "-width" -- these
       * will be needed if we are to add anything to the exclusion lists
       */

      strcpy (ParentVarName, ParentDimName);
      ParentVar = ncvarid (ParentCDF, ParentVarName);

      strcat (ParentVarName, "-width");
      WidthVar = ncvarid (ParentCDF, ParentVarName);

      /* Skip to next parent dimension if NEITHER one was found */

      if ((ParentVar == -1) && (WidthVar == -1))
      {
	 continue;
      }

#ifdef DEBUG
      printf ("  Dimension variable ID: %d; dimension-width variable ID: %d\n",
	      ParentVar, WidthVar);
#endif

      /* 
       * Loop through the names of the dimensions in the child file,
       * stopping only when we find one that matches ParentDimName
       * (or have gone through all the child's dimensions)
       */

      CurChildDim = 0;
      do
      {
#ifdef DEBUG
	 printf ("   Comparing with child dimension %d (%s)\n",
		 CurChildDim, ChildDimNames[CurChildDim]);
#endif
	 DimMatch = strcmp (ParentDimName, ChildDimNames[CurChildDim]);
	 CurChildDim++;
      } while ((DimMatch != 0) && (CurChildDim < NumChildDims));

      /*
       * If we got here without finding a dimension in the child file  
       * with the same name is the current dimension in the parent file,
       * then add this dimension's dimension and dimension-width variables
       * to both exclusion lists (but only if these variables actually
       * exist!)
       */

      if (DimMatch != 0)
      {
	 if (ParentVar != -1)
	 {
	    Exclude [(*NumExclude)++] = ParentVar;
	 }

	 if (WidthVar != -1)
	 {
	    Exclude [(*NumExclude)++] = WidthVar;
	 }
      }
   }     /* for CurParentDim */

   /* 
    * Now add all the obvious ones: MIrootvariable, MIimage, 
    * MIimagemax, MIimagemin 
    */

   ParentVar = ncvarid (ParentCDF, MIrootvariable);
   if (ParentVar != -1)
   {
      Exclude [(*NumExclude)++] = ParentVar;
   }
   
   ParentVar = ncvarid (ParentCDF, MIimage);
   if (ParentVar != -1)
   {
      Exclude [(*NumExclude)++] = ParentVar;
   }
   
   ParentVar = ncvarid (ParentCDF, MIimagemax);
   if (ParentVar != -1)
   {
      Exclude [(*NumExclude)++] = ParentVar;
   }
   
   ParentVar = ncvarid (ParentCDF, MIimagemin);
   if (ParentVar != -1)
   {
      Exclude [(*NumExclude)++] = ParentVar;
   }
   

#ifdef DEBUG
   printf (" Final list of variables to exclude from copying:\n");
   for (i = 0; i < *NumExclude; i++)
   {
      ParentVar = Exclude [i];
      ncvarinq (ParentCDF, ParentVar, ParentVarName, NULL, NULL, NULL, NULL);
      printf ("  %s (ID %d)\n", ParentVarName, ParentVar);
   }
   putchar ('\n');
#endif

}     /* FinishExclusionLists () */
Esempio n. 28
0
int main(int argc, char *argv[])
{
   char *filename;
   int mincid, imgid, icvid, ndims, dims[MAX_VAR_DIMS];
   nc_type datatype;
   int is_signed;
   long start[MAX_VAR_DIMS], count[MAX_VAR_DIMS], end[MAX_VAR_DIMS];
   long size;
   int idim;
   void *data;
   double temp;

   /* Check arguments */
   if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) {
      (void) fprintf(stderr, "\nUsage: %s [<options>] <mincfile>\n", argv[0]);
      (void) fprintf(stderr,   "       %s -help\n\n", argv[0]);
      exit(EXIT_FAILURE);
   }
   filename = argv[1];

   /* Check that a normalization option was specified */
   if (normalize_output == VIO_BOOL_DEFAULT) {
      (void) fprintf(stderr, 
                     "Please specify either -normalize or -nonormalize\n");
      (void) fprintf(stderr, "Usually -normalize is most appropriate\n");
      exit(EXIT_FAILURE);
   }

   /* Open the file */
   mincid = miopen(filename, NC_NOWRITE);

   /* Inquire about the image variable */
   imgid = ncvarid(mincid, MIimage);
   (void) ncvarinq(mincid, imgid, NULL, NULL, &ndims, dims, NULL);
   (void)miget_datatype(mincid, imgid, &datatype, &is_signed);

   /* Check if arguments set */

   /* Get output data type */
   if (output_datatype == INT_MAX) output_datatype = datatype;

   /* Get output sign */ 
   if (output_signed == INT_MAX) {
      if (output_datatype == datatype)
         output_signed = is_signed;
      else 
         output_signed = (output_datatype != NC_BYTE);
   }

   /* Get output range */
   if (valid_range[0] == DBL_MAX) {
      if ((output_datatype == datatype) && (output_signed == is_signed)) {
         (void) miget_valid_range(mincid, imgid, valid_range);
      }
      else {
         (void) miget_default_range(output_datatype, output_signed, 
                                    valid_range);
      }
   }
   if (valid_range[0] > valid_range[1]) {
      temp = valid_range[0];
      valid_range[0] = valid_range[1];
      valid_range[1] = temp;
   }

   /* Set up image conversion */
   icvid = miicv_create();
   (void) miicv_setint(icvid, MI_ICV_TYPE, output_datatype);
   (void) miicv_setstr(icvid, MI_ICV_SIGN, (output_signed ? 
                                            MI_SIGNED : MI_UNSIGNED));
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MIN, valid_range[0]);
   (void) miicv_setdbl(icvid, MI_ICV_VALID_MAX, valid_range[1]);
   if ((output_datatype == NC_FLOAT) || (output_datatype == NC_DOUBLE)) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
      (void) miicv_setint(icvid, MI_ICV_USER_NORM, TRUE);
   }
   else if (normalize_output) {
      (void) miicv_setint(icvid, MI_ICV_DO_NORM, TRUE);
   }
   (void) miicv_attach(icvid, mincid, imgid);

   /* Set input file start, count and end vectors for reading a slice
      at a time */
   for (idim=0; idim < ndims; idim++) {
      (void) ncdiminq(mincid, dims[idim], NULL, &end[idim]);
   }
   (void) miset_coords(ndims, (long) 0, start);
   (void) miset_coords(ndims, (long) 1, count);
   size = nctypelen(output_datatype);
   for (idim=ndims-2; idim < ndims; idim++) {
      count[idim] = end[idim];
      size *= count[idim];
   }

   /* Allocate space */
   data = malloc(size);

   /* Loop over input slices */

   while (start[0] < end[0]) {

      /* Read in the slice */
      (void) miicv_get(icvid, start, count, data);

      /* Write out the slice */
      if (fwrite(data, sizeof(char), (size_t) size, stdout) != size) {
         (void) fprintf(stderr, "Error writing data.\n");
         exit(EXIT_FAILURE);
      }

      /* Increment start counter */
      idim = ndims-1;
      start[idim] += count[idim];
      while ( (idim>0) && (start[idim] >= end[idim])) {
         start[idim] = 0;
         idim--;
         start[idim] += count[idim];
      }

   }       /* End loop over slices */

   /* Clean up */
   (void) miclose(mincid);
   (void) miicv_free(icvid);
   free(data);

   exit(EXIT_SUCCESS);
}