changeset 72:88eb55ed2a4a

Initial revision
author neelin <neelin>
date Fri, 22 Jan 1993 09:00:51 +0000
parents ac73ce020b77
children d3c53d43b3ee
files conversion/scxtominc/Makefile conversion/scxtominc/isotope_list.h conversion/scxtominc/scx_file.c conversion/scxtominc/scx_file.h conversion/scxtominc/scx_header_def.h conversion/scxtominc/scxtominc.c
diffstat 6 files changed, 1964 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/Makefile
@@ -0,0 +1,79 @@
+# --------------------------------------------------------------------
+#
+# MINC Makefile
+#
+
+# Executable names
+PROGS    = scxtominc
+EXTRA_OBJS = scx_file.o
+HEADERS  = scx_file.h
+PROG_LIB_DIR = ../proglib
+PROG_LIB  = mincprog
+LIB_DIR  = ../../src#                         directory for library
+LIBRARY  = minc#                           library
+CDEFINES = -DDEBUG#                        cpp defines
+OPT      = -g#                             compiler options
+LDOPT    = -L/usr/local/lib -lnetcdf -lsun -lm -lgl_s -lm -lc_s # ld options
+INCLUDES = -I. -I../proglib -I../../src -I/usr/local/include
+
+# For cleaning up
+RM       = rm
+RM_FLAGS = -f
+
+# --------------------------------------------------------------------
+
+CFLAGS    = $(CDEFINES) $(INCLUDES) $(OPT)# CFLAGS and LINTFLAGS should
+LINTFLAGS = $(CDEFINES) $(INCLUDES)#        be same, except for -g/-O
+
+PROG_OBJ  = $(PROGS:=.o)#                 list of objects
+CC_LIB    = lib$(LIBRARY).a#              C library file
+CC_PROG_LIB= $(PROG_LIB_DIR)/lib$(PROG_LIB).a# library for prog objs
+LINT_LIST = $(PROG_OBJ:.o=.ln)
+LINT_EXTRA= $(EXTRA_OBJS:.o=.ln)
+LINT_LIST_EXE = $(LINT_LIST:.ln=.)#       list of executable names to lint
+LINT_LIB  = llib-l$(LIBRARY).ln#          lint library file
+LINT_PROG_LIB = $(PROG_LIB_DIR)/llib-l$(PROG_LIB).ln#
+
+# --------------------------------------------------------------------
+
+.SUFFIXES: .ln#                           tell make to watch for .ln's
+
+default: $(PROGS)
+
+#Dependency on Makefile
+$(PROG_OBJ) $(LINT_OBJS) : Makefile
+
+all: $(PROGS) lint
+
+.c.ln:#                                   defines the rule for creating .ln
+	lint $(LINTFLAGS) -c $< -o $@
+
+.c.o:#                                    defines the rule for creating .o
+	$(CC) $(CFLAGS) -c $< -o $@
+
+#Dependency of .o and .ln on .h
+$(PROG_OBJ) $(EXTRA_OBJS) : $(HEADERS)
+
+$(LINT_LIST) $(LINT_EXTRA) : $(HEADERS)
+
+# How to make executables
+$(PROGS) : $$@.o $(EXTRA_OBJS) $(CC_PROG_LIB) $(LIB_DIR)/$(CC_LIB)
+	$(CC) -o $@ $@.o $(EXTRA_OBJS) $(CC_PROG_LIB) -L$(LIB_DIR) -l$(LIBRARY) $(LDOPT)
+
+#  how to lint the executable source
+lint: $(LINT_LIST_EXE)
+
+$(LINT_LIST_EXE) : $$@ln $(LINT_EXTRA) $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+	lint -u $(LINTFLAGS) $@ln $(LINT_EXTRA) $(LINT_PROG_LIB) $(LIB_DIR)/$(LINT_LIB)
+
+# Remove all derived files in this directory
+clean:
+	$(RM) $(RM_FLAGS) $(LINT_LIST) $(PROGS) $(PROG_OBJ)
+
+# Dependencies for scx file routines
+scx_file.o scx_file.ln : scx_header_def.h
+
+# How to create scx_header_def.h
+scx_header_def.h : define_scx_header.perl pc5r1.drs
+	define_scx_header.perl scx_header_def.h pc5r1.drs
+
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/isotope_list.h
@@ -0,0 +1,24 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : isotope_list.h
+@DESCRIPTION: Header file containing list of isotopes and their half-lives.
+@METHOD     : 
+@GLOBALS    : isotope_list
+@CALLS      : 
+@CREATED    : January 13, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+struct {
+   char *name;
+   double half_life;      /* Half life in seconds */
+} isotope_list[] = {
+   {"GA-68", 68.3*60.0},
+   {"C-11", 20.3*60.0},
+   {"F-18", 109.8*60.0},
+   {"O-15", 2.03*60.0},
+   {"N-13", 9.96*60.0},
+   {"GE-68", 414720*60.0},
+   {"CU-64", 762*60.0},
+   {"CS-137", 999999*60.0},
+   {NULL, -1.0}
+};
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/scx_file.c
@@ -0,0 +1,472 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_file.c
+@DESCRIPTION: File containing routines to read scanditronix image files
+@GLOBALS    : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+#ifndef lint
+static char rcsid[]="$Header: /private-cvsroot/minc/conversion/scxtominc/scx_file.c,v 1.1 1993-01-22 09:00:51 neelin Exp $";
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <scx_header_def.h>
+#include <scx_file.h>
+#include <vax_conversions.h>
+
+/* Private functions */
+private void scx_get_value(unsigned char *header, long position, 
+                           scx_mnem_types type, int length, 
+                           long *lvalue, float *fvalue, char *svalue);
+
+/* Constants */
+#define TRUE 1
+#define FALSE 0
+#define HEADER_SIZE 2048
+#define FILE_TYPE_POSITION 0
+#define FILE_TYPE_TYPE scx_word
+#define SCX_NCS  "NCS"
+#define SCX_SPOS "SPOS"
+#define SCX_DPR  "DPR"
+#define SCX_FHS  "FHS"
+#define SCX_REC  "REC"
+#define SCX_DTYP "DTYP"
+#define SCX_IMFM "IMFM"
+#define SCX_SPOS "SPOS"
+#define MAX_PIX_SIZE 2
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_open
+@INPUT      : filename - name of file to open
+@OUTPUT     : (none)
+@RETURNS    : Pointer to scanditronix file descriptor or NULL if an error 
+              occurs.
+@DESCRIPTION: Routine to open a scanditronix file (for reading only), given 
+              its pathname.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+public scx_file *scx_open(char *filename)
+{
+   scx_file *file;
+   long file_type, nslice, spos;
+   int i;
+
+   /* Allocate space for a scx file structure */
+   file = malloc(sizeof(scx_file));
+
+   /* Open the file */
+   if ((file->file_pointer=fopen(filename, "rb")) == NULL) {
+      free(file);
+      return NULL;
+   }
+
+   /* Read in the header */
+   file->header = malloc(HEADER_SIZE);
+   if (fread(file->header, sizeof(char), (size_t) HEADER_SIZE, 
+             file->file_pointer) != HEADER_SIZE) {
+      free(file->header);
+      free(file);
+      return NULL;
+   }
+
+   /* Get the file type from the header */
+   scx_get_value(file->header, FILE_TYPE_POSITION, FILE_TYPE_TYPE, 1,
+                 &file_type, NULL, NULL);
+
+   /* Search for the file type */
+   for (i=0; (scx_file_types[i].file_type!=0) && 
+             (file_type!=scx_file_types[i].file_type); i++) {}
+   if (scx_file_types[i].file_type==0) {
+      free(file->header);
+      free(file);
+      return NULL;
+   }
+   file->blocks = scx_file_types[i].block_list;
+   file->mnemonics = scx_file_types[i].mnemonic_list;
+
+   /* Get the number of mnemonics in the header */
+   for (i=0; file->mnemonics[i].name!=NULL; i++) {}
+   file->num_mnemonics = i;
+
+   /* Check for a consistent header by looking at the slice positions */
+   if (scx_get_mnem(file, SCX_NCS, 0, &nslice, NULL, NULL) || (nslice<=0)) {
+      free(file->header);
+      free(file);
+      return NULL;
+   }
+   for (i=0; i<nslice; i++) {
+      if (scx_get_mnem(file, SCX_SPOS, i, &spos, NULL, NULL) ||
+          (spos<0) || (spos>nslice)) {
+         free(file->header);
+         free(file);
+         return NULL;
+      }
+   }
+
+   return file;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_close
+@INPUT      : file - scanditronix file descriptor to close
+@OUTPUT     : (none)
+@RETURNS    : (nothing)
+@DESCRIPTION: Routine to close a scanditronix file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+public void scx_close(scx_file *file)
+{
+   if (file==NULL) return;
+   (void) fclose(file->file_pointer);
+   free(file->header);
+   free(file);
+
+   return;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_get_mnem
+@INPUT      : file - scanditronix file descriptor
+              mnem - mnemonic to find
+              multiplicity - index of value to get
+@OUTPUT     : lvalue - long integer value to return
+              fvalue - floating point value to return
+              svalue - string value to return
+@RETURNS    : TRUE if an error occurs, FALSE otherwise
+@DESCRIPTION: Routine to get a mnemonic's value from a scanditronix file
+              header.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+public int scx_get_mnem(scx_file *file, char *mnem, int multiplicity,
+                        long *lvalue, float *fvalue, char *svalue)
+{
+   scx_block_type *block_ptr;
+   scx_mnemonic_type *mnem_ptr;
+   long position;
+
+   /* Check file pointer */
+   if (file==NULL) return TRUE;
+
+   /* Check for negative multiplicity */
+   if (multiplicity < 0) return TRUE;
+
+   /* Search for the mnemonic */
+   for (mnem_ptr=file->mnemonics; 
+           (mnem_ptr->name!=NULL) && (strcmp(mnem_ptr->name, mnem)!=0);
+              mnem_ptr++) {}
+   if (mnem_ptr->name==NULL) return TRUE;
+
+   /* Check for a mnemonic not in the file (a constant). We only handle
+      integer constants */
+   if (!mnem_ptr->in_file) {
+      switch (mnem_ptr->type) {
+      case scx_byte:
+      case scx_word:
+      case scx_long:
+         if (lvalue!=NULL) *lvalue = mnem_ptr->mdefault;
+         if (fvalue!=NULL) *fvalue = mnem_ptr->mdefault;
+         if (svalue!=NULL) 
+            (void) sprintf(svalue, "%d", (int) mnem_ptr->mdefault);
+         break;
+      default:
+         return TRUE;
+      }
+   }
+
+   /* Mnemonic is in file header */
+   else {
+
+      /* Calculate the position of the mnemonic by looping through
+         the list of parent blocks */
+      position = mnem_ptr->start;
+      for (block_ptr = mnem_ptr->block;
+              (multiplicity>0) && (block_ptr!=NULL);
+                 block_ptr = block_ptr->parent) {
+         position += block_ptr->length *
+            (multiplicity % block_ptr->multiplicity);
+         multiplicity /= block_ptr->multiplicity;
+      }
+      if (multiplicity > 0) return TRUE;
+
+      /* Get the value */
+      scx_get_value(file->header, position, mnem_ptr->type, mnem_ptr->length,
+                    lvalue, fvalue, svalue);
+
+   }
+
+   return FALSE;
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_get_value
+@INPUT      : header - pointer to header data
+              position - postion of value to read
+              type - type of value to get
+              length - number of values to get
+@OUTPUT     : lvalue - long integer value to return
+              fvalue - floating point value to return
+              svalue - string value to return
+@RETURNS    : (nothing)
+@DESCRIPTION: Routine to get a mnemonic's value from a scanditronix file
+              header, given the position and type.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+private void scx_get_value(unsigned char *header, long position, 
+                           scx_mnem_types type, int length, 
+                           long *lvalue, float *fvalue, char *svalue)
+{
+   void *data;
+   unsigned char *bdata;
+   short *idata;
+   long *ldata;
+   float *fdata;
+
+   /* Check length */
+   if (length<=0) return;
+   
+   /* Get the values */
+   data = malloc(length * scx_mnem_type_size[type]);
+   bdata = data; idata = data; ldata = data; fdata = data;
+   switch (type) {
+   case scx_byte:
+   case scx_string:
+   case scx_time:
+   case scx_date:
+      (void) memcpy(bdata, &header[position], length);
+      break;
+   case scx_word:
+   case scx_short_float:
+      get_vax_short(length, &header[position], idata);
+      break;
+   case scx_long:
+      get_vax_long(length, &header[position], ldata);
+      break;
+   case scx_float:
+      get_vax_float(length, &header[position], fdata);
+   }
+
+   /* Convert the values */
+   switch (type) {
+   case scx_byte:
+      if (lvalue!=NULL) *lvalue = bdata[0];
+      if (fvalue!=NULL) *fvalue = bdata[0];
+      if (svalue!=NULL) (void) sprintf(svalue, "%d", (int) bdata[0]);
+      break;
+   case scx_string:
+      if (lvalue!=NULL) *lvalue = 0;
+      if (fvalue!=NULL) *fvalue = 0;
+      if (svalue!=NULL) {
+         (void) memcpy(svalue, bdata, length);
+         svalue[length]='\0';
+      }
+      break;
+   case scx_time:
+      if (lvalue!=NULL) *lvalue = 0;
+      if (fvalue!=NULL) *fvalue = 0;
+      if (svalue!=NULL) {
+         if (length==3)
+            (void) sprintf(svalue, "%02d:%02d:%02d", 
+                           (int) bdata[0], (int) bdata[1], (int) bdata[2]);
+         else if (length==4)
+            (void) sprintf(svalue, "%02d:%02d:%02d.%02d", 
+                           (int) bdata[0], (int) bdata[1], 
+                           (int) bdata[2], (int) bdata[3]);
+         else
+            svalue[0]='\0';
+      }
+      break;
+   case scx_date:
+      if (lvalue!=NULL) *lvalue = 0;
+      if (fvalue!=NULL) *fvalue = 0;
+      if (svalue!=NULL) {
+         if (length==3)
+            (void) sprintf(svalue, "%02d-%02d-%02d", 
+                           (int) bdata[0], (int) bdata[1], (int) bdata[2]);
+         else
+            svalue[0]='\0';
+      }
+      break;
+   case scx_word:
+      if (lvalue!=NULL) *lvalue = idata[0];
+      if (fvalue!=NULL) *fvalue = idata[0];
+      if (svalue!=NULL) (void) sprintf(svalue, "%d", (int) idata[0]);
+      break;
+   case scx_short_float:
+      if (lvalue!=NULL) *lvalue = idata[0]/100.0;
+      if (fvalue!=NULL) *fvalue = idata[0]/100.0;
+      if (svalue!=NULL) (void) sprintf(svalue, "%8g", (double) idata[0]/100.0);
+      break;
+   case scx_long:
+      if (lvalue!=NULL) *lvalue = ldata[0];
+      if (fvalue!=NULL) *fvalue = ldata[0];
+      if (svalue!=NULL) (void) sprintf(svalue, "%d", (int) ldata[0]);
+      break;
+   case scx_float:
+      if (lvalue!=NULL) *lvalue = fdata[0];
+      if (fvalue!=NULL) *fvalue = fdata[0];
+      if (svalue!=NULL) (void) sprintf(svalue, "%8g", (double) fdata[0]);
+      break;
+   }
+
+   free(data);
+      
+   return;
+
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_get_image
+@INPUT      : file - scanditronix file pointer
+              image_num - image to get (first image is zero)
+@OUTPUT     : image - pointer to array into which image should be written.
+@RETURNS    : TRUE if an error occurs, false otherwise.
+@DESCRIPTION: Routine to get an image from a scanditronix image file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 11, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+public int scx_get_image(scx_file *file, int image_num, short *image)
+{
+   long data_present, header_size, record_size, data_type;
+   long image_width, image_pos, image_npix, image_size;
+   long file_offset, array_offset, ipix;
+   int pix_size;
+   unsigned char *bimage;
+
+   /* Check file pointer */
+   if (file==NULL) return TRUE;
+
+   /* Check that data is in file */
+   if (scx_get_mnem(file, SCX_DPR, 0, &data_present, NULL, NULL) || 
+       (data_present!=1)) {
+      return TRUE;
+   }
+
+   /* Parameters for calculating image position */
+   if (scx_get_mnem(file, SCX_FHS, 0, &header_size, NULL, NULL) ||
+       scx_get_mnem(file, SCX_REC, 0, &record_size, NULL, NULL) ||
+       scx_get_mnem(file, SCX_DTYP, 0, &data_type, NULL, NULL) ||
+       scx_get_mnem(file, SCX_IMFM, 0, &image_width, NULL, NULL) ||
+       scx_get_mnem(file, SCX_SPOS, image_num, &image_pos, NULL, NULL) ||
+       (header_size<0) || (record_size<0) || (image_width<0) ||
+       (image_pos<0)) {
+      return TRUE;
+   }
+
+   /* Check that image is in file */
+   if (image_pos<1) return TRUE;
+
+   /* Check data type */
+   switch (data_type) {
+   case 0: pix_size=2; break;
+   case 1: pix_size=1; break;
+   default: return TRUE;
+   }
+
+   /* Calculate image size and offsets */
+   image_npix = image_width * image_width;
+   image_size = image_npix * pix_size;
+   file_offset = header_size * record_size + (image_pos-1) * image_size;
+   array_offset = image_npix * (MAX_PIX_SIZE - pix_size);
+   bimage = (unsigned char *) image;
+
+   /* Read in the image */
+   if (fseek(file->file_pointer, file_offset, SEEK_SET) ||
+       (fread(&bimage[array_offset], (size_t) pix_size, (size_t) image_npix, 
+              file->file_pointer) != image_npix)) {
+      return TRUE;
+   }
+
+   /* Transform the image to the right type */
+   switch (pix_size) {
+   case 1:
+      for (ipix=0; ipix<image_npix; ipix++) {
+         image[ipix] = bimage[array_offset+ipix];
+      }
+      break;
+   case 2:
+      get_vax_short(image_npix, image, image);
+      break;
+   default:
+      return TRUE;
+   }
+
+   return FALSE;
+
+}
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_list_mnems
+@INPUT      : file - pointer to an open scanditronix file
+              index - counter to identify next mnemonic
+@OUTPUT     : mname - pointer to array into which name should be written
+              mmult - multiplicity of mnemonic
+              mtype - type of mnemonic (can be scx_long, scx_float or 
+                 scx_string)
+@RETURNS    : Value of mname or NULL if index out of range.
+@DESCRIPTION: Routine to list the mnemonics that can be found in a scanditronix
+              file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 19, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+public char *scx_list_mnems(scx_file *file,int index, char *mname, 
+                            int *mmult, scx_mnem_types *mtype)
+{
+   scx_block_type *block_ptr;
+
+   /* Check file pointer and index */
+   if ((file == NULL) || (index < 0) || (index >= file->num_mnemonics))
+      return NULL;
+
+   /* Copy the name */
+   (void) strcpy(mname, file->mnemonics[index].name);
+
+   /* Get the multiplicity */
+   *mmult = 1;
+   for (block_ptr = file->mnemonics[index].block;
+        block_ptr!=NULL;
+        block_ptr = block_ptr->parent) {
+      *mmult *= block_ptr->multiplicity;
+   }
+
+   /* Get the mnemonic type */
+   switch (file->mnemonics[index].type) {
+   case scx_byte: *mtype = scx_long; break;
+   case scx_string: *mtype = scx_string; break;
+   case scx_time: *mtype = scx_string; break;
+   case scx_date: *mtype = scx_string; break;
+   case scx_word: *mtype = scx_long; break;
+   case scx_short_float: *mtype = scx_float; break;
+   case scx_long: *mtype = scx_long; break;
+   case scx_float: *mtype = scx_float; break;
+   }
+
+   return mname;
+
+}
+
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/scx_file.h
@@ -0,0 +1,40 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scx_file.h
+@DESCRIPTION: Header file for routines that read scanditonix image files
+@GLOBALS    : 
+@CREATED    : January 8, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+#ifndef public
+#define public
+#endif
+#ifndef private
+#define private static
+#endif
+
+#ifndef SCX_FILE_HEADER_DEFINITION_H
+typedef struct {int dummy;}  scx_block_type;
+typedef struct {int dummy;}  scx_mnemonic_type;
+typedef enum scx_mnem_types_enum {
+   scx_time, scx_byte, scx_string, scx_short_float, scx_date, scx_float, 
+   scx_word, scx_long
+} scx_mnem_types;
+#endif
+
+typedef struct {
+   FILE *file_pointer;
+   scx_block_type *blocks;
+   scx_mnemonic_type *mnemonics;
+   int num_mnemonics;
+   void *header;
+} scx_file;
+
+/* Routine declarations */
+public scx_file *scx_open(char *filename);
+public void scx_close(scx_file *file);
+public int scx_get_mnem(scx_file *file, char *mnem, int multiplicity,
+                        long *lvalue, float *fvalue, char *svalue);
+public int scx_get_image(scx_file *file, int image_num, short *image);
+public char *scx_list_mnems(scx_file *file,int index, char *mname, 
+                            int *mmult, scx_mnem_types *mtype);
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/scx_header_def.h
@@ -0,0 +1,168 @@
+
+/* Header file for scanditronix file definition */
+#ifndef SCX_FILE_HEADER_DEFINITION_H
+#define SCX_FILE_HEADER_DEFINITION_H
+
+/* Mnemonic types */
+typedef enum scx_mnem_types_enum 
+   {scx_time, scx_byte, scx_string, scx_short_float, scx_date, scx_float, scx_word, scx_long} scx_mnem_types;
+static int scx_mnem_type_size[] =
+   {1, 1, 1, 2, 1, 4, 2, 4};
+
+/* Block type */
+typedef struct scx_block_struct scx_block_type;
+struct scx_block_struct {
+   int length;
+   int multiplicity;
+   scx_block_type *parent;
+};
+
+/* Mnemonic type */
+typedef struct scx_mnemonic_struct scx_mnemonic_type;
+struct scx_mnemonic_struct {
+   char *name;
+   scx_mnem_types type;
+   int length;
+   int in_file;
+   long mdefault;
+   long start;
+   scx_block_type *block;
+};
+
+
+/* Blocks for drs file with id pc_5_r_1 */
+static scx_block_type drs_block_pc_5_r_1[] = {
+   1872, 1, NULL,
+   4, 8, &(drs_block_pc_5_r_1[0]),
+   4, 8, &(drs_block_pc_5_r_1[0]),
+   18, 5, &(drs_block_pc_5_r_1[0]),
+   18, 1, &(drs_block_pc_5_r_1[0]),
+   87, 15, &(drs_block_pc_5_r_1[0]),
+   2, 32, &(drs_block_pc_5_r_1[5]),
+   4, 15, &(drs_block_pc_5_r_1[0]),
+   0, 0, NULL
+};
+
+
+/* Mnemonics for drs file with id pc_5_r_1 */
+static scx_mnemonic_type drs_mnems_pc_5_r_1[] = {
+   "FHS", scx_byte, 1, 0, 4, -1, &(drs_block_pc_5_r_1[0]),
+   "REC", scx_word, 1, 0, 512, -1, &(drs_block_pc_5_r_1[0]),
+   "TYP", scx_word, 1, 1, 5, 0, &(drs_block_pc_5_r_1[0]),
+   "NCS", scx_byte, 1, 1, 15, 2, &(drs_block_pc_5_r_1[0]),
+   "SITE", scx_string, 4, 1, 0, 3, &(drs_block_pc_5_r_1[0]),
+   "REV", scx_word, 1, 1, 1, 7, &(drs_block_pc_5_r_1[0]),
+   "NDET", scx_word, 1, 1, 256, 9, &(drs_block_pc_5_r_1[0]),
+   "NPRO", scx_word, 1, 1, 256, 11, &(drs_block_pc_5_r_1[0]),
+   "NMEM", scx_word, 1, 1, 48, 13, &(drs_block_pc_5_r_1[0]),
+   "NWOB", scx_byte, 1, 1, 5, 15, &(drs_block_pc_5_r_1[0]),
+   "CDI", scx_short_float, 1, 1, 0, 16, &(drs_block_pc_5_r_1[0]),
+   "CSZ", scx_short_float, 1, 1, 0, 18, &(drs_block_pc_5_r_1[0]),
+   "CSX", scx_short_float, 1, 1, 0, 20, &(drs_block_pc_5_r_1[0]),
+   "RID", scx_string, 10, 1, 0, 22, &(drs_block_pc_5_r_1[0]),
+   "RIN", scx_long, 1, 1, 0, 32, &(drs_block_pc_5_r_1[0]),
+   "ETN", scx_word, 1, 1, 0, 36, &(drs_block_pc_5_r_1[0]),
+   "PNM", scx_string, 24, 1, 0, 38, &(drs_block_pc_5_r_1[0]),
+   "BRN", scx_long, 1, 1, 0, 62, &(drs_block_pc_5_r_1[0]),
+   "ASS", scx_string, 22, 1, 0, 66, &(drs_block_pc_5_r_1[0]),
+   "DOC", scx_string, 22, 1, 0, 88, &(drs_block_pc_5_r_1[0]),
+   "DAT", scx_date, 3, 1, 0, 110, &(drs_block_pc_5_r_1[0]),
+   "DATY", scx_byte, 1, 1, 0, 110, &(drs_block_pc_5_r_1[0]),
+   "DATM", scx_byte, 1, 1, 0, 111, &(drs_block_pc_5_r_1[0]),
+   "DATD", scx_byte, 1, 1, 0, 112, &(drs_block_pc_5_r_1[0]),
+   "TIM", scx_time, 4, 1, 0, 113, &(drs_block_pc_5_r_1[0]),
+   "TIMH", scx_byte, 1, 1, 0, 113, &(drs_block_pc_5_r_1[0]),
+   "TIMM", scx_byte, 1, 1, 0, 114, &(drs_block_pc_5_r_1[0]),
+   "TIMS", scx_byte, 1, 1, 0, 115, &(drs_block_pc_5_r_1[0]),
+   "TIHU", scx_byte, 1, 1, 0, 116, &(drs_block_pc_5_r_1[0]),
+   "QES", scx_string, 12, 1, 0, 117, &(drs_block_pc_5_r_1[0]),
+   "POR", scx_string, 4, 1, 0, 129, &(drs_block_pc_5_r_1[0]),
+   "PAN", scx_word, 1, 1, 0, 133, &(drs_block_pc_5_r_1[0]),
+   "CLV", scx_short_float, 1, 1, 0, 135, &(drs_block_pc_5_r_1[0]),
+   "ZDI", scx_short_float, 1, 1, 0, 137, &(drs_block_pc_5_r_1[0]),
+   "NRV", scx_word, 1, 1, 0, 139, &(drs_block_pc_5_r_1[0]),
+   "NME", scx_word, 1, 1, 0, 141, &(drs_block_pc_5_r_1[0]),
+   "MTM", scx_float, 1, 1, 0, 143, &(drs_block_pc_5_r_1[0]),
+   "RPRT", scx_short_float, 1, 1, 0, 147, &(drs_block_pc_5_r_1[0]),
+   "ISO", scx_string, 6, 1, 0, 149, &(drs_block_pc_5_r_1[0]),
+   "HALF", scx_float, 1, 1, 0, 155, &(drs_block_pc_5_r_1[0]),
+   "CAR", scx_string, 8, 1, 0, 159, &(drs_block_pc_5_r_1[0]),
+   "ACT", scx_float, 1, 1, 0, 167, &(drs_block_pc_5_r_1[0]),
+   "INP", scx_string, 4, 1, 0, 171, &(drs_block_pc_5_r_1[0]),
+   "INT", scx_string, 4, 1, 0, 175, &(drs_block_pc_5_r_1[0]),
+   "ITM", scx_time, 3, 1, 0, 179, &(drs_block_pc_5_r_1[0]),
+   "ITMH", scx_byte, 1, 1, 0, 179, &(drs_block_pc_5_r_1[0]),
+   "ITMM", scx_byte, 1, 1, 0, 180, &(drs_block_pc_5_r_1[0]),
+   "ITMS", scx_byte, 1, 1, 0, 181, &(drs_block_pc_5_r_1[0]),
+   "COL", scx_string, 1, 1, 0, 182, &(drs_block_pc_5_r_1[0]),
+   "SAMP", scx_byte, 1, 1, 0, 183, &(drs_block_pc_5_r_1[0]),
+   "DTYP", scx_byte, 1, 1, 0, 184, &(drs_block_pc_5_r_1[0]),
+   "FOV", scx_byte, 1, 1, 0, 185, &(drs_block_pc_5_r_1[0]),
+   "PRJL", scx_word, 1, 1, 0, 186, &(drs_block_pc_5_r_1[0]),
+   "TILT", scx_short_float, 1, 1, 0, 188, &(drs_block_pc_5_r_1[0]),
+   "SLEW", scx_short_float, 1, 1, 0, 190, &(drs_block_pc_5_r_1[0]),
+   "ELV", scx_word, 1, 1, 0, 192, &(drs_block_pc_5_r_1[0]),
+   "TIW", scx_short_float, 1, 1, 0, 194, &(drs_block_pc_5_r_1[0]),
+   "COM", scx_string, 20, 1, 0, 196, &(drs_block_pc_5_r_1[0]),
+   "STYP", scx_byte, 1, 1, 0, 216, &(drs_block_pc_5_r_1[0]),
+   "BLAN", scx_long, 1, 1, 0, 217, &(drs_block_pc_5_r_1[0]),
+   "TRAN", scx_long, 1, 1, 0, 221, &(drs_block_pc_5_r_1[0]),
+   "PAR", scx_byte, 1, 1, 0, 225, &(drs_block_pc_5_r_1[0]),
+   "NORM", scx_word, 1, 1, 0, 226, &(drs_block_pc_5_r_1[0]),
+   "DPR", scx_byte, 1, 1, 0, 228, &(drs_block_pc_5_r_1[0]),
+   "TNM", scx_string, 8, 1, 0, 229, &(drs_block_pc_5_r_1[0]),
+   "FERR", scx_long, 1, 1, 0, 237, &(drs_block_pc_5_r_1[0]),
+   "FLOS", scx_float, 1, 1, 0, 241, &(drs_block_pc_5_r_1[0]),
+   "INVA", scx_float, 1, 1, 0, 245, &(drs_block_pc_5_r_1[0]),
+   "TRAT", scx_float, 1, 1, 0, 249, &(drs_block_pc_5_r_1[0]),
+   "TAC", scx_word, 1, 1, 0, 253, &(drs_block_pc_5_r_1[0]),
+   "IMFM", scx_word, 1, 1, 0, 255, &(drs_block_pc_5_r_1[0]),
+   "IMTP", scx_string, 10, 1, 0, 257, &(drs_block_pc_5_r_1[0]),
+   "IMUN", scx_string, 10, 1, 0, 267, &(drs_block_pc_5_r_1[0]),
+   "PXS", scx_short_float, 1, 1, 0, 277, &(drs_block_pc_5_r_1[0]),
+   "FFN", scx_string, 4, 1, 0, 279, &(drs_block_pc_5_r_1[0]),
+   "FWD", scx_short_float, 1, 1, 0, 283, &(drs_block_pc_5_r_1[0]),
+   "SLOT", scx_word, 1, 1, 0, 285, &(drs_block_pc_5_r_1[0]),
+   "CNTX", scx_string, 10, 1, 0, 287, &(drs_block_pc_5_r_1[0]),
+   "AGE", scx_byte, 1, 1, 0, 297, &(drs_block_pc_5_r_1[0]),
+   "SEX", scx_string, 1, 1, 0, 298, &(drs_block_pc_5_r_1[0]),
+   "MAX", scx_word, 1, 1, 0, 299, &(drs_block_pc_5_r_1[0]),
+   "SING", scx_float, 1, 1, 0, 335, &(drs_block_pc_5_r_1[1]),
+   "XRAT", scx_float, 1, 1, 0, 367, &(drs_block_pc_5_r_1[2]),
+   "USR", scx_float, 1, 1, 0, 399, &(drs_block_pc_5_r_1[3]),
+   "USI", scx_long, 1, 1, 0, 403, &(drs_block_pc_5_r_1[3]),
+   "USC", scx_string, 10, 1, 0, 407, &(drs_block_pc_5_r_1[3]),
+   "CYCL", scx_float, 1, 1, 0, 489, &(drs_block_pc_5_r_1[4]),
+   "CYCH", scx_float, 1, 1, 0, 493, &(drs_block_pc_5_r_1[4]),
+   "GTLL", scx_short_float, 1, 1, 0, 497, &(drs_block_pc_5_r_1[4]),
+   "GTLH", scx_short_float, 1, 1, 0, 499, &(drs_block_pc_5_r_1[4]),
+   "GTNR", scx_byte, 1, 1, 0, 501, &(drs_block_pc_5_r_1[4]),
+   "FRNR", scx_word, 1, 1, 0, 502, &(drs_block_pc_5_r_1[4]),
+   "DCY", scx_short_float, 1, 1, 0, 504, &(drs_block_pc_5_r_1[4]),
+   "NGAT", scx_byte, 1, 1, 0, 506, &(drs_block_pc_5_r_1[4]),
+   "STOT", scx_float, 1, 1, 0, 507, &(drs_block_pc_5_r_1[5]),
+   "CAL", scx_float, 1, 1, 0, 511, &(drs_block_pc_5_r_1[5]),
+   "MAG", scx_float, 1, 1, 0, 515, &(drs_block_pc_5_r_1[5]),
+   "SPOS", scx_byte, 1, 1, 0, 519, &(drs_block_pc_5_r_1[5]),
+   "SCA", scx_float, 1, 1, 0, 520, &(drs_block_pc_5_r_1[5]),
+   "RAN", scx_float, 1, 1, 0, 524, &(drs_block_pc_5_r_1[5]),
+   "DTC", scx_short_float, 1, 1, 0, 528, &(drs_block_pc_5_r_1[5]),
+   "PERX", scx_byte, 1, 1, 0, 530, &(drs_block_pc_5_r_1[6]),
+   "PERY", scx_byte, 1, 1, 0, 531, &(drs_block_pc_5_r_1[6]),
+   "OFFS", scx_float, 1, 1, 0, 1812, &(drs_block_pc_5_r_1[7]),
+   NULL, scx_byte, 0, 0, 0, NULL
+};
+
+
+/* List of drs files and types */
+
+static struct {
+   int file_type;
+   scx_block_type *block_list;
+   scx_mnemonic_type *mnemonic_list;
+} scx_file_types[] = {
+   5, drs_block_pc_5_r_1, drs_mnems_pc_5_r_1,
+   0, NULL, NULL
+};
+
+#endif  /* SCX_FILE_HEADER_DEFINITION_H */
new file mode 100644
--- /dev/null
+++ b/conversion/scxtominc/scxtominc.c
@@ -0,0 +1,1181 @@
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : scxtominc
+@INPUT      : argc, argv - command line arguments
+@OUTPUT     : (none)
+@RETURNS    : error status
+@DESCRIPTION: Converts scanditronix format files to a minc format file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 11, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+
+#ifndef lint
+static char rcsid[]="$Header: /private-cvsroot/minc/conversion/scxtominc/scxtominc.c,v 1.1 1993-01-22 09:01:15 neelin Exp $";
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <math.h>
+#include <ParseArgv.h>
+#include <scx_file.h>
+#include <minc.h>
+#include "isotope_list.h"
+
+/* Macro definitions */
+#define  MALLOC( n_items, type ) \
+   ( malloc( (size_t) (n_items) * sizeof(type) ) )
+#define  REALLOC( ptr, n_items, type ) \
+   ( realloc( (void *) ptr, (size_t) (n_items) * sizeof(type) ) )
+#define  FREE( ptr ) \
+   free( (void *) ptr )
+
+/* Type declarations */
+typedef struct {
+   char name[8];
+   int mult;
+   nc_type type;
+   void *att_vector;
+} scx_mnem_list_type;
+
+typedef struct {
+   int nslices;
+   int low_slice;
+   int high_slice;
+   double scan_time;
+   double time_width;
+   double half_life;
+   double zstart;
+   double zstep;
+   char isotope[16];
+   int image_size;
+   int ordered_file;
+   int *ordered_slices;
+} scx_file_info_type;
+
+typedef struct {
+   int num_scx_slices;
+   int max_nslices;
+   int max_size;
+   float zwidth;
+   float xystep;
+   float xywidth;
+   long vmax;
+   char img_units[16];
+   char patient_name[32];
+   char patient_sex[8];
+   long patient_age;
+   char study_id[40];
+   char start_time[40];
+   long start_year;
+   long start_month;
+   long start_day;
+   long start_hour;
+   long start_minute;
+   float start_seconds;
+   char tracer[10];
+   char injection_time[40];
+   long injection_hour;
+   long injection_minute;
+   float injection_seconds;
+   float injection_dose;
+   scx_mnem_list_type *mnem_list;
+   int num_mnems;
+} scx_general_info_type;
+
+typedef struct {
+   double sort_key;
+   void *sort_value;
+} scx_sort_type;
+
+/* Function declarations */
+void usage_error(char *progname);
+int get_scx_file_info(int num_scx_files, char **scx_files, 
+                      int slice_range[2],
+                      scx_file_info_type *scx_file_info, 
+                      scx_general_info_type *scx_general_info);
+void sort_scx_slices(int sort_over_time, int num_scx_files, 
+                     scx_file_info_type *scx_file_info,
+                     scx_general_info_type *scx_general_info);
+int sortcmp(const void *val1, const void *val2);
+int setup_minc_file(int mincid, int write_byte_data, int copy_all_header,
+                    int ndims, long count[], int num_scx_files,
+                    scx_file_info_type *scx_file_info,
+                    scx_general_info_type *scx_general_info);
+int write_minc_slice(double scale, int write_byte_data,
+                     int mincid, int icvid, 
+                     int ndims,long start[], long count[], 
+                     short *image, int image_size, 
+                     long pixel_max, float image_max,
+                     double scan_time, double time_width, double zpos);
+int get_scx_slice(scx_file *scx_fp, int slice_num, 
+                  long *pixel_max, float *image_max, short *image, 
+                  scx_file_info_type *scx_file_info,
+                  scx_general_info_type *scx_general_info);
+double decay_correction(double scan_time, double measure_time, 
+                        double start_time, double half_life);
+
+/* Constants */
+#define TRUE 1
+#define FALSE 0
+#define MAX_DIMS 4
+#define HOURS_PER_DAY 24
+#define MIN_PER_HOUR 60
+#define SEC_PER_MIN 60
+
+/* Scanditronix mnemonics used */
+#define SCX_NCS  "NCS"
+#define SCX_IMFM "IMFM"
+#define SCX_DATY "DATY"
+#define SCX_DATM "DATM"
+#define SCX_DATD "DATD"
+#define SCX_TIM  "TIM"
+#define SCX_TIMH "TIMH"
+#define SCX_TIMM "TIMM"
+#define SCX_TIMS "TIMS"
+#define SCX_TIHU "TIHU"
+#define SCX_ITM  "ITM"
+#define SCX_ITMH "ITMH"
+#define SCX_ITMM "ITMM"
+#define SCX_ITMS "ITMS"
+#define SCX_MTM  "MTM"
+#define SCX_ISO  "ISO"
+#define SCX_CLV  "CLV"
+#define SCX_CDI  "CDI"
+#define SCX_CSZ  "CSZ"
+#define SCX_PXS  "PXS"
+#define SCX_MAX  "MAX"
+#define SCX_IMUN "IMUN"
+#define SCX_MAG  "MAG"
+#define SCX_FWD  "FWD"
+#define SCX_PNM  "PNM"
+#define SCX_SEX  "SEX"
+#define SCX_AGE  "AGE"
+#define SCX_RIN  "RIN"
+#define SCX_CAR  "CAR"
+#define SCX_ACT  "ACT"
+
+/* Main program */
+
+int main(int argc, char *argv[])
+{
+   /* Variables for arguments */
+   static int write_byte_data=TRUE;
+   static int sort_over_time=TRUE;
+   static int clobber=TRUE;
+   static int verbose=TRUE;
+   static int decay_correct=TRUE;
+   static int slice_range[2]={0, 9999};
+   static int copy_all_header=FALSE;
+
+   /* Argument option table */
+   static ArgvInfo argTable[] = {
+      {"-byte", ARGV_CONSTANT, (char *) TRUE, (char *) &write_byte_data,
+          "Write out data as bytes (default)."},
+      {"-short", ARGV_CONSTANT, (char *) FALSE, (char *) &write_byte_data,
+          "Write out data as short integers."},
+      {"-time", ARGV_CONSTANT, (char *) TRUE, (char *) &sort_over_time,
+          "Keep time ordering of data (default)."},
+      {"-zposition", ARGV_CONSTANT, (char *) FALSE, (char *) &sort_over_time,
+          "Sort data according to z position."},
+      {"-decay_correct", ARGV_CONSTANT, (char *) TRUE, (char *) &decay_correct,
+          "Do decay correction on images (default)."},
+      {"-nodecay_correct", ARGV_CONSTANT, (char *) FALSE, 
+          (char *) &decay_correct, "Don't do decay correction."},
+      {"-clobber", ARGV_CONSTANT, (char *) TRUE, (char *) &clobber,
+          "Overwrite existing file (default)."},
+      {"-noclobber", ARGV_CONSTANT, (char *) FALSE, (char *) &clobber,
+          "Don't overwrite existing file."},
+      {"-verbose", ARGV_CONSTANT, (char *) TRUE, (char *) &verbose,
+          "List files as they are converted (default)"},
+      {"-quiet", ARGV_CONSTANT, (char *) FALSE, (char *) &verbose,
+          "Do not list files as they are converted."},
+      {"-small_header", ARGV_CONSTANT, (char *) FALSE, 
+          (char *) &copy_all_header,
+          "Copy only basic header information (default)."},
+      {"-all_header", ARGV_CONSTANT, (char *) TRUE, (char *) &copy_all_header,
+          "Copy all scanditronix header information."},
+      {"-slices", ARGV_INT, (char *) 2, (char *) slice_range,
+          "Range of slices to copy."},
+      {NULL, ARGV_END, NULL, NULL, NULL}
+   };
+
+   /* Other variables */
+   char *pname;
+   char *mincfile;
+   char **scx_files;
+   int num_scx_files;
+   scx_file_info_type *scx_file_info;
+   scx_general_info_type *scx_general_info;
+   long count[MAX_DIMS], start[MAX_DIMS];
+   int ndims;
+   int mincid, icvid;
+   int islice, ifile, i, slice_num;
+   long pixel_max;
+   float image_max;
+   double scale;
+   short *image;
+   scx_file *scx_fp;
+   int status;
+
+   /* Check arguments */
+   pname = argv[0];
+   if (ParseArgv(&argc, argv, argTable, 0) || (argc < 3)) {
+      usage_error(pname);
+   }
+
+   /* Check the slice range */
+   if ((slice_range[0] < 0) || (slice_range[1] < 0) ||
+       (slice_range[1] < slice_range[0])) {
+      (void) fprintf(stderr, "%s: Error in slice range: %d to %d.\n",
+                     pname, slice_range[0], slice_range[1]);
+   }
+
+   /* Get file names */
+   mincfile = argv[argc-1];
+   argv[argc-1] = NULL;    /* Null-terminate scx file list */
+   num_scx_files = argc - 2;
+   scx_files = &argv[1];
+
+   /* Read the files to get basic information */
+   scx_general_info=MALLOC(1, *scx_general_info);
+   scx_file_info = MALLOC(num_scx_files, *scx_file_info);
+   status=get_scx_file_info(num_scx_files, scx_files, slice_range,
+                            scx_file_info, scx_general_info);
+   if (status >= 0) {
+      (void) fprintf(stderr, "%s: Error reading scanditronix file %s.\n", 
+                     pname, scx_files[status]);
+      return EXIT_FAILURE;
+   }
+
+   /* Allocate space for ordered slice list if sorting over z position */
+   if (!sort_over_time) {
+      for (ifile=0; ifile<num_scx_files; ifile++) {
+         scx_file_info[ifile].ordered_slices = 
+            MALLOC(scx_file_info[ifile].nslices, int);
+      }
+   }
+
+   /* Sort the slices */
+   sort_scx_slices(sort_over_time, num_scx_files, 
+                   scx_file_info, scx_general_info);
+ 
+   /* Setup the minc file using the first scanditronix file */
+   if (sort_over_time && (num_scx_files>1)) {
+      ndims = 4;
+      count[0]=num_scx_files;
+      count[1]=scx_general_info->max_nslices;
+   }
+   else {
+      ndims=3;
+      count[0]=scx_general_info->num_scx_slices;
+   }
+   count[ndims-1] = count[ndims-2] = scx_general_info->max_size;
+   mincid = nccreate(mincfile, (clobber ? NC_CLOBBER : NC_NOCLOBBER));
+   icvid=setup_minc_file(mincid, write_byte_data, copy_all_header,
+                         ndims, count, num_scx_files,
+                         scx_file_info, scx_general_info);
+   if (icvid==MI_ERROR) {
+      (void) fprintf(stderr, 
+                     "%s: Error setting up minc file %s from scx file %s.\n",
+                     pname, mincfile, scx_files[0]);
+      return EXIT_FAILURE;
+   }
+
+   /* Initialize minc start and count vectors */
+   for (i=0; i<ndims-2; i++) count[0]=1;
+   (void) miset_coords(ndims, (long) 0, start);
+
+   /* Set up values for decay correction */
+   scale = 1.0;
+
+   /* Allocate an image buffer */
+   image = MALLOC(scx_general_info->max_size * scx_general_info->max_size, 
+                  short);
+
+   /* Loop through files */
+   for (ifile=0; ifile<num_scx_files; ifile++) {
+
+      /* Open the scanditronix file */
+      if ((scx_fp=scx_open(scx_files[ifile]))==NULL) {
+         (void) fprintf(stderr, "%s: Error re-opening file %s.\n",
+                        pname, scx_files[0]);
+         return EXIT_FAILURE;
+      }
+
+      /* Print log message */
+      if (verbose) {
+         (void) fprintf(stderr, "Copying file %s.\n", scx_files[ifile]);
+      }
+
+      /* Get decay correction (scan time is already measured from injection
+         time) */
+      if (decay_correct) 
+         scale = decay_correction(scx_file_info[ifile].scan_time, 
+                                  scx_file_info[ifile].time_width,
+                                  0.0,
+                                  scx_file_info[ifile].half_life);
+      else
+         scale = 1.0;
+      
+      /* Loop through slices */
+      for (islice = 0; islice < scx_file_info[ifile].nslices; islice++) {
+
+         /* Set the minc coordinates */
+         if (sort_over_time && (num_scx_files>1)) {
+            start[0]=scx_file_info[ifile].ordered_file;
+            start[1]=islice;
+         }
+         else if (sort_over_time) 
+            start[0]=islice;
+         else
+            start[0]=scx_file_info[ifile].ordered_slices[islice];
+         count[ndims-1] = count[ndims-2] = scx_file_info[ifile].image_size;
+
+         /* Copy the slice */
+         slice_num = islice + scx_file_info[ifile].low_slice;
+         if (get_scx_slice(scx_fp, slice_num, &pixel_max, &image_max,
+                           image, &scx_file_info[ifile], scx_general_info) ||
+             write_minc_slice(scale, write_byte_data,
+                              mincid, icvid, ndims, start, count, 
+                              image, scx_file_info[ifile].image_size, 
+                              pixel_max, image_max,
+                              scx_file_info[ifile].scan_time,
+                              scx_file_info[ifile].time_width,
+                              scx_file_info[ifile].zstep * (double) slice_num +
+                              scx_file_info[ifile].zstart)) {
+            (void) fprintf(stderr, "%s: Error copying slice from file %s.\n",
+                           pname, scx_files[ifile]);
+            return EXIT_FAILURE;
+         }
+
+      }        /* End slice loop */
+
+      /* Close the scanditronix file */
+      scx_close(scx_fp);
+
+   }         /* End file loop */
+
+   (void) ncclose(mincid);
+
+   FREE(image);
+   if (!sort_over_time) {
+      for (ifile=0; ifile<num_scx_files; ifile++) {
+         FREE(scx_file_info[ifile].ordered_slices);
+      }
+   }
+   FREE(scx_file_info);
+   FREE(scx_general_info);
+
+   return EXIT_SUCCESS;
+
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : usage_error
+@INPUT      : progname - program name
+@OUTPUT     : (none)
+@RETURNS    : (nothing)
+@DESCRIPTION: Prints a usage error message and exits.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 11, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void usage_error(char *progname)
+{
+   (void) fprintf(stderr, 
+             "\nUsage: %s [<options>] <infile> [...] <outfile>\n", progname);
+   (void) fprintf(stderr,   
+               "       %s [-help]\n\n", progname);
+
+   exit(EXIT_FAILURE);
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_scx_file_info
+@INPUT      : num_scx_files - number of scanditronix files.
+              scx_files - array of scanditronix file names.
+              slice_range - 2-component array giving range of slices
+@OUTPUT     : scx_file_info - array of structures containing information
+                 about each file.
+              scx_general_info - general information about the scx files.
+@RETURNS    : (-1) if no error occurs, otherwise, the index (in scx_file)
+              of the first file that could not be read.
+@DESCRIPTION: Reads information from each scanditronix file given by scx_files.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 12, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int get_scx_file_info(int num_scx_files, char **scx_files, 
+                      int slice_range[2],
+                      scx_file_info_type *scx_file_info, 
+                      scx_general_info_type *scx_general_info)
+{
+   static char *the_months[]=
+      {NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", 
+          "Aug", "Sep", "Oct", "Nov", "Dec"};
+   int *num_scx_slices, *max_nslices, *max_size;
+   scx_file *fp;
+   scx_file_info_type *sfip;
+   long lvalue, timh, timm, tims, tihu, daty, datm, datd;
+   float fvalue;
+   char svalue[40];
+   struct tm the_time;
+   double inj_time;
+   int ifile, i, imnem, imult, length;
+   scx_mnem_types mtype;
+   scx_mnem_list_type *mnem_list;
+   void *att_vector;
+
+   /* Initialize number of scanditronix slices */
+   num_scx_slices = &(scx_general_info->num_scx_slices);
+   max_nslices = &(scx_general_info->max_nslices);
+   max_size = &(scx_general_info->max_size);
+   *num_scx_slices = 0;
+   *max_nslices = 0;
+   *max_size = 0;
+
+   /* Loop through files, reading information */
+   for (ifile=0; ifile<num_scx_files; ifile++) {
+
+      /* Open file */
+      fp=scx_open(scx_files[ifile]);
+      if (fp==NULL) return ifile;
+      sfip = &scx_file_info[ifile];
+
+      /* Get number of slices */
+      if (scx_get_mnem(fp, SCX_NCS, 0, &lvalue, NULL, NULL)) return ifile;
+      sfip->low_slice = 0; 
+      sfip->high_slice = lvalue - 1;
+      if (slice_range[0] > sfip->low_slice)
+         sfip->low_slice = slice_range[0];
+      if (slice_range[1] < sfip->high_slice)
+         sfip->high_slice = slice_range[1];
+      if (sfip->low_slice > sfip->high_slice)
+         sfip->low_slice = sfip->high_slice;
+      sfip->nslices = sfip->high_slice - sfip->low_slice + 1;
+      *num_scx_slices += sfip->nslices;
+      if (sfip->nslices > *max_nslices) 
+         *max_nslices = sfip->nslices;
+
+      /* Get image width */
+      if (scx_get_mnem(fp, SCX_IMFM, 0, &lvalue, NULL, NULL)) return ifile;
+      sfip->image_size = lvalue;
+      if (lvalue > *max_size) *max_size = lvalue;
+
+      /* Get time (in seconds) */
+      if (scx_get_mnem(fp, SCX_DATY, 0, &daty, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_DATM, 0, &datm, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_DATD, 0, &datd, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_TIMH, 0, &timh, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_TIMM, 0, &timm, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_TIMS, 0, &tims, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_TIHU, 0, &tihu, NULL, NULL)) {
+         return ifile;
+      }
+      the_time.tm_sec  = tims;
+      the_time.tm_min  = timm;
+      the_time.tm_hour = timh;
+      the_time.tm_mday = datd;
+      the_time.tm_mon  = datm;
+      the_time.tm_year = daty;
+      the_time.tm_isdst= FALSE;
+      sfip->scan_time = 
+         (double) mktime(&the_time) + (double) tihu/100.0;
+
+      /* Get injection time (in seconds) (use date from before and check
+         for time before inj_time) */
+      if (scx_get_mnem(fp, SCX_ITMH, 0, &timh, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_ITMM, 0, &timm, NULL, NULL) ||
+          scx_get_mnem(fp, SCX_ITMS, 0, &tims, NULL, NULL)) {
+         return ifile;
+      }
+      the_time.tm_sec  = tims;
+      the_time.tm_min  = timm;
+      the_time.tm_hour = timh;
+      the_time.tm_isdst= FALSE;
+      inj_time = (double) mktime(&the_time);
+
+      /* Set scan time to be from injection time. Check for scans over 
+         midnight (cannot deal with scans longer than 1 day */
+      sfip->scan_time -= inj_time;
+      if (sfip->scan_time < 0.0)
+         sfip->scan_time += HOURS_PER_DAY * MIN_PER_HOUR * SEC_PER_MIN;
+
+      /* Get length of frame (in seconds) */
+      if (scx_get_mnem(fp, SCX_MTM, 0, NULL, &fvalue, NULL))
+         return ifile;
+      sfip->time_width = fvalue;
+
+      /* Get isotope and half-life */
+      if (scx_get_mnem(fp, SCX_ISO, 0, NULL, NULL, 
+                       sfip->isotope))
+         return ifile;
+      for (i=0; isotope_list[i].name !=NULL; i++) {
+         if (strncmp(isotope_list[i].name, sfip->isotope, 
+                     strlen(isotope_list[i].name))==0)
+            break;
+      }
+      sfip->half_life = isotope_list[i].half_life;
+
+      /* Get z start and step (correct start for non-zero first slice */
+      if (scx_get_mnem(fp, SCX_CDI, 0, NULL, &fvalue, NULL)) return ifile;
+      sfip->zstep = fvalue;
+      if (scx_get_mnem(fp, SCX_CLV, 0, NULL, &fvalue, NULL)) return ifile;
+      sfip->zstart = fvalue + sfip->low_slice * sfip->zstep;
+
+      /* Get general information from first scx file */
+      if (ifile==0) {
+         if (scx_get_mnem(fp, SCX_CSZ, 0, 
+                          NULL, &scx_general_info->zwidth, NULL))
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_PXS, 0,
+                          NULL, &scx_general_info->xystep, NULL))
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_FWD, 0, 
+                          NULL, &scx_general_info->xywidth, NULL))
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_MAX, 0, 
+                          &scx_general_info->vmax, NULL, NULL))
+            return MI_ERROR;
+         if ((scx_general_info->vmax<=0) || (scx_general_info->vmax>32767))
+            scx_general_info->vmax=32000;
+         if (scx_get_mnem(fp, SCX_IMUN, 0, 
+                          NULL, NULL, scx_general_info->img_units))
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_PNM, 0,
+                          NULL, NULL, scx_general_info->patient_name)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_SEX, 0,
+                          NULL, NULL, scx_general_info->patient_sex)) 
+            return MI_ERROR;
+         if (scx_general_info->patient_sex[0]=='M')
+            (void) strcpy(scx_general_info->patient_sex, MI_MALE);
+         else if (scx_general_info->patient_sex[0]=='F')
+            (void) strcpy(scx_general_info->patient_sex, MI_FEMALE);
+         else
+            (void) strcpy(scx_general_info->patient_sex, MI_OTHER);
+         if (scx_get_mnem(fp, SCX_AGE, 0,
+                          &scx_general_info->patient_age, NULL, NULL))
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_RIN, 0,
+                          NULL, NULL, scx_general_info->study_id)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_DATY, 0,
+                          &scx_general_info->start_year, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_DATM, 0,
+                          &scx_general_info->start_month, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_DATD, 0,
+                          &scx_general_info->start_day, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_TIMH, 0,
+                          &scx_general_info->start_hour, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_TIMM, 0,
+                          &scx_general_info->start_minute, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_TIMS, 0,
+                          NULL, &scx_general_info->start_seconds, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_TIHU, 0,
+                          NULL, &fvalue, NULL)) 
+            return MI_ERROR;
+         scx_general_info->start_seconds += fvalue/100.0;
+         if (scx_get_mnem(fp, SCX_TIM, 0, NULL, NULL, svalue))
+            return MI_ERROR;
+         (void) sprintf(scx_general_info->start_time, "%d-%s-%d %s",
+                        (int) scx_general_info->start_day,
+                        the_months[scx_general_info->start_month],
+                        (int) scx_general_info->start_year+1900,
+                        svalue);
+         if (scx_get_mnem(fp, SCX_CAR, 0,
+                          NULL, NULL, scx_general_info->tracer)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_ITM, 0,
+                          NULL, NULL, scx_general_info->injection_time)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_ITMH, 0,
+                          &scx_general_info->injection_hour, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_ITMM, 0,
+                          &scx_general_info->injection_minute, NULL, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_ITMS, 0,
+                          NULL, &scx_general_info->injection_seconds, NULL)) 
+            return MI_ERROR;
+         if (scx_get_mnem(fp, SCX_ACT, 0,
+                          NULL, &scx_general_info->injection_dose, NULL)) 
+            return MI_ERROR;
+
+         /* Get list of header values */
+
+         /* Get space for first mnemonic */
+         mnem_list = MALLOC(1, *mnem_list);
+
+         /* Loop through mnemonics */
+         for (imnem=0; 
+              scx_list_mnems(fp, imnem, mnem_list[imnem].name, 
+                             &mnem_list[imnem].mult, &mtype)!=NULL;
+              imnem++){
+
+            /* Get space for attributes (handle strings differently) */
+            switch (mtype) {
+            case scx_string:
+               mnem_list[imnem].type = NC_CHAR;
+               length = 2;
+               att_vector = MALLOC(length, char);
+               *((char *) att_vector) = '\0';
+               break;
+            case scx_long:
+               mnem_list[imnem].type = NC_LONG;
+               att_vector = MALLOC(mnem_list[imnem].mult, long);
+               break;
+            case scx_float:
+               mnem_list[imnem].type = NC_FLOAT;
+               att_vector = MALLOC(mnem_list[imnem].mult, float); 
+               break;
+            }
+         
+            /* Loop through multiplicity */
+            for (imult=0; imult < mnem_list[imnem].mult; imult++) {
+               if (scx_get_mnem(fp, mnem_list[imnem].name, imult, 
+                                &lvalue, &fvalue, svalue))
+                  return MI_ERROR;
+               switch (mtype) {
+               case scx_string:
+                  if (imult>0) {
+                     *((char *) att_vector + length - 2) = '\n';
+                     *((char *) att_vector + length - 1) = '\0';
+                     length += 1;
+                  }
+                  length += strlen(svalue);
+                  att_vector = REALLOC(att_vector, length, char);
+                  att_vector = strcat((char *) att_vector, svalue);
+                  break;
+               case scx_long:
+                  *(((long *) att_vector) + imult) = lvalue;
+                  break;
+               case scx_float:
+                  *(((float *) att_vector) + imult) = fvalue;
+                  break;
+               }
+               
+            }  /* Loop over multiplicity */
+
+            /* Save length of string */
+            if (mtype==scx_string) {
+               mnem_list[imnem].mult = length;
+            }
+            
+            /* Save pointer to attributes */
+            mnem_list[imnem].att_vector = att_vector;
+
+            /* Get space for next mnemonic */
+            mnem_list = REALLOC(mnem_list, imnem+2, *mnem_list);
+         }
+         scx_general_info->mnem_list=mnem_list;
+         scx_general_info->num_mnems=imnem;
+            
+      }  /* If first file */
+
+      /* Close file */
+      scx_close(fp);
+
+   }   /* Loop over files */
+
+   return -1;
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : sort_scx_slices
+@INPUT      : sort_over_time - boolean indicating whether sort should be
+                 over time or z position.
+              num_scx_files - number of scanditronix files.
+              scx_file_info - array of scanditronix file information.
+              scx_general_info - general information about scx files. 
+@OUTPUT     : scx_file_info - modified to give slice ordering information.
+@RETURNS    : (nothing)
+@DESCRIPTION: Sorts the scanditronix slices for the output file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 12, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+void sort_scx_slices(int sort_over_time, int num_scx_files, 
+                     scx_file_info_type *scx_file_info,
+                     scx_general_info_type *scx_general_info)
+{
+   int ifile, islice, isort, num_sort, slice_num;
+   /* Variables for sorting */
+   scx_sort_type *scx_sort;
+   struct {
+      int file;
+      int slice;
+   } *slice_ptr;
+   scx_file_info_type *file_ptr;
+
+   /* Allocate array for sorting */
+   num_sort = (sort_over_time) ? num_scx_files : 
+                                 scx_general_info->num_scx_slices;
+   scx_sort = MALLOC (num_sort, *scx_sort);
+
+   /* Are we sorting over time or z position */
+   if (sort_over_time) {
+      /* Go through the files */
+      for (ifile=0; ifile<num_scx_files; ifile++) {
+         scx_sort[ifile].sort_key = scx_file_info[ifile].scan_time;
+         scx_sort[ifile].sort_value = &scx_file_info[ifile];
+      }
+   }
+   /* Otherwise we are sorting over z position */
+   else {
+      /* Go through the files and slices */
+      isort=0;
+      for (ifile=0; ifile<num_scx_files; ifile++) {
+         for (islice = 0; islice < scx_file_info[ifile].nslices; islice++) {
+            slice_num = islice + scx_file_info[ifile].low_slice;
+            scx_sort[isort].sort_key = scx_file_info[ifile].zstart +
+               slice_num * scx_file_info[ifile].zstep;
+            slice_ptr = MALLOC(1, *slice_ptr);
+            slice_ptr->file = ifile;
+            slice_ptr->slice = islice;
+            scx_sort[isort].sort_value = slice_ptr;
+            isort++;
+         }
+      }
+   }
+
+   /* Sort the slices */
+   qsort(scx_sort, num_sort, sizeof(*scx_sort), sortcmp);
+
+   /* Loop through sorted list */
+   for (isort=0; isort<num_sort; isort++) {
+      if (sort_over_time) {
+         file_ptr=scx_sort[isort].sort_value;
+         file_ptr->ordered_file = isort;
+      }
+      else {
+         slice_ptr = scx_sort[isort].sort_value;
+         ifile = slice_ptr->file;
+         islice = slice_ptr->slice;
+         scx_file_info[ifile].ordered_slices[islice] = isort;
+         FREE(slice_ptr);
+      }
+   }
+
+   /* Free the sorting array */
+   FREE(scx_sort);
+
+   return;
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : sortcmp
+@INPUT      : val1 - first value
+              val2 - second value
+@OUTPUT     : (none)
+@RETURNS    : 0 if values are the same, -1 if val1->sort_key < val2->sort_key
+              and +1 if val1->sort_key > val2->sort_key.
+@DESCRIPTION: Compares two double precision values. If they are the same,
+              then return 0. If val1 < val2, return -1. If val1 > val2, 
+              return +1.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 12, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int sortcmp(const void *val1, const void *val2)
+{
+
+   if (((scx_sort_type *)val1)->sort_key < 
+       ((scx_sort_type *)val2)->sort_key) 
+      return -1;
+   else if (((scx_sort_type *)val1)->sort_key > 
+            ((scx_sort_type *)val2)->sort_key)
+      return 1;
+   else return 0;
+
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : setup_minc_file
+@INPUT      : mincid - id of minc file
+              write_byte_data - boolean indicating whether data should be
+                 written as bytes (TRUE) or shorts (FALSE).
+              copy_all_header - boolean indicating whether all of the 
+                 scanditronix header information should be copied or not.
+              ndims - number of dimensions for minc file
+              count - lengths of dimensions minc file
+              scx_filename - name of scanditronix file for header values
+              num_scx_files - number of scanditronix files.
+              scx_file_info - array of information on scanditronix files.
+              scx_general_info - general information about scx files
+@OUTPUT     : (nothing)
+@RETURNS    : Image conversion variable id or MI_ERROR if an error occurs.
+@DESCRIPTION: Initializes the header of the minc file using information from
+              the scanditronix file and the other structures.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 12, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int setup_minc_file(int mincid, int write_byte_data, int copy_all_header,
+                    int ndims, long count[], int num_scx_files,
+                    scx_file_info_type *scx_file_info,
+                    scx_general_info_type *scx_general_info)
+{
+   static char *dim_names_array[]={MItime, MIzspace, MIyspace, MIxspace};
+   char **dim_names;
+   static char *dimwidth_names_array[]={
+      MItime_width, MIzspace_width, MIyspace_width, MIxspace_width};
+   char **dimwidth_names;
+   int dim[MAX_DIMS];
+   int img, imgmax, imgmin, dimvarid, widvarid, icv, varid, scx_var;
+   int idim, imnem;
+   double vrange[2];
+
+   /* Create the dimensions */
+   dim_names = dim_names_array + MAX_DIMS - ndims;
+   dimwidth_names = dimwidth_names_array + MAX_DIMS - ndims;
+   for (idim=0; idim<ndims; idim++) {
+      dim[idim]=ncdimdef(mincid, dim_names[idim], count[idim]);
+      dimvarid=micreate_std_variable(mincid, dim_names[idim], NC_DOUBLE, 
+                                     ((idim==0) && (num_scx_files>1)) ? 1 : 0, 
+                                     &dim[idim]);
+      widvarid=micreate_std_variable(mincid, dimwidth_names[idim], NC_DOUBLE, 
+                                     (strcmp(dim_names[idim], MItime)==0) ? 
+                                        1 : 0, 
+                                     &dim[idim]);
+
+      /* Add attributes to the dimension variables */
+      if (strcmp(dim_names[idim], MIzspace)==0) {
+         if ((ndims==MAX_DIMS) || (num_scx_files==1)) {
+            (void) miattputdbl(mincid, dimvarid, MIstep, 
+                               scx_file_info[0].zstep);
+            (void) miattputdbl(mincid, dimvarid, MIstart, 
+                               scx_file_info[0].zstart);
+         }
+         (void) miattputstr(mincid, dimvarid, MIunits, "mm");
+         (void) miattputstr(mincid, dimvarid, MIspacetype, MI_NATIVE);
+         (void) miattputdbl(mincid, widvarid, MIwidth, 
+                            (double) scx_general_info->zwidth);
+         (void) miattputstr(mincid, widvarid, MIunits, "mm");
+         (void) miattputstr(mincid, widvarid, MIfiltertype, MI_GAUSSIAN);
+      }
+      else if ((strcmp(dim_names[idim], MIyspace)==0) ||
+               (strcmp(dim_names[idim], MIxspace)==0)) {
+         (void) miattputstr(mincid, dimvarid, MIunits, "mm");
+         (void) miattputdbl(mincid, dimvarid, MIstep, 
+                            (double) scx_general_info->xystep);
+         (void) miattputstr(mincid, dimvarid, MIspacetype, MI_NATIVE);
+         (void) miattputdbl(mincid, widvarid, MIwidth, 
+                            (double) scx_general_info->xywidth);
+         (void) miattputstr(mincid, widvarid, MIfiltertype, MI_GAUSSIAN);
+      }
+      else if (strcmp(dim_names[idim], MItime)==0) {
+         (void) miattputstr(mincid, dimvarid, MIunits, "seconds");
+         (void) miattputstr(mincid, widvarid, MIunits, "seconds");
+      }
+   }
+
+   /* Create the image variable */
+   if (write_byte_data) {
+      img=micreate_std_variable(mincid, MIimage, NC_BYTE, ndims, dim);
+      (void) miattputstr(mincid, img, MIsigntype, MI_UNSIGNED);
+      vrange[0]=0; vrange[1]=255;
+   }
+   else {
+      img=micreate_std_variable(mincid, MIimage, NC_SHORT, ndims, dim);
+      (void) miattputstr(mincid, img, MIsigntype, MI_SIGNED);
+      vrange[0] = -scx_general_info->vmax;
+      vrange[1] = scx_general_info->vmax;
+   }
+   (void) ncattput(mincid, img, MIvalid_range, NC_DOUBLE, 2, vrange);
+
+   /* Create the image max and min variables */
+   imgmax=micreate_std_variable(mincid, MIimagemax, NC_DOUBLE, ndims-2, dim);
+   imgmin=micreate_std_variable(mincid, MIimagemin, NC_DOUBLE, ndims-2, dim);
+   (void) miattputstr(mincid, imgmax, MIunits,
+                      scx_general_info->img_units);
+   (void) miattputstr(mincid, imgmin, MIunits,
+                      scx_general_info->img_units);
+
+   /* Create the image conversion variable */
+   icv=miicv_create();
+   (void) miicv_setint(icv, MI_ICV_TYPE, NC_SHORT);
+   (void) miicv_setdbl(icv, MI_ICV_VALID_MAX, 
+                       (double) scx_general_info->vmax);
+   (void) miicv_setdbl(icv, MI_ICV_VALID_MIN, 
+                       (double) -scx_general_info->vmax);
+
+   /* Save patient info */
+   varid = micreate_group_variable(mincid, MIpatient);
+   (void) miattputstr(mincid, varid, MIfull_name, 
+                      scx_general_info->patient_name);
+   (void) miattputstr(mincid, varid, MIsex, 
+                      scx_general_info->patient_sex);
+   (void) ncattput(mincid, varid, MIage, NC_LONG, 1, 
+                   &scx_general_info->patient_age);
+
+   /* Save study info */
+   varid = micreate_group_variable(mincid, MIstudy);
+   (void) miattputstr(mincid, varid, MImodality, MI_PET);
+   (void) miattputstr(mincid, varid, MImanufacturer, "Scanditronix");
+   (void) miattputstr(mincid, varid, MIstudy_id,
+                      scx_general_info->study_id);
+   (void) miattputstr(mincid, varid, MIstart_time,
+                      scx_general_info->start_time);
+   (void) ncattput(mincid, varid, MIstart_year, NC_LONG, 1,
+                   &scx_general_info->start_year);
+   (void) ncattput(mincid, varid, MIstart_month, NC_LONG, 1,
+                   &scx_general_info->start_month);
+   (void) ncattput(mincid, varid, MIstart_day, NC_LONG, 1,
+                   &scx_general_info->start_day);
+   (void) ncattput(mincid, varid, MIstart_hour, NC_LONG, 1,
+                   &scx_general_info->start_hour);
+   (void) ncattput(mincid, varid, MIstart_minute, NC_LONG, 1,
+                   &scx_general_info->start_minute);
+   (void) ncattput(mincid, varid, MIstart_seconds, NC_FLOAT, 1, 
+                   &scx_general_info->start_seconds);
+
+   /* Save acquisition info */
+   varid = micreate_group_variable(mincid, MIacquisition);
+   (void) miattputstr(mincid, varid, MIradionuclide,
+                      scx_file_info[0].isotope);
+   if (scx_file_info[0].half_life > 0.0) {
+      (void) miattputdbl(mincid, varid, MIradionuclide_halflife,
+                         (double) scx_file_info[0].half_life);
+   }
+   (void) miattputstr(mincid, varid, MItracer, 
+                      scx_general_info->tracer);
+   (void) miattputstr(mincid, varid, MIinjection_time,
+                      scx_general_info->injection_time);
+   (void) ncattput(mincid, varid, MIinjection_hour, NC_LONG, 1, 
+                   &scx_general_info->injection_hour);
+   (void) ncattput(mincid, varid, MIinjection_minute, NC_LONG, 1,
+                   &scx_general_info->injection_minute);
+   (void) ncattput(mincid, varid, MIinjection_seconds, NC_FLOAT, 1,
+                   &scx_general_info->injection_seconds);
+   (void) ncattput(mincid, varid, MIinjection_dose, NC_FLOAT, 1,
+                   &scx_general_info->injection_dose);
+   (void) miattputstr(mincid, varid, MIdose_units, "mCurie");
+
+   /* If we want all of the values from the scanditronix header, get them */
+   if (copy_all_header) {
+
+      /* Create a variable for scx mnemonics */
+      scx_var = ncvardef(mincid, "scanditronix", NC_LONG, 0, NULL);
+      (void) miattputstr(mincid, scx_var, MIvartype, MI_GROUP);
+      (void) miattputstr(mincid, scx_var, MIvarid, "MNI SCX variable");
+      (void) miadd_child(mincid, ncvarid(mincid, MIrootvariable), scx_var);
+
+      /* Loop through mnemonics */
+      for (imnem=0; scx_general_info->num_mnems; imnem++){
+         ncattput(mincid, scx_var, 
+                  scx_general_info->mnem_list[imnem].name,
+                  scx_general_info->mnem_list[imnem].type,
+                  scx_general_info->mnem_list[imnem].mult,
+                  scx_general_info->mnem_list[imnem].att_vector);
+      } /* Loop through mnemonics */
+   }   /* If copy_all_header */
+
+   /* Attach the icv */
+   (void) ncendef(mincid);
+   (void) miicv_attach(icv, mincid, img);
+
+   return icv;
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : get_scx_slice
+@INPUT      : scx_fp - file pointer for scanditronix file
+              slice_num - slice to copy
+              scx_file_info - information on scanditronix file.
+              scx_general_info - general scx file information
+@OUTPUT     : pixel_max - maximum pixel value
+              image_max - real value to which pixel_max corresponds
+              image - scanditronix image
+@RETURNS    : Returns TRUE if an error occurs.
+@DESCRIPTION: Gets a scanditronix image.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 20, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int get_scx_slice(scx_file *scx_fp, int slice_num, 
+                  long *pixel_max, float *image_max, short *image, 
+                  scx_file_info_type *scx_file_info,
+                  scx_general_info_type *scx_general_info)
+{       /* ARGSUSED */
+   long npix, ix, iy, y_offset, off1, off2;
+   short temp;
+
+   /* Get the image from the scanditronix file */
+   if (scx_get_image(scx_fp, slice_num, image)) return TRUE;
+
+   /* Flip the scanditronix image to give positive x & y axes */
+   npix = scx_file_info->image_size * scx_file_info->image_size;
+   for (iy=0; iy<scx_file_info->image_size/2; iy++) {
+      y_offset = iy * scx_file_info->image_size;
+      for (ix=0; ix<scx_file_info->image_size/2; ix++) {
+         off1 = y_offset + ix;
+         off2 = npix - off1 - 1;
+         temp = image[off1];
+         image[off1] = image[off2];
+         image[off2] = temp;
+      }
+   }
+
+   /* Get image and pixel max */
+   if (scx_get_mnem(scx_fp, SCX_MAG, slice_num, NULL, image_max, NULL))
+      return TRUE;
+   if (scx_get_mnem(scx_fp, SCX_MAX, 0, pixel_max, NULL, NULL)) return TRUE;
+   if ((*pixel_max<=0) || (*pixel_max>32767)) *pixel_max = 32000;
+
+   return FALSE;
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : write_minc_slice
+@INPUT      : scale - scale for decay correcting image
+              write_byte_data - boolean indicating whether data should be
+                 written as bytes (TRUE) or shorts (FALSE).
+              mincid - id of minc file
+              icvid - id of image conversion variable
+              start - coordinate of slice in minc file
+              count - edge lengths of image to write in minc file
+              image - pointer to image buffer
+              pixel_max - maximum pixel value
+              image_max - real value to which pixel_max corresponds
+              scan_time - time of slice
+              time_width - time width of slice
+              zpos - z position of slice
+              scx_file_info - information on scanditronix file.
+              scx_general_info - general scx file information
+@OUTPUT     : (nothing)
+@RETURNS    : Returns TRUE if an error occurs.
+@DESCRIPTION: Writes out the image to the minc file.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 12, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+int write_minc_slice(double scale, int write_byte_data,
+                     int mincid, int icvid, 
+                     int ndims,long start[], long count[], 
+                     short *image, int image_size, 
+                     long pixel_max, float image_max,
+                     double scan_time, double time_width, double zpos)
+{
+   double pixmin, pixmax;
+   long ipix, npix;
+   double maximum, minimum;
+
+   /* If converting to byte data, look for pixel max/min */
+   if (write_byte_data) {
+
+      /* Search for pixel max and min */
+      npix = image_size * image_size;
+      pixmin = pixmax = image[0];
+      for (ipix=1; ipix<npix; ipix++) {
+         if (image[ipix]>pixmax) pixmax = image[ipix];
+         if (image[ipix]<pixmin) pixmin = image[ipix];
+      }
+
+      /* Get image max and min */
+      maximum = image_max * pixmax / (double) pixel_max;
+      minimum = image_max * pixmin / (double)pixel_max;
+
+      /* Change valid range on icv */
+      (void) miicv_detach(icvid);
+      (void) miicv_setdbl(icvid, MI_ICV_VALID_MAX, (double) pixmax);
+      (void) miicv_setdbl(icvid, MI_ICV_VALID_MIN, (double) pixmin);
+      (void) miicv_attach(icvid, mincid, ncvarid(mincid, MIimage));
+      
+   }
+
+   /* Not converting data to bytes */
+   else {
+      maximum = image_max;
+      minimum = -image_max;
+   }
+   maximum = maximum * scale;
+   minimum = minimum * scale;
+
+   /* Write out the image */
+   (void) miicv_put(icvid, start, count, image);
+
+   /* Write out image max and min */
+   (void) ncvarput1(mincid, ncvarid(mincid, MIimagemax), start, &maximum);
+   (void) ncvarput1(mincid, ncvarid(mincid, MIimagemin), start, &minimum);
+
+   /* Write out time and z position */
+   if (ndims==MAX_DIMS) {
+      (void) mivarput1(mincid, ncvarid(mincid, MItime), start, 
+                       NC_DOUBLE, NULL, &scan_time);
+      (void) mivarput1(mincid, ncvarid(mincid, MItime_width), start,
+                       NC_DOUBLE, NULL, &time_width);
+   }
+   (void) mivarput1(mincid, ncvarid(mincid, MIzspace), &start[ndims-2],
+                    NC_DOUBLE, NULL, &zpos);
+
+   return FALSE;
+}
+
+
+/* ----------------------------- MNI Header -----------------------------------
+@NAME       : decay_correction
+@INPUT      : scan_time - time of beginning of sample
+              measure_time - length of sample
+              start_time - time to which we should decay correct
+              half_life - half life of isotope
+@OUTPUT     : (nothing)
+@RETURNS    : decay correction scaling factor
+@DESCRIPTION: Calculates the decay correction needed to get equivalent counts
+              at start_time. Correction assumes constant activity (without
+              decay) over measure_time.
+@METHOD     : 
+@GLOBALS    : 
+@CALLS      : 
+@CREATED    : January 21, 1993 (Peter Neelin)
+@MODIFIED   : 
+---------------------------------------------------------------------------- */
+double decay_correction(double scan_time, double measure_time, 
+                        double start_time, double half_life)
+{
+   double decay;
+
+   scan_time -= start_time;
+   if (half_life > 0.0) {
+      decay = half_life/log(2.0) * 
+         (pow(2.0, -scan_time/half_life) - 
+          pow(2.0, -(scan_time+measure_time)/half_life));
+      if (decay!=0.0) decay = 1.0/decay;
+   }
+   else {
+      decay = 1.0;
+   }
+   return decay;
+}
+