Mercurial > hg > minc-tools
changeset 32:95d44e26fede
Initial revision
author | neelin <neelin> |
---|---|
date | Tue, 01 Dec 1992 16:12:08 +0000 |
parents | 598d93a7fe72 |
children | b3808a3ac649 |
files | doc/prog_guide.tex doc/prog_ref.tex |
diffstat | 2 files changed, 1711 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/doc/prog_guide.tex @@ -0,0 +1,717 @@ +\documentstyle{article} +\title{MINC User Guide} +\author{Peter Neelin} +\date{November, 1992} +\textwidth 6.0in +\oddsidemargin 0.125in +\textheight 8.5in +\topmargin -0.75in + +\begin{document} + +\maketitle + +\section{Introduction} + +The MINC file format (Medical Image NetCDF) is based on the NetCDF +file format (Network Common Data Form) distributed by the Unidata +Program Center. NetCDF provides a software interface for storing +named, multi-dimensional variables in files in a machine-independent +way. This interface removes applications from the concerns of +portability and file structure and encourages a self-describing form +of data. + +Each NetCDF multi-dimensional variable in a file is described by a +name, by its dimensions and by attributes. For example, an image +stored in a file might be stored as byte data in a variable called +``\verb+image+'', with dimensions ``\verb+x+'' and ``\verb+y+'' (each +of length 256) and with an attribute called ``\verb+long_name+'' which +is a string describing the content of the image. Many variables can be +stored in one file and each variable can have many attributes. +Dimensions exist independently of variables and can subscript more +than one variable. + +MINC provides three things on top of the NetCDF interface. It provides +a standard for dimension, variable and attribute names suitable for +medical imaging, it provides some convenience functions to complement +the NetCDF interface (not specific to the MINC conventions) and it +provides convenience functions for using MINC files. + +\section{An Introduction to NetCDF} + +(For a complete description, see the ``NetCDF User's Guide''). + +\subsection{The NetCDF file} + +It is useful to look at an example file while considering the NetCDF +interface. Fortunately, the NetCDF package provides utilities (ncdump +and ncgen) for converting the binary NetCDF files to an ascii format +call CDL. A simple NetCDF file, converted to CDL notation by ncdump, +is given below: + +\begin{verbatim} +netcdf test { +dimensions: + ycoord = 3 ; + xcoord = 4 ; + +variables: + double image(ycoord, xcoord) ; + image:long_name = "My favorite tiny image" ; + double xcoord(xcoord) ; + +data: + + image = + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12 ; + + xcoord = 100, 200, 300, 400 ; +} +\end{verbatim} + +The sample file stores a 3 by 4 image of double precision values. The +first thing defined are the dimensions : \verb+xcoord+ and +\verb+ycoord+. Dimensions can represent physical dimensions like x +coordinate, y coordinate etc., or they can represent abstract things +like lookup-table index. Each dimension has a name and a length and +when joined with other dimensions defines the shape of a variable --- +the variable image is subscripted by \verb+ycoord+ and \verb+xcoord+. +Dimensions can also be used across variables, relating them to each +other. For example, if the file contained another image also +subscripted by \verb+ycoord+ and \verb+xcoord+, we would have the +important information that the two variables were sampled on the same +grid. Also, coordinate systems can be defined by creating variables +by the same name as the dimension, like \verb+xcoord+ in the example +above, giving the x coordinate of each point in the image. + +Variables are the next thing defined in the cdl file. Each variable +has a name, data type and a shape specified by a list of dimensions +(up to a maximum of \verb+MAX_VAR_DIMS+ = 32 dimensions per variable). +The data types are \verb+NC_CHAR+, \verb+NC_BYTE+, \verb+NC_SHORT+, +\verb+NC_LONG+, \verb+NC_FLOAT+ and \verb+NC_DOUBLE+. Information +about each variable is stored in attributes. The attribute +``\verb+long_name+'' gives a character string describing the variable +``\verb+image+''. Attributes are either scalars or vectors of one of +the six types listed above (a character string is a vector of type +\verb+NC_CHAR+). + +\subsection{Programming with NetCDF} + +Programming with NetCDF can be quite simple. The file listed above was +produced by the following program: + +\begin{verbatim} +#include <netcdf.h> + +#define THE_NAME "My favorite tiny image" +static double vals[][4]={ + 1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0,10.0,11.0,12.0 +}; +static int ysize=sizeof(vals)/sizeof(vals[0]); +static int xsize=sizeof(vals[0])/sizeof(vals[0][0]); + +static double xcoord[]={100.,200.,300.,400.}; + +main() +{ + int cdf, img, xvar; + int dim[MAX_VAR_DIMS]; + long count[MAX_VAR_DIMS], start[MAX_VAR_DIMS]; + + /* Create the file */ + cdf=nccreate("test.cdf",NC_CLOBBER); + + /* Define the dimensions */ + dim[0]=ncdimdef(cdf, "ycoord", ysize); + dim[1]=ncdimdef(cdf, "xcoord", xsize); + + /* Define the variables */ + img=ncvardef(cdf, "image", NC_DOUBLE, 2, dim); + xvar=ncvardef(cdf,"xcoord", NC_DOUBLE, 1, &dim[1]); + + /* Add an attribute */ + ncattput(cdf, img, "long_name", NC_CHAR, strlen(THE_NAME)+1, THE_NAME); + + /* End definition mode */ + ncendef(cdf); + + /* Write the variable values */ + start[0]=start[1]=0; + count[0]=ysize; count[1]=xsize; + ncvarput(cdf, img, start, count, vals); + ncvarput(cdf, xvar, &start[1], &count[1], xcoord); + ncclose(cdf); +} +\end{verbatim} + +The first executable line of the program creates a new NetCDF file. An +open file is either in ``define'' mode or in ``data'' mode. In define +mode, dimensions, variables and attributes can be defined, but data +cannot be written to or read from variables. In data mode, variable +values can be written or read, but no changes to dimensions or +variables can be made and attributes can only be written if they exist +already and will not get larger with the write. Newly created files +are automatically in define mode. + +The lines following the call to nccreate define the dimensions and +variables in the file. Notice that the NetCDF file, dimensions and +variables are all identified by an integer returned when they are +created. These id's are subsequently used to refer to each object. The +attribute ``\verb+long_name+'' for the image variable is identified +only by its name. + +Once everything is defined, ncendef puts the file into data mode and +values are written. The values to write are defined by a vector of +starting indices and a vector of the number of values to write in each +dimension. This defines a multi-dimensional rectangle within the +variable called a hyperslab. In the C interface, the first element of +the vector refers to the slowest varying index of the variable, so in +this example, the array vals has the \verb+xcoord+ varying fastest. In +the FORTRAN interface, the convention has the first subscript varying +fastest. These conventions follow the language conventions for +multi-dimensional arrays. + +\section{The MINC format} + +It is possible to build MINC format files using only NetCDF function +calls, however a C include file is provided to facilitate (and help +ensure) adherence to the standard. This file defines useful constants, +standard dimension, variable and attribute names and some attribute +values. It also declares the functions defined in a library of minc +convenience functions, designed to make an application programmer's +life easier. + +\subsection{The MINC standard} + +Various requirements for file formats have been put forward. One such +list is as follows: A protocol should be: 1) simple, 2) self +describing, 3) maintainable, 4) extensible, 5) N dimensional, and 6) +have a universal data structure. The NetCDF format meets all of these +requirements, suggesting that it is a good place to start. I would, +however, add some more requirements to the list. Implied in the above +list is the requirement that there be a standard for accessing data +(how do I get the patient name) --- this is not provided by NetCDF. +Furthermore, a useful format should come with a software interface +that makes it easy to use, particularly in a development environment. +Finally, a format that stores many associated pieces of information +should also provide some data organization. + +The MINC format attempts to add these things to the NetCDF format. + +\subsubsection{MINC variable types} + +Medical imaging tends to produce files with a large amount of +ancillary data (patient information, image information, acquisition +information, etc.). To organise this information in a useful fashion, +MINC uses variables to group together related attributes. The variable +itself may or may not contain useful data. For example, the variable +\verb+MIimage+ contains the image data and has attributes relevant to this +data. The variable \verb+MIpatient+ has no relevant variable data, but +serves to group together all attributes describing the patient (name, +birthdate, etc.). This sort of variable is called a group variable. + +Variables that correspond to dimensions are called dimension variables +and describe the coordinate system corresponding to the dimension. An +example is MIxspace --- both a dimension and a variable describing the +x coordinate of other variables. + +The NetCDF conventions allow for these dimension variables to specify +the coordinate at each point, but there is nothing to describe the +width of the sample at that point. MINC provides the convention of +dimension width variables, e.g. \verb+MIxspace_width+, to give this +information. + +Finally, it is possible to have attributes that vary over some of the +dimensions of the variable. For example, if we have a volume of image +data, varying over \verb+MIxspace+, \verb+MIyspace+ and +\verb+MIzspace+, we may want an attribute giving the maximum value of +the each image, varying over \verb+MIzspace+. To achieve this we use a +variable, called a variable attribute, pointed to by an attribute of +the image variable. + +Thus MINC introduces a number of types of variables: group variables, +dimension variables, dimension width variables and variable +attributes. + +\subsubsection{Data organization} + +MINC attempts to provide some level of data organization through a +hierarchy of group variables. As mentioned above, attributes are +grouped according to type in group variables. Each group variable can +have an \verb+MIparent+ and an \verb+MIchildren+ attribute --- the +former specifying the name of another variable that is above this one +in the hierarchy, the latter specifying a newline-separated list of +variables that come below this one in the hierarchy. At the root of +the hierarchy is the \verb+MIrootvariable+ variable, with no parent. +Although it is not necessary to make use of this structure, it can +provide a mechanism for ordering large amounts of information. + +\subsubsection{MINC dimension, variable and attribute names} + +The NetCDF format says nothing about variable and dimension naming +conventions and little about attribute names. It does provide a few +standards, such as the attribute ``\verb+long_name+'' for describing a +variable, which have been adopted by the MINC standard. MINC defines a +set of standard names for commonly used entities and the include file +defines constants specifying these names. These are described at +length in the MINC reference manual. The most interesting of these is +\verb+MIimage+, the name of the variable used for storing the actual image +data in the file. + +\subsubsection{Image dimensions} + +The MINC standard gives some special status to the concept of an +image. There is nothing inherent in NetCDF that suggests any special +status for particular dimensions, but it can be convenient to place +limitations on what can vary over which dimensions in an imaging +context. For example, the requirement that the variables that specify +how to rescale images (see later section on pixel values) not vary +with image dimensions means that we can treat the image as a simple +unit. In the simplest case, the image dimensions are simply the two +fastest varying dimensions of the \verb+MIimage+ variable. + +It can also be helpful to allow for vector fields --- images or image +volumes that have a vector of values at each point. A simple example +of a vector field is an RGB image. At each point in space, there are +three values: red, green and blue. The dimension +\verb+MIvector_dimension+ is used for the components of the vector and +it should be the fastest varying dimension in the \verb+MIimage+ variable. If +it is present, then the three fastest varying dimensions of \verb+MIimage+ +are the image dimensions. + +\subsubsection{MINC coordinate system} + +The MINC standard defines how spatial coordinates should be oriented +relative to patients. Files are free to have data stored in the +desired direction, but positive coordinates are given a definite +meaning in the medical image context. The standard is that the +positive x axis points from the patient's left to right, the positive +y axis points from posterior to anterior and the positive z axis +points from inferior to superior. + +\subsubsection{Pixel values and real values} + +In medical imaging, pixel values are frequently stored as bytes or +shorts, but there is a generally a real value associated with each +pixel as well. This real value is obtained by a scale factor and +offset associated with each image or image volume. The MINC standard +indicates how pixel values should be interpreted. + +Image data in the \verb+MIimage+ variable can be stored as bytes, shorts, +longs, floats or doubles. NetCDF conventions use the attributes +\verb+MIvalid_range+ or \verb+MIvalid_max+ and \verb+MIvalid_min+ to +indicate the range of values that can be found in the variable. For +short values, for example, we might have a valid range of 0 to 32000. +To convert these integers to real values, we could use a scale and +offset. However, these values would have to change if the data where +converted to bytes in the range 23 to 228. If we specify an image +maximum and minimum to which \verb+MIvalid_max+ and \verb+MIvalid_min+ +should be mapped by an appropriate scale and offset, then we can +convert type and valid range without having to change the real maximum +and minimum. To allow the maximum dynamic range in an image, we use +the variables \verb+MIimagemax+ and \verb+MIimagemin+ to store the +real maximum and minimum --- these can vary over any of the non-image +dimensions of \verb+MIimage+. + +\subsection{General convenience functions} + +MINC provides a number of convenience functions that have nothing to +do with medical imaging, but that make the use of NetCDF files a +little easier. One of the drawbacks of the NetCDF format is that data +can come in any form (byte, short, long, float, double) and the +calling program must handle the general case. Rather than restrict +this, MINC provides functions to convert types. + +The first set of convenience functions are for type conversion. A list +follows : +\begin{itemize} + \item {\bf \verb+miattget+} - reads an attribute vector, specifying + the numeric type desired and the maximum number of values to read. + \item {\bf \verb+miattget1+} - reads one attribute value of the + specified type. + \item {\bf \verb+miattgetstr+} - read a character attribute of a specified + maximum length. + \item {\bf \verb+miattputdbl+} - write a double precision attribute. + \item {\bf \verb+miattputstr+} - write a string attribute. + \item {\bf \verb+mivarget+} - get a hyperslab of values of the + specified type. + \item {\bf \verb+mivarget1+} - get a single value of the specified type. + \item {\bf \verb+mivarput+} - put a hyperslab of values of the + specified type. + \item {\bf \verb+mivarput1+} - put a single value of the specified type. +\end{itemize} + +Next we have some functions for handling coordinate vectors : +\begin{itemize} + \item {\bf \verb+miset_coords+} - set a vector of coordinates to a + single value. + \item {\bf \verb+mitranslate_coords+} - translate the coordinates for one + variable to a vector for subscripting another variable. +\end{itemize} + +Finally, there are functions for dealing with variables as groups of +attributes, making it easier to modify a file while keeping ancillary +information : +\begin{itemize} + \item {\bf \verb+micopy_all_atts+} - copy all of the attributes of + one variable to another (possibly across files). + \item {\bf \verb+micopy_var_def+} - copy a variable definition (including + attributes) from one file to another. + \item {\bf \verb+micopy_var_vals+} - copy a variable's values from + one variable to another (possibly across files). + \item {\bf \verb+micopy_all_var_defs+} - copy all variable + definitions from one file to another, excluding a list of variables. + \item {\bf \verb+micopy_all_var_vals+} - copy all variable values + from one file to another, excluding a list of variables. +\end{itemize} + +\subsection{MINC specific convenience functions} + +A few routines are provided to deal with some of the minc structures. +\verb+miattput_pointer+ and \verb+miattget_pointer+ put/get a pointer to a +variable attribute. \verb+miadd_child+ helps maintain the hierarchy of +variables by handling the \verb+MIparent+ and \verb+MIchildren+ +attributes of two variables. Finally \verb+micreate_std_variable+ and +\verb+micreate_group_variable+ create some of the standard variables +and fill in a few of the default attributes. + +\subsection{Image conversion variables} + +One of the requirements for file formats mentioned earlier was +a software interface to make the interface easy to use. The biggest +difficulty in using a flexible format is that the application must +handle many possibilities. Where images are concerned, this means +various data types and scale factors, and images of differing sizes. +The image conversion variable functions of MINC attempt to remove this +complication for the programmer. + +An image conversion variable (icv) is essentially a specification of what +the program wants images to look like, in type, scale and dimension. +When an MINC image is read through an icv, it is converted for the +calling program to a standard format regardless of how data is stored +in the file. + +There are two categories of conversion: Type and range conversions +change the datatype (and sign) of image values and optionally scale +them for proper normalization. Dimension conversions allow programs to +specify image dimension size and image axis orientation (should +\verb+MIxspace+ coordinates be increasing or decreasing? should the +patient's left side appear on the left or right of the image?). + +\subsubsection{ICV routines} + +Accessing a file through an icv is a straight-forward process. +Create the icv with \verb+miicv_create+, set properties +(like desired datatype) with \verb+miicv_set+, attach the icv to a NetCDF +variable with \verb+miicv_attach+ and access the data with +\verb+miicv_get+ or \verb+miicv_put+. The icv can be detached from a +NetCDF variable with \verb+miicv_detach+ and can be freed with +\verb+miicv_free+. + +Icv properties are strings, integers, long integers or doubles. For +example, \verb+MI_ICV_SIGN+ (the sign of variable values) is a string, +while \verb+MI_ICV_IMAGE_MAX+ (image maximum) is a double precision +value. Two functions, \verb+miicv_setint+ and \verb+miicv_setdbl+, +are provided to simplify the setting of property values. Programs can +inquire about property values with \verb+miicv_inq+. + +\subsubsection{Type and range conversion} + +Pixel values are converted for type and sign by specifying values for +the properties \verb+MI_ICV_TYPE+ and \verb+MI_ICV_SIGN+ (they default +to \verb+NC_SHORT+ and \verb+MI_SIGNED+). Values can also be converted +for valid range and for normalization. These conversions are enabled +by setting \verb+MI_ICV_DO_RANGE+ to \verb+TRUE+ (the default). + +If \verb+MI_ICV_DO_NORM+ is \verb+FALSE+ (the default) then only +conversions for valid range are made. This means that if the input +file has shorts in the range 0 to 4095, then they can be converted to +bytes in the range 64 to 248 (for example). The real image maximum and +minimum (\verb+MIimagemax+ and \verb+MIimagemin+) are ignored. The +valid range is specified by the properties \verb+MI_ICV_VALID_MAX+ and +\verb+MI_ICV_VALID_MIN+, which default to the legal range for the type +and sign. + +We may want to scale values so that they are normalized either to all +values in the \verb+MIimage+ variable or to some user-defined range. +To do normalization, set \verb+MI_ICV_DO_NORM+ to \verb+TRUE+. Setting +\verb+MI_ICV_USER_NORM+ to \verb+FALSE+ (the default) causes normalization to +the real maximum and minimum of the variable (the maximum of +\verb+MIimagemax+ and the minimum of \verb+MIimagemin+). If +\verb+MI_ICV_USER_NORM+ is true then the values of \verb+MI_ICV_IMAGE_MAX+ +and \verb+MI_ICV_IMAGE_MIN+ are used (defaulting to 1.0 and 0.0). + +Note that when converting to integer types, values are rounded to the +nearest integer and limited to be within the legal range for the data +type. + +The above transformations are simple enough, but the use of +floating-point values adds to the complexity, since in general we do +not want to rescale these values to get the real values. The various +possibilities are described in greater detail below. + +\subsubsection{The details of pixel value conversion} + +The easiest way to think about the rescaling is through four ranges +(maximum-minimum pairs). In the file variable, values have a +valid range \verb+var_vrange+ and these correspond to real values +\verb+var_imgrange+. The user/application wants to convert real values +\verb+usr_imgrange+ to a useful valid range \verb+usr_vrange+. From +\verb+var_vrange+, \verb+var_imgrange+, \verb+usr_imgrange+ and +\verb+usr_vrange+, we can determine a scale and offset for converting +pixel values: Input values are scaled to real values by +\verb+var_vrange+ to \verb+var_imgrange+ and then scaled again to user +values by \verb+usr_imgrange+ to \verb+usr_vrange+. + +If either of the \verb+vrange+ variables are not specified, they default to +maximum possible range for integer types and to 0.0 to 1.0 for +floating point. If the user type is floating point, then \verb+usr_vrange+ is +set equal to \verb+usr_imgrange+ (ie. no conversion of real values). + +If normalization is not being done, then \verb+var_imgrange+ and +\verb+usr_imgrange+ are set to [0,1] (scale down to [0,1] and +scale up again). Otherwise, \verb+usr_imgrange+ is set to either the full +range of the variable ([0,1] if not found) or the user's requested +range. If the variable values are floating point, or if the real range +of the variable is not known, then \verb+var_imgrange+ is set to +\verb+var_vrange+ (no scaling to real values), otherwise +\verb+var_imgrange+ is read for each image. + +What this means for reading and writing images is discussed below. + +\subsubsection{Reading with pixel conversion} + +When reading integers, things behave as expected. Without +normalization, each image is scaled to full range, with normalization +they are scaled to the specified range. Reading in floating point, +however, will give values between [0,1] with no normalization and +appropriate real values with normalization. + +When the input file is missing either +\verb+MIimagemax+/\verb+MIimagemin+ (\verb+var_imgrange+ information) +or \verb+MIvalid_range+, the routines try to provide sensible +defaults, but funny things can still happen. The biggest problem is +the absence of \verb+MIvalid_range+ if the defaults are not correct +(full range for integer values and [0,1] for floating point). When +converting floating point values to an integer type, there will be +overflows if values are outside the range [0,1]. + +\subsubsection{Writing with pixel conversion} + +The conversion routines can be used for writing values. This can be +useful for data compression --- e.g. converting internal floats to +byte values in the file, or converting internal shorts to bytes. When +doing this with normalization (to rescale bytes to the slice maximum, +for example) it is important to write the slice maximum and minimum in +\verb+MIimagemax+ and \verb+MIimagemin+ before writing the slice. + +The other concern is that \verb+MIvalid_range+ or \verb+MIvalid_max+ +and \verb+MIvalid_min+ be written properly (especially if the defaults +are not correct). When writing floating point values, +\verb+MIvalid_range+ should be set to the full range of values in the +variable. In this case, the attribute does not have to be set +correctly before writing the variable, but if it exists, the values +should be reasonable (maximum greater than minimum and values not +likely to cause overflow). These will be set automatically if the +routine \verb+micreate_std_variable+ is used with +\verb+NC_FILL+ mode on (the default). + +\subsubsection{Example: Reading values} + +Read an image without normalization: +\begin{verbatim} + /* Create the icv */ + icv=miicv_create(); + (void) miicv_setint(icv, MI_ICV_TYPE, NC_SHORT); + (void) miicv_set(icv, MI_ICV_SIGN, MI_UNSIGNED); + (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, 32000.0); + (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, 0.0); + + /* Open the file, attach the image variable */ + cdfid=ncopen(filename, NC_NOWRITE); + + /* Attach image variable */ + img=ncvarid(cdfid, MIimage); + (void) miicv_attach(icv, cdfid, img); + + /* Get the data - we assume that coord and count are set properly */ + (void) miicv_get(icv, coord, count, image); + + /* Close the file and free the icv */ + (void) ncclose(cdfid); + (void) miicv_free(icv); +\end{verbatim} + +Read an integer image with normalization: +\begin{verbatim} + /* Create the icv */ + icv=miicv_create(); + (void) miicv_setint(icv, MI_ICV_TYPE, NC_SHORT); + (void) miicv_set(icv, MI_ICV_SIGN, MI_UNSIGNED); + (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, 32000.0); + (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, 0.0); + (void) miicv_setint(icv, MI_ICV_DO_NORM, TRUE); + (void) miicv_setint(icv, MI_ICV_USER_NORM, TRUE); + (void) miicv_setdbl(icv, MI_ICV_IMAGE_MAX, 1.83); + (void) miicv_setdbl(icv, MI_ICV_IMAGE_MIN, -0.57); + ... +\end{verbatim} + +Read a floating point image : +\begin{verbatim} + /* Create the icv */ + icv=miicv_create(); + (void) miicv_setint(icv, MI_ICV_TYPE, NC_FLOAT); + ... +\end{verbatim} + +\subsubsection{Example: Writing values} + +Writing from floating point to byte values : + +\begin{verbatim} + /* Create the icv */ + icv=miicv_create(); + (void) miicv_setint(icv, MI_ICV_TYPE, NC_FLOAT); + (void) miicv_setint(icv, MI_ICV_DO_NORM, TRUE); + + /* Create the file */ + cdf=nccreate(filename, NC_CLOBBER); + + /* Define the dimensions */ + dim[0]=ncdimdef(cdf, MIyspace, ysize); + dim[1]=ncdimdef(cdf, MIxspace, xsize); + + /* Define the variables */ + img=micreate_std_variable(cdf, MIimage, NC_BYTE, 2, dim); + (void) miattputstr(cdf, img, MIsigntype, MI_UNSIGNED); + vrange[0]=0; vrange[1]=200; + (void) ncattput(cdf, img, MIvalid_range, NC_DOUBLE, 2, vrange); + max=micreate_std_variable(cdf, MIimagemax, NC_DOUBLE, 0, NULL); + min=micreate_std_variable(cdf, MIimagemin, NC_DOUBLE, 0, NULL); + + /* End definition mode */ + ncendef(cdf); + + /* Attach image variable */ + (void) miicv_attach(icv, cdf, img); + + /* Write the image max and min */ + ncvarput1(cdf, max, NULL, &image_maximum); + ncvarput1(cdf, min, NULL, &image_minimum); + + /* Write the image */ + start[0]=start[1]=0; + count[0]=ysize; count[1]=xsize; + miicv_put(icv, start, count, vals); + + /* Close the file and free the icv */ + (void) ncclose(cdf); + (void) miicv_free(icv); +\end{verbatim} + +If we were writing a floating point image, the only difference (apart +from changing \verb+NC_BYTE+ to \verb+NC_FLOAT+) would be that we +would rewrite \verb+MIvalid_range+ at the end of the file with the +full range of floating point values. + +\subsubsection{Dimension conversion} + +One of the problems of arbitrary dimensioned images is that it becomes +necessary for software to handle the general case. It is easier to write +application software if it is known in advance that all images will +have a specific size (e.g. $256\times 256$) and a specific orientation +(e.g. the first pixel is at the patient's anterior, right side). + +By setting the icv property \verb+MI_ICV_DO_DIM_CONV+ to \verb+TRUE+ +these conversions can be done automatically. The orientation of +spatial axes is determined by the properties \verb+MI_ICV_XDIM_DIR+, +\verb+MI_ICV_YDIM_DIR+ and \verb+MI_ICV_ZDIM_DIR+. These affect any +image dimensions that are \verb+MI?space+ or \verb+MI?frequency+ where +\verb+?+ corresponds to \verb+x+, \verb+y+ or \verb+z+. These +properties can have values \verb+MI_ICV_POSITIVE+, +\verb+MI_ICV_NEGATIVE+ or \verb+MI_ICV_ANYDIR+. The last of these will +prevent flipping of the dimension. The first two will flip the +dimension if necessary so that the attribute \verb+MIstep+ of the +dimension variable will have the correct sign. + +The two image dimensions are referred to as dimensions A and B. +Dimension A is the fastest varying dimension of the two. Setting +properties \verb+MI_ICV_ADIM_SIZE+ and \verb+MI_ICV_BDIM_SIZE+ specify +the desired size for the image dimension. Dimensions are resized so +that the file image will fit entirely in the calling program's image, +and is centred in the image. The size \verb+MI_ICV_ANYSIZE+ allows +one of the dimensions to have a variable size. If property +\verb+MI_ICV_KEEP_ASPECT+ is set to \verb+TRUE+, then the two +dimensions are rescaled by the same amount. It is possible to inquire +about the new step and start, corresponding to attributes +\verb+MIstep+ and \verb+MIstart+ (where pixel position = ipixel*step + +start, with ipixel counting from zero). The properties +\verb+MI_ICV_?DIM_STEP+ and \verb+MI_ICV_?DIM_START+ (\verb+?+ = +\verb+A+ or \verb+B+) are set automatically and can be inquired but +not set. + +Although vector images are allowed, many applications would rather +only deal with scalar images (one intensity value at each point). +Setting \verb+MI_ICV_DO_SCALAR+ to \verb+TRUE+ (the default) will +cause vector images to be converted to scalar images by averaging the +components. (Thus, RGB images are automatically converted to +gray-scale images in this simple way). + +It can sometimes be useful for a program to perform dimension +conversions on three (or perhaps more) dimensions, not just the two +standard image dimensions. To perform dimension flipping and/or +resizing on dimensions beyond the usual two, the property +\verb+MI_ICV_NUM_IMGDIMS+ can be set to an integer value between +one and \verb+MI_MAX_IMGDIMS+. To set the size of a dimension, +set the property \verb+MI_ICV_DIM_SIZE+ (analogous to +\verb+MI_ICV_ADIM_SIZE+). To specify the dimension to be set, add +the dimension to the property (adding zero corresponds to the fastest +varying dimension --- add zero for the ``A'' dimension, one for the +``B'' dimension, etc.). Voxel separation and +location can be inquired about through the properties +\verb+MI_ICV_DIM_STEP+ and \verb+MI_ICV_DIM_START+ (analogous to +\verb+MI_ICV_ADIM_STEP+ and \verb+MI_ICV_ADIM_START+), again +adding the dimension number to the property. + +\subsubsection{Example: Reading with dimension conversion} + +Reading a $256 \times 256$ image with the first pixel at the patient's +inferior, posterior, left side as short values between 0 and 32000: +\begin{verbatim} + /* Create the icv */ + icv=miicv_create(); + (void) miicv_setint(icv, MI_ICV_TYPE, NC_SHORT); + (void) miicv_set(icv, MI_ICV_SIGN, MI_UNSIGNED); + (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, 32000.0); + (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, 0.0); + (void) miicv_setint(icv, MI_ICV_DO_DIM_CONV, TRUE); + (void) miicv_setint(icv, MI_ICV_ADIM_SIZE, 256); + (void) miicv_setint(icv, MI_ICV_BDIM_SIZE, 256); + (void) miicv_setint(icv, MI_ICV_KEEP_ASPECT, TRUE); + (void) miicv_setint(icv, MI_ICV_XDIM_DIR, MI_POSITIVE); + (void) miicv_setint(icv, MI_ICV_YDIM_DIR, MI_POSITIVE); + (void) miicv_setint(icv, MI_ICV_ZDIM_DIR, MI_POSITIVE); + + /* Open the file, attach the image variable */ + cdfid=ncopen(filename, NC_NOWRITE); + + /* Attach image variable */ + img=ncvarid(cdfid, MIimage); + (void) miicv_attach(icv, cdfid, img); + + /* Get the data - we assume that coord and count are set properly */ + (void) miicv_get(icv, coord, count, image); + + /* Close the file and free the icv */ + (void) ncclose(cdfid); + (void) miicv_free(icv); +\end{verbatim} + + +\end{document} +
new file mode 100644 --- /dev/null +++ b/doc/prog_ref.tex @@ -0,0 +1,994 @@ +\documentstyle{article} +\title{MINC Reference Manual} +\author{Peter Neelin} +\date{November, 1992} +\textwidth 6.0in +\oddsidemargin 0.125in +\textheight 8.5in +\topmargin -0.75in +\parindent 0in + +\begin{document} + +\def\code#1{{\tt #1}} + +\maketitle + +\section{Dimension, variable and attribute names} + +Of all of the variables, dimensions and attributes described here, only +the variable \code{MIimage} and its dimensions are required to be +present in a MINC file. Additional variables, dimensions and +attributes may be present in the file --- unrecognised variables and +attributes should be ignored. + +A word on attribute conventions. All numeric values should be stored +in one of the numeric types (\code{NC\_BYTE}, \code{NC\_SHORT}, +\code{NC\_LONG}, \code{NC\_FLOAT} or \code{NC\_DOUBLE}). Some numeric +attributes must be specified in a definite unit --- time attributes +(such as \code{MIrepetition\_time} and \code{MIradionuclide\_halflife}) +are given in seconds. Other attributes have an associated attribute that +gives the unit --- e.g. \code{MIinjection\_dose} and \code{MIdose\_units}. + +\subsection{NetCDF standard attributes} + +These attributes can be used with any variable. Fuller descriptions +can be obtained from the NetCDF user's guide. + +\begin{description} + \item [\code{MIunits}] Specifies the units of the variable values + as a string --- units should be compatible with the udunits + library. + \item [\code{MIlong\_name}] A string giving a textual description of + the variable for human consumption. + \item [\code{MIvalid\_range}] A vector of two numbers specifying the + minimum and maximum valid values in the variable. For the MINC + routines the order is not important. For the \code{MIimage} + variable, this attribute (or \code{MIvalid\_max} and + \code{MIvalid\_min}) should always be present unless the + defaults of full range for integer types and [0.0,1.0] for floating + point types is correct. + \item [\code{MIvalid\_max}] A number giving the valid maximum for + the variable. + \item [\code{MIvalid\_min}] A number giving the valid maximum for + the variable. + \item [\code{MI\_FillValue}] Number to be used for filling in values in + the variable that are not explicitly written. + \item [\code{MItitle}] A global string that provides a description + of what is in the file. + \item [\code{MIhistory}] A global string that should store one line + for each program that has modified the file. Each line should + contain the program name and arguments. +\end{description} + +\subsection{MINC general attributes} + +These attributes apply to any variable in the file. + +\begin{description} + \item [\code{MIvartype}] A string identifying the type of variable. + Should be one of \code{MI\_GROUP}, \code{MI\_DIMENSION}, + \code{MI\_DIM\_WIDTH} or \code{MI\_VARATT}. + \item [\code{MIvarid}] A string that identifies the origin of the + variable. All standard MINC variables should have this attribute + with value \code{MI\_STDVAR}. Variables created by users should have a + distinctive name that will not be the same as the names used by + other applications. + \item [\code{MIsigntype}] The NetCDF format does not need to know + the sign of variables since it does not interpret values --- it + is left up to the invoking program to worry about the signs of + integers. Because the MINC interface translates variables, it + must have this information. \code{MIsigntype} is a string with + value \code{MI\_SIGNED} or \code{MI\_UNSIGNED}. The default values are + \code{MI\_UNSIGNED} for bytes and \code{MI\_SIGNED} for all other types. + \item [\code{MIparent}] A string identifying by name the parent + variable of this variable (either in the data hierarchy or as + the parent of this variable attribute). + \item [\code{MIchildren}] A newline-separated list of the children + of this variable (in the data hierarchy). + \item [\code{MIcomments}] Any text that should be included with + this variable. + \item [\code{MIversion}] A string identifying the file version. The + current version is \code{MI\_CURRENT\_VERSION}. Each version can be + identified by a constant of the form \code{MI\_VERSION\_1\_0}. +\end{description} + +The constants \code{MI\_TRUE} and \code{MI\_FALSE} are provided for +boolean attributes. + +\subsection{Dimensions and dimension variables} + +The following are the names of dimensions and their corresponding +dimension variables. Only \code{MIvector\_dimension} does not have a +corresponding dimension variable. +\begin{description} + \item [\code{MIxspace}] Dimension and coordinate variable for x axis. + \item [\code{MIyspace}] Dimension and coordinate variable for y axis. + \item [\code{MIzspace}] Dimension and coordinate variable for z axis. + \item [\code{MItime}] Dimension and coordinate for variable time axis. + \item [\code{MItfrequency}] Dimension and coordinate variable for + temporal frequency. + \item [\code{MIxfrequency}] Dimension and coordinate variable for spatial + frequency along the x axis. + \item [\code{MIyfrequency}] Dimension and coordinate variable for spatial + frequency along the y axis. + \item [\code{MIzfrequency}] Dimension and coordinate variable for spatial + frequency along the z axis. + \item [\code{MIvector\_dimension}] Dimension only for components of + a vector field. +\end{description} + +In addition to dimension variables, we can have dimension width +variables that specify the FWHM width of the sample at each point. +\begin{description} + \item [\code{MIxspace\_width}] Width of samples along x axis. + \item [\code{MIyspace\_width}] Width of samples along y axis. + \item [\code{MIzspace\_width}] Width of samples along z axis. + \item [\code{MItime\_width}] Width of samples along time axis. + \item [\code{MItfrequency\_width}] Width of samples along temporal + frequency axis. + \item [\code{MIxfrequency\_width}] Width of samples along x spatial + frequency axis. + \item [\code{MIyfrequency\_width}] Width of samples along y spatial + frequency axis. + \item [\code{MIzfrequency\_width}] Width of samples along z spatial + frequency axis. +\end{description} + +The attributes associated with dimension and dimension width variables +are given below: +\begin{description} + \item [\code{MIspacing}] A string with value \code{MI\_REGULAR} (for + a regularly spaced grid) or \code{MI\_IRREGULAR} (for irregular + spacing of samples). If the value is \code{MI\_REGULAR}, then the + variable is permitted to be a scalar instead of a vector varying + with the dimension of the same name. Can be used for both + dimension and dimension width variables. + \item [\code{MIstep}] A number indicating the step between samples + for regular spacing. This value may be negative to indicate + orientation (to specify that \code{MIxspace} runs from patient + right to left, for example). If the spacing is irregular, then + the value can be an average step size. Applies only to dimension + variables. + \item [\code{MIstart}] The coordinate of the index 0 of the dimension. + Applies only to dimension variables. + \item [\code{MIspacetype}] A string identifying the type of + coordinate space. Currently one of \code{MI\_NATIVE} (the + coordinate system of the scanner), \code{MI\_TALAIRACH} (a + standardized coordinate system), or \code{MI\_CALLOSAL} (another + standardized coordinate system). Applies only to dimension variables. + \item [\code{MIalignment}] A string indicating the position of the + coordinates relative to each sample (remembering that each sample + has a width). Can be one of \code{MI\_START}, \code{MI\_CENTRE} or + \code{MI\_END}. Applies only to dimension variables. + \item [\code{MIdirection\_cosines}] A vector with + \code{MI\_NUM\_SPACE\_DIMS}(=3) elements giving the + direction cosines of the axes. Although axes are labelled x, y + and z, they may in fact have a signficantly different + orientation --- this attribute allows the direction relative to + the true axes to be specified exactly. Applies only to dimension + variables. + \item [\code{MIwidth}] For regularly dimension widths, this + numeric attribute gives the FWHM width of all samples. It can be used + for irregular widths to specify the average width. Applies only + to dimension width variables. + \item [\code{MIfiltertype}] A string specifying the shape of the + convolving filter. Currently, can be one of \code{MI\_SQUARE}, + \code{MI\_GAUSSIAN} or \code{MI\_TRIANGULAR}. Applies only to + dimension width variables. +\end{description} + +\subsection{Root variable} + +The variable \code{MIrootvariable} is used as the root of the data +hierarchy, with its \code{MIchildren} attribute pointing to the first +level of group variables (including all of the MINC group variables), +and with its \code{MIparent} attribute an empty string. + +\subsection{Image variable} + +The variable \code{MIimage} is used to store the image data. + +\begin{description} + \item [\code{MIimagemax}] A variable attribute (ie. an attribute + pointing to a variable of the same name) that stores the real + value maximum for the image. This variable should not vary over + the image dimensions of MIimage. The units of this variable + define the units of the image. + \item [\code{MIimagemin}] Like \code{MIimagemax}, but stores the + real value minimum for the image. + \item [\code{MIcomplete}] A boolean attribute (with values + \code{MI\_TRUE} or \code{MI\_FALSE}) that indicates whether the variable + has been written in its entirety. This can be used to detect + program failure when writing out images as they are processed : + \code{MIcomplete} is set to \code{MI\_FALSE} at the beginning and + changed to \code{MI\_TRUE} at the end of processing. +\end{description} + +\subsection{Patient variable} + +The variable \code{MIpatient} is a group variable with no dimensions +and no useful value. It serves only to group together information +about the patient. Attributes are modelled after ACR-NEMA conventions. + +\begin{description} + \item [\code{MIfull\_name}] A string specifying the full name of the + patient. + \item [\code{MIother\_names}] A string giving other names for the + patient. + \item [\code{MIidentification}] A string specifying identification + information for the patient. + \item [\code{MIother\_ids}] A string giving other id's. + \item [\code{MIbirthdate}] A string specifying the patient's + birthdate. + \item [\code{MIsex}] A string specifying the patient's sex: + \code{MI\_MALE}, \code{MI\_FEMALE} or \code{MI\_OTHER}. + \item [\code{MIage}] A number giving the patient's age. + \item [\code{MIweight}] The patient's weight in kilograms. + \item [\code{MIsize}] The patient's height or length in metres. + \item [\code{MIaddress}] A string giving the patient's address. + \item [\code{MIinsurance\_id}] A string giving the patient's + insurance plan id. +\end{description} + +\subsection{Study variable} + +Information about the study is grouped together in the \code{MIstudy} +variable which has no dimensions or values. Attributes are modelled +after ACR-NEMA conventions. + +\begin{description} + \item [\code{MIstart\_time}] String giving time (and date) of start + of the study. + \item [\code{MIstart\_year}] Integer giving year of start. + \item [\code{MIstart\_month}] Integer giving month (1-12) of start. + \item [\code{MIstart\_day}] Integer giving day (1-31) of start. + \item [\code{MIstart\_hour}] Integer giving hour (0-23) of start. + \item [\code{MIstart\_minute}] Integer giving minute (0-59) of start. + \item [\code{MIstart\_seconds}] Floating-point value giving seconds + of start. + \item [\code{MImodality}] Imaging modality : one of \code{MI\_PET}, + \code{MI\_SPECT}, \code{MI\_GAMMA}, \code{MI\_MRI}, + \code{MI\_MRS}, \code{MI\_MRA}, \code{MI\_CT}, \code{MI\_DSA}, + \code{MI\_DR}. + \item [\code{MImanufacturer}] String giving name of device + manufacturer. + \item [\code{MIdevice\_model}] String identifying device model. + \item [\code{MIinstitution}] String identifying institution. + \item [\code{MIdepartment}] String identifying department. + \item [\code{MIstation\_id}] String identifying machine that generated + the images. + \item [\code{MIreferring\_physician}] Name of patient's primary + physician. + \item [\code{MIattending\_physician}] Physician administering the + examination. + \item [\code{MIradiologist}] Radiologist interpreting the examination. + \item [\code{MIoperator}] Name of technologist operating scanner. + \item [\code{MIadmitting\_diagnosis}] String description of admitting + diagnosis. + \item [\code{MIprocedure}] String description of the procedure employed. +\end{description} + +\subsection{Acquisition variable} + +Information about the acquisition itself is stored as attributes of +the \code{MIacquisition} variable (again, no dimensions and no values). + +\begin{description} + \item [\code{MIprotocol}] String description of the protocol for + image acquisition. + \item [\code{MIscanning\_sequence}] String description of type of data + taken (eg. for MR --- IR, SE, PS, etc.). + \item [\code{MIrepetition\_time}] Time in seconds between pulse + sequences. + \item [\code{MIecho\_time}] Time in seconds between the middle of a 90 + degree pulse and the middle of spin echo production. + \item [\code{MIinversion\_time}] Time in seconds after the middle of + the inverting RF pulse to the middle of the 90 degree pulse to + detect the amount of longitudinal magnetization. + \item [\code{MInum\_averages}] Number of times a given pulse sequence + is repeated before any parameter is changed. + \item [\code{MIimaging\_frequency}] Precession frequency in Hz of the + imaged nucleus. + \item [\code{MIimaged\_nucleus}] String specifying the nucleus that is + resonant at the imaging frequency. + \item [\code{MIradionuclide}] String specifying the isotope administered. + \item [\code{MIcontrast\_agent}] String identifying the contrast or + bolus agent. + \item [\code{MIradionuclide\_halflife}] Half-life of radionuclide in + seconds. + \item [\code{MItracer}] String identifying tracer labelled with + radionuclide that was injected. + \item [\code{MIinjection\_time}] String giving time (and date) of + injection. + \item [\code{MIinjection\_year}] Integer giving year of injection. + \item [\code{MIinjection\_month}] Integer giving month (1-12) of + injection. + \item [\code{MIinjection\_day}] Integer giving day (1-31) of + injection. + \item [\code{MIinjection\_hour}] Integer giving hour (0-23) of + injection. + \item [\code{MIinjection\_minute}] Integer giving minute (0-59) of + injection. + \item [\code{MIinjection\_seconds}] Floating-point value giving + seconds of injection. + \item [\code{MIinjection\_length}] Length of time of injection (in + seconds). + \item [\code{MIinjection\_dose}] Total dose of radionuclide or contrast + agent injected (in units specified by \code{MIdose\_units}). + \item [\code{MIdose\_units}] String giving units of dose. + \item [\code{MIinjection\_volume}] Volume of injection in mL. + \item [\code{MIinjection\_route}] String identifying administration + route of injection. +\end{description} + +\section{NetCDF routines} + +Because it is necessary to use NetCDF routines to access MINC files, a +brief description of all NetCDF routines is provided here. For more +information, see the NetCDF User's Guide. Note that the header file +netcdf.h is automatically included by the header file minc.h. + +\subsection{Error handling} + +If an error occurs, the default behaviour is to print an error message +and exit. It is possible to change this behaviour by modifying the +value of the global variable ncopts. The default setting is +\begin{verbatim} + ncopts = NC_VERBOSE | NC_FATAL; +\end{verbatim} +which means print error messages and exit when an error occurs. To +get error messages without having fatal errors, set +\begin{verbatim} + ncopts = NC_VERBOSE; +\end{verbatim} +For neither error messages nor fatal errors, set +\begin{verbatim} + ncopts = 0; +\end{verbatim} + +In these last two cases, the calling routine should check the function +value returned by each call to a NetCDF function. All routines return +an integer value. If the value is $-1$ (\code{MI\_ERROR}), then an +error has occurred. The value of the global variable \code{ncerr} +gives more information on the type of error (see file \code{netcdf.h} +for error codes). + +\subsection{NetCDF file operations} + +\begin{itemize} + +\item \code{nccreate} : Create the file specified by \code{path}. +The argument \code{cmode} must have a +value of either \code{NC\_CLOBBER} or \code{NC\_NOCLOBBER}. The return +value is an identifier for the NetCDF file and is used by subsequent +NetCDF function calls. +\begin{verbatim} +int nccreate(char* path,int cmode); +\end{verbatim} + +\item \code{ncopen} : Open the file specified by \code{path}. \code{mode} +must have value +\code{NC\_NOWRITE} or \code{NC\_WRITE}. The return value is a NetCDF +file identifier. +\begin{verbatim} +int ncopen(char* path,int mode); +\end{verbatim} + +\item \code{ncredef} : Put an open file into define mode. +\begin{verbatim} +int ncredef(int cdfid); +\end{verbatim} + +\item \code{ncendef} : Put file into data mode. +\begin{verbatim} +int ncendef(int cdfid); +\end{verbatim} + +\item \code{ncclose} : Close a NetCDF file. +\begin{verbatim} +int ncclose(int cdfid); +\end{verbatim} + +\item \code{ncinquire} : Inquire about the number of dimensions in a file, the +number of +variables, the number of global attributes or the id of the unlimited +record dimension. Passing a NULL value for any of the pointers means +do not return the associated value. +\begin{verbatim} +int ncinquire(int cdfid,int* ndims,int* nvars,int* natts,int* recdim); +\end{verbatim} + +\item \code{ncsync} : Synchronize an open file to disk. +\begin{verbatim} +int ncsync(int cdfid); +\end{verbatim} + +\item \code{ncabort} : Abort any changes to the file if it is in define mode. +\begin{verbatim} +int ncabort(int cdfid); +\end{verbatim} + +\end{itemize} + +\subsection{Dimension operations} + +\begin{itemize} + +\item \code{ncdimdef} : Define a dimension with a name and a length. The +return value is a +dimension id to be used in subsequent calls. +\begin{verbatim} +int ncdimdef(int cdfid,char* name,long length); +\end{verbatim} + +\item \code{ncdimid} : Get a dimension id from a name. +\begin{verbatim} +int ncdimid(int cdfid,char* name); +\end{verbatim} + +\item \code{ncdiminq} : Inquire about a dimension (name or length). +\begin{verbatim} +int ncdiminq(int cdfid,int dimid,char* name,long* length); +\end{verbatim} + +\item \code{ncdimrename} : Rename a dimension. +\begin{verbatim} +int ncdimrename(int cdfid,int dimid,char* name); +\end{verbatim} + +\end{itemize} + +\subsection{Variable operations} + +\begin{itemize} + +\item \code{ncvardef} : Define a variable by name, giving its datatype, number +of dimensions +and the dimension id's that subscript the variable. Returns a variable +id to be used in subsequent calls. +\begin{verbatim} +int ncvardef(int cdfid,char* name,nc_type datatype,int ndims,int dim[]); +\end{verbatim} + +\item \code{ncvarid} : Get a variable id from a name. +\begin{verbatim} +int ncvarid(int cdfid,char* name); +\end{verbatim} + +\item \code{ncvarinq} : Inquire about a variable. Any NULL pointers mean do +not return the +associated value. It is possible to get the variable name, type, +number of dimensions, dimension id's and number of attributes. +\begin{verbatim} +int ncvarinq(int cdfid,int varid,char* name,nc_type* datatype,int* ndims, + int dim[],int* natts); +\end{verbatim} + +\item \code{ncvarput1} : Store a single value at the coordinate specified by +\code{coords}. +\code{value} must be of the correct data type. +\begin{verbatim} +int ncvarput1(int cdfid,int varid,long coords[],void* value); +\end{verbatim} + +\item \code{ncvarget1} : Get a single value from the coordinate specified by +coords. +\begin{verbatim} +int ncvarget1(int cdfid,int varid,long coords[],void* value); +\end{verbatim} + +\item \code{ncvarput} : Put a hyperslab (multi-dimensional rectangle) of +values starting at +\code{start} with edge lengths given by \code{count}. For the C +interface, the last dimension varies fastest. Values must be of the +correct type. +\begin{verbatim} +int ncvarput(int cdfid,int varid,long start[],long count[],void* value); +\end{verbatim} + +\item \code{ncvarget} : Get a hyperslab (multi-dimensional rectangle) of +values starting at +\code{start} with edge lengths given by \code{count}. For the C +interface, the last dimension varies fastest. Values must be of the +correct type. +\begin{verbatim} +int ncvarget(int cdfid,int varid,long start[],long count[],void* value); +\end{verbatim} + +\item \code{ncvarrename} : Rename a variable. +\begin{verbatim} +int ncvarrename(int cdfid,int varid,char* name); +\end{verbatim} + +\item \code{ncattput} : Store an attribute by name with variable \code{varid}. +The type and +length of the attribute must be specified. +\begin{verbatim} +int ncattput(int cdfid,int varid,char* name,nc_type datatype,int len, + void* value); +\end{verbatim} + +\item \code{ncattinq} : Inquire about an attribute by name. Can get either +type or length. +\begin{verbatim} +int ncattinq(int cdfid,int varid,char* name,nc_type* datatype,int* len); +\end{verbatim} + +\item \code{ncattget} : Get an attribute's value by name. +\begin{verbatim} +int ncattget(int cdfid,int varid,char* name,void* value); +\end{verbatim} + +\item \code{ncattcopy} : Copy an attribute from one variable to another. +\begin{verbatim} +int ncattcopy(int incdf,int invar,char* name,int outcdf,int outvar); +\end{verbatim} + +\item \code{ncattname} : Get the name of an attribute from its number. The +number is not an id, +but can change as the number of attributes associated with a variable +changes. Attribute numbers run from 0 to natts-1. +\begin{verbatim} +int ncattname(int cdfid,int varid,int attnum,char* name); +\end{verbatim} + +\item \code{ncattrename} : Rename an attribute. +\begin{verbatim} +int ncattrename(int cdfid,int varid,char* name,char* newname); +\end{verbatim} + +\item \code{ncattdel} : Delete an attribute. +\begin{verbatim} +int ncattdel(int cdfid,int varid,char* name); +\end{verbatim} + +\item \code{nctypelen} : Get the length (in bytes) of a data type. +\begin{verbatim} +int nctypelen(nc_type datatype); +\end{verbatim} + +\item \code{ncsetfill} : When \code{ncendef} is called, all variables are +filled with a fill +value by default. To turn this off, call this routine with +\code{fillmode} set to \code{NC\_NOFILL} (to turn it back on, use +\code{NC\_FILL}). +\begin{verbatim} +int ncsetfill(int cdfid,int fillmode); +\end{verbatim} + +\end{itemize} + +\section{MINC routines} + +Error handling for MINC routines is the same as for NetCDF functions, +with the exception that routines returning pointers will return +\code{NULL} instead of \code{MI\_ERROR} when an error occurs. Error +codes (returned in \code{ncerr}) can be found in the header file +minc.h. + +\subsection{General convenience functions} + +\begin{itemize} + +\item \code{miattget} : Like \code{ncattget}, but the caller specifies +the desired numeric type and maximum number of values to get. Type is +specified with \code{datatype} (the sign is the default for the type: +\code{MI\_UNSIGNED} for \code{NC\_BYTE} and \code{MI\_SIGNED} +otherwise). \code{max\_length} gives the maximum number of values to +get and \code{att\_length} returns the number of values actually read. +An error will occur if the attribute type is not numeric. +\begin{verbatim} +public int miattget(int cdfid, int varid, char *name, nc_type datatype, + int max_length, void *value, int *att_length); +\end{verbatim} + +\item \code{miattget1} : Like \code{miattget}, but only one value is +returned. If there is more than one value, an error occurs. +\begin{verbatim} +public int miattget1(int cdfid, int varid, char *name, nc_type datatype, + void *value); +\end{verbatim} + +\item \code{miattgetstr} : Gets a string value from an attribute. +\code{maxlen} gives the maximum number of characters to be returned +(including the terminating \verb+'\0'+). The string is written to the array +specified by value and a pointer to the string is returned. +\begin{verbatim} +public char *miattgetstr(int cdfid, int varid, char *name, + int maxlen, char *value); +\end{verbatim} + +\item \code{miattputint} : Write an integer attribute. +\begin{verbatim} +public int miattputint(int cdfid, int varid, char *name, int value); +\end{verbatim} + +\item \code{miattputdbl} : Write a double precision attribute. +\begin{verbatim} +public int miattputdbl(int cdfid, int varid, char *name, double value); +\end{verbatim} + +\item \code{miattputstr} : Write a string attribute. +\begin{verbatim} +public int miattputstr(int cdfid, int varid, char *name, char *value); +\end{verbatim} + +\item \code{mivarget} : Like \code{ncvarget}, but the caller specifies +the desired numeric type and sign (either \code{MI\_SIGNED} or +\code{MI\_UNSIGNED}). +\begin{verbatim} +public int mivarget(int cdfid, int varid, long start[], long count[], + nc_type datatype, char *sign, void *values); +\end{verbatim} + +\item \code{mivarget1} : Like \code{ncvarget1}, but the caller +specifies the desired numeric type and sign. +\begin{verbatim} +public int mivarget1(int cdfid, int varid, long mindex[], + nc_type datatype, char *sign, void *value); +\end{verbatim} + +\item \code{mivarput} : Like \code{ncvarput}, but the caller specifies +the numeric type and sign of the values being passed. +\begin{verbatim} +public int mivarput(int cdfid, int varid, long start[], long count[], + nc_type datatype, char *sign, void *values); +\end{verbatim} + +\item \code{mivarput1} : Like \code{ncvarput1}, but the caller specifies +the numeric type and sign of the values being passed. +\begin{verbatim} +public int mivarput1(int cdfid, int varid, long mindex[], + nc_type datatype, char *sign, void *value); +\end{verbatim} + +\item \code{miset\_coords} : Set \code{nvals} values of the coordinate +vector \code{coords} to \code{value}. A pointer to \code{coords} is +returned. +\begin{verbatim} +public long *miset_coords(int nvals, long value, long coords[]); +\end{verbatim} + +\item \code{mitranslate\_coords} : Translates the coordinate vector +\code{incoords} for subscripting variable \code{invar} of file +\code{cdfid} to vector \code{outcoords} for subscripting variable +\code{outvar}. This is useful when two variables have similar +dimensions, but not necessarily the same order of dimensions. If +\code{invar} has a dimension that is not in \code{outvar}, then the +corresponding coordinate is ignored. If \code{outvar} has a dimension +that is not in \code{invar}, then the corresponding coordinate is not +modified. A pointer to \code{outcoords} is returned. +\begin{verbatim} +public long *mitranslate_coords(int cdfid, + int invar, long incoords[], + int outvar, long outcoords[]); +\end{verbatim} + +\item \code{micopy\_all\_atts} : Copy all of the attributes of one +variable to another (possibly across files). +\begin{verbatim} +public int micopy_all_atts(int incdfid, int invarid, + int outcdfid, int outvarid); +\end{verbatim} + +\item \code{micopy\_var\_def} : Copy a variable definition (including +attributes) from one file to another. \code{outcdfid} must be in +define mode. +\begin{verbatim} +public int micopy_var_def(int incdfid, int invarid, int outcdfid); +\end{verbatim} + +\item \code{micopy\_var\_values} : Copy a variable's values from one +file to another. \code{incdfid} and \code{outcdfid} must be in data +mode. +\begin{verbatim} +public int micopy_var_values(int incdfid, int invarid, + int outcdfid, int outvarid); +\end{verbatim} + +\item \code{micopy\_all\_var\_defs} : Copy all variable definitions from +one file to another, excluding a list of variables. The list of +\code{nexclude} variable id's is given in \code{excluded\_vars}. +\code{outcdfid} must be in define mode. +\begin{verbatim} +public int micopy_all_var_defs(int incdfid, int outcdfid, int nexclude, + int excluded_vars[]); +\end{verbatim} + +\item \code{micopy\_all\_var\_values} : Copy all variable values from one +file to another, excluding a list of variables. The list of +\code{nexclude} variable id's is given in \code{excluded\_vars}. +\code{outcdfid} must be in define mode. +\begin{verbatim} +public int micopy_all_var_values(int incdfid, int outcdfid, int nexclude, + int excluded_vars[]); +\end{verbatim} + +\end{itemize} + +\subsection{MINC-specific convenience functions} + +\begin{itemize} + +\item \code{miattput\_pointer} : Create an attribute \code{name} in the +variable \code{varid} that points to the variable \code{ptrvarid}. +\begin{verbatim} +public int miattput_pointer(int cdfid, int varid, char *name, int ptrvarid); +\end{verbatim} + +\item \code{miattget\_pointer} : Returns the variable id pointed to by +attribute \code{name} of variable \code{varid}. +\begin{verbatim} +public int miattget_pointer(int cdfid, int varid, char *name); +\end{verbatim} + +\item \code{miadd\_child} : Add the name of variable +\code{child\_varid} to the \code{MIchildren} attribute of variable +\code{parent\_varid} and set the \code{MIparent} attribute of variable +\code{child\_varid} to the name of variable \code{parent\_varid}. If +the attributes do not exist, they are created. The names in the +attribute \code{MIchildren} are separated by newlines. +\begin{verbatim} +public int miadd_child(int cdfid, int parent_varid, int child_varid); +\end{verbatim} + +\item \code{micreate\_std\_variable} : Create any of the standard MINC +variables and set some attributes. Called in the manner of +\code{ncvardef}. For all variable, attributes \code{MIvarid}, +\code{MIvartype} and \code{MIversion} are all set. For dimension +variables, \code{MIspacing} is set to \code{MI\_REGULAR} and +\code{MIalignment} is set to \code{MI\_CENTRE} (unless the variable is +\code{MItime}, then it is set to \code{MI\_START}). For dimension +width variables, \code{MIspacing} is set to \code{MI\_REGULAR} and +\code{MIfiltertype} is set to \code{MI\_SQUARE}. For \code{MIimage} +and for \code{MIimagemax} and \code{MIimagemin}, dimensions are +checked to ensure that the last two do not vary over image dimensions +and attribute pointers from \code{MIimage} are created to point to the +other two. +\begin{verbatim} +public int micreate_std_variable(int cdfid, char *name, nc_type datatype, + int ndims, int dim[]); +\end{verbatim} + +\item \code{micreate\_group\_variable} : Like +\code{micreate\_std\_variable}, but \code{ndims} is always set to zero +and the datatype is \code{NC\_LONG}. +\begin{verbatim} +public int micreate_group_variable(int cdfid, char *name); +\end{verbatim} + +\end{itemize} + +\subsection{Image conversion variable functions} + +\begin{itemize} + +\item \code{miicv\_create} : Create an image conversion variable and +set the defaults --- an icv identifier is returned for later use (or +\code{MI\_ERROR} if an error occurs). A maximum of +\code{MI\_MAX\_NUM\_ICV} icv's can exist at one time (this is set to +the value of \code{MAX\_NC\_OPEN} which is 32 by default). +\begin{verbatim} +public int miicv_create(); +\end{verbatim} + +\item \code{miicv\_free} : Free an image conversion variable. +\begin{verbatim} +public int miicv_free(int icvid); +\end{verbatim} + +\item \code{miicv\_setdbl} : Set a double precision icv property. +\begin{verbatim} +public int miicv_setdbl(int icvid, int icv_property, double value); +\end{verbatim} + +\item \code{miicv\_setint} : Set an integer icv property +(\code{MI\_ICV\_ADIM\_SIZE} and \code{MI\_ICV\_BDIM\_SIZE} can also be +set with this routine, even though they are long values). +\begin{verbatim} +public int miicv_setint(int icvid, int icv_property, int value); +\end{verbatim} + +\item \code{miicv\_set} : Set an icv property. A pointer to the value +is passed - this value must be of the correct type since no compiler +or run-time checking is done. +\begin{verbatim} +public int miicv_set(int icvid, int icv_property, void *value); +\end{verbatim} + +\item \code{miicv\_inq} : Inquire about an icv property. \code{value} +points to a the variable in which the value should be returned (the +variable must of the correct type). +\begin{verbatim} +public int miicv_inq(int icvid, int icv_property, void *value); +\end{verbatim} + +\item \code{miicv\_attach} : Attach a MINC file and image variable to +an icv. Note that icv properties cannot be modified while a variable +is attached to the icv. If a variable is already attached to the icv, +then it is automatically detached. The file \code{icvid} must be in +data mode. +\begin{verbatim} +public int miicv_attach(int icvid, int cdfid, int varid); +\end{verbatim} + +\item \code{miicv\_ndattach} : Like \code{miicv\_attach} but no +dimension conversion facilities are available (much like setting +\code{MI\_ICV\_DO\_DIM\_CONV} to \code{FALSE}). This avoids linking in +all of the dimension conversion routines when they are not needed (for +machines where memory may be a concern). +\begin{verbatim} +public int miicv_ndattach(int icvid, int cdfid, int varid); +\end{verbatim} + +\item \code{miicv\_detach} : Detach a variable from an icv. +\begin{verbatim} +public int miicv_detach(int icvid); +\end{verbatim} + +\item \code{miicv\_get} : Get a hyperslab of values from a variable +through an icv. +\begin{verbatim} +public int miicv_get(int icvid, long start[], long count[], void *values); +\end{verbatim} + +\item \code{miicv\_put} : Put a hyperslab of values to a variable +through an icv. +\begin{verbatim} +public int miicv_put(int icvid, long start[], long count[], void *values); +\end{verbatim} + +\end{itemize} + +\section{Image conversion variable properties} + +\begin{itemize} + +\item \code{MI\_ICV\_TYPE} (type \code{nc\_type}) : Specifies the type +of values that the user wants. Modifying this property automatically +causes \code{MI\_ICV\_VALID\_MAX} and \code{MI\_ICV\_VALID\_MIN} to +be set to their default values. Default = \code{NC\_SHORT}. + +\item \code{MI\_ICV\_SIGN} (type \code{char []}) : Specifies the sign of +values that the user wants (irrelevant for floating point types). +Modifying this property automatically causes +\code{MI\_ICV\_VALID\_MAX} and \code{MI\_ICV\_VALID\_MIN} to be set to +their default values. Default = \code{MI\_SIGNED}. + +\item \code{MI\_ICV\_DO\_RANGE} (type \code{int}) : When \code{TRUE}, +range conversions (for valid max and min and for value normalization) +are done. When \code{FALSE}, values are not modified. Default = +\code{TRUE}. + +\item \code{MI\_ICV\_VALID\_MAX} (type \code{double}) : Valid maximum +value (ignored for floating point types). Default = maximum legal +value for type and sign (1.0 for floating point types). + +\item \code{MI\_ICV\_VALID\_MIN} (type \code{double}) : Valid minimum +value (ignored for floating point types). Default = minimum legal +value for type and sign (1.0 for floating point types). + +\item \code{MI\_ICV\_DO\_NORM} (type \code{int}) : If \code{TRUE}, +then normalization of values is done (see user guide for details of +normalization). Default = \code{FALSE}. + +\item \code{MI\_ICV\_USER\_NORM} (type \code{int}) : If \code{TRUE}, +then the user specifies the normalization maximum and minimum. If +\code{FALSE}, values are taken as maximum and minimum for whole image +variable. Default = \code{FALSE}. + +\item \code{MI\_ICV\_IMAGE\_MAX} (type \code{double}) : Image maximum +for user normalization. Default = 1.0. + +\item \code{MI\_ICV\_IMAGE\_MIN} (type \code{double}) : Image minimum +for user normalization. Default = 0.0. + +\item \code{MI\_ICV\_NORM\_MAX} (type \code{double}) : Read-only value +giving the user image maximum when doing normalization (either the +maximum in the variable or the user specified maximum). + +\item \code{MI\_ICV\_NORM\_MIN} (type \code{double}) : Read-only value +giving the user image minimum when doing normalization (either the +minimum in the variable or the user specified minimum). + +\item \code{MI\_ICV\_DO\_DIM\_CONV} (type \code{int}) : If set to +\code{TRUE}, then dimension conversions may be done. Default = +\code{FALSE}. + +\item \code{MI\_ICV\_DO\_SCALAR} (type \code{int}) : If \code{TRUE}, +then if \code{MIvector\_dimension} is the fastest varying dimension of +the variable, elements are averaged and the icv behaves as though this +dimension did not exist. Default = \code{TRUE}. + +\item \code{MI\_ICV\_XDIM\_DIR} (type \code{int}) : Indicates the +desired orientation of the x image dimensions (\code{MIxspace} and +\code{MIxfrequency}). Values can be one of \code{MI\_ICV\_POSITIVE}, +\code{MI\_ICV\_NEGATIVE} or \code{MI\_ICV\_ANYDIR}. A positive +orientation means that the \code{MIstep} attribute of the dimension is +positive. \code{MI\_ICV\_ANYDIR} means that no flipping is done. +Default = \code{MI\_ICV\_POSITIVE}. + +\item \code{MI\_ICV\_YDIM\_DIR} (type \code{int}) : Indicates the +desired orientation of the y image dimensions. Default = +\code{MI\_ICV\_POSITIVE}. + +\item \code{MI\_ICV\_ZDIM\_DIR} (type \code{int}) : Indicates the +desired orientation of the z image dimensions. Default = +\code{MI\_ICV\_POSITIVE}. + +\item \code{MI\_ICV\_ADIM\_SIZE} (type \code{long}) : Specifies the +desired size of the fastest varying image dimension. A value of +\code{MI\_ICV\_ANYSIZE} means that the actual size of the dimension +should be used. This value can be specified through a call to +\code{miicv\_setint} --- the conversion to \code{int} is done +automatically. Default = \code{MI\_ICV\_ANYSIZE}. + +\item \code{MI\_ICV\_BDIM\_SIZE} (type \code{long}) : Specifies the +desired size of the second image dimension. This value can be +specified through a call to \code{miicv\_setint} --- the conversion +to \code{int} is done automatically. Default = +\code{MI\_ICV\_ANYSIZE}. + +\item \code{MI\_ICV\_KEEP\_ASPECT} (type \code{int}) : If \code{TRUE}, +then image dimensions are resized by the same amount so that aspect +ratio is maintained. Default = \code{TRUE}. + +\item \code{MI\_ICV\_ADIM\_STEP} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstep} for the +first (fastest varying) image dimension after dimension conversion. + +\item \code{MI\_ICV\_BDIM\_STEP} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstep} for the +second image dimension after dimension conversion. + +\item \code{MI\_ICV\_ADIM\_START} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstart} for the +first (fastest varying) image dimension after dimension conversion. + +\item \code{MI\_ICV\_BDIM\_START} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstart} for the +second image dimension after dimension conversion. + +\item \code{MI\_ICV\_NUM\_IMGDIMS} (type \code{int}) : Specifies the +number of image dimensions used in dimension conversions. Default = 2. + +\item \code{MI\_ICV\_DIM\_SIZE} (type \code{long}) : Specifies the +desired size of an image dimension. The number of the dimension to be +changed should be added to the property (adding zero corresponds to +the fastest varying dimension). This value can be +specified through a call to \code{miicv\_setint} --- the conversion +to \code{int} is done automatically. Default = +\code{MI\_ICV\_ANYSIZE}. + +\item \code{MI\_ICV\_DIM\_STEP} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstep} for the +an image dimension after dimension conversion. The number of the +dimension to be queried should be added to the property (adding zero +corresponds to the fastest varying dimension). + +\item \code{MI\_ICV\_DIM\_START} (type \code{double}) : Read-only +property that gives the equivalent of attribute \code{MIstart} for an +image dimension after dimension conversion. The number of the +dimension to be queried should be added to the property (adding zero +corresponds to the fastest varying dimension). + +\end{itemize} + +\section{Known bugs} + +\begin{itemize} + +\item The NetCDF package will crash on a rename system call in the +routine \code{ncendef} if the environment variable \code{TMPDIR} is set +when \code{ncredef} is called. + +\item For dimension conversion with image conversion variables, the +values of \code{MI\_ICV\_DIM\_START}, \code{MI\_ICV\_ADIM\_START} and +\code{MI\_ICV\_BDIM\_START} are computed assuming that +\code{MIalignment} is equal to \code{MI\_CENTRE}. + +\end{itemize} + +\end{document} +