Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis12/src/compiler/nrrd/nrrd-info.sml
ViewVC logotype

View of /branches/vis12/src/compiler/nrrd/nrrd-info.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1997 - (download) (annotate)
Thu Oct 4 11:00:44 2012 UTC (6 years, 11 months ago) by jhr
File size: 5935 byte(s)
  Moved nrrd support into its own directory
(* nrrd-info.sml
 *
 * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *
 * Information about a NRRD file.
 *
 * TODO:
 *	handle files where the symmetries are exploited.
 *)

structure NrrdInfo : sig

    datatype info = NrrdInfo of {
	id : OS.FileSys.file_id,	(* ID of nrrd file *)
	dim : int,			(* dimension of space *)
	ty : RawTypes.ty,               (* types of data values *)
	origin : FloatLit.float list,	(* center of first sample *)
	dataKind : NrrdEnums.axis_kind, (* the nrrd axis kind of the data axis *)
        nElems : int,                   (* the number of elements per voxel *)
        sizes : int list                (* number of samples along each axis (not including
                                         * the data axis); we follow the Nrrd convention of
					 * listing the axes in fast to slow order.
					 *)
      }

  (* are the underlying files the same? *)
    val same : info * info -> bool

  (* hash value (based on nrrd file ID) *)
    val hash : info -> word

  (* get info from a Nrrd file *)
    val getInfo : string -> info

    val dim : info -> int		(* dimension of space *)
    val sizes : info -> int list	(* size of each dimension (not including the data axis) *)
    val voxelInfo : info -> {           (* get information about the data in the file *)
            elemTy : RawTypes.ty,         (* type of voxel elements *)
            kind : NrrdEnums.axis_kind,   (* nrrd file kind of voxel *)
            nElems : int                  (* number of elements per voxel *)
          }
    val voxelSzB : info -> int		(* size in bytes of a voxel *)
    val stride : info -> int		(* for non-scalar data, this returns the *)
					(* number of samples between voxels *)
    val sampleTy : info -> RawTypes.ty	(* representation type of samples *)

  end = struct

    datatype info = NrrdInfo of {
	id : OS.FileSys.file_id,	(* ID of nrrd file *)
	dim : int,			(* dimension of space *)
	ty : RawTypes.ty,               (* the type of the elements *)
	origin : FloatLit.float list,	(* center of first sample *)
	dataKind : NrrdEnums.axis_kind, (* the nrrd axis kind of the data axis *)
        nElems : int,                   (* the number of elements per voxel *)
        sizes : int list                (* number of samples along each axis (not including
                                         * the data axis); we follow the Nrrd convention of
					 * listing the axes in fast to slow order.
					 *)
      }

    fun same (NrrdInfo{id=a, ...}, NrrdInfo{id=b, ...}) = (a = b)

    fun hash (NrrdInfo{id, ...}) = OS.FileSys.hash id

    fun doHeader (fileName, header) = let
	  fun fields s = String.tokens Char.isSpace s
	  fun set (r, v) = (r := SOME v)
	  fun get (tag, r) = (case !r of NONE => raise Fail("missing "^tag) | SOME v => v)
	  val ty = ref NONE
	  val totalDim = ref NONE
	  val dim = ref NONE
	  val kinds = ref NONE
	  val sizes = ref NONE
	  fun doValue ("type", v) = (case NrrdEnums.tyFromString v
                 of SOME ty' => set(ty, ty')
                  | NONE => raise Fail(concat[
                        "bogus dnorm output: \"", "type: ", String.toString v, "\n"
                      ])
                (* end case *))
	    | doValue ("dimension", v) = set (totalDim, valOf(Int.fromString v))
	    | doValue ("space dimension", v) = set (dim, valOf(Int.fromString v))
	    | doValue ("sizes", v) = let
		fun atoi s = (case Int.fromString s
		       of SOME i => i
			| NONE => raise Fail(concat[
			      "bogus dnorm output: \"", "sizes: ", String.toString v, "\n"
			    ])
		      (* end case *))
		in
		  set (sizes, List.map atoi (fields v))
		end
	    | doValue ("space directions", v) = ()
	    | doValue ("kinds", v) = let
		fun s2kind s = (case NrrdEnums.kindFromString s
                       of SOME k => k
                        | NONE => raise Fail(concat["axis kind \"", s, "\" not supported"])
                      (* end case *))
		in
		  set (kinds, List.map s2kind (fields v))
		end
	    | doValue ("endian", v) = ()
	    | doValue ("encoding", v) = ()
	    | doValue ("space origin", v) = ()
	    | doValue _ = ()
	  in
	    Log.msg (concat[fileName, " file header:\n"]);
	    List.app (fn (tag, value) => Log.msg(concat["  ", tag, ": ", value, "\n"])) header;
	    List.app doValue header;
	    let
	    val dim = get ("space dimension", dim)
	    val totalDim = get ("dimension", totalDim)
	  (* split the sizes into the data axis size, which comes first
	   * in the list, and those that span the space's dimensions. Note
           * that for some scalar images, there is no data axis.
	   *)
	    val (nElems, sizes, dataKind) = if (dim = totalDim)
                  then (1, get ("sizes", sizes), NrrdEnums.KindScalar)
                  else let
                    val (nElems::sizes) = get ("sizes", sizes)
                    in
                      (nElems, sizes, hd (get ("kinds", kinds)))
                    end
	    in
	      NrrdInfo{
		  id = OS.FileSys.fileId fileName,
		  dim = dim,
		  ty = NrrdEnums.tyToRaw (get ("type", ty)),
		  origin = [],	(* FIXME *)
		  dataKind = dataKind,
                  nElems = nElems,
		  sizes = sizes
		}
	    end
	  end

    fun getInfo fileName = if OS.FileSys.access(fileName, [OS.FileSys.A_READ])
	  then let
	    val {version, header} = RunDNorm.run fileName
	    in
	      doHeader (fileName, header)
	    end
	  else raise Fail(concat["Nrrd file \"", fileName, "\" does not exist"])

    fun dim (NrrdInfo{dim, ...}) = dim

    fun sizes (NrrdInfo{sizes, ...}) = sizes

  (* get information about the data in the nrrd file *)
    fun voxelInfo (NrrdInfo{ty, dataKind, nElems, ...}) =
          {elemTy = ty, kind = dataKind, nElems = nElems}

    fun voxelSzB (NrrdInfo{ty, nElems, ...}) = nElems * RawTypes.sizeb ty

    fun stride (NrrdInfo{nElems, ...}) = nElems

    fun sampleTy (NrrdInfo{ty, ...}) = ty

  end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0