/* regrid using a minc volume */ void regrid_minc(char *in_fn, int buffer_size, VIO_Volume * totals, VIO_Volume * weights, int v_size, double regrid_floor, double regrid_ceil) { Loop_Data ld; Loop_Options *loop_opt; int mincid; /* Open the file to get some information */ mincid = miopen(in_fn, NC_NOWRITE); ld.file_ndims = get_minc_ndims(mincid); get_minc_spatial_dims(mincid, ld.space_to_dim, ld.dim_to_space); get_minc_voxel_to_world(mincid, ld.voxel_to_world); /* alloc space for data_buf */ ld.data_buf = (double *)malloc(sizeof(double) * v_size); ld.floor = regrid_floor; ld.ceil = regrid_ceil; ld.totals = totals; ld.weights = weights; /* set up and do voxel_loop */ loop_opt = create_loop_options(); set_loop_first_input_mincid(loop_opt, mincid); set_loop_verbose(loop_opt, verbose); set_loop_buffer_size(loop_opt, (long)1024 * buffer_size); voxel_loop(1, &in_fn, 0, NULL, NULL, loop_opt, regrid_loop, (void *)&ld); free_loop_options(loop_opt); /* tidy up */ free(ld.data_buf); }
/* get info from a model file (steps, starts, etc */ int get_model_file_info(char *dst, char *key, char *nextArg) { int mincid; char *fname; /* Get pointer to volume definition structure */ Volume_Definition *vd = (Volume_Definition *) dst; /* Check for following argument */ if(nextArg == NULL){ (void)fprintf(stderr, "\"%s\" option requires an additional argument\n", key); exit(EXIT_FAILURE); } fname = nextArg; /* check that the file exists */ if(!file_exists(fname)){ fprintf(stderr, "Couldn't find -like file %s.\n\n", fname); exit(EXIT_FAILURE); } /* get volume definition from input filename */ mincid = miopen(fname, NC_NOWRITE); get_vol_def(mincid, vd); /* Close the file */ miclose(mincid); return TRUE; }
MNCAPI int minc_format_convert(const char *input,const char *output) { int old_fd; int new_fd; int flags; struct mi2opts opts; old_fd = miopen((char *)input, NC_NOWRITE); if (old_fd < 0) { perror(input); return MI_ERROR; } flags = NC_CLOBBER|MI2_CREATE_V2; memset(&opts,0,sizeof(struct mi2opts)); opts.struct_version = MI2_OPTS_V1; new_fd = micreatex((char *)output, flags, &opts); if (new_fd < 0) { perror(output); exit MI_ERROR; } micopy(old_fd, new_fd); miclose(old_fd); miclose(new_fd); return MI_NOERROR; }
MNCAPI int minc_get_world_transform(char *path, double transform[MINC_3D][MINC_3D+1]) { int i, j; double dircos[MINC_3D]; double step, start; char *dimensions[] = { MIxspace, MIyspace, MIzspace }; int length; int fd; int varid; int old_ncopts; old_ncopts =get_ncopts(); set_ncopts(0); fd = miopen(path, NC_NOWRITE); if (fd < 0) { set_ncopts(old_ncopts); return (MINC_STATUS_ERROR); } /* Zero the matrix */ for (i = 0; i < MINC_3D; i++) { for (j = 0; j < MINC_3D + 1; j++) { transform[i][j] = 0.0; } transform[i][i] = 1.0; } for (j = 0; j < MINC_3D; j++) { /* Set default values */ step = 1.0; start = 0.0; for (i = 0; i < MINC_3D; i++) { dircos[i] = 0.0; } dircos[j] = 1.0; varid = ncvarid(fd, dimensions[j]); miattget(fd, varid, MIstart, NC_DOUBLE, 1, &start, &length); miattget(fd, varid, MIstep, NC_DOUBLE, 1, &step, &length); miattget(fd, varid, MIdirection_cosines, NC_DOUBLE, 3, dircos, &length); normalize_vector(dircos); /* Put them in the matrix. */ for (i = 0; i < MINC_3D; i++) { transform[i][j] = step * dircos[i]; transform[i][MINC_3D] += start * dircos[i]; } } set_ncopts(old_ncopts); return (MINC_STATUS_OK); }
int main(int argc, char *argv[]) { char **input_files; char *output_file; char *arg_string; int num_input_files; int inmincid; Loop_Options *loop_options; Program_Data program_data; /* Save time stamp and args */ arg_string = time_stamp(argc, argv); /* Get arguments */ if (ParseArgv(&argc, argv, argTable, 0) || (argc < 3)) { (void) fprintf(stderr, "\nUsage: %s [options] <in1.mnc> [...] <out.mnc>\n", argv[0]); (void) fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } input_files = &argv[1]; num_input_files = argc - 2; output_file = argv[argc-1]; /* Open the first input file and get the vector length */ inmincid = miopen(input_files[0], NC_NOWRITE); if (get_vector_length(inmincid) > 1) { (void) fprintf(stderr, "Input file %s is not a scalar file\n", input_files[0]); exit(EXIT_FAILURE); } /* Set up looping options */ loop_options = create_loop_options(); set_loop_clobber(loop_options, clobber); set_loop_verbose(loop_options, verbose); #if MINC2 set_loop_v2format(loop_options, v2format); #endif /* MINC2 */ set_loop_datatype(loop_options, datatype, is_signed, valid_range[0], valid_range[1]); set_loop_output_vector_size(loop_options, num_input_files); set_loop_buffer_size(loop_options, (long) buffer_size * 1024); set_loop_first_input_mincid(loop_options, inmincid); set_loop_accumulate(loop_options, TRUE, 0, NULL, NULL); /* Do loop */ voxel_loop(num_input_files, input_files, 1, &output_file, arg_string, loop_options, do_makevector, (void *) &program_data); exit(EXIT_SUCCESS); }
/* ----------------------------- MNI Header ----------------------------------- @NAME : get_volume_info @INPUT : infile - input file name @OUTPUT : volume_info - input volume information @RETURNS : Id of icv created @DESCRIPTION: Routine to read volume information for a file. @METHOD : @GLOBALS : @CALLS : @CREATED : August 22, 1993 (Peter Neelin) @MODIFIED : ---------------------------------------------------------------------------- */ static int get_volume_info(char *infile, Volume_Info *volume_info) { int icvid, mincid; /* Create and set up icv for input */ icvid = miicv_create(); setup_input_icv(icvid); /* Open the image file */ mincid = miopen(infile, NC_NOWRITE); /* Attach the icv to the file */ (void) miicv_attach(icvid, mincid, ncvarid(mincid, MIimage)); /* Get dimension information */ get_dimension_info(infile, icvid, volume_info); /* Get the volume min and max */ (void) miicv_inqdbl(icvid, MI_ICV_NORM_MIN, &volume_info->minimum); (void) miicv_inqdbl(icvid, MI_ICV_NORM_MAX, &volume_info->maximum); return icvid; }
int main(int argc, char *argv[]) { char *infile, *outfile; char *arg_string; Loop_Options *loop_options; int inmincid; Lookup_Data lookup_data; /* Save time stamp and args */ arg_string = time_stamp(argc, argv); /* Get arguments */ if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) { (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n", argv[0]); (void) fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } infile = argv[1]; outfile = argv[2]; /* Get the appropriate lookup table */ if ((lookup_file != NULL) || (lookup_string != NULL)) { lookup_data.lookup_table = read_lookup_table(lookup_file, lookup_string); } else { switch (lookup_type) { case LU_GRAY: lookup_data.lookup_table = &gray_lookup; break; case LU_HOTMETAL: lookup_data.lookup_table = &hotmetal_lookup; break; case LU_SPECTRAL: lookup_data.lookup_table = &spectral_lookup; break; case LU_TABLE: break; default: fprintf(stderr, "Unknown lookup type: %d\n", lookup_type); break; } } /* Get the null value */ lookup_data.null_value = get_null_value(lookup_data.lookup_table->vector_length, null_value_string); /* Open the input file and get the range */ inmincid = miopen(infile, NC_NOWRITE); if (!discrete_lookup && (lookup_range[0] == DEFAULT_RANGE)) { get_full_range(inmincid, lookup_range); } if (lookup_min != DEFAULT_RANGE) lookup_range[0] = lookup_min; if (lookup_max != DEFAULT_RANGE) lookup_range[1] = lookup_max; /* Set up lookup information */ lookup_data.invert = invert_table; lookup_data.range[0] = lookup_range[0]; lookup_data.range[1] = lookup_range[1]; lookup_data.discrete = discrete_lookup; /* Set up looping options */ loop_options = create_loop_options(); set_loop_clobber(loop_options, clobber); set_loop_verbose(loop_options, verbose); #if MINC2 set_loop_v2format(loop_options, minc2_format); #endif /* MINC2 */ set_loop_datatype(loop_options, datatype, is_signed, valid_range[0], valid_range[1]); set_loop_convert_input_to_scalar(loop_options, TRUE); set_loop_output_vector_size(loop_options, lookup_data.lookup_table->vector_length); set_loop_buffer_size(loop_options, (long) buffer_size * 1024); set_loop_first_input_mincid(loop_options, inmincid); /* Do loop */ voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options, do_lookup, (void *) &lookup_data); /* Free stuff */ if (lookup_data.null_value != NULL) free(lookup_data.null_value); if (lookup_data.lookup_table->free_data) { free(lookup_data.lookup_table->table); free(lookup_data.lookup_table); } exit(EXIT_SUCCESS); }
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); }
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); }
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); }
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); }
int main(int argc, char *argv[]) { char *infile, *outfile; char *arg_string; int inmincid; int input_vector_length; int ivalue; Loop_Options *loop_options; Program_Data program_data; /* Save time stamp and args */ arg_string = time_stamp(argc, argv); /* Get arguments */ if (ParseArgv(&argc, argv, argTable, 0) || (argc != 3)) { (void) fprintf(stderr, "\nUsage: %s [options] <in.mnc> <out.mnc>\n", argv[0]); (void) fprintf(stderr, " %s -help\n\n", argv[0]); exit(EXIT_FAILURE); } infile = argv[1]; outfile = argv[2]; /* Check for conflicting options */ if ((conversion_type != CONV_DEFAULT) && (linear_coefficients.numvalues > 0)) { (void) fprintf(stderr, "Do not specify -linear with other conversion options\n"); exit(EXIT_FAILURE); } /* Set up conversion information */ if (conversion_type == CONV_DEFAULT) conversion_type = CONV_MAGNITUDE; program_data.conversion_type = conversion_type; program_data.num_coefficients = 0; program_data.linear_coefficients = NULL; /* Check for coefficients for linear combination */ if (linear_coefficients.numvalues > 0) { conversion_type = CONV_LINEAR; program_data.conversion_type = conversion_type; program_data.num_coefficients = linear_coefficients.numvalues; program_data.linear_coefficients = malloc(linear_coefficients.numvalues * sizeof(*program_data.linear_coefficients)); for (ivalue=0; ivalue < linear_coefficients.numvalues; ivalue++) { program_data.linear_coefficients[ivalue] = linear_coefficients.values[ivalue]; } } /* Open the input file and get the vector length */ inmincid = miopen(infile, NC_NOWRITE); input_vector_length = get_vector_length(inmincid); if (input_vector_length < 0) { fprintf(stderr, str_wrong_dimension_order); exit(EXIT_FAILURE); } if (input_vector_length < 1) input_vector_length = 1; /* Check that this length is okay */ if ((conversion_type == CONV_GREY) && (input_vector_length != 3) && (input_vector_length > 1)) { (void) fprintf(stderr, "Input file does not contain RGB data\n"); exit(EXIT_FAILURE); } if ((conversion_type == CONV_LINEAR) && (input_vector_length != program_data.num_coefficients) && (input_vector_length > 1)) { (void) fprintf(stderr, "Input vector length does not match number of linear coefficients\n"); exit(EXIT_FAILURE); } /* Set up looping options */ loop_options = create_loop_options(); set_loop_clobber(loop_options, clobber); set_loop_verbose(loop_options, verbose); #if MINC2 set_loop_v2format(loop_options, v2format); #endif /* MINC2 */ set_loop_datatype(loop_options, datatype, is_signed, valid_range[0], valid_range[1]); set_loop_output_vector_size(loop_options, 1); set_loop_buffer_size(loop_options, (long) buffer_size * 1024); set_loop_first_input_mincid(loop_options, inmincid); /* Do loop */ voxel_loop(1, &infile, 1, &outfile, arg_string, loop_options, do_makescalar, (void *) &program_data); /* Free stuff */ if (program_data.linear_coefficients != NULL) { free(program_data.linear_coefficients); } if (linear_coefficients.values != NULL) { free(linear_coefficients.values); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { char *pname; char *filename, *tempfile, *newfile; char string[1024]; char *variable_name, *attribute_name; int created_tempfile; int done_redef; int iatt; int mincid, varid; int variable_exists, attribute_exists; nc_type attribute_type, new_type; int attribute_length, new_length; void *new_value; int total_length, alloc_length, ival; char *zeros; int old_ncopts; /* Parse the command line */ pname=argv[0]; if (ParseArgv(&argc, argv, argTable, 0) || (argc != 2)) { (void) fprintf(stderr, "\nUsage: %s [<options>] <file.mnc>\n", pname); (void) fprintf(stderr, " %s [-help]\n\n", pname); exit(EXIT_FAILURE); } filename = argv[1]; /* Create temp file name. First try looking for minc extension, then a compression extension. Chop off the unwanted extension. */ (void) strncpy(string, filename, sizeof(string)-1); tempfile = strstr(string, MINC_EXTENSION); if (tempfile != NULL) { tempfile += strlen(MINC_EXTENSION); if (*tempfile == '\0') tempfile = NULL; } else { tempfile = strstr(string, GZIP_EXTENSION); if (tempfile == NULL) tempfile = strstr(string, BZIP_EXTENSION); if (tempfile == NULL) tempfile = strstr(string, BZIP2_EXTENSION); if (tempfile == NULL) tempfile = strstr(string, COMPRESS_EXTENSION); if (tempfile == NULL) tempfile = strstr(string, PACK_EXTENSION); if (tempfile == NULL) tempfile = strstr(string, ZIP_EXTENSION); } if (tempfile != NULL) { *tempfile = '\0'; tempfile = string; } /* If tempfile == NULL, then either we have a minc file or we don't know how to edit the file in place. Check that it is a minc file. */ if (tempfile == NULL) { newfile = miexpand_file(filename, tempfile, TRUE, &created_tempfile); if (created_tempfile) { if (newfile != NULL) { (void) remove(newfile); free(newfile); } (void) fprintf(stderr, "Cannot edit file \"%s\" in place.\n", filename); exit(EXIT_FAILURE); } } /* Expand the file. */ newfile = miexpand_file(filename, tempfile, FALSE, &created_tempfile); if (newfile == NULL) { (void) fprintf(stderr, "Error decompressing file \"%s\"\n", filename); exit(EXIT_FAILURE); } /* If a new file was created, get rid of the old one */ if (created_tempfile) { (void) remove(filename); } /* Open the file */ mincid = miopen(newfile, NC_WRITE); /* Loop through attribute list, modifying values */ done_redef = FALSE; ncopts = NC_VERBOSE; zeros = NULL; alloc_length = 0; for (iatt=0; iatt < attribute_list_size; iatt++) { /* Get variable and attribute name */ variable_name = attribute_list[iatt].variable; attribute_name = attribute_list[iatt].attribute; /* Check for attribute existence */ if (strlen(variable_name) == 0) { varid = NC_GLOBAL; variable_exists = TRUE; } else { old_ncopts = ncopts; ncopts = 0; varid = ncvarid(mincid, variable_name); ncopts = old_ncopts; variable_exists = (varid != MI_ERROR); } attribute_type = NC_CHAR; attribute_length = 0; if (variable_exists) { old_ncopts = ncopts; ncopts = 0; attribute_exists = (ncattinq(mincid, varid, attribute_name, &attribute_type, &attribute_length) != MI_ERROR); ncopts = old_ncopts; } else attribute_exists = FALSE; /* Are we inserting or deleting? */ switch (attribute_list[iatt].action) { case Insert_attribute: case Append_attribute: if (attribute_list[iatt].value != NULL) { new_type = NC_CHAR; new_length = strlen(attribute_list[iatt].value)+1; new_value = (void *) attribute_list[iatt].value; } else { new_type = NC_DOUBLE; new_length = attribute_list[iatt].num_doubles; new_value = (void *) attribute_list[iatt].double_values; } /* For append we have to copy the entire attribute, if it * already exists. */ if (attribute_list[iatt].action == Append_attribute && attribute_exists) { char *tmp_value; /* Verify that the existing type matches the newly * requested type. Don't allow a -dappend on a * string attribute, for example. */ if (new_type != attribute_type) { fprintf(stderr, "Can't append %s data to %s attribute %s:%s.\n", (new_type == NC_DOUBLE) ? "double" : "string", (attribute_type == NC_DOUBLE) ? "double" : "string", variable_name, attribute_name); exit(EXIT_FAILURE); } new_type = attribute_type; tmp_value = malloc((attribute_length + new_length) * nctypelen(new_type)); ncattget(mincid, varid, attribute_name, tmp_value); /* For string attributes, remove any trailing null * character before appending. */ if (new_type == NC_CHAR && tmp_value[attribute_length-1] == 0) { attribute_length--; } memcpy(tmp_value + attribute_length * nctypelen(new_type), new_value, new_length * nctypelen(new_type)); new_length += attribute_length; new_value = (void *) tmp_value; } total_length = attribute_length*nctypelen(attribute_type); if (!attribute_exists || (total_length < new_length*nctypelen(new_type))) { if (! done_redef) { done_redef = TRUE; (void) ncredef(mincid); } } else if (!done_redef && attribute_exists && (total_length > 0)) { if (total_length > alloc_length) { if (zeros != NULL) free(zeros); zeros = malloc(total_length); alloc_length = total_length; for (ival=0; ival < alloc_length; ival++) zeros[ival] = '\0'; } (void) ncattput(mincid, varid, attribute_name, NC_CHAR, total_length, zeros); (void) ncsync(mincid); } if (!variable_exists) { old_ncopts = ncopts; ncopts = 0; varid = micreate_group_variable(mincid, variable_name); ncopts = old_ncopts; if (varid == MI_ERROR) { varid = ncvardef(mincid, variable_name, NC_INT, 0, NULL); } variable_exists = (varid != MI_ERROR); } if (variable_exists) { (void) ncattput(mincid, varid, attribute_name, new_type, new_length, new_value); } break; case Delete_attribute: if (attribute_exists) { if (! done_redef) { done_redef = TRUE; (void) ncredef(mincid); } (void) ncattdel(mincid, varid, attribute_name); } break; default: (void) fprintf(stderr, "Program error: unknown action %d\n", (int) attribute_list[iatt].action); exit(EXIT_FAILURE); } } ncopts = NC_VERBOSE | NC_FATAL; /* Close the file */ (void) miclose(mincid); /* Free stuff */ free(newfile); if (zeros != NULL) free(zeros); exit(EXIT_SUCCESS); }
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); }
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); }