[Scipy-svn] r3492 - in branches/ndimage_segmenter/scipy: . NDISegmenter

scipy-svn@scip... scipy-svn@scip...
Fri Nov 2 15:09:21 CDT 2007


Author: tom.waite
Date: 2007-11-02 15:09:04 -0500 (Fri, 02 Nov 2007)
New Revision: 3492

Added:
   branches/ndimage_segmenter/scipy/NDISegmenter/
   branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter.py
   branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_EXT.c
   branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_IMPL.c
   branches/ndimage_segmenter/scipy/NDISegmenter/__multiarray_api.h
   branches/ndimage_segmenter/scipy/NDISegmenter/__ufunc_api.h
   branches/ndimage_segmenter/scipy/NDISegmenter/arrayobject.h
   branches/ndimage_segmenter/scipy/NDISegmenter/arrayscalars.h
   branches/ndimage_segmenter/scipy/NDISegmenter/config.h
   branches/ndimage_segmenter/scipy/NDISegmenter/control.py
   branches/ndimage_segmenter/scipy/NDISegmenter/ndImage_Segmenter_structs.h
   branches/ndimage_segmenter/scipy/NDISegmenter/ndarrayobject.h
   branches/ndimage_segmenter/scipy/NDISegmenter/noprefix.h
   branches/ndimage_segmenter/scipy/NDISegmenter/npy_interrupt.h
   branches/ndimage_segmenter/scipy/NDISegmenter/old_defines.h
   branches/ndimage_segmenter/scipy/NDISegmenter/oldnumeric.h
   branches/ndimage_segmenter/scipy/NDISegmenter/setup.py
   branches/ndimage_segmenter/scipy/NDISegmenter/slice112.raw
   branches/ndimage_segmenter/scipy/NDISegmenter/testShenCastan.py
   branches/ndimage_segmenter/scipy/NDISegmenter/ufuncobject.h
   branches/ndimage_segmenter/scipy/NDISegmenter/volumeInput.py
Log:
Add NDISegmenter code.

Added: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter.py
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter.py	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter.py	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,129 @@
+import numpy as N
+import NDI_Segmenter as S
+import volumeInput as V
+import struct
+
+def ShenCastan(image, IIRFilter=0.8, scLow=0.3, window=7, lowThreshold=220+2048, highThreshold=600+2048, dust=16):
+	datatype = [('L', 'i', 1), ('R', 'i', 1), ('T', 'i', 1), ('B', 'i', 1),
+            	    ('Label', 'i', 1), ('Area', 'i', 1), ('cX', 'f', 1), ('cY', 'f', 1),
+            	    ('curveClose', 'i', 1), ('cXB', 'f', 1), ('cYB', 'f', 1), ('bLength', 'f', 1),
+            	    ('minRadius', 'f', 1), ('maxRadius', 'f', 1), ('aveRadius', 'f', 1), ('ratio', 'f', 1),
+            	    ('compactness', 'f', 1), ('voxelMean', 'f', 1), ('voxelVar', 'f', 1), ('TEM', 'f', 20)]
+	labeledEdges, numberObjects = S.ShenCastanEdges(scLow, IIRFilter, window, lowThreshold, highThreshold, image)
+	# allocated struct array for edge object measures. for now just the rect bounding box
+	ROIList = N.zeros(numberObjects, dtype=datatype)
+	# return the bounding box for each connected edge
+	S.SetObjectStats(labeledEdges, ROIList)
+	return labeledEdges, ROIList[ROIList['Area']>dust]
+
+def Sobel(image, sLow=0.3, tMode=1, lowThreshold=220+2048, highThreshold=600+2048, BPHigh=10.0, apearture=21, dust=16):
+	datatype = [('L', 'i', 1), ('R', 'i', 1), ('T', 'i', 1), ('B', 'i', 1),
+            	    ('Label', 'i', 1), ('Area', 'i', 1), ('cX', 'f', 1), ('cY', 'f', 1),
+            	    ('curveClose', 'i', 1), ('cXB', 'f', 1), ('cYB', 'f', 1), ('bLength', 'f', 1),
+            	    ('minRadius', 'f', 1), ('maxRadius', 'f', 1), ('aveRadius', 'f', 1), ('ratio', 'f', 1),
+            	    ('compactness', 'f', 1), ('voxelMean', 'f', 1), ('voxelVar', 'f', 1), ('TEM', 'f', 20)]
+	# get sobel edge points. return edges that are labeled (1..numberObjects)
+	labeledEdges, numberObjects = S.SobelEdges(sLow, tMode, lowThreshold, highThreshold, BPHigh, apearture, image)
+	# allocated struct array for edge object measures. for now just the rect bounding box
+	ROIList = N.zeros(numberObjects, dtype=datatype)
+	# return the bounding box for each connected edge
+	S.GetObjectStats(labeledEdges, ROIList)
+	# thin (medial axis transform) of the sobel edges as the sobel produces a 'band edge'
+	S.MorphoThinFilt(labeledEdges, ROIList)
+	return labeledEdges, ROIList[ROIList['Area']>dust]
+
+def Canny(image, cSigma=1.0, cLow=0.5, cHigh=0.8, tMode=1, lowThreshold=220+2048, highThreshold=600+2048,
+          BPHigh=10.0, apearture=21, dust=16):
+	datatype = [('L', 'i', 1), ('R', 'i', 1), ('T', 'i', 1), ('B', 'i', 1),
+            	    ('Label', 'i', 1), ('Area', 'i', 1), ('cX', 'f', 1), ('cY', 'f', 1),
+            	    ('curveClose', 'i', 1), ('cXB', 'f', 1), ('cYB', 'f', 1), ('bLength', 'f', 1),
+            	    ('minRadius', 'f', 1), ('maxRadius', 'f', 1), ('aveRadius', 'f', 1), ('ratio', 'f', 1),
+            	    ('compactness', 'f', 1), ('voxelMean', 'f', 1), ('voxelVar', 'f', 1), ('TEM', 'f', 20)]
+	# get canny edge points. return edges that are labeled (1..numberObjects)
+	labeledEdges, numberObjects = S.CannyEdges(cSigma, cLow, cHigh, tMode, lowThreshold, highThreshold, 
+			                           BPHigh, apearture, image)
+	# allocated struct array for edge object measures. for now just the rect bounding box
+	ROIList = N.zeros(numberObjects, dtype=datatype)
+	# return the bounding box for each connected edge
+	S.GetObjectStats(labeledEdges, ROIList)
+	return labeledEdges, ROIList[ROIList['Area']>dust]
+
+def GetShapeMask(labeledEdges, ROIList):
+	# pass in Sobel morph-thinned labeled edge image (LEI) and ROIList
+	# GetShapeMask will augment the ROI list
+	# labeledEdges is the original edge image and overwritten as mask image
+	# maskImage is the mask that is used for blob texture / pixel features
+	S.BuildBoundary(labeledEdges, ROIList)
+	return 
+
+def GetVoxelMeasures(rawImage, labeledEdges, ROIList):
+	#
+	# pass raw image, labeled mask and the partially filled ROIList
+	# VoxelMeasures will fill the voxel features in the list
+	#
+	S.VoxelMeasures(rawImage, labeledEdges, ROIList)
+	return 
+
+def GetTextureMeasures(rawImage, labeledEdges, ROIList):
+	#
+	# pass raw image, labeled mask and the partially filled ROIList
+	# VoxelMeasures will fill the texture (Law's, co-occurence, Gabor) features in the list
+	#
+	S.TextureMeasures(rawImage, labeledEdges, ROIList)
+	return 
+
+def SegmentRegions(volSlice=112):
+	# get slice from the CT volume
+    	image = GetSliceFromVolume(volSlice)
+	# need a copy of original image as filtering will occur on the extracted slice
+    	sourceImage = image.copy()
+	# Sobel is the first level segmenter. Sobel magnitude and MAT (medial axis transform)
+	# followed by connected component analysis. What is returned is labeled edges and the object list
+    	labeledMask, ROIList = Sobel(image)
+	# From the labeled edges and the object list get the labeled mask for each blob object
+    	GetShapeMask(labeledMask, ROIList)
+	# Use the labeled mask and source image (raw) to get voxel features 
+    	GetVoxelMeasures(sourceImage, labeledMask, ROIList)
+	# Use the labeled mask and source image (raw) to get texture features 
+	GetTextureMeasures(sourceImage, labeledMask, ROIList)
+	return sourceImage, labeledMask, ROIList
+
+def GrowRegions(volSlice=112):
+	# get slice from the CT volume
+    	image = GetSliceFromVolume(volSlice)
+	regionMask, numberRegions = RegionGrow(image)
+	return regionMask, numberRegions 
+
+
+def RegionGrow(image, lowThreshold=220+2048, highThreshold=600+2048, open=7, close=7):
+	# morphology filters need to be clipped to 11 max and be odd
+	regionMask, numberRegions = S.RegionGrow(lowThreshold, highThreshold, close, open, image)
+	return regionMask, numberRegions
+          
+
+def GetSlice(imageName='junk.raw', bytes=2, rows=512, columns=512):
+	# get a slice alrady extracted from the CT volume
+	image = open(imageName, 'rb')
+	slice = image.read(rows*columns*bytes)
+	values = struct.unpack('h'*rows*columns, slice)
+	ImageSlice = N.array(values, dtype=float).reshape(rows, columns)
+	return (ImageSlice)
+
+def GetSliceFromVolume(mySlice, rows=512, columns=512, bytes=2):
+	# extract a slice the CT volume. Hardwirred 
+	image = open('C:\PythonStuff\CardiacCT.vol', 'rb')
+	image.seek(mySlice*rows*columns*bytes)
+	slice = image.read(rows*columns*bytes)
+	values = struct.unpack('h'*rows*columns, slice)
+	ImageSlice = N.array(values, dtype=float).reshape(rows, columns)
+	return (ImageSlice+2048)
+
+def SaveSlice(mySlice, filename='junk.raw', rows=512, columns=512, bytes=2):
+	# just save the slice to a fixed file
+	slice = mySlice.astype(int)
+	image = open(filename, 'wb')
+	image.write(slice)
+	image.close()
+	return
+
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter.py
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_EXT.c
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_EXT.c	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_EXT.c	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,445 @@
+#include "ndImage_Segmenter_structs.h"
+#include "Python.h"
+#include "noprefix.h"
+
+static PyObject *NDI_Segmenter_CannyEdges(PyObject *self, PyObject *args)
+{
+
+    double sigma;
+    double cannyLow;
+    double cannyHigh;
+    double BPHigh;
+    int lowThreshold;
+    int highThreshold;
+    int apearture;
+    int num;
+    int nd;
+    int type;
+    int itype;
+    int mode;
+    int groups;
+    npy_intp *dims;
+    double *fP1;
+    unsigned short *fP2;
+    PyObject *iArray = NULL;
+    PyObject *eArray = NULL;
+
+    //
+    // pass in 2D LPF coefficients
+    if(!PyArg_Parse(args, "(dddiiidiO)", &sigma, &cannyLow, &cannyHigh, &mode, &lowThreshold, &highThreshold,
+			                 &BPHigh, &apearture, &iArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    itype  = 4;
+    eArray = (PyObject*)PyArray_SimpleNew(nd, dims, itype);
+    fP2    = (unsigned short *)PyArray_DATA(eArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray) || !PyArray_ISCONTIGUOUS(eArray))
+	    goto exit;
+
+    if(!NI_CannyEdges(num, (int)dims[0], (int)dims[1], sigma, cannyLow, cannyHigh, mode, lowThreshold,
+		      highThreshold, BPHigh, apearture, fP1, fP2, &groups))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("Oi", eArray, groups);
+
+}
+
+static PyObject *NDI_Segmenter_SobelEdges(PyObject *self, PyObject *args)
+{
+
+    double sobelLow;
+    double BPHigh;
+    int lowThreshold;
+    int highThreshold;
+    int apearture;
+    int num;
+    int nd;
+    int type;
+    int itype;
+    int groups;
+    int mode;
+    npy_intp *dims;
+    double *fP1;
+    unsigned short *fP2;
+    PyObject *iArray = NULL;
+    PyObject *eArray = NULL;
+
+    //
+    // pass in 2D LPF coefficients
+    if(!PyArg_Parse(args, "(diiidiO)", &sobelLow, &mode, &lowThreshold, &highThreshold, &BPHigh, &apearture, &iArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    // this is int type and hard-wirred. pass this in from Python code
+    itype  = 4; // unsigned short
+    eArray = (PyObject*)PyArray_SimpleNew(nd, dims, itype);
+    fP2    = (unsigned short *)PyArray_DATA(eArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray) || !PyArray_ISCONTIGUOUS(eArray))
+	    goto exit;
+
+    
+    if(!NI_SobelEdges(num, (int)dims[0], (int)dims[1], sobelLow, mode, lowThreshold, highThreshold, BPHigh, apearture,
+		      fP1, fP2, &groups))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("Oi", eArray, groups-1);
+
+}
+
+
+
+static PyObject *NDI_Segmenter_ShenCastanEdges(PyObject *self, PyObject *args)
+{
+    int window;
+    int lowThreshold;
+    int highThreshold;
+    double ShenCastanLow;
+    double b;
+    int num;
+    int nd;
+    int type;
+    int itype;
+    npy_intp *dims;
+    double *fP1;
+    unsigned short *fP2;
+    int groups;
+    PyObject *iArray = NULL;
+    PyObject *eArray = NULL;
+
+    if(!PyArg_Parse(args, "(ddiiiO)", &ShenCastanLow, &b, &window, &lowThreshold, &highThreshold, &iArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    // this is int type and hard-wirred. pass this in from Python code
+    itype  = 4; // unsigned short
+    eArray = (PyObject*)PyArray_SimpleNew(nd, dims, itype);
+    fP2    = (unsigned short *)PyArray_DATA(eArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray) || !PyArray_ISCONTIGUOUS(eArray))
+	    goto exit;
+
+    if(!NI_ShenCastanEdges(num, (int)dims[0], (int)dims[1], b, ShenCastanLow, window, lowThreshold, highThreshold, 
+			   fP1, fP2, &groups))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("Oi", eArray, groups-1);
+
+}
+
+static PyObject *NDI_Segmenter_GetObjectStats(PyObject *self, PyObject *args)
+{
+
+
+    int num;
+    int nd;
+    int type;
+    npy_intp *dims;
+    npy_intp *objNumber;
+    unsigned short *fP1;
+    PyObject  *iArray = NULL;
+    PyObject  *nArray = NULL;
+    objStruct *myData;
+
+    if(!PyArg_Parse(args, "(OO)", &iArray, &nArray))
+	    goto exit;
+
+    if(!PyArray_ISCONTIGUOUS(iArray) || !PyArray_ISCONTIGUOUS(nArray))
+	    goto exit;
+
+    	//
+	//   PyArray_ContiguousFromObject or PyArray_ContiguousFromAny to be explored 
+	//   for non-contiguous
+	//
+
+	
+    // pointer to the edge-labeled image
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+    fP1  = (unsigned short *)PyArray_DATA(iArray);
+
+    // the object descriptor array that was allocated from numpy
+    objNumber = PyArray_DIMS(nArray); // this is the number of labels in the edge image
+    myData = (objStruct*)PyArray_DATA(nArray);
+
+    if(!NI_GetObjectStats((int)dims[0], (int)dims[1], (int)objNumber[0], fP1, myData))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("");
+
+}
+
+static PyObject *NDI_Segmenter_MorphoThinFilt(PyObject *self, PyObject *args)
+{
+
+    int num;
+    int nd;
+    int type;
+    npy_intp *dims;
+    npy_intp *objNumber;
+    unsigned short *fP1;
+    PyObject  *iArray = NULL;
+    PyObject  *nArray = NULL;
+    objStruct *ROIList;
+
+    if(!PyArg_Parse(args, "(OO)", &iArray, &nArray))
+	    goto exit;
+
+    fP1  = (unsigned short *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    objNumber = PyArray_DIMS(nArray); // this is the number of labels in the edge image
+    ROIList = (objStruct*)PyArray_DATA(nArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray))
+	    goto exit;
+
+    if(!NI_ThinFilter(num, (int)dims[0], (int)dims[1], (int)objNumber[0], fP1, ROIList))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("");
+
+}
+
+static PyObject *NDI_Segmenter_BuildBoundary(PyObject *self, PyObject *args)
+{
+
+    int num;
+    int nd;
+    int type;
+    npy_intp *dims;
+    npy_intp *objNumber;
+    unsigned short *fP1;
+    PyObject  *iArray = NULL;
+    PyObject  *nArray = NULL;
+    objStruct *ROIList;
+
+    if(!PyArg_Parse(args, "(OO)", &iArray, &nArray))
+	    goto exit;
+
+    fP1  = (unsigned short *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+    //
+    // this is int type and hard-wirred. pass this in from Python code
+
+    objNumber = PyArray_DIMS(nArray); // this is the number of labels in the edge image
+    ROIList = (objStruct*)PyArray_DATA(nArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray))
+	    goto exit;
+
+    //
+    // pass in ROI list and labeled edges
+    // return an augmented ROI list
+    // replace the edgeImage with maskImage
+    //
+    if(!NI_BuildBoundary(num, (int)dims[0], (int)dims[1], (int)objNumber[0], fP1, ROIList))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("");
+
+}
+
+
+static PyObject *NDI_Segmenter_VoxelMeasures(PyObject *self, PyObject *args)
+{
+
+    int num;
+    int nd;
+    int type;
+    npy_intp *dims;
+    npy_intp *objNumber;
+    double *fP1;
+    unsigned short *fP2;
+    PyObject  *iArray = NULL;
+    PyObject  *nArray = NULL;
+    PyObject  *eArray = NULL;
+    objStruct *ROIList;
+
+    if(!PyArg_Parse(args, "(OOO)", &iArray, &eArray, &nArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    // eArray and iArray are same dims
+    fP2  = (unsigned short *)PyArray_DATA(eArray);
+
+    objNumber = PyArray_DIMS(nArray); // this is the number of labels in the edge image
+    ROIList = (objStruct*)PyArray_DATA(nArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray))
+	    goto exit;
+
+    //
+    // pass in ROI list and labeled edges
+    // return an augmented ROI list
+    // replace the edgeImage with maskImage
+    //
+
+    if(!NI_VoxelMeasures(num, (int)dims[0], (int)dims[1], (int)objNumber[0], fP1, fP2, ROIList))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("");
+
+}
+
+static PyObject *NDI_Segmenter_TextureMeasures(PyObject *self, PyObject *args)
+{
+
+    int num;
+    int nd;
+    int type;
+    npy_intp *dims;
+    npy_intp *objNumber;
+    double *fP1;
+    unsigned short *fP2;
+    PyObject  *iArray = NULL;
+    PyObject  *nArray = NULL;
+    PyObject  *eArray = NULL;
+    objStruct *ROIList;
+
+    if(!PyArg_Parse(args, "(OOO)", &iArray, &eArray, &nArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    // eArray and iArray are same dims
+    fP2  = (unsigned short *)PyArray_DATA(eArray);
+
+    objNumber = PyArray_DIMS(nArray); // this is the number of labels in the edge image
+    ROIList = (objStruct*)PyArray_DATA(nArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray))
+	    goto exit;
+
+    //
+    // pass in ROI list and labeled edges
+    // return an augmented ROI list
+    // replace the edgeImage with maskImage
+    //
+
+    if(!NI_TextureMeasures(num, (int)dims[0], (int)dims[1], (int)objNumber[0], fP1, fP2, ROIList))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("");
+
+}
+
+static PyObject *NDI_Segmenter_RegionGrow(PyObject *self, PyObject *args)
+{
+
+    int lowThreshold;
+    int highThreshold;
+    int closeWindow;
+    int openWindow;
+    int num;
+    int nd;
+    int type;
+    int itype;
+    int groups;
+    int mode;
+    npy_intp *dims;
+    double *fP1;
+    unsigned short *fP2;
+    PyObject *iArray = NULL;
+    PyObject *eArray = NULL;
+
+    //
+    // pass in 2D LPF coefficients
+    if(!PyArg_Parse(args, "(iiiiO)", &lowThreshold, &highThreshold, &closeWindow, &openWindow, &iArray))
+	    goto exit;
+
+    fP1  = (double *)PyArray_DATA(iArray);
+    nd   = PyArray_NDIM(iArray);
+    dims = PyArray_DIMS(iArray);
+    type = PyArray_TYPE(iArray);
+    num  = PyArray_SIZE(iArray);
+
+    // this is int type and hard-wirred. pass this in from Python code
+    itype  = 4; // unsigned short
+    eArray = (PyObject*)PyArray_SimpleNew(nd, dims, itype);
+    fP2    = (unsigned short *)PyArray_DATA(eArray);
+
+    if(!PyArray_ISCONTIGUOUS(iArray) || !PyArray_ISCONTIGUOUS(eArray))
+	    goto exit;
+
+    
+    if(!NI_RegionGrow(num, (int)dims[0], (int)dims[1], lowThreshold, highThreshold, closeWindow, openWindow,
+		      fP1, fP2, &groups))
+	    goto exit;
+
+exit:
+
+    return PyErr_Occurred() ? NULL : (PyObject*)Py_BuildValue("Oi", eArray, groups-1);
+
+}
+
+static PyMethodDef NDI_SegmenterMethods[] =
+{
+    { "CannyEdges",       NDI_Segmenter_CannyEdges,      METH_VARARGS },
+    { "ShenCastanEdges",  NDI_Segmenter_ShenCastanEdges, METH_VARARGS },
+    { "SobelEdges",       NDI_Segmenter_SobelEdges,      METH_VARARGS },
+    { "GetObjectStats",   NDI_Segmenter_GetObjectStats,  METH_VARARGS },
+    { "MorphoThinFilt",   NDI_Segmenter_MorphoThinFilt,  METH_VARARGS },
+    { "BuildBoundary",    NDI_Segmenter_BuildBoundary,   METH_VARARGS },
+    { "VoxelMeasures",    NDI_Segmenter_VoxelMeasures,   METH_VARARGS },
+    { "TextureMeasures",  NDI_Segmenter_TextureMeasures, METH_VARARGS },
+    { "RegionGrow",       NDI_Segmenter_RegionGrow,      METH_VARARGS },
+    {  NULL, NULL },
+};
+
+void initNDI_Segmenter()
+{
+    Py_InitModule("NDI_Segmenter", NDI_SegmenterMethods);
+    import_array();
+}
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_EXT.c
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_IMPL.c
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_IMPL.c	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_IMPL.c	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,2965 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "ndImage_Segmenter_structs.h"
+
+// these are for this standalone and come out with the full build
+//
+#define MAX(a, b) ((a) > (b) ? (a) : (b)) 
+#define FALSE 0
+#define TRUE  1
+
+int NI_GetObjectStats(int rows, int cols, int numberObjects, unsigned short *labeledEdges, objStruct objectMetrics[]){
+
+	int i, j, k, m;
+	int offset;
+	int count;
+	int LowX;
+	int LowY;
+	int HighX;
+	int HighY;
+	int status;
+	float centerX;
+	float centerY;
+
+	for(k = 1; k < numberObjects; ++k){
+	    offset     = cols;
+	    LowX       = 32767;
+	    LowY       = 32767;
+	    HighX      = 0;
+	    HighY      = 0;
+	    count      = 0;
+	    centerX    = (float)0.0;
+	    centerY    = (float)0.0;
+	    for(i = 1; i < (rows-1); ++i){
+		for(j = 1; j < (cols-1); ++j){
+		    m = labeledEdges[offset+j];
+		    if(k == m){
+			if(i < LowY)   LowY = i;
+			if(j < LowX)   LowX = j;
+			if(i > HighY) HighY = i;
+			if(j > HighX) HighX = j;
+	    		centerX += (float)j;
+	    		centerY += (float)i;
+	    		++count;
+		    }
+		}
+		offset += cols;
+	    }
+	    // the bounding box for the 2D blob
+	    objectMetrics[k-1].L     = LowX;
+	    objectMetrics[k-1].R     = HighX;
+	    objectMetrics[k-1].B     = LowY;
+	    objectMetrics[k-1].T     = HighY;
+	    objectMetrics[k-1].Area  = count;
+	    objectMetrics[k-1].cX    = centerX/(float)count;
+	    objectMetrics[k-1].cY    = centerY/(float)count;
+	    objectMetrics[k-1].Label = k;
+	}
+
+	status = numberObjects;
+	return status;
+
+}
+
+
+void buildKernel(double BPHigh, int HalfFilterTaps, int apearture, float *kernel){
+
+	int i, j;
+	float r, t1, t2, t3, t4;
+	float LC, HC, tLOW, tHIGH;
+	float pi = (float)3.14159, rad = (float)0.01745;
+
+	LC = (float)0.0;
+	HC = BPHigh * rad; 
+	t2 = (float)2.0*pi; 
+	t1 = (float)2.0*HalfFilterTaps + (float)1.0;
+	//
+	// build the Filter Kernel 
+	// the kernel starts at 1 only because it is linked to the internal filter2D routine
+	// the code is not a Fortran code
+	//
+	j = 1;
+	for(i = -HalfFilterTaps; i <= HalfFilterTaps; ++i){
+	    r = (float)i;
+	    if(r == (float)0.0){
+		tLOW  = LC;
+	        tHIGH = HC;
+	    }
+	    else{
+		tLOW  = (float)(sin(r*LC))/r;
+	        tHIGH = (float)(sin(r*HC))/r;
+	    }
+	    t3 = (float)0.54 + (float)0.46*((float)cos(r*t2/t1));
+	    t4 = t3*(tHIGH-tLOW);
+	    kernel[j++] = t4;
+	}
+
+	// normalize the kernel so unity gain (as is LP filter this is easy)
+	t1 = (float)0.0;
+	for(j = 1; j <= apearture; ++j){  
+	    t1 += kernel[j];
+	}
+	for(j = 1; j <= apearture; ++j){  
+	    kernel[j] /= t1;
+	}
+
+	t1 = (float)0.0;
+	for(j = 1; j <= apearture; ++j){  
+	    t1 += kernel[j];
+	}
+	return;
+}
+
+void filter2D(int HalfFilterTaps, int rows, int cols, int lowThreshold, int highThreshold, float *kernel, double *Image){
+
+	int i, j, k, n, num1;
+    	int offset;
+	float sum, value;
+	float buffer[1024];
+
+	num1 = HalfFilterTaps + 1;
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    // copy image row to local buffer 
+	    for(j = 0; j < cols; ++j){
+		buffer[num1+j] = Image[offset+j];
+	    }
+	    // constant pad the ends of the buffer
+	    for(j = 0; j < num1; ++j){
+		buffer[j] = buffer[num1];
+	    }
+	    for(j = cols+num1; j < cols+2*num1; ++j){
+		buffer[j] = buffer[cols-1+num1];
+	    }
+
+	    // Perform Symmetric Convolution in the X dimension.
+	    for(n = 0, j = num1; j < (cols+num1); ++j, ++n){
+	        sum = buffer[j] * kernel[num1];
+	        for(k = 1; k < num1; ++k){
+	            sum += kernel[num1-k] * (buffer[j+k] + buffer[j-k]);
+	        }
+	        Image[offset+n] = sum;
+	    }
+	    offset += cols;
+	}
+
+	offset = 0;
+	for(i = 0; i < cols; ++i){
+	    // copy image column to local buffer 
+	    offset = 0;
+	    for(j = 0; j < rows; ++j){
+            buffer[num1+j] = Image[offset+i];
+	        offset += cols;
+	    }
+	    // constant pad the ends of the buffer
+	    for(j = 0; j < num1; ++j){
+		buffer[j] = buffer[num1];
+	    }
+	    for(j = rows+num1; j < rows+2*num1; ++j){
+	        buffer[j] = buffer[rows-1+num1];
+	    }
+
+	    // Perform Symmetric Convolution in the Y dimension.
+	    offset = 0;
+	    for(j = num1; j < (rows+num1); ++j){
+	        sum = buffer[j] * kernel[num1];
+	        for(k = 1; k < num1; ++k){
+	            sum += kernel[num1-k] * (buffer[j+k] + buffer[j-k]);
+	        }
+	        Image[offset+i] = sum;
+	        offset += cols;
+	    }
+	}
+
+	// threshold the image
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		value = Image[offset+j];
+		if(value < (float)lowThreshold)  value = (float)0.0;
+		if(value > (float)highThreshold) value = (float)0.0;
+		Image[offset+j] = value;
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+void doPreProcess(int samples, int rows, int cols, double *rawImage, double BPHigh, int apearture, int lowThreshold, int highThreshold){
+
+	//
+	// 2D low pass filter using bisinc and threshold 
+	// this specific example is on cardiac CT and focuses on segmenting the
+	// aorta and blood-filled chambers. for MRI the threshold will be different
+	//
+
+	float *kernel;
+	int HalfFilterTaps = (apearture-1)/2;
+	kernel = calloc(apearture+16, sizeof(float));
+
+	buildKernel(BPHigh, HalfFilterTaps, apearture, kernel);
+	filter2D(HalfFilterTaps, rows, cols, lowThreshold, highThreshold, kernel, rawImage);
+
+	free(kernel);
+
+	return;
+
+}
+
+
+int ConnectedEdgePoints(int rows, int cols, unsigned short *connectedEdges){
+
+	int            i, j, k, l, m;
+	int            offset;
+	int            Label;
+	int            Classes[4096];
+	bool           NewLabel;
+	bool           Change;
+	unsigned short T[12];
+
+	//
+	// connected components labeling. pixels touch within 3x3 mask for edge connectedness. 
+	//
+	Label  = 1;
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(connectedEdges[offset+j] == 1){
+		    connectedEdges[offset+j] = Label++; 
+		}
+	    }
+	    offset += cols;
+	}
+
+	while(1){
+	    Change = FALSE;
+	    //
+	    // TOP-DOWN Pass for labeling
+	    //
+	    offset = cols;
+	    for(i = 1; i < rows-1; ++i){
+		for(j = 1; j < cols-1; ++j){
+		    if(connectedEdges[offset+j] != 0){
+			T[0] = connectedEdges[offset+j];
+			T[1] = connectedEdges[offset+j+1];
+			T[2] = connectedEdges[offset-cols+j+1];
+			T[3] = connectedEdges[offset-cols+j];
+			T[4] = connectedEdges[offset-cols+j-1];
+			T[5] = connectedEdges[offset+j-1];
+			T[6] = connectedEdges[offset+cols+j-1];
+			T[7] = connectedEdges[offset+cols+j];
+			T[8] = connectedEdges[offset+cols+j+1];
+			m = T[0];
+			for(l = 1; l < 9; ++l){
+			    if(T[l] != 0){
+				if(T[l] < m) m = T[l];
+			    }
+			}
+			if(m != connectedEdges[offset+j]){
+			    Change = TRUE;
+			    connectedEdges[offset+j] = m;
+			}
+		    }
+		}
+		offset += cols;
+	    }
+	    //
+	    // BOTTOM-UP Pass for labeling
+	    //
+	    offset = (rows-1)*cols;
+	    for(i = (rows-1); i > 1; --i){
+		for(j = (cols-1); j > 1; --j){
+		    if(connectedEdges[offset+j] != 0){
+			T[0] = connectedEdges[offset+j];
+			T[1] = connectedEdges[offset+j+1];
+			T[2] = connectedEdges[offset-cols+j+1];
+			T[3] = connectedEdges[offset-cols+j];
+			T[4] = connectedEdges[offset-cols+j-1];
+			T[5] = connectedEdges[offset+j-1];
+			T[6] = connectedEdges[offset+cols+j-1];
+			T[7] = connectedEdges[offset+cols+j];
+			T[8] = connectedEdges[offset+cols+j+1];
+			m = T[0];
+			for(l = 1; l < 9; ++l){
+			    if(T[l] != 0){
+				if(T[l] < m) m = T[l];
+			    }
+			}
+			if(m != connectedEdges[offset+j]){
+			    Change = TRUE;
+			    connectedEdges[offset+j] = m;
+			}
+		    }
+		}
+		offset -= cols;
+	    }
+	    if(!Change) break;
+	}   // end while loop
+
+	Classes[0] = 0;
+	Label      = 1;
+	offset     = cols;
+	for(i = 1; i < (rows-1); ++i){
+	    for(j = 1; j < (cols-1); ++j){
+		m = connectedEdges[offset+j];
+		if(m > 0){
+		    NewLabel = TRUE;
+		    for(k = 1; k < Label; ++k){
+			if(Classes[k] == m) NewLabel = FALSE;
+		    }
+		    if(NewLabel){
+			Classes[Label++] = m;
+			if(Label > 4000){
+			    return 0; // too many labeled regions. this is a pathology in the image slice
+			}
+		    }
+		}
+	    }
+	    offset += cols;
+	}
+
+	//
+	// re-label the connected blobs in continuous label order
+	//
+	offset = cols;
+	for(i = 1; i < (rows-1); ++i){
+	    for(j = 1; j < (cols-1); ++j){
+		m = connectedEdges[offset+j];
+		if(m > 0){
+		    for(k = 1; k < Label; ++k){
+			if(Classes[k] == m){
+			    connectedEdges[offset+j] = (unsigned short)k;
+			    break;
+			}
+		    }
+		}
+	    }
+	    offset += cols;
+	}
+
+	return Label;
+}
+
+float magnitude(float X, float Y){
+
+	return (float)sqrt(X*X + Y*Y);
+}
+
+int traceEdge(int i, int j, int rows, int cols, double cannyLow, float *magImage, float *HYSImage){
+
+	int n, m;
+	int ptr;
+	int flag;
+
+	ptr = i * cols;
+	if(HYSImage[ptr+j] == (float)0.0){
+	    //
+	    // this point is above high threshold
+	    //
+	    HYSImage[ptr+j] = (float)1.0;
+	    flag = 0;
+	    for(n = -1; n <= 1; ++n){
+		for(m = -1; m <= 1; ++m){
+		    if(n == 0 && m == 0) continue;
+		    if(((i+n) > 0) && ((j+m) > 0) && ((i+n) < rows) && ((j+m) < cols)){
+			ptr = (i+n) * cols;
+			if(magImage[ptr+j+m] > cannyLow){
+	    		    //
+	    		    // this point is above low threshold
+	    		    //
+			    if(traceEdge(i+n, j+m, rows, cols, cannyLow, magImage, HYSImage)){
+				flag = 1;
+				break;
+			    }
+			}
+		    }
+		}
+		if(flag) break;
+	    }
+	    return(1);
+	}
+
+	return(0);
+
+}
+
+
+void edgeThreshold(int rows, int cols, double cannyLow, float *magImage, float *HYSImage){
+
+	int i, j;
+	int ptr;
+
+	for(i = 0; i < rows; ++i){
+	    ptr = i * cols;
+	    for(j = 0; j < cols; ++j){
+		if(magImage[ptr+j] > cannyLow){
+		    HYSImage[ptr+j] = (float)1.0;
+		}
+	    }
+	}
+
+	return;
+
+}
+
+void edgeHysteresis(int rows, int cols, double cannyLow, double cannyHigh, float *magImage, float *HYSImage){
+
+	int i, j;
+	int ptr;
+
+	for(i = 0; i < rows; ++i){
+	    ptr = i * cols;
+	    for(j = 0; j < cols; ++j){
+		if(magImage[ptr+j] > cannyHigh){
+		    traceEdge(i, j, rows, cols, cannyLow, magImage, HYSImage);
+		}
+	    }
+	}
+
+	return;
+
+}
+
+void nonMaxSupress(int rows, int cols, float aveXValue, float aveYValue, double *cannyLow, double *cannyHigh,
+                   int mode, float *hDGImage, float *vDGImage, float *magImage){
+
+	int i, j;
+	int ptr, ptr_m1, ptr_p1;
+	float xSlope, ySlope, G1, G2, G3, G4, G, xC, yC;
+	float scale;
+	float maxValue = (float)0.0;
+	float minValue = (float)-1.0;
+	int histogram[256];
+	int value;
+	int mValue;
+	int mIndex;
+	int count;
+	double step;
+	double tAve;
+
+	for(i = 1; i < rows-1; ++i){
+	    ptr = i * cols;
+	    ptr_m1 = ptr - cols;
+	    ptr_p1 = ptr + cols;
+	    for(j = 1; j < cols; ++j){
+		magImage[ptr+j] = (float)0.0;
+		xC = hDGImage[ptr+j];
+		yC = vDGImage[ptr+j];
+		if((fabs(xC) < aveXValue) && (fabs(yC) < aveYValue)) continue;
+		G = magnitude(xC, yC);
+		if(fabs(yC) > fabs(xC)){
+		    // vertical gradient
+		    xSlope = (float)(fabs(xC) / fabs(yC));
+		    ySlope = (float)1.0;
+		    G2 = magnitude(hDGImage[ptr_m1+j], vDGImage[ptr_m1+j]);
+		    G4 = magnitude(hDGImage[ptr_p1+j], vDGImage[ptr_p1+j]);	
+		    if((xC*yC) > (float)0.0){
+			G1 = magnitude(hDGImage[ptr_m1+j-1], vDGImage[ptr_m1+j-1]);
+			G3 = magnitude(hDGImage[ptr_p1+j+1], vDGImage[ptr_p1+j+1]);
+		    }
+		    else{
+			G1 = magnitude(hDGImage[ptr_m1+j+1], vDGImage[ptr_m1+j+1]);
+			G3 = magnitude(hDGImage[ptr_p1+j-1], vDGImage[ptr_p1+j-1]);
+		    }
+		}
+		else{
+		    // horizontal gradient
+		    xSlope = (float)(fabs(yC) / fabs(xC));
+		    ySlope = (float)1.0;
+		    G2 = magnitude(hDGImage[ptr+j+1], vDGImage[ptr+j+1]);
+		    G4 = magnitude(hDGImage[ptr+j-1], vDGImage[ptr+j-1]);	
+		    if((xC*yC) > (float)0.0){
+			G1 = magnitude(hDGImage[ptr_p1+j+1], vDGImage[ptr_p1+j+1]);
+			G3 = magnitude(hDGImage[ptr_m1+j-1], vDGImage[ptr_m1+j-1]);
+		    }
+		    else{
+			G1 = magnitude(hDGImage[ptr_m1+j+1], vDGImage[ptr_m1+j+1]);
+			G3 = magnitude(hDGImage[ptr_p1+j-1], vDGImage[ptr_p1+j-1]);
+		    }
+		}
+		if( (G > (xSlope*G1 + (ySlope-xSlope)*G2)) && (G > (xSlope*G3 + (ySlope-xSlope)*G4)) ){
+		    magImage[ptr+j] = G;	
+		}
+		if(magImage[ptr+j] > maxValue) maxValue = magImage[ptr+j];
+		if(magImage[ptr+j] < minValue) minValue = magImage[ptr+j];
+	    }
+	}
+
+	scale = (float)1.0 / (maxValue-minValue);
+	ptr   = 0;
+	count = 0;
+	tAve  = 0.0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		magImage[ptr] = scale * (magImage[ptr]-minValue);
+		if(magImage[ptr] > 0.0){
+		    tAve += magImage[ptr];
+		    ++count;
+		}
+		++ptr;
+	    }
+	}
+	tAve /= (float)count;
+
+	step = 255.0;
+	for(i = 0; i < 256; ++i){
+	    histogram[i] = 0;
+	}
+	ptr = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		value = (int)(step*(magImage[ptr]));
+	        ++histogram[value];
+		++ptr;
+	    }
+	}
+	//
+	// now get the max after skipping the low values
+	//
+	mValue = -1;
+	mIndex = 0;
+	for(i = 10; i < 256; ++i){
+	    if(histogram[i] > mValue){
+		mValue = histogram[i];
+		mIndex = i;
+	    }
+	}
+
+	if(mode == 1){
+	    // based on the mean value of edge energy
+	    *cannyLow  = ((*cannyLow)  * tAve);
+	    *cannyHigh = ((*cannyHigh) * tAve);
+	}
+	else{
+	    // based on the mode value of edge energy
+	    *cannyLow  = ((*cannyLow)  * ((float)mIndex/step));
+	    *cannyHigh = ((*cannyHigh) * ((float)mIndex/step));
+	}
+
+	return;
+
+}
+
+void DGFilters(int samples, int rows, int cols, double cannySigma, int gWidth,
+               float *aveXValue, float *aveYValue, double *rawImage,
+               double *dgKernel, float *hDGImage, float *vDGImage){
+
+	//
+	// implements the derivative of Gaussian filter. kernel set by CannyEdges
+	//
+	int i, j, k;
+	int ptr;
+	int mLength;
+	int count;
+	float *tBuffer = NULL;
+	double sum;
+
+	*aveXValue = (float)0.0;
+	*aveYValue = (float)0.0;	
+
+	mLength = MAX(rows, cols) + 64;
+	tBuffer = calloc(mLength, sizeof(float));
+
+	//
+	// filter X 
+	//
+	count = 0;
+	for(i = 0; i < rows; ++i){
+	    ptr = i * cols;
+	    for(j = gWidth; j < cols-gWidth; ++j){
+		sum = dgKernel[0] * rawImage[ptr+j];
+		for(k = 1; k < gWidth; ++k){
+		    sum += dgKernel[k] * (-rawImage[ptr+j+k] + rawImage[ptr+j-k]);
+		}
+		hDGImage[ptr+j] = (float)sum;
+		if(sum != (float)0.0){
+		    ++count;
+		    *aveXValue += (float)fabs(sum);
+		}
+	    }
+	}
+	if(count){
+	    *aveXValue /= (float)count;
+	    *aveXValue = (float)0.5 * (*aveXValue);
+	    // this is 50% of the max, hardwirred for now, and is part of the threshold
+	}
+	//
+	// filter Y 
+	//
+	count = 0;
+	for(i = 0; i < cols; ++i){
+	    for(j = 0; j < rows; ++j){
+		ptr = j * cols;
+		tBuffer[j] = rawImage[ptr+i];
+	    }
+	    for(j = gWidth; j < rows-gWidth; ++j){
+		ptr = j * cols;
+		sum = dgKernel[0] * tBuffer[j];
+		for(k = 1; k < gWidth; ++k){
+		    sum += dgKernel[k] * (-tBuffer[j+k] + tBuffer[j-k]);
+		}
+		vDGImage[ptr+i] = sum;
+		if(sum != (float)0.0){
+		    ++count;
+		    *aveYValue += (float)fabs(sum);
+		}
+	    }
+	}
+	if(count){
+	    *aveYValue /= (float)count;
+	    *aveYValue = (float)0.5 * (*aveYValue);
+	    // this is 50% of the max, hardwirred for now, and is part of the threshold
+	}
+
+	free(tBuffer);
+
+	return;
+
+}
+
+
+int NI_CannyEdges(int samples, int rows, int cols, double cannySigma, double cannyLow, double cannyHigh, int mode, 
+                  int lowThreshold, int highThreshold, double BPHigh, int apearture, double *rawImage,
+		  unsigned short *edgeImage, int *groups){
+
+	int i, j;
+	int offset;
+	int doHysteresis = 0;
+	int gWidth;
+	int mLength;
+	int status;
+	float aveXValue;
+	float aveYValue;
+	double t;
+	double dgKernel[20];
+	float *HYSImage = NULL;
+	float *hDGImage = NULL;
+	float *vDGImage = NULL;
+	float *magImage = NULL;
+	float *tBuffer  = NULL;
+
+	// filter
+	printf("do preProcess\n");
+	doPreProcess(samples, rows, cols, rawImage, BPHigh, apearture, lowThreshold, highThreshold);
+	printf("do Canny\n");
+
+	//
+	// memory for magnitude, horizontal and vertical derivative of Gaussian filter
+	//
+	mLength  = MAX(rows, cols) + 64;
+	HYSImage = calloc(samples, sizeof(float));
+	hDGImage = calloc(samples, sizeof(float));
+	vDGImage = calloc(samples, sizeof(float));
+	magImage = calloc(samples, sizeof(float));
+	tBuffer  = calloc(mLength, sizeof(float));
+
+	//
+	// build derivative of Gaussian filter kernel
+	// kernel is anti-symmetric so convolution is k[j]*(v[i+j] - v[i-j]) 
+	//
+	gWidth = 20;
+	for(i = 0; i < gWidth; ++i){
+	    t = (float)i;
+	    dgKernel[i]  = (float)exp((double)((-t*t)/((float)2.0 * cannySigma * cannySigma)));
+	    dgKernel[i] *= -(t / (cannySigma * cannySigma));
+	}
+	for(i = 0; i < samples; ++i){
+	    HYSImage[i] = (float)0.0;
+	}
+
+	DGFilters(samples, rows, cols, cannySigma, gWidth, &aveXValue, &aveYValue, rawImage, dgKernel, hDGImage, vDGImage); 
+	nonMaxSupress(rows, cols, aveXValue, aveYValue, &cannyLow, &cannyHigh, mode, hDGImage, vDGImage, magImage);
+	if(doHysteresis){
+	    edgeHysteresis(rows, cols, cannyLow, cannyHigh, magImage, HYSImage);
+	}
+	else{
+	    edgeThreshold(rows, cols, cannyLow, magImage, HYSImage);
+	}
+
+	//
+	// edge image
+	//
+	for(i = 0; i < samples; ++i){
+	    edgeImage[i] = (unsigned short)HYSImage[i];
+	}
+	*groups = ConnectedEdgePoints(rows, cols, edgeImage);
+
+	//
+	// prune the isolated pixels
+	//
+	offset  = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(edgeImage[offset+j] > (*groups)){
+		    edgeImage[offset+j] = 0;
+		}	
+	    }
+	    offset  += cols;
+	}
+
+
+	free(tBuffer);
+	free(hDGImage);
+	free(vDGImage);
+	free(magImage);
+	free(HYSImage);
+
+	status = *groups;
+	return status;
+
+}
+
+void doSobel(int samples, int rows, int cols, double sobelLow, int mode, double *rawImage, unsigned short *edgeImage){
+
+	int i, j;
+	int p, m, n;
+	int offset;
+	int offsetM1;
+	int offsetP1;
+	int minValue, maxValue;
+	int pAve  = 0;
+	int count = 0;
+	int histogram[256];
+	int value;
+	int maxIndex;
+	float pThreshold;
+	double scale;
+	double step;
+	float *filteredImage = NULL;
+
+	filteredImage = calloc(samples, sizeof(float));
+
+	minValue = 10000;
+	maxValue = -10000;
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		filteredImage[offset+j] = 0;
+		edgeImage[offset+j]     = 0;
+	    }
+	    offset += cols;
+	}
+
+	//
+	// Sobel
+	//
+	offset = cols;
+	for(i = 1; i < rows-1; ++i){
+	    offsetM1 = offset - cols;
+	    offsetP1 = offset + cols;
+	    for(j = 1; j < cols-1; ++j){
+	        n = 2*rawImage[offsetM1+j] + rawImage[offsetM1+j-1] + rawImage[offsetM1+j+1] -
+	            2*rawImage[offsetP1+j] - rawImage[offsetP1+j-1] - rawImage[offsetP1+j+1];
+	        m = 2*rawImage[offset+j-1] + rawImage[offsetM1+j-1] + rawImage[offsetP1+j-1] -
+	            2*rawImage[offset+j+1] - rawImage[offsetM1+j+1] - rawImage[offsetP1+j+1];
+	        p = (int)sqrt((float)(m*m) + (float)(n*n));
+		if(p > 0){
+		    pAve += p;
+		    ++count;
+		    if(p > maxValue) maxValue = p;
+		    if(p < minValue) minValue = p;
+		}
+	        filteredImage[offset+j] = p;
+	    }
+	    offset += cols;
+	}
+
+	// threshold based on ave
+	pAve /= count;
+	scale = 1.0 / maxValue;
+
+	step = 255.0/(maxValue-minValue);
+	for(i = 0; i < 256; ++i){
+	    histogram[i] = 0;
+	}
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		value = (int)(step*(filteredImage[offset+j]-minValue));
+	        ++histogram[value];
+	    }
+	    offset += cols;
+	}
+	//
+	// now get the max after skipping the low values
+	//
+	maxValue = -1;
+	maxIndex = 0;
+	for(i = 10; i < 256; ++i){
+	    if(histogram[i] > maxValue){
+		maxValue = histogram[i];
+		maxIndex = i;
+	    }
+	}
+
+	if(mode == 1){
+	    // based on the mean value of edge energy
+	    pThreshold = (int)(sobelLow * (float)pAve);
+	}
+	else{
+	    // based on the mode value of edge energy
+	    pThreshold = (sobelLow * (minValue + ((float)maxIndex/step)));
+	}
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(filteredImage[offset+j] > pThreshold){
+		    edgeImage[offset+j] = 1;
+		}
+		else{
+		    edgeImage[offset+j] = 0;
+		}
+		filteredImage[offset+j] *= scale; 
+	    }
+	    offset += cols;
+	}
+
+	free(filteredImage);
+
+	return;
+
+
+}
+
+void estimateThreshold(float *lowThreshold, float *highThreshold, float ShenCastanLow, int rows, int cols, float *SourceImage){
+
+	int i, j;
+	int offset;
+	int value;
+	int mIndex;
+	int histogram[256];
+	float low, high;
+	float scale;
+
+	low  = (float)1000.0;
+	high = (float)-1000.0;
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+	        if(fabs(SourceImage[offset+j]) > high) high = fabs(SourceImage[offset+j]);
+	        if(fabs(SourceImage[offset+j]) < low)  low  = fabs(SourceImage[offset+j]);
+	    }
+	    offset += cols;
+	}
+
+	scale = (float)255.0 / (high-low);
+	for(i = 0; i < 256; ++i){
+	    histogram[i] = 0;
+	}
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+	        value = (int)(scale*(fabs(SourceImage[offset+j]) - low)); 
+	        ++histogram[value];
+	    }
+	    offset += cols;
+	}
+
+	//
+	// now get the edge energy mode
+	//
+	value  = 0;
+	mIndex = 10;
+	for(i = 10; i < 256; ++i){
+	    if(histogram[i] > value){
+	        value  = histogram[i];
+	        mIndex = i;
+	    }
+	}
+
+	*highThreshold = ((float)mIndex / scale) + low;
+	*lowThreshold  = ((float)mIndex / scale) + low;
+
+	*highThreshold *= ShenCastanLow;
+	*lowThreshold  *= ShenCastanLow;
+
+	return;
+
+}
+
+void thresholdEdges(float *SourceImage, unsigned short *EdgeImage, double ShenCastanLow, int rows, int cols){
+
+	int i, j;
+	int offset;
+	float tLow, tHigh;
+
+	//
+	// SourceImage contains the adaptive gradient
+	// get threshold from the mode of the edge energy
+	//
+	estimateThreshold(&tLow, &tHigh, ShenCastanLow, rows, cols, SourceImage);
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(SourceImage[offset+j] > tLow){
+		    EdgeImage[offset+j] = 1;
+		}
+		else{
+		    EdgeImage[offset+j] = 0;
+		}
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+float adaptiveGradient(float *BLImage, float *FilterImage, int nrow, int ncol, int cols, int window){
+
+	int i, j;
+	int offset;
+	int numOn, numOff;
+	int hWindow = window/2;
+	float sumOn, sumOff;
+	float aveOn, aveOff;
+
+	numOn  = 0;
+       	numOff = 0;
+
+	sumOn  = (float)0.0;
+       	sumOff = (float)0.0;
+
+	aveOn  = (float)0.0;
+       	aveOff = (float)0.0;
+
+	offset = nrow * cols;
+	for(i = -hWindow; i < hWindow; ++i){
+	    for(j = -hWindow; j < hWindow; ++j){
+		if(BLImage[offset+(i*cols)+(j+ncol)] == 1){
+		    sumOn += FilterImage[offset+(i*cols)+(j+ncol)]; 
+		    ++numOn;
+		}
+		else{
+		    sumOff += FilterImage[offset+(i*cols)+(j+ncol)]; 
+		    ++numOff;
+		}
+	    }
+	}
+
+	if(numOn){
+	    aveOn = sumOn / numOn;
+	}
+
+	if(numOff){
+	    aveOff = sumOff / numOff;
+	}
+
+	return (aveOff-aveOn);
+
+}
+
+void getZeroCrossings(float *SourceImage, float *FilterImage, float *BLImage, int rows, int cols, int window){
+
+	int i, j;
+	int offset;
+	bool validEdge;
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		SourceImage[offset+j] = 0.0; 
+	    }
+	    offset += cols;
+	}
+
+	offset = window*cols;
+	for(i = window; i < rows-window; ++i){
+	    for(j = window; j < cols-window; ++j){
+		validEdge = FALSE;
+		if((BLImage[offset+j] == 1) && (BLImage[offset+cols+j] == 0)){
+		    if((FilterImage[offset+cols+j] - FilterImage[offset-cols+j]) > 0.0){
+			validEdge = TRUE;
+		    } 
+		}
+		else if((BLImage[offset+j] == 1) && (BLImage[offset+j+1] == 0)){
+		    if((FilterImage[offset+j+1] - FilterImage[offset+j-1]) > 0.0){
+			validEdge = TRUE;
+		    } 
+		}
+		else if((BLImage[offset+j] == 1) && (BLImage[offset-cols+j] == 0)){
+		    if((FilterImage[offset+cols+j] - FilterImage[offset-cols+j]) < 0.0){
+			validEdge = TRUE;
+		    } 
+		}
+		else if((BLImage[offset+j] == 1) && (BLImage[offset+j-1] == 0)){
+		    if((FilterImage[offset+j+1] - FilterImage[offset+j-1]) < 0.0){
+			validEdge = TRUE;
+		    } 
+		}
+		if(validEdge){
+		    // adaptive gradeint is signed
+		    SourceImage[offset+j] = (float)fabs(adaptiveGradient(BLImage, FilterImage, i, j, cols, window));
+		}
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+
+void computeBandedLaplacian(float *image1, float *image2, float *BLImage, int rows, int cols){
+
+	int i, j;
+	int offset;
+	float t;
+
+	//
+	// like an unsharp mask
+	//
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+	        t = image1[offset+j] - image2[offset+j];
+		if(t < (float)0.0){
+		    t = (float)0.0;
+		}
+		else{
+		    t = (float)1.0;
+		}
+		BLImage[offset+j] = t;
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+void thresholdImage(float *Raw, float *Filtered, int rows, int cols, int tLow, int tHigh){
+
+	int i, j;
+	int ptr;
+
+	ptr = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(Raw[ptr] > tHigh){
+		    Raw[ptr]      = 0.0;
+		    Filtered[ptr] = 0.0;
+		}
+		if(Raw[ptr] < tLow){
+		    Raw[ptr]      = 0.0;
+		    Filtered[ptr] = 0.0;
+		}
+		++ptr;
+	    }
+	}
+
+	return;
+
+}
+
+void ISEF_Vertical(float *SourceImage, float *FilterImage, float *A, float *B, int rows, int cols, double b){
+
+
+	int i, j;
+	int offset;
+	float b1, b2;
+
+	b1 = ((float)1.0 - b)/((float)1.0 + b);
+	b2 = b * b1;
+
+	//
+	// set the boundaries
+	//
+	offset = (rows-1)*cols;
+	for(i = 0; i < cols; ++i){
+	    // process row 0
+	    A[i] = b1 * SourceImage[i];
+	    // process row N-1
+	    B[offset+i] = b2 * SourceImage[offset+i];
+	}
+
+	//
+	// causal component of IIR filter
+	//
+	offset = cols;
+	for(i = 1; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		//
+	        // IIR ISEF filter applied across rows
+		//
+	        A[offset+j] = (b * A[offset-cols+j]) + (b1 * SourceImage[offset+j]);
+	    }
+	    offset += cols;
+	}
+
+	//
+	// anti-causal component of IIR filter
+	//
+	offset = (rows-2)*cols;
+	for(i = rows-2; i >= 0; --i){
+	    for(j = 0; j < cols; ++j){
+		//
+	        // IIR ISEF filter applied across rows
+		//
+	        B[offset+j] = (b * B[offset+cols+j]) + (b2 * SourceImage[offset+j]); 
+	    }
+	    offset -= cols;
+	}
+
+	offset = (rows-1)*cols;
+	for(j = 0; j < cols-1; ++j){
+	    FilterImage[offset+j] = A[offset+j];
+	}
+
+	//
+	// add causal and anti-causal IIR parts
+	//
+	offset = 0;
+	for(i = 1; i < rows-2; ++i){
+	    for(j = 0; j < cols-1; ++j){
+	        FilterImage[offset+j] = A[offset+j] + B[offset+cols+j];
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+void ISEF_Horizontal(float *SourceImage, float *FilterImage, float *A, float *B, int rows, int cols, double b){
+
+
+	//
+	// source and smooth are the same in this pass of the 2D IIR
+	//
+
+	int i, j;
+	int offset;
+	float b1, b2;
+
+	b1 = ((float)1.0 - b)/((float)1.0 + b);
+	b2 = b * b1;
+
+	//
+	// columns boundaries
+	//
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    // col 0
+	    A[offset] = b1 * SourceImage[offset];
+	    // col N-1
+	    B[offset+cols-1] = b2 * SourceImage[offset+cols-1];
+	}
+
+	//
+	// causal IIR part
+	//
+	offset = 0;
+	for(j = 1; j < cols; ++j){
+	    for(i = 0; i < rows; ++i){
+		A[offset+j] = (b * A[offset+j-1]) + (b1 * SourceImage[offset+j]);
+	    }
+	    offset += cols;
+	}
+
+	//
+	// anti-causal IIR part
+	//
+	offset = 0;
+	for(j = cols-2; j > 0; --j){
+	    for(i = 0; i < rows; ++i){
+		B[offset+j] = (b * B[offset+j+1]) + (b2 * SourceImage[offset+j]);
+	    }
+	    offset += cols;
+	}
+
+	//
+	// filtered output. this is 2-pass IIR and pass 1 is vertical
+	//
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    FilterImage[offset+cols-1] = A[offset+cols-1];
+	}
+
+	//
+	// add causal and anti-causal IIR parts
+	//
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols-1; ++j){
+	        FilterImage[offset+j] = A[offset+j] + B[offset+j+1];
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+
+void computeISEF(float *SourceImage, float *FilterImage, int rows, int cols, double b){
+
+	int imageSize = rows*cols;
+	float *A;
+	float *B;
+
+	A = calloc(imageSize, sizeof(float));
+	B = calloc(imageSize, sizeof(float));
+
+	ISEF_Vertical(SourceImage, FilterImage, A, B, rows, cols, b);
+	ISEF_Horizontal(FilterImage, FilterImage, A, B, rows, cols, b);
+
+	free(A);
+	free(B);
+
+	return;
+
+}
+
+void Shen_Castan(double b, double ShenCastanLow, int rows, int cols, int window, int lowThreshold, int highThreshold,
+	       	 double *RawImage, unsigned short *EdgeImage){
+
+	int i;
+	int imageSize = rows*cols;
+	float *FilterImage;
+	float *BinaryLaplacianImage;
+	float *SourceImage;
+
+	FilterImage          = calloc(imageSize, sizeof(float));
+	BinaryLaplacianImage = calloc(imageSize, sizeof(float));
+	SourceImage          = calloc(imageSize, sizeof(float));
+
+	for(i = 0; i < imageSize; ++i){
+	    SourceImage[i] = RawImage[i];
+	}
+	computeISEF(SourceImage, FilterImage, rows, cols, b);
+	// optional thresholding based on low, high
+	thresholdImage(SourceImage, FilterImage, rows, cols, lowThreshold, highThreshold);
+	computeBandedLaplacian(FilterImage, SourceImage, BinaryLaplacianImage, rows, cols);
+	// the new source image is now the adaptive gradient
+	getZeroCrossings(SourceImage, FilterImage, BinaryLaplacianImage, rows, cols, window);
+	thresholdEdges(SourceImage, EdgeImage, ShenCastanLow, rows, cols);
+
+	free(FilterImage);
+	free(BinaryLaplacianImage);
+	free(SourceImage);
+
+	return;
+
+}
+
+int NI_ShenCastanEdges(int samples, int rows, int cols, double b, double ShenCastanLow, int window, int lowThreshold,
+                       int highThreshold, double *rawImage, unsigned short *edgeImage, int *groups){
+
+
+	int i, j;
+	int offset;
+	int status = 0;
+
+	Shen_Castan(b, ShenCastanLow, rows, cols, window, lowThreshold, highThreshold, rawImage, edgeImage);
+	*groups = ConnectedEdgePoints(rows, cols, edgeImage);
+
+
+	//
+	// prune the isolated pixels
+	//
+	offset  = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(edgeImage[offset+j] > (*groups)){
+		    edgeImage[offset+j] = 0;
+		}	
+	    }
+	    offset  += cols;
+	}
+
+	status = *groups;
+
+	return status;
+
+}
+
+void buildBinaryImage(int rows, int cols, double *rawImage, unsigned short *edgeImage, int lowThreshold, int highThreshold){
+
+	int i, j;
+	int offset;
+	double value;
+	int maskValue;
+
+	offset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		value = rawImage[offset+j];
+		maskValue = 1;
+		if(value < (double)lowThreshold)  maskValue = 0;
+		if(value > (double)highThreshold) maskValue = 0;
+		edgeImage[offset+j] = maskValue;
+	    }
+	    offset += cols;
+	}
+
+	return;
+
+}
+
+
+
+void morphoFilterBinaryImage(int rows, int cols, unsigned short *edgeImage, int CloseSize, int OpenSize){
+
+
+	int i, j;
+	int offset, offset2;
+	unsigned short cmask[11][11];
+	unsigned short omask[11][11];
+	int olapValuesC[4];
+	int olapValuesO[4];
+	int CloseMaskSize;
+	int OpenMaskSize;
+	int LowValue1, HighValue1;   
+	int LowValue2, HighValue2;  
+	int spadSize;
+	unsigned char *ImageE;
+	unsigned char *ImageC;
+
+	spadSize = MAX(rows, cols);
+
+	ImageE = calloc(spadSize*spadSize, sizeof(unsigned char));
+	ImageC = calloc(spadSize*spadSize, sizeof(unsigned char));
+
+	//
+	// Close filter
+	//
+	if(CloseSize){
+	    CloseMaskSize = (CloseSize-1)/2;
+	    for(i = 0; i < 2*CloseMaskSize+1; ++i){
+	        for(j = 0; j < 2*CloseMaskSize+1; ++j){
+	            cmask[i][j] = 1;
+	        }
+	    }
+	    LowValue1      = 0;   
+	    HighValue1     = 1;   
+	    LowValue2      = 1;   
+	    HighValue2     = 0;   
+	    olapValuesC[0] = LowValue1;
+	    olapValuesC[1] = HighValue1;
+	    olapValuesC[2] = LowValue2;
+	    olapValuesC[3] = HighValue2;
+	}
+
+	//
+	// Open filter
+	//
+	if(OpenSize){
+	    OpenMaskSize = (OpenSize-1)/2;
+	    for(i = 0; i < 2*OpenMaskSize+1; ++i){
+	        for(j = 0; j < 2*OpenMaskSize+1; ++j){
+	            omask[i][j] = 1;
+	        }
+	    }
+	    LowValue1      = 1;   
+	    HighValue1     = 0;   
+	    LowValue2      = 0;   
+	    HighValue2     = 1;   
+	    olapValuesO[0] = LowValue1;
+	    olapValuesO[1] = HighValue1;
+	    olapValuesO[2] = LowValue2;
+	    olapValuesO[3] = HighValue2;
+	}
+
+	offset  = 0;
+	offset2 = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		ImageE[offset2+j] = (unsigned char)edgeImage[offset+j]; 
+	    }
+	    offset2 += spadSize;
+	    offset  += cols;
+	}
+
+	if(OpenSize){
+	    OpenCloseFilter(olapValuesO, OpenMaskSize, rows, cols, spadSize, ImageE, ImageC, omask);
+	}
+
+	if(CloseSize){
+	    OpenCloseFilter(olapValuesC, CloseMaskSize, rows, cols, spadSize, ImageE, ImageC, cmask);
+	}
+
+	offset  = 0;
+	offset2 = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(ImageE[offset2+j] == 1){
+		    // this will activate some original off-pixels
+		    edgeImage[offset+j] = 1;
+		}
+		else{
+		    // this will zero some original on-pixels
+		    edgeImage[offset+j] = 0;
+		}
+	    }
+	    offset2 += spadSize;
+	    offset  += cols;
+	}
+
+	free(ImageE);
+	free(ImageC);
+
+	return;
+
+}
+
+void doRegionGrow(int samples, int rows, int cols, double *rawImage, unsigned short *edgeImage, int lowThreshold, 
+		  int highThreshold, int closeWindow, int openWindow){
+
+	buildBinaryImage(rows, cols, rawImage, edgeImage, lowThreshold, highThreshold);
+	morphoFilterBinaryImage(rows, cols, edgeImage, closeWindow, openWindow);
+
+	return;
+
+}
+
+int NI_RegionGrow(int samples, int rows, int cols, int lowThreshold, int highThreshold, int closeWindow,   
+                  int openWindow, double *rawImage, unsigned short *edgeImage, int *groups){
+
+	int i, j;
+	int offset;
+	int status;
+
+	doRegionGrow(samples, rows, cols, rawImage, edgeImage, lowThreshold, highThreshold, closeWindow, openWindow);
+	*groups = ConnectedEdgePoints(rows, cols, edgeImage);
+
+	//
+	// prune the isolated pixels
+	//
+	offset  = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(edgeImage[offset+j] > (*groups)){
+		    edgeImage[offset+j] = 0;
+		}	
+	    }
+	    offset  += cols;
+	}
+
+	status = *groups;
+	return status;
+
+}
+
+int NI_SobelEdges(int samples, int rows, int cols, double sobelLow, int mode, int lowThreshold, int highThreshold, double BPHigh,   
+                  int apearture, double *rawImage, unsigned short *edgeImage, int *groups){
+
+
+	int i, j;
+	int offset;
+	int status;
+
+	doPreProcess(samples, rows, cols, rawImage, BPHigh, apearture, lowThreshold, highThreshold);
+	doSobel(samples, rows, cols, sobelLow, mode, rawImage, edgeImage);
+	*groups = ConnectedEdgePoints(rows, cols, edgeImage);
+	
+	
+	//
+	// prune the isolated pixels
+	//
+	offset  = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < cols; ++j){
+		if(edgeImage[offset+j] > (*groups)){
+		    edgeImage[offset+j] = 0;
+		}	
+	    }
+	    offset  += cols;
+	}
+
+	status = *groups;
+	return status;
+
+}
+
+void initThinFilter(int J_mask[3][30], int K_mask[3][30]){
+
+	int i, j;
+	int Column;
+
+	for(i = 0; i < 3; ++i){
+	    for(j = 0; j < 30; ++j){
+		J_mask[i][j] = 0;
+		K_mask[i][j] = 0;
+	    }
+	}
+
+	Column = 0;
+   	J_mask[0][Column+0] = 1;
+   	J_mask[0][Column+1] = 1;
+   	J_mask[0][Column+2] = 1;
+   	J_mask[1][Column+1] = 1;
+
+	Column += 3;
+   	J_mask[0][Column+1] = 1;
+   	J_mask[1][Column+1] = 1;
+   	J_mask[1][Column+2] = 1;
+
+	Column += 3;
+   	J_mask[0][Column+0] = 1;
+   	J_mask[1][Column+0] = 1;
+   	J_mask[2][Column+0] = 1;
+   	J_mask[1][Column+1] = 1;
+
+	Column += 3;
+   	J_mask[0][Column+1] = 1;
+   	J_mask[1][Column+0] = 1;
+   	J_mask[1][Column+1] = 1;
+
+	Column += 3;
+   	J_mask[0][Column+2] = 1;
+   	J_mask[1][Column+1] = 1;
+   	J_mask[1][Column+2] = 1;
+   	J_mask[2][Column+2] = 1;
+
+	Column += 3;
+   	J_mask[1][Column+0] = 1;
+   	J_mask[1][Column+1] = 1;
+   	J_mask[2][Column+1] = 1;
+
+	Column += 3;
+   	J_mask[1][Column+1] = 1;
+   	J_mask[2][Column+0] = 1;
+   	J_mask[2][Column+1] = 1;
+   	J_mask[2][Column+2] = 1;
+
+	Column += 3;
+   	J_mask[1][Column+1] = 1;
+   	J_mask[1][Column+2] = 1;
+   	J_mask[2][Column+1] = 1;
+
+	Column = 0;
+   	K_mask[2][Column+0] = 1;
+   	K_mask[2][Column+1] = 1;
+   	K_mask[2][Column+2] = 1;
+
+	Column += 3;
+   	K_mask[1][Column+0] = 1;
+   	K_mask[2][Column+0] = 1;
+   	K_mask[2][Column+1] = 1;
+
+	Column += 3;
+   	K_mask[0][Column+2] = 1;
+   	K_mask[1][Column+2] = 1;
+   	K_mask[2][Column+2] = 1;
+
+	Column += 3;
+   	K_mask[1][Column+2] = 1;
+   	K_mask[2][Column+1] = 1;
+   	K_mask[2][Column+2] = 1;
+
+	Column += 3;
+   	K_mask[0][Column+0] = 1;
+   	K_mask[1][Column+0] = 1;
+   	K_mask[2][Column+0] = 1;
+
+	Column += 3;
+   	K_mask[0][Column+1] = 1;
+   	K_mask[0][Column+2] = 1;
+   	K_mask[1][Column+2] = 1;
+
+	Column += 3;
+   	K_mask[0][Column+0] = 1;
+   	K_mask[0][Column+1] = 1;
+   	K_mask[0][Column+2] = 1;
+
+	Column += 3;
+   	K_mask[0][Column+0] = 1;
+   	K_mask[0][Column+1] = 1;
+   	K_mask[1][Column+0] = 1;
+
+	return;
+
+}
+
+void ThinningFilter(int regRows, int regColumns, int spadSize, int J_mask[3][30], int K_mask[3][30],
+	            unsigned char *Input, unsigned char *CInput, unsigned char *ErosionStage,
+	            unsigned char *DialationStage, unsigned char *HMT, unsigned char *Copy){
+
+	int i, j, k, l, m, n, overlap, hit;
+	int LowValue1, HighValue1;   
+	int LowValue2, HighValue2;   
+	int Column, T, nloop;
+	int Offset;
+	int N, M;
+	int j_mask[3][3];
+	int k_mask[3][3];
+
+	N = regRows;
+	M = regColumns;
+
+	LowValue1  = 1;   
+	HighValue1 = 0;   
+
+	LowValue2  = 0;   
+	HighValue2 = 1;   
+
+	Offset = 0;
+	for(i = 0; i < N; ++i){
+	    for(j = 0; j < M; ++j){
+		Copy[Offset+j] = Input[Offset+j];
+	    }
+	    Offset += spadSize;
+	}
+
+	nloop = 0;
+	while(1){
+	    // erode
+	    Column = 0;
+	    for(n = 0; n < 8; ++n){
+		for(i = 0; i < 3; ++i){
+		    for(j = 0; j < 3; ++j){
+			j_mask[i][j] = J_mask[i][Column+j];
+		    }
+		}
+		for(i = 0; i < 3; ++i){
+		    for(j = 0; j < 3; ++j){
+			k_mask[i][j] = K_mask[i][Column+j];
+		    }
+		}
+		Column += 3;
+
+		Offset = spadSize;
+		for(i = 1; i < N-1; ++i){
+		    for(j = 1; j < M-1; ++j){
+			hit = LowValue1; 
+			for(k = -1; k < 2; ++k){
+			    for(l = -1; l < 2; ++l){
+				T = j_mask[k+1][l+1];
+				if(T == 1){
+				    overlap = T*Input[Offset+(k*spadSize)+j+l];
+				    if(overlap == HighValue1) hit = HighValue1;
+				}
+			    }
+			}
+			ErosionStage[Offset+j] = hit;
+		    }
+		    Offset += spadSize;
+		}
+
+		// dialate
+		Offset = 0;
+		for(i = 0; i < N; ++i){
+		    for(j = 0; j < M; ++j){
+			CInput[Offset+j] = (~Input[Offset+j]) & 0x1; 
+		    }
+		    Offset += spadSize;
+		}
+
+		Offset = spadSize;
+		for(i = 1; i < N-1; ++i){
+		    for(j = 1; j < M-1; ++j){
+			hit = LowValue1; 
+			for(k = -1; k < 2; ++k){
+			    for(l = -1; l < 2; ++l){
+				T = k_mask[k+1][l+1];
+				if(T == 1){
+				    overlap = T*CInput[Offset+(k*spadSize)+j+l];
+				    if(overlap == HighValue1) hit = HighValue1;
+			        }
+			    }
+			}
+			DialationStage[Offset+j] = hit;
+		    }
+		    Offset += spadSize;
+		}
+
+		// form the HMT
+		Offset = 0;
+		for(i = 0; i < N; ++i){
+		    for(j = 0; j < M; ++j){
+			m = (ErosionStage[Offset+j]*DialationStage[Offset+j]);
+			HMT[Offset+j] = m;
+		    }
+		    Offset += spadSize;
+		}
+
+		// Thin for stage n
+
+		Offset = 0;
+		for(i = 0; i < N; ++i){
+		    for(j = 0; j < M; ++j){
+			HMT[Offset+j] = (~HMT[Offset+j]) & 0x1; 
+		    }
+		    Offset += spadSize;
+		}
+
+		Offset = 0;
+		for (i = 0; i < N; ++i){
+		    for (j = 0; j < M; ++j){
+			m = (Input[Offset+j]*HMT[Offset+j]);
+			Input[Offset+j] = m;
+		    }
+		    Offset += spadSize;
+		}
+	    }
+
+	    // check for the NULL set
+	    hit = 0;
+	    Offset = 0;
+	    for(i = 0; i < N; ++i){
+		for(j = 0; j < M; ++j){
+		    hit += abs(Copy[Offset+j]-Input[Offset+j]);
+		}
+		Offset += spadSize;
+	    }
+	    if(!hit) break;
+
+	    hit = 0;
+	    Offset = 0;
+	    for(i = 0; i < N; ++i){
+		for(j = 0; j < M; ++j){
+		    Copy[Offset+j] = Input[Offset+j];
+		    if(Input[Offset+j]) ++hit;
+		}
+		Offset += spadSize;
+	    }
+	    ++nloop;
+	}
+
+
+	return;
+
+}
+
+
+int NI_ThinFilter(int samples, int rows, int cols, int numberObjects, unsigned short *edgeImage, objStruct objectMetrics[]){
+
+	int i, j;
+	int loop;
+	int label;
+	int left, right, top, bottom;
+	int roiRows, roiCols;
+	int srcOffset;
+	int dstOffset;
+	int status;
+	int inflate = 1;
+	int J_mask[3][30];
+	int K_mask[3][30];
+
+	unsigned char *Input;
+	unsigned char *CInput;
+	unsigned char *ErosionStage;
+	unsigned char *DialationStage;
+	unsigned char *HMT;
+	unsigned char *Copy;
+	unsigned short *thinEdgeImage;
+
+	//
+	// scratch pad (spad) memory
+	//
+	Input          = calloc(samples, sizeof(unsigned char));
+	CInput         = calloc(samples, sizeof(unsigned char));
+	ErosionStage   = calloc(samples, sizeof(unsigned char));
+	DialationStage = calloc(samples, sizeof(unsigned char));
+	HMT            = calloc(samples, sizeof(unsigned char));
+	Copy           = calloc(samples, sizeof(unsigned char));
+	thinEdgeImage  = calloc(samples, sizeof(unsigned short));
+
+	initThinFilter(J_mask, K_mask);
+	for(loop = 0; loop < numberObjects; ++loop){
+	    label   = objectMetrics[loop].Label;
+	    left    = objectMetrics[loop].L;
+	    right   = objectMetrics[loop].R;
+	    top     = objectMetrics[loop].T;
+	    bottom  = objectMetrics[loop].B;
+	    roiRows = top-bottom+2*inflate;
+	    roiCols = right-left+2*inflate;
+
+	    //
+	    // clear the scratch pad
+	    //
+	    srcOffset = 0;
+	    for(i = 0; i < roiRows; ++i){
+	        for(j = 0; j < roiCols; ++j){
+		    Input[srcOffset+j] = 0; 
+	        }
+	        srcOffset += cols;
+	    }
+
+	    //
+	    // copy the ROI for MAT (medial axis transformation) filter
+	    //
+	    dstOffset = inflate*rows;
+	    for(i = bottom; i < top; ++i){
+		srcOffset = i*cols;
+		for(j = left; j < right; ++j){
+		    if(edgeImage[srcOffset+j] == label){
+			Input[dstOffset+j-left+inflate] = 1;
+		    }
+		}
+		dstOffset += cols;
+	    }
+	    ThinningFilter(roiRows, roiCols, cols, J_mask, K_mask, Input, CInput, ErosionStage, DialationStage, HMT, Copy);
+
+	    //
+	    // copy the MAT roi to the new edgeImage (clip the inflate border)
+	    //
+	    dstOffset = inflate*rows;
+	    for(i = bottom; i < top; ++i){
+		srcOffset = i*cols;
+		for(j = left; j < right; ++j){
+		    if(Input[dstOffset+j-left+inflate]){
+		        thinEdgeImage[srcOffset+j] = label;
+		    }
+		}
+		dstOffset += cols;
+	    }
+	}
+
+	//
+	// copy the MAT edges and return the thinned edges
+	// this will prune the isolated edge points from the edgeImage source
+	//
+	for(i = 0; i < rows*cols; ++i){
+	    edgeImage[i] = thinEdgeImage[i];
+	}
+
+	free(Input);
+	free(CInput);
+	free(ErosionStage);
+	free(DialationStage);
+	free(HMT);
+	free(Copy);
+	free(thinEdgeImage);
+
+	status = 1;
+
+	return status;
+
+}
+
+
+void generateMask(unsigned char *ImageH, bPOINT *boundary, int newSamples, int label, int cols){
+
+	//
+	// get the boundary point pairs (left, right) for each line
+	// if there is no pair, then the boundary is open
+	// then fill the image in with the current label
+	//
+
+	int i, j, k, m;
+	int list[512];
+	int distance;
+	int neighbor = 4;
+	int index;
+	int offset;
+	int maxDistance = 1024;
+	int x, y;
+	int low, high;
+	
+	for(i = 0; i < newSamples; ++i){
+	    boundary[i].haveLink  = FALSE;
+	    boundary[i].linkIndex = -1;
+	}
+	
+	for(i = 0; i < newSamples; ++i){
+	    if(!boundary[i].haveLink){
+		boundary[i].haveLink = TRUE;
+		x = boundary[i].x;
+		y = boundary[i].y;
+		for(k = 0, j = 0; j < newSamples; ++j){
+		    if((j != i)){
+			if(boundary[j].y == y){
+			    list[k] = j;
+			    ++k;
+			}
+		    }
+		}
+		// now get the closest boundary
+		if(k){
+		    distance = maxDistance;
+		    index    = -1;
+		    for(j = 0; j < k; ++j){
+			m = abs(x - boundary[list[j]].x);
+			if((m < distance) && (m > neighbor)){
+			    distance = m;
+			    index = list[j];
+			}
+			else if(m <= neighbor){
+			    boundary[list[j]].haveLink = TRUE;
+			}
+		    }
+		    if(index != -1){
+			boundary[i].linkIndex     = index;
+			boundary[index].linkIndex = i;
+			boundary[index].haveLink  = TRUE;
+			if(boundary[i].x < boundary[index].x){
+			    low  = boundary[i].x;
+			    high = boundary[index].x;
+			}
+			else{
+			    low  = boundary[index].x;
+			    high = boundary[i].x;
+			}
+			//
+			// do the fill
+			//
+			offset = y * cols;
+			for(j = low; j <= high; ++j){
+			    ImageH[offset+j] = label;
+			}
+		    }
+		}
+		else{
+		    // boundary point is isolated
+		    boundary[i].linkIndex = i;
+		}
+	    }
+	}
+
+	return;
+
+}
+
+void getBoundaryMetrics(bPOINT *boundary, float *length, float *minRadius, float *maxRadius, float *aveRadius,
+	         	float Xcenter, float Ycenter, int newSamples){
+
+	int j;
+	float dX, dY;
+	float distance;
+
+	if(newSamples < 2){
+	    *length    = (float)0.0;
+	    *minRadius = (float)0.0;
+	    *maxRadius = (float)0.0;
+	    *aveRadius = (float)0.0;
+	    return;
+	}
+
+	*length = (float)0.0;
+	for(j = 1; j < newSamples; ++j){
+	    dX = (float)(boundary[j].x - boundary[j-1].x);
+	    dY = (float)(boundary[j].y - boundary[j-1].y);
+	    distance = (float)sqrt(dX*dX + dY*dY);
+	    *length += distance;
+	}
+
+	*minRadius = (float)10000.0;
+	*maxRadius = (float)-10000.0;
+	*aveRadius = (float)0.0;
+	for(j = 0; j < newSamples; ++j){
+	    dX = (float)(boundary[j].x - Xcenter);
+	    dY = (float)(boundary[j].y - Ycenter);
+	    distance = (float)sqrt(dX*dX + dY*dY);
+	    *aveRadius += distance;
+	    if(distance < *minRadius) *minRadius = distance;
+	    if(distance > *maxRadius) *maxRadius = distance;
+	}
+
+	if(newSamples){
+	    *aveRadius /= (float)newSamples;
+	}
+
+	return;
+
+}
+
+void trackBoundary(unsigned char *Input, blobBoundary lBoundary[], int mcount, int spadSize, 
+		   blobBoundary seedValue, int searchWindow){
+
+
+	int i, j, k, m, p;
+	int offset;
+	int CurI;
+	int CurJ;
+	int StrI;
+	int StrJ;
+	int NewI;
+	int NewJ;
+	int MinD;
+	int inflate = searchWindow;
+
+    	CurI = seedValue.xy.x;
+    	CurJ = seedValue.xy.y;
+    	StrI = CurI;
+    	StrJ = CurJ;
+
+	p = 0;
+	lBoundary[p].xy.x = StrI;
+	lBoundary[p].xy.y = StrJ;
+	offset = StrI * spadSize;
+
+	p = 1;
+	while(p <= mcount){
+	    offset = (CurI-inflate)*spadSize;
+	    MinD   = 1024;
+	    NewI   = 0;
+	    NewJ   = 0;
+	    for(i = CurI-inflate; i < CurI+inflate; ++i){
+		for(j = CurJ-inflate; j < CurJ+inflate; ++j){
+		    m = Input[offset+j];
+		    if(m == 1){
+			// city block distance
+			k = abs(i-CurI) + abs(j-CurJ);
+			if(k < MinD){
+			    MinD = k;
+			    NewI = i;
+			    NewJ = j;
+			}
+		    }
+		}
+		offset += spadSize;
+	    }
+	    CurI   = NewI;
+	    CurJ   = NewJ;
+	    offset = CurI * spadSize;
+	    Input[offset+CurJ] = 0;
+	    lBoundary[p].xy.x = CurJ;
+	    lBoundary[p].xy.y = CurI;
+            ++p;
+	}
+
+	return;
+
+}
+
+
+void OpenCloseFilter(int olapValues[], int maskSize, int rows, int columns, int spadSize, 
+                     unsigned char *input, unsigned char *output, unsigned short mask[11][11]){
+
+
+	//
+	// do morphological open/close image filtering. the olapValues array determines
+    	// if the filter is Open or Close. 
+	//
+	int i, j, k, l, m, overlap, hit;
+	int offset;
+	int LowValue1, HighValue1;   
+	int LowValue2, HighValue2;  
+
+	LowValue1  = olapValues[0];
+	HighValue1 = olapValues[1];
+	LowValue2  = olapValues[2];
+	HighValue2 = olapValues[3];
+
+	// close - step 1 is dialate
+	// open  - step 1 is erode
+	offset = maskSize*spadSize;
+	for(i = maskSize; i < rows-maskSize; ++i){
+	    for(j = maskSize; j < columns-maskSize; ++j){
+	        hit = LowValue1; 
+		for(k = -maskSize; k < maskSize; ++k){
+	    	    m = k*spadSize;
+		    for(l = -maskSize; l < maskSize; ++l){
+	    		overlap = mask[k+maskSize][l+maskSize]*input[offset+m+j+l];
+			if(overlap == HighValue1){
+			    hit = HighValue1;
+			}
+		    }
+		}
+	    	output[offset+j] = hit;
+	    }
+	    offset += spadSize;
+	}
+
+	// close - step 2 is erode
+	// open -  step 2 is dialate
+	offset = maskSize*spadSize;
+	for(i = maskSize; i < rows-maskSize; ++i){
+	    for(j = maskSize; j < columns-maskSize; ++j){
+	        hit = LowValue2; 
+		for(k = -maskSize; k < maskSize; ++k){
+	    	    m = k*spadSize;
+		    for(l = -maskSize; l < maskSize; ++l){
+	    		overlap = mask[k+maskSize][l+maskSize]*output[offset+m+j+l];
+			if(overlap == HighValue2){
+			    hit = HighValue2;
+			}
+		    }
+		}
+	    	input[offset+j] = hit;
+	    }
+	    offset += spadSize;
+	}
+
+	return;
+}
+
+void getCompactness(unsigned char *Input, RECT roi, int label, int spadSize, float *vCompactness, float length){
+
+	int i, j;
+	int maskOffset;
+	int area;
+	static float fpi = (float)(4.0 * 3.14159);
+
+	area = 0;
+	for(i = roi.bottom; i < roi.top; ++i){
+	    maskOffset = i*spadSize;
+	    for(j = roi.left; j < roi.right; ++j){
+		if(Input[maskOffset+j] == label){
+		    ++area;
+		}
+	    }
+	}
+	if(area && (length != (float)0.0)){
+	    *vCompactness = (fpi * (float)area) / (length*length);
+	}
+	else{
+	    *vCompactness = (float)0.0;
+	}
+
+	return;
+}
+
+
+void doMorphology(unsigned char *Input, unsigned char *ImageE, unsigned char *ImageC, unsigned char *ImageH,
+       	          int olapValuesC[],int olapValuesO[], unsigned short cmask[11][11], unsigned short omask[11][11],
+	          RECT roi, int label, int CloseMaskSize, int OpenMaskSize, int spadSize){
+
+	int i, j;
+	int rows, cols;
+	int srcOffset;
+	int dstOffset;
+	int maskSize;
+
+	cols = roi.right - roi.left;
+	rows = roi.top - roi.bottom;
+
+	for(i = 0; i < spadSize*spadSize; ++i){
+	    ImageE[i] = 0;
+	    ImageC[i] = 0;
+	}
+
+	//
+	// put the ROI in the ImageE array centered in ULC
+	//
+	dstOffset = 0;
+	for(i = roi.bottom; i < roi.top; ++i){
+	    srcOffset = i*spadSize;
+	    for(j = roi.left; j < roi.right; ++j){
+		if(ImageH[srcOffset+j] == label){
+		    ImageE[dstOffset+j-roi.left] = 1;
+		}
+	    }
+	    dstOffset += spadSize;
+	}
+
+	//
+	// open
+	//
+	maskSize = OpenMaskSize;
+	OpenCloseFilter(olapValuesO, maskSize, rows, cols, spadSize, ImageE, ImageC, omask);
+	//
+	// close
+	//
+	maskSize = CloseMaskSize;
+	OpenCloseFilter(olapValuesC, maskSize, rows, cols, spadSize, ImageE, ImageC, cmask);
+
+	//
+	// put the closed ROI (in ImageE) back in its roi space
+	//
+
+	srcOffset = 0;
+	for(i = roi.bottom; i < roi.top+2*maskSize+1; ++i){
+	    dstOffset = (i-(2*maskSize+1))*spadSize;
+	    for(j = roi.left-maskSize-1; j < roi.right+maskSize+1; ++j){
+		if(ImageE[srcOffset+j-roi.left] == 1){
+		    Input[dstOffset+j-maskSize+1] = label;
+		}
+	    }
+	    srcOffset += spadSize;
+	}
+
+	return;
+
+}
+
+
+void getBoundary(unsigned short *ThinEdgeImage, unsigned char *Input, blobBoundary *pBoundary, blobBoundary *lBoundary, 
+	         boundaryIndex *pBoundaryIndex, RECT boundBox, int label, int bBox, int nextSlot, int memOffset,
+		 int spadSize, int searchWindow){
+
+	int i, j;
+	int dstOffset;
+	int srcOffset;
+	int mcount;
+	int rows;
+	int columns;
+	bool first;
+	blobBoundary value;
+	int inflate = 1;
+	int count;
+
+	pBoundaryIndex[bBox+1].rectangle.left   = boundBox.left;
+	pBoundaryIndex[bBox+1].rectangle.right  = boundBox.right;
+	pBoundaryIndex[bBox+1].rectangle.top    = boundBox.top;
+	pBoundaryIndex[bBox+1].rectangle.bottom = boundBox.bottom;
+
+	for(i = 0; i < spadSize*spadSize; ++i){
+	    Input[i] = 0;
+	}
+
+	// copy to spad
+	count = 0;
+	rows    = boundBox.top-boundBox.bottom+2*inflate;
+	columns = boundBox.right-boundBox.left+2*inflate;
+	dstOffset = inflate*spadSize;
+	for(i = boundBox.bottom; i < boundBox.top; ++i){
+	    srcOffset = i*spadSize;
+	    for(j = boundBox.left; j < boundBox.right; ++j){
+		if(ThinEdgeImage[srcOffset+j] == label){
+		    Input[dstOffset+j-boundBox.left+inflate] = 1;
+		    ++count;
+		}
+	    }
+	    dstOffset += spadSize;
+	}
+
+	mcount    = 0;
+	first     = TRUE;
+	srcOffset = 0;
+	for(i = 0; i < rows; ++i){
+	    for(j = 0; j < columns; ++j){
+		if(Input[srcOffset+j]){
+		    if(first){
+			first = FALSE;
+			// index of the seed sample
+			value.xy.x = i;
+			value.xy.y = j;
+		    }
+		    ++mcount;
+		}
+	    }
+	    srcOffset += spadSize;
+	}
+
+	trackBoundary(Input, lBoundary, mcount, spadSize, value, searchWindow);	
+
+	pBoundaryIndex[nextSlot].numberPoints = mcount;
+	for(i = 0; i < mcount; ++i){
+	    value.xy.x = lBoundary[i].xy.x + boundBox.left   - inflate;
+	    value.xy.y = lBoundary[i].xy.y + boundBox.bottom - inflate + 1;
+	    pBoundary[memOffset].xy.x = value.xy.x;
+	    pBoundary[memOffset].xy.y = value.xy.y;
+	    ++memOffset;
+	}
+
+	return;
+
+}
+
+
+void buildBoundary(objStruct objectMetrics[], int searchWindow, unsigned short *ThinEdgeImage,
+		  int numberObjects, int srcRows, int srcCols){
+
+
+	int i, j, k;
+	int count;
+	int numBoundaries;
+	int numSamples;
+	int offset;
+	int offset2;
+	int end;
+	int label;
+	int distance;
+	// these should be setup parameters
+	int closureDistance = 12;
+	int CloseSize       = 5;
+	int OpenSize        = 5;
+	int threshold       = 3;
+	int newSamples;
+	int spadSize;
+	POINT rectPoint[4];
+	int in[4];
+	float length;
+	float minRadius;
+	float maxRadius;
+	float aveRadius;
+	float vCompactness;
+	// for morphological close of mask. max structuring element is 11x11
+	unsigned short cmask[11][11];
+	unsigned short omask[11][11];
+	int olapValuesC[4];
+	int olapValuesO[4];
+	int CloseMaskSize;
+	int OpenMaskSize;
+	int LowValue1, HighValue1;   
+	int LowValue2, HighValue2;  
+
+	//
+	// Close filter
+	//
+	CloseMaskSize = (CloseSize-1)/2;
+	for(i = 0; i < 2*CloseMaskSize+1; ++i){
+	    for(j = 0; j < 2*CloseMaskSize+1; ++j){
+	        cmask[i][j] = 1;
+	    }
+	}
+	LowValue1      = 0;   
+	HighValue1     = 1;   
+	LowValue2      = 1;   
+	HighValue2     = 0;   
+	olapValuesC[0] = LowValue1;
+	olapValuesC[1] = HighValue1;
+	olapValuesC[2] = LowValue2;
+	olapValuesC[3] = HighValue2;
+
+	//
+	// Open filter
+	//
+	OpenMaskSize = (OpenSize-1)/2;
+	for(i = 0; i < 2*OpenMaskSize+1; ++i){
+	    for(j = 0; j < 2*OpenMaskSize+1; ++j){
+	        omask[i][j] = 1;
+	    }
+	}
+	LowValue1      = 1;   
+	HighValue1     = 0;   
+	LowValue2      = 0;   
+	HighValue2     = 1;   
+	olapValuesO[0] = LowValue1;
+	olapValuesO[1] = HighValue1;
+	olapValuesO[2] = LowValue2;
+	olapValuesO[3] = HighValue2;
+
+	RECT bBox;
+	boundaryIndex *pBoundaryIndex;
+	blobBoundary  *pBoundary;
+	blobBoundary  *lBoundary;
+	bPOINT        *boundary;
+	unsigned char *Input;
+	unsigned char *ImageE;
+	unsigned char *ImageC;
+	unsigned char *ImageH;
+
+	spadSize = MAX(srcRows, srcCols);
+	pBoundaryIndex = calloc(srcRows+srcCols,   sizeof(boundaryIndex));
+	Input          = calloc(spadSize*spadSize, sizeof(unsigned char));
+	ImageE         = calloc(spadSize*spadSize, sizeof(unsigned char));
+	ImageC         = calloc(spadSize*spadSize, sizeof(unsigned char));
+	ImageH         = calloc(spadSize*spadSize, sizeof(unsigned char));
+	pBoundary      = calloc(srcRows*srcCols,   sizeof(blobBoundary));
+	lBoundary      = calloc(32767, sizeof(blobBoundary));
+	boundary       = calloc(32767, sizeof(POINT));
+
+	for(i = 0; i < (srcRows+srcCols); ++i){
+	    pBoundaryIndex[i].numberPoints = 0;
+	    pBoundaryIndex[i].curveClose   = 0;
+	    pBoundaryIndex[i].isWithin     = FALSE;
+	    pBoundaryIndex[i].criticalSize = FALSE;
+	    pBoundaryIndex[i].closedCurve  = FALSE;
+	}
+
+	for(i = 0; i < numberObjects; ++i){
+	    ++pBoundaryIndex[0].numberPoints;
+	    count = 0;
+	    j = 1;
+	    while(pBoundaryIndex[j].numberPoints){
+		count += pBoundaryIndex[j++].numberPoints;
+	    }
+	    bBox.left   = objectMetrics[i].L;
+	    bBox.right  = objectMetrics[i].R;
+	    bBox.top    = objectMetrics[i].T;
+	    bBox.bottom = objectMetrics[i].B;
+	    label       = objectMetrics[i].Label;
+	    pBoundaryIndex[i+1].Label = label;
+	    getBoundary(ThinEdgeImage, Input, pBoundary, lBoundary, pBoundaryIndex, bBox, label,
+		        i, pBoundaryIndex[0].numberPoints, count, spadSize, searchWindow);
+	}
+
+	//
+	// Input will now be used in the fill. Copy the labeled edge image
+	//
+
+	//
+	// numBoundaries = numberObjects
+	//
+	offset = 0;
+	numBoundaries = pBoundaryIndex[0].numberPoints;
+	for(i = 0; i < numBoundaries; ++i){
+	    numSamples = pBoundaryIndex[i+1].numberPoints;
+	    end        = numSamples-2; 
+	    newSamples = numSamples-1;
+	    for(j = 0; j < numSamples; ++j){
+		boundary[j].x = pBoundary[offset+j+1].xy.x;
+		boundary[j].y = pBoundary[offset+j+1].xy.y;
+	    }
+
+	    //
+	    // clip off the ends where stray boundary pixels were left over
+	    //
+	    while(1){
+		distance = abs(boundary[end].x-boundary[end-1].x) + abs(boundary[end].y-boundary[end-1].y);
+		if(distance > threshold){
+		    --end;
+		    --newSamples;
+		}
+		else{
+		    break;
+		}
+	    }
+
+	    distance = abs(boundary[0].x-boundary[end-2].x) + abs(boundary[0].y-boundary[end-2].y);
+	    pBoundaryIndex[i+1].curveClose = distance;
+
+	    if(pBoundaryIndex[i+1].curveClose < closureDistance){
+		pBoundaryIndex[i+1].closedCurve = TRUE;
+	    }
+	    pBoundaryIndex[i+1].centroid.x = 0;
+	    pBoundaryIndex[i+1].centroid.y = 0;
+	    for(j = 0; j < newSamples; ++j){
+	        pBoundaryIndex[i+1].centroid.x += boundary[j].x;
+	        pBoundaryIndex[i+1].centroid.y += boundary[j].y;
+	    }
+	    if(newSamples){
+	        pBoundaryIndex[i+1].centroid.x /= newSamples;
+	        pBoundaryIndex[i+1].centroid.y /= newSamples;
+	    }
+	    getBoundaryMetrics(boundary, &length, &minRadius, &maxRadius, &aveRadius,
+		       	      (float)pBoundaryIndex[i+1].centroid.x, (float)pBoundaryIndex[i+1].centroid.y, newSamples);
+	    pBoundaryIndex[i+1].boundaryLength = length;
+	    pBoundaryIndex[i+1].minRadius      = minRadius;
+	    pBoundaryIndex[i+1].maxRadius      = maxRadius;
+	    pBoundaryIndex[i+1].aveRadius      = aveRadius;
+	    if(minRadius != 0.0){
+	        pBoundaryIndex[i+1].ratio = maxRadius / minRadius;
+	    }
+	    else{
+	        pBoundaryIndex[i+1].ratio = -1.0;
+	    }
+
+	    //
+	    // augment the ROI boundary
+	    //
+	    pBoundaryIndex[i+1].rectangle.left   -= 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.right  += 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.bottom -= 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.top    += 2*CloseMaskSize;
+	    label = pBoundaryIndex[i+1].Label;
+
+	    //
+	    // mask goes in ImageH. morpho filter the mask first
+	    //
+	    generateMask(ImageH, boundary, newSamples, label, spadSize);
+
+	    //
+	    // open-close the mask 
+	    //
+	    doMorphology(Input, ImageE, ImageC, ImageH, olapValuesC, olapValuesO, cmask, omask,
+		         pBoundaryIndex[i+1].rectangle, label, CloseMaskSize, OpenMaskSize, spadSize);
+
+	    //
+	    // now get the compactness metrics
+	    //
+	    getCompactness(Input, pBoundaryIndex[i+1].rectangle, label, spadSize, &vCompactness, length);
+	    pBoundaryIndex[i+1].compactness = vCompactness;
+
+	    //
+	    // reset the ROI boundary
+	    //
+	    pBoundaryIndex[i+1].rectangle.left   += 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.right  -= 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.bottom += 2*CloseMaskSize;
+	    pBoundaryIndex[i+1].rectangle.top    -= 2*CloseMaskSize;
+	    offset += numSamples;
+	}
+	
+
+	for(i = 0; i < numBoundaries; ++i){
+	    for(j = 0; j < numBoundaries; ++j){
+		if(j != i){
+		    rectPoint[0].x = pBoundaryIndex[j+1].rectangle.left;
+		    rectPoint[0].y = pBoundaryIndex[j+1].rectangle.bottom;
+		    rectPoint[1].x = pBoundaryIndex[j+1].rectangle.left;
+		    rectPoint[1].y = pBoundaryIndex[j+1].rectangle.top;
+		    rectPoint[2].x = pBoundaryIndex[j+1].rectangle.right;
+		    rectPoint[2].y = pBoundaryIndex[j+1].rectangle.bottom;
+		    rectPoint[3].x = pBoundaryIndex[j+1].rectangle.right;
+		    rectPoint[3].y = pBoundaryIndex[j+1].rectangle.top;
+		    in[0] = 0;
+		    in[1] = 0;
+		    in[2] = 0;
+		    in[3] = 0;
+		    for(k = 0; k < 4; ++k){
+			if((rectPoint[k].x > pBoundaryIndex[i+1].rectangle.left) &&
+			   (rectPoint[k].x < pBoundaryIndex[i+1].rectangle.right)){
+			    if((rectPoint[k].y > pBoundaryIndex[i+1].rectangle.bottom) &&
+			       (rectPoint[k].y < pBoundaryIndex[i+1].rectangle.top)){
+				in[k] = 1;
+			    }
+			}
+		    }
+		    if(in[0] && in[1] && in[2] && in[3]){
+			pBoundaryIndex[j+1].isWithin = TRUE;
+		    }
+		}
+	    }
+	}
+
+	//
+	// fill in the Python features
+	//
+	for(i = 0; i < numBoundaries; ++i){
+	    objectMetrics[i].curveClose     = pBoundaryIndex[i+1].curveClose;
+	    objectMetrics[i].cXBoundary     = pBoundaryIndex[i+1].centroid.x;
+	    objectMetrics[i].cYBoundary     = pBoundaryIndex[i+1].centroid.y;
+	    objectMetrics[i].boundaryLength = pBoundaryIndex[i+1].boundaryLength;
+	    objectMetrics[i].minRadius      = pBoundaryIndex[i+1].minRadius;
+	    objectMetrics[i].maxRadius      = pBoundaryIndex[i+1].maxRadius;
+	    objectMetrics[i].aveRadius      = pBoundaryIndex[i+1].aveRadius;
+	    objectMetrics[i].ratio          = pBoundaryIndex[i+1].ratio;
+	    objectMetrics[i].compactness    = pBoundaryIndex[i+1].compactness;
+	} 
+
+	// debug only
+	if(0){
+	for(i = 0; i < numBoundaries; ++i){
+	    if(pBoundaryIndex[i+1].boundaryLength != (float)0.0){
+	        printf("boundary %d:\n", i);
+	        printf("\t\tRect (%d, %d, %d, %d)\n", pBoundaryIndex[i+1].rectangle.left,
+	                                              pBoundaryIndex[i+1].rectangle.right,
+	                                              pBoundaryIndex[i+1].rectangle.top,
+	                                              pBoundaryIndex[i+1].rectangle.bottom);
+	        printf("\t\tCentroid (%d, %d)\n",     pBoundaryIndex[i+1].centroid.x, pBoundaryIndex[i+1].centroid.y);
+	        printf("\t\tLength (%f)\n",           pBoundaryIndex[i+1].boundaryLength);
+	        printf("\t\tRatio (%f)\n",            pBoundaryIndex[i+1].ratio);
+	        printf("\t\taveRadius (%f)\n",        pBoundaryIndex[i+1].aveRadius);
+	        printf("\t\tLabel (%d)\n",            pBoundaryIndex[i+1].Label);
+	        printf("\t\tCompactness (%f)\n",      pBoundaryIndex[i+1].compactness);
+	        printf("\t\tCurveClose (%d)\n",       pBoundaryIndex[i+1].curveClose);
+	        if(pBoundaryIndex[i+1].isWithin){
+	            printf("\t\tContained (T)\n");
+	        }
+	        else{
+	            printf("\t\tContained (F)\n");
+	        }
+	        if(pBoundaryIndex[i+1].closedCurve){
+	            printf("\t\tclosedCurve (T)\n");
+	        }
+	        else{
+	            printf("\t\tclosedCurve (F)\n");
+	        }
+	    }
+	}
+	}
+
+	//
+	// need to return input which is now mask image
+	//
+	offset  = 0;
+	offset2 = 0;
+	for(i = 0; i < srcRows; ++i){
+	    for(j = 0; j < srcCols; ++j){
+	        ThinEdgeImage[offset+j] = (unsigned short)Input[offset2+j];
+	    }
+	    offset  += srcCols;
+	    offset2 += spadSize;
+	}
+
+	free(pBoundaryIndex);
+	free(Input);
+	free(ImageE);
+	free(ImageC);
+	free(ImageH);
+	free(pBoundary);
+	free(lBoundary);
+	free(boundary);
+
+	return;
+
+}
+
+
+void initLaws(LawsFilter7 *lawsFilter){
+
+	int i;
+	float sum;
+	float L7[7] = { 1.0,  6.0,  15.0, 20.0,  15.0,  6.0,  1.0};
+	float E7[7] = {-1.0, -4.0,  -5.0,  0.0,   5.0,  4.0,  1.0};
+	float S7[7] = {-1.0, -2.0,   1.0,  4.0,   1.0, -2.0, -1.0};
+	float W7[7] = {-1.0,  0.0,   3.0,  0.0,  -3.0,  0.0,  1.0};
+	float R7[7] = { 1.0, -2.0,  -1.0,  4.0,  -1.0, -2.0,  1.0};
+	float O7[7] = {-1.0,  6.0, -15.0, 20.0, -15.0,  6.0, -1.0};
+	
+	lawsFilter->numberKernels      = 6;
+	lawsFilter->kernelLength       = 7;
+	lawsFilter->numberFilterLayers = 21;
+	lawsFilter->name[0] = 'L';
+	lawsFilter->name[1] = 'E';
+	lawsFilter->name[2] = 'S';
+	lawsFilter->name[3] = 'W';
+	lawsFilter->name[4] = 'R';
+	lawsFilter->name[5] = 'O';
+	for(i = 0; i < 7; ++i){
+	    lawsFilter->lawsKernel[0][i] = L7[i];
+	    lawsFilter->lawsKernel[1][i] = E7[i];
+	    lawsFilter->lawsKernel[2][i] = S7[i];
+	    lawsFilter->lawsKernel[3][i] = W7[i];
+	    lawsFilter->lawsKernel[4][i] = R7[i];
+	    lawsFilter->lawsKernel[5][i] = O7[i];
+	}
+
+	// DC filter is unity gain
+	sum = (float)0.0;
+	for(i = 0; i < 7; ++i){
+	    sum += lawsFilter->lawsKernel[0][i];
+	}
+	for(i = 0; i < 7; ++i){
+	    lawsFilter->lawsKernel[0][i] /= sum;
+	}
+	
+	return;
+
+}
+
+float lawsConvolution(float *image, float *rowFilter, float *colFilter, int kernelSize){
+
+	int i, j;
+	int offset;
+	float result[7];
+	float sum;
+
+	// filter rows
+	for(i = 0; i < kernelSize; ++i){
+	    sum = (float)0.0;
+	    offset = i * kernelSize;
+	    for(j = 0; j < kernelSize; ++j){
+		sum += (rowFilter[j]*image[offset+j]);
+	    }
+	    result[i] = sum;
+	}
+
+	// filter columns
+	sum = (float)0.0;
+	for(j = 0; j < kernelSize; ++j){
+	    sum += (rowFilter[j]*result[j]);
+	}
+
+	return(sum);
+
+}
+
+
+void getLawsTexture(LawsFilter7 lawsFilter, tTEM LawsFeatures[], objStruct objectMetrics[], double *sourceImage, 
+	            unsigned short *MaskImage, int numberObjects, int srcRows, int srcCols){
+
+	int i, j;
+	int label;
+	RECT bBox;
+	int aperature = (lawsFilter.kernelLength-1)/2;
+	unsigned char *ImageH;
+	float *ImageT;
+	float *lawsImage;
+
+	/*
+	 //  TO DO. return all 21 filter slices from a user selected blob
+	int debugBlob = 8; 
+	int index;
+	int offset;
+	int layerStep = srcRows*srcCols;
+	*/
+
+	ImageH    = calloc(srcRows*srcCols, sizeof(unsigned char));
+	ImageT    = calloc(srcRows*srcCols, sizeof(float));
+	lawsImage = calloc(lawsFilter.numberFilterLayers*srcRows*srcCols, sizeof(float));
+	
+	for(i = 0; i < numberObjects; ++i){
+	    bBox.left   = objectMetrics[i].L;
+	    bBox.right  = objectMetrics[i].R;
+	    bBox.top    = objectMetrics[i].T;
+	    bBox.bottom = objectMetrics[i].B;
+	    label       = objectMetrics[i].Label;
+	    if(objectMetrics[i].voxelMean != (float)0.0){
+		//
+		// valid size region
+		//
+	        computeLaws(lawsFilter, LawsFeatures, bBox, label, aperature, srcRows, srcCols, ImageH, ImageT,
+		            MaskImage, lawsImage, sourceImage);
+		for(j = 1; j < lawsFilter.numberFilterLayers; ++j){
+		    objectMetrics[i].TEM[j-1] = LawsFeatures[j].Variance;
+		}
+	        /*
+	        if(label == debugBlob){ 
+		    index = 0;
+		    for(j = 1; j < lawsFilter.numberFilterLayers; ++j){
+		        if(LawsFeatures[j].Variance == (float)1.0) index = j;
+		    }
+		    // overwrite the raw image with the texture filter that has the largest variance
+		    offset = index * layerStep;
+		    for(j = 0; j < layerStep; ++j){
+		        sourceImage[j] = lawsImage[offset+j];
+	            }
+	        }
+		*/
+	    }
+	}
+
+	free(ImageH);
+	free(ImageT);
+	free(lawsImage);
+
+	return;
+
+}
+
+void computeLaws(LawsFilter7 lawsFilter, tTEM LawsFeatures[], RECT roi, int label, int aperature, int srcRows, int srcCols, 
+	         unsigned char *ImageH, float *ImageT, unsigned short *MaskImage, float *lawsImage, double *sourceImage){
+
+	//
+	// hard-wirred to Law's 7 kernels
+	//
+	int i, j, k;
+	int lawsLayer;
+	int column, row;
+	int offset;
+	int maskOffset[7];
+	int dataOffset[7];
+	float myImage[49];
+	int count;
+	int outerKernelNumber;
+	int innerKernelNumber;
+	int rowNumber;
+	int kernelSize = lawsFilter.kernelLength;
+	int fullMask   = kernelSize*kernelSize;
+	int layerStep  = srcRows*srcCols;
+	float *rowFilter;
+	float *colFilter;
+	float filterResult1;
+	float filterResult2;
+	float lawsLL;
+	float t;
+	float maxValue;
+	float scale;
+	char I, J;
+	char combo[24];
+	char dual[24];
+
+
+	// zero the laws mask memory first
+	for(i = 0; i < srcRows*srcCols; ++i){
+	    ImageH[i] = 0;
+	}
+	for(j = 0; j < lawsFilter.numberFilterLayers; ++j){
+	    LawsFeatures[j].Mean     = (float)0.0;
+	    LawsFeatures[j].Variance = (float)0.0;
+	}
+
+	for(i = roi.bottom+aperature; i < roi.top-aperature; ++i){
+	    // get the row array offset for mask and data source. 
+	    for(row = -aperature; row <= aperature; ++row){
+		maskOffset[row+aperature] = (i+row)*srcCols;
+		dataOffset[row+aperature] = maskOffset[row+aperature];
+	    }
+	    for(j = roi.left+aperature; j < roi.right-aperature; ++j){
+		//
+		// get 7x7 segment and make sure have 100% mask coverage
+		//
+		count = 0;
+		for(row = -aperature; row <= aperature; ++row){
+		    rowNumber = (row+aperature)*kernelSize;
+		    for(column = -aperature; column <= aperature; ++column){
+			if(MaskImage[maskOffset[row+aperature]+j+column] == label){
+			    myImage[rowNumber+column+aperature] = sourceImage[dataOffset[row+aperature]+j+column];
+			    ++count;
+			}
+		    }
+		}
+		if(count == fullMask){
+		    //
+		    // full mask. 100% coverage. now do the Law's texture filters
+		    //
+		    ImageH[i*srcCols+j] = 1;
+		    lawsLayer = 0;
+		    for(outerKernelNumber = 0; outerKernelNumber < lawsFilter.numberKernels; ++outerKernelNumber){
+			//
+			// outer loop pulls the i'th kernel. kernel 0 is the LP kernel
+			// the outer loop is the iso-kernel
+			//
+			I = lawsFilter.name[outerKernelNumber];
+			sprintf(dual, "%c_%c", I, I);
+			rowFilter = &lawsFilter.lawsKernel[outerKernelNumber][0];
+			colFilter = &lawsFilter.lawsKernel[outerKernelNumber][0];
+			filterResult1 = lawsConvolution(myImage, rowFilter, colFilter, kernelSize);
+			// lawsLayer 0 is the LP and needs to be used to scale.
+			if(outerKernelNumber){
+			    lawsImage[lawsLayer*layerStep + i*srcCols + j] = (float)2.0 * filterResult1 / lawsLL;
+			}
+			else{
+			    lawsLL = (float)2.0 * filterResult1;
+			    lawsImage[lawsLayer*layerStep + i*srcCols + j] = (float)2.0 * filterResult1;
+			}
+			strcpy(&LawsFeatures[lawsLayer].filterName[0], dual);
+			++lawsLayer;
+			//
+			// now do the inner loop and get the column filters for the other laws kernels
+			//
+			for(innerKernelNumber = outerKernelNumber+1; innerKernelNumber < lawsFilter.numberKernels; ++innerKernelNumber){
+			    J = lawsFilter.name[innerKernelNumber];
+			    sprintf(combo, "%c_%c", I, J);
+			    strcpy(&LawsFeatures[lawsLayer].filterName[0], combo);
+			    colFilter = &lawsFilter.lawsKernel[innerKernelNumber][0];
+			    filterResult1 = lawsConvolution(myImage, rowFilter, colFilter, kernelSize);
+			    filterResult2 = lawsConvolution(myImage, colFilter, rowFilter, kernelSize);
+			    lawsImage[lawsLayer*layerStep + i*srcCols + j] = (filterResult1 / lawsLL) + (filterResult2 / lawsLL);
+			    ++lawsLayer;
+			}
+		    }
+		}
+	    }
+	}
+
+	for(i = 0; i < lawsFilter.numberFilterLayers; ++i){
+	    LawsFeatures[i].Mean     = (float)0.0;
+	    LawsFeatures[i].Variance = (float)0.0;
+	}
+
+	count = 0;
+	for(i = roi.bottom+aperature; i < roi.top-aperature; ++i){
+	    row = i * srcCols;
+	    for(j = roi.left+aperature; j < roi.right-aperature; ++j){
+		if(ImageH[row+j]){
+		    ++count;
+		    for(k = 0; k < lawsFilter.numberFilterLayers; ++k){
+			offset = k * layerStep + row;
+			LawsFeatures[k].Mean += lawsImage[offset+j];
+		    }
+	        }
+	    }
+	}
+
+	if(count == 0){
+	    //printf("no samples for texture\n");
+	    return;
+	}
+
+	for(k = 0; k < lawsFilter.numberFilterLayers; ++k){
+	    LawsFeatures[k].Mean /= (float)count;
+	}
+	for(i = roi.bottom+aperature; i < roi.top-aperature; ++i){
+	    row = i * srcCols;
+	    for(j = roi.left+aperature; j < roi.right-aperature; ++j){
+		if(ImageH[row+j]){
+		    for(k = 0; k < lawsFilter.numberFilterLayers; ++k){
+			offset = k * layerStep + row;
+			t = lawsImage[offset+j] - LawsFeatures[k].Mean;
+			LawsFeatures[k].Variance += (t * t);
+		    }
+		}
+	    }
+	}
+	for(k = 0; k < lawsFilter.numberFilterLayers; ++k){
+	    LawsFeatures[k].Variance /= (float)count;
+	    LawsFeatures[k].Variance = (float)(sqrt(LawsFeatures[k].Variance));
+	}
+
+	//
+	// now normalize the variance feature (TEM)
+	//
+	maxValue = (float)0.0;
+	for(i = 1; i < lawsFilter.numberFilterLayers; ++i){
+	    if((LawsFeatures[i].Variance) > maxValue) maxValue = LawsFeatures[i].Variance;
+	}
+	scale = (float)1.0 / maxValue;
+	for(i = 1; i < lawsFilter.numberFilterLayers; ++i){
+	    LawsFeatures[i].Variance = scale * LawsFeatures[i].Variance;
+	}
+
+
+	return;
+
+}
+
+void getVoxelMeasures(objStruct objectMetrics[], double *sourceImage, unsigned short *MaskImage,
+		      int numberObjects, int srcRows, int srcCols){
+
+	int i, j, k;
+	int label;
+	int offset;
+	int count;
+	float mean, std, t;
+	RECT bBox;
+
+	for(i = 0; i < numberObjects; ++i){
+	    bBox.left   = objectMetrics[i].L;
+	    bBox.right  = objectMetrics[i].R;
+	    bBox.top    = objectMetrics[i].T;
+	    bBox.bottom = objectMetrics[i].B;
+	    label       = objectMetrics[i].Label;
+	    count = 0;
+	    mean  = (float)0.0;
+	    for(j = bBox.bottom; j < bBox.top; ++j){
+	        offset = j * srcCols;
+	        for(k = bBox.left; k < bBox.right; ++k){
+		    if(MaskImage[offset+k] == label){
+	    		mean += sourceImage[offset+k];
+			++count;
+		    }
+	        }
+	    }
+	    if(count){
+	    	mean /= (float)count; 
+	        std = (float)0.0;
+	        for(j = bBox.bottom; j < bBox.top; ++j){
+	            offset = j * srcCols;
+	            for(k = bBox.left; k < bBox.right; ++k){
+		        if(MaskImage[offset+k] == label){
+	    		    t = (sourceImage[offset+k]-mean);
+			    std += (t * t);
+		        }
+	            }
+	        }
+	    }
+	    if(count){
+	        std /= (float)count; 
+	        std = sqrt(std);
+	        objectMetrics[i].voxelMean = mean - 2048.0; // the 2048 is only for the cardiac CT volume
+	        objectMetrics[i].voxelVar  = std;
+	    }
+	    else{
+	        objectMetrics[i].voxelMean = 0.0;
+	        objectMetrics[i].voxelVar  = 0.0;
+	    }
+	    if(0) printf("(%d) mean %f, std %f\n", label, objectMetrics[i].voxelMean, objectMetrics[i].voxelVar); 
+	}
+
+	return;
+
+}
+
+int NI_BuildBoundary(int samples, int rows, int cols, int numberObjects, unsigned short *edgeImage,
+	             objStruct objectMetrics[]){
+
+	int searchWindow = 5;  // 5 is good value for Sobel - (should be 13 for Canny edges)
+	int status = 1;
+
+	buildBoundary(objectMetrics, searchWindow, edgeImage, numberObjects, rows, cols);
+
+	return status;
+
+}
+
+int NI_VoxelMeasures(int samples, int rows, int cols, int numberObjects, double *sourceImage,
+	             unsigned short *maskImage, objStruct objectMetrics[]){
+
+	int status = 1;
+	getVoxelMeasures(objectMetrics, sourceImage, maskImage, numberObjects, rows, cols);
+
+	return status;
+
+}
+
+
+int NI_TextureMeasures(int samples, int rows, int cols, int numberObjects, double *sourceImage,
+	               unsigned short *maskImage, objStruct objectMetrics[]){
+
+	int status = 1;
+	LawsFilter7 lawsFilter;
+	tTEM LawsFeatures[21];
+
+	initLaws(&lawsFilter);
+	getLawsTexture(lawsFilter, LawsFeatures, objectMetrics, sourceImage, maskImage, numberObjects, rows, cols);
+
+	return status;
+
+}
+
+
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/Segmenter_IMPL.c
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/__multiarray_api.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/__multiarray_api.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/__multiarray_api.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,974 @@
+
+#ifdef _MULTIARRAYMODULE
+
+typedef struct {
+        PyObject_HEAD
+        npy_bool obval;
+} PyBoolScalarObject;
+
+
+static unsigned int PyArray_GetNDArrayCVersion (void);
+static PyTypeObject PyBigArray_Type;
+static PyTypeObject PyArray_Type;
+static PyTypeObject PyArrayDescr_Type;
+static PyTypeObject PyArrayFlags_Type;
+static PyTypeObject PyArrayIter_Type;
+static PyTypeObject PyArrayMapIter_Type;
+static PyTypeObject PyArrayMultiIter_Type;
+static int NPY_NUMUSERTYPES=0;
+static PyTypeObject PyBoolArrType_Type;
+static PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+
+static PyTypeObject PyGenericArrType_Type;
+static PyTypeObject PyNumberArrType_Type;
+static PyTypeObject PyIntegerArrType_Type;
+static PyTypeObject PySignedIntegerArrType_Type;
+static PyTypeObject PyUnsignedIntegerArrType_Type;
+static PyTypeObject PyInexactArrType_Type;
+static PyTypeObject PyFloatingArrType_Type;
+static PyTypeObject PyComplexFloatingArrType_Type;
+static PyTypeObject PyFlexibleArrType_Type;
+static PyTypeObject PyCharacterArrType_Type;
+static PyTypeObject PyByteArrType_Type;
+static PyTypeObject PyShortArrType_Type;
+static PyTypeObject PyIntArrType_Type;
+static PyTypeObject PyLongArrType_Type;
+static PyTypeObject PyLongLongArrType_Type;
+static PyTypeObject PyUByteArrType_Type;
+static PyTypeObject PyUShortArrType_Type;
+static PyTypeObject PyUIntArrType_Type;
+static PyTypeObject PyULongArrType_Type;
+static PyTypeObject PyULongLongArrType_Type;
+static PyTypeObject PyFloatArrType_Type;
+static PyTypeObject PyDoubleArrType_Type;
+static PyTypeObject PyLongDoubleArrType_Type;
+static PyTypeObject PyCFloatArrType_Type;
+static PyTypeObject PyCDoubleArrType_Type;
+static PyTypeObject PyCLongDoubleArrType_Type;
+static PyTypeObject PyObjectArrType_Type;
+static PyTypeObject PyStringArrType_Type;
+static PyTypeObject PyUnicodeArrType_Type;
+static PyTypeObject PyVoidArrType_Type;
+static int PyArray_SetNumericOps \
+       (PyObject *);
+static PyObject * PyArray_GetNumericOps \
+       (void);
+static int PyArray_INCREF \
+       (PyArrayObject *);
+static int PyArray_XDECREF \
+       (PyArrayObject *);
+static void PyArray_SetStringFunction \
+       (PyObject *, int);
+static PyArray_Descr * PyArray_DescrFromType \
+       (int);
+static PyObject * PyArray_TypeObjectFromType \
+       (int);
+static char * PyArray_Zero \
+       (PyArrayObject *);
+static char * PyArray_One \
+       (PyArrayObject *);
+static PyObject * PyArray_CastToType \
+       (PyArrayObject *, PyArray_Descr *, int);
+static int PyArray_CastTo \
+       (PyArrayObject *, PyArrayObject *);
+static int PyArray_CastAnyTo \
+       (PyArrayObject *, PyArrayObject *);
+static int PyArray_CanCastSafely \
+       (int, int);
+static npy_bool PyArray_CanCastTo \
+       (PyArray_Descr *, PyArray_Descr *);
+static int PyArray_ObjectType \
+       (PyObject *, int);
+static PyArray_Descr * PyArray_DescrFromObject \
+       (PyObject *, PyArray_Descr *);
+static PyArrayObject ** PyArray_ConvertToCommonType \
+       (PyObject *, int *);
+static PyArray_Descr * PyArray_DescrFromScalar \
+       (PyObject *);
+static PyArray_Descr * PyArray_DescrFromTypeObject \
+       (PyObject *);
+static npy_intp PyArray_Size \
+       (PyObject *);
+static PyObject * PyArray_Scalar \
+       (void *, PyArray_Descr *, PyObject *);
+static PyObject * PyArray_FromScalar \
+       (PyObject *, PyArray_Descr *);
+static void PyArray_ScalarAsCtype \
+       (PyObject *, void *);
+static int PyArray_CastScalarToCtype \
+       (PyObject *, void *, PyArray_Descr *);
+static int PyArray_CastScalarDirect \
+       (PyObject *, PyArray_Descr *, void *, int);
+static PyObject * PyArray_ScalarFromObject \
+       (PyObject *);
+static PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+       (PyArray_Descr *, int);
+static PyObject * PyArray_FromDims \
+       (int, int *, int);
+static PyObject * PyArray_FromDimsAndDataAndDescr \
+       (int, int *, PyArray_Descr *, char *);
+static PyObject * PyArray_FromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+static PyObject * PyArray_EnsureArray \
+       (PyObject *);
+static PyObject * PyArray_EnsureAnyArray \
+       (PyObject *);
+static PyObject * PyArray_FromFile \
+       (FILE *, PyArray_Descr *, npy_intp, char *);
+static PyObject * PyArray_FromString \
+       (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+static PyObject * PyArray_FromBuffer \
+       (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+static PyObject * PyArray_FromIter \
+       (PyObject *, PyArray_Descr *, npy_intp);
+static PyObject * PyArray_Return \
+       (PyArrayObject *);
+static PyObject * PyArray_GetField \
+       (PyArrayObject *, PyArray_Descr *, int);
+static int PyArray_SetField \
+       (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+static PyObject * PyArray_Byteswap \
+       (PyArrayObject *, npy_bool);
+static PyObject * PyArray_Resize \
+       (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER);
+static int PyArray_MoveInto \
+       (PyArrayObject *, PyArrayObject *);
+static int PyArray_CopyInto \
+       (PyArrayObject *, PyArrayObject *);
+static int PyArray_CopyAnyInto \
+       (PyArrayObject *, PyArrayObject *);
+static int PyArray_CopyObject \
+       (PyArrayObject *, PyObject *);
+static PyObject * PyArray_NewCopy \
+       (PyArrayObject *, NPY_ORDER);
+static PyObject * PyArray_ToList \
+       (PyArrayObject *);
+static PyObject * PyArray_ToString \
+       (PyArrayObject *, NPY_ORDER);
+static int PyArray_ToFile \
+       (PyArrayObject *, FILE *, char *, char *);
+static int PyArray_Dump \
+       (PyObject *, PyObject *, int);
+static PyObject * PyArray_Dumps \
+       (PyObject *, int);
+static int PyArray_ValidType \
+       (int);
+static void PyArray_UpdateFlags \
+       (PyArrayObject *, int);
+static PyObject * PyArray_New \
+       (PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *);
+static PyObject * PyArray_NewFromDescr \
+       (PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *);
+static PyArray_Descr * PyArray_DescrNew \
+       (PyArray_Descr *);
+static PyArray_Descr * PyArray_DescrNewFromType \
+       (int);
+static double PyArray_GetPriority \
+       (PyObject *, double);
+static PyObject * PyArray_IterNew \
+       (PyObject *);
+static PyObject * PyArray_MultiIterNew \
+       (int, ...);
+static int PyArray_PyIntAsInt \
+       (PyObject *);
+static npy_intp PyArray_PyIntAsIntp \
+       (PyObject *);
+static int PyArray_Broadcast \
+       (PyArrayMultiIterObject *);
+static void PyArray_FillObjectArray \
+       (PyArrayObject *, PyObject *);
+static int PyArray_FillWithScalar \
+       (PyArrayObject *, PyObject *);
+static npy_bool PyArray_CheckStrides \
+       (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *);
+static PyArray_Descr * PyArray_DescrNewByteorder \
+       (PyArray_Descr *, char);
+static PyObject * PyArray_IterAllButAxis \
+       (PyObject *, int *);
+static PyObject * PyArray_CheckFromAny \
+       (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+static PyObject * PyArray_FromArray \
+       (PyArrayObject *, PyArray_Descr *, int);
+static PyObject * PyArray_FromInterface \
+       (PyObject *);
+static PyObject * PyArray_FromStructInterface \
+       (PyObject *);
+static PyObject * PyArray_FromArrayAttr \
+       (PyObject *, PyArray_Descr *, PyObject *);
+static NPY_SCALARKIND PyArray_ScalarKind \
+       (int, PyArrayObject **);
+static int PyArray_CanCoerceScalar \
+       (int, int, NPY_SCALARKIND);
+static PyObject * PyArray_NewFlagsObject \
+       (PyObject *);
+static npy_bool PyArray_CanCastScalar \
+       (PyTypeObject *, PyTypeObject *);
+static int PyArray_CompareUCS4 \
+       (npy_ucs4 *, npy_ucs4 *, register size_t);
+static int PyArray_RemoveSmallest \
+       (PyArrayMultiIterObject *);
+static int PyArray_ElementStrides \
+       (PyObject *);
+static void PyArray_Item_INCREF \
+       (char *, PyArray_Descr *);
+static void PyArray_Item_XDECREF \
+       (char *, PyArray_Descr *);
+static PyObject * PyArray_FieldNames \
+       (PyObject *);
+static PyObject * PyArray_Transpose \
+       (PyArrayObject *, PyArray_Dims *);
+static PyObject * PyArray_TakeFrom \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+static PyObject * PyArray_PutTo \
+       (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+static PyObject * PyArray_PutMask \
+       (PyArrayObject *, PyObject*, PyObject*);
+static PyObject * PyArray_Repeat \
+       (PyArrayObject *, PyObject *, int);
+static PyObject * PyArray_Choose \
+       (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+static int PyArray_Sort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+static PyObject * PyArray_ArgSort \
+       (PyArrayObject *, int, NPY_SORTKIND);
+static PyObject * PyArray_SearchSorted \
+       (PyArrayObject *, PyObject *, NPY_SEARCHSIDE);
+static PyObject * PyArray_ArgMax \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_ArgMin \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Reshape \
+       (PyArrayObject *, PyObject *);
+static PyObject * PyArray_Newshape \
+       (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+static PyObject * PyArray_Squeeze \
+       (PyArrayObject *);
+static PyObject * PyArray_View \
+       (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+static PyObject * PyArray_SwapAxes \
+       (PyArrayObject *, int, int);
+static PyObject * PyArray_Max \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Min \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Ptp \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Mean \
+       (PyArrayObject *, int, int, PyArrayObject *);
+static PyObject * PyArray_Trace \
+       (PyArrayObject *, int, int, int, int, PyArrayObject *);
+static PyObject * PyArray_Diagonal \
+       (PyArrayObject *, int, int, int);
+static PyObject * PyArray_Clip \
+       (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+static PyObject * PyArray_Conjugate \
+       (PyArrayObject *, PyArrayObject *);
+static PyObject * PyArray_Nonzero \
+       (PyArrayObject *);
+static PyObject * PyArray_Std \
+       (PyArrayObject *, int, int, PyArrayObject *, int);
+static PyObject * PyArray_Sum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+static PyObject * PyArray_CumSum \
+       (PyArrayObject *, int, int, PyArrayObject *);
+static PyObject * PyArray_Prod \
+       (PyArrayObject *, int, int, PyArrayObject *);
+static PyObject * PyArray_CumProd \
+       (PyArrayObject *, int, int, PyArrayObject *);
+static PyObject * PyArray_All \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Any \
+       (PyArrayObject *, int, PyArrayObject *);
+static PyObject * PyArray_Compress \
+       (PyArrayObject *, PyObject *, int, PyArrayObject *);
+static PyObject * PyArray_Flatten \
+       (PyArrayObject *, NPY_ORDER);
+static PyObject * PyArray_Ravel \
+       (PyArrayObject *, NPY_ORDER);
+static npy_intp PyArray_MultiplyList \
+       (register npy_intp *, register int);
+static int PyArray_MultiplyIntList \
+       (register int *, register int);
+static void * PyArray_GetPtr \
+       (PyArrayObject *, register npy_intp*);
+static int PyArray_CompareLists \
+       (npy_intp *, npy_intp *, int);
+static int PyArray_AsCArray \
+       (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+static int PyArray_As1D \
+       (PyObject **, char **, int *, int);
+static int PyArray_As2D \
+       (PyObject **, char ***, int *, int *, int);
+static int PyArray_Free \
+       (PyObject *, void *);
+static int PyArray_Converter \
+       (PyObject *, PyObject **);
+static int PyArray_IntpFromSequence \
+       (PyObject *, npy_intp *, int);
+static PyObject * PyArray_Concatenate \
+       (PyObject *, int);
+static PyObject * PyArray_InnerProduct \
+       (PyObject *, PyObject *);
+static PyObject * PyArray_MatrixProduct \
+       (PyObject *, PyObject *);
+static PyObject * PyArray_CopyAndTranspose \
+       (PyObject *);
+static PyObject * PyArray_Correlate \
+       (PyObject *, PyObject *, int);
+static int PyArray_TypestrConvert \
+       (int, int);
+static int PyArray_DescrConverter \
+       (PyObject *, PyArray_Descr **);
+static int PyArray_DescrConverter2 \
+       (PyObject *, PyArray_Descr **);
+static int PyArray_IntpConverter \
+       (PyObject *, PyArray_Dims *);
+static int PyArray_BufferConverter \
+       (PyObject *, PyArray_Chunk *);
+static int PyArray_AxisConverter \
+       (PyObject *, int *);
+static int PyArray_BoolConverter \
+       (PyObject *, npy_bool *);
+static int PyArray_ByteorderConverter \
+       (PyObject *, char *);
+static int PyArray_OrderConverter \
+       (PyObject *, NPY_ORDER *);
+static unsigned char PyArray_EquivTypes \
+       (PyArray_Descr *, PyArray_Descr *);
+static PyObject * PyArray_Zeros \
+       (int, npy_intp *, PyArray_Descr *, int);
+static PyObject * PyArray_Empty \
+       (int, npy_intp *, PyArray_Descr *, int);
+static PyObject * PyArray_Where \
+       (PyObject *, PyObject *, PyObject *);
+static PyObject * PyArray_Arange \
+       (double, double, double, int);
+static PyObject * PyArray_ArangeObj \
+       (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+static int PyArray_SortkindConverter \
+       (PyObject *, NPY_SORTKIND *);
+static PyObject * PyArray_LexSort \
+       (PyObject *, int);
+static PyObject * PyArray_Round \
+       (PyArrayObject *, int, PyArrayObject *);
+static unsigned char PyArray_EquivTypenums \
+       (int, int);
+static int PyArray_RegisterDataType \
+       (PyArray_Descr *);
+static int PyArray_RegisterCastFunc \
+       (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+static int PyArray_RegisterCanCast \
+       (PyArray_Descr *, int, NPY_SCALARKIND);
+static void PyArray_InitArrFuncs \
+       (PyArray_ArrFuncs *);
+static PyObject * PyArray_IntTupleFromIntp \
+       (int, npy_intp *);
+static int PyArray_TypeNumFromName \
+       (char *);
+static int PyArray_ClipmodeConverter \
+       (PyObject *, NPY_CLIPMODE *);
+static int PyArray_OutputConverter \
+       (PyObject *, PyArrayObject **);
+static PyObject * PyArray_BroadcastToShape \
+       (PyObject *, npy_intp *, int);
+static void _PyArray_SigintHandler \
+       (int);
+static void* _PyArray_GetSigintBuf \
+       (void);
+static int PyArray_DescrAlignConverter \
+       (PyObject *, PyArray_Descr **);
+static int PyArray_DescrAlignConverter2 \
+       (PyObject *, PyArray_Descr **);
+static int PyArray_SearchsideConverter \
+       (PyObject *, void *);
+
+#else
+
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+void **PyArray_API;
+#else
+static void **PyArray_API=NULL;
+#endif
+#endif
+
+#define PyArray_GetNDArrayCVersion (*(unsigned int (*)(void)) PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[40])
+#define PyArray_GetNumericOps \
+        (*(PyObject * (*)(void)) \
+         PyArray_API[41])
+#define PyArray_INCREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[42])
+#define PyArray_XDECREF \
+        (*(int (*)(PyArrayObject *)) \
+         PyArray_API[43])
+#define PyArray_SetStringFunction \
+        (*(void (*)(PyObject *, int)) \
+         PyArray_API[44])
+#define PyArray_DescrFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+        (*(PyObject * (*)(int)) \
+         PyArray_API[46])
+#define PyArray_Zero \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[47])
+#define PyArray_One \
+        (*(char * (*)(PyArrayObject *)) \
+         PyArray_API[48])
+#define PyArray_CastToType \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[49])
+#define PyArray_CastTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[50])
+#define PyArray_CastAnyTo \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[51])
+#define PyArray_CanCastSafely \
+        (*(int (*)(int, int)) \
+         PyArray_API[52])
+#define PyArray_CanCastTo \
+        (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[53])
+#define PyArray_ObjectType \
+        (*(int (*)(PyObject *, int)) \
+         PyArray_API[54])
+#define PyArray_DescrFromObject \
+        (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+        (*(PyArrayObject ** (*)(PyObject *, int *)) \
+         PyArray_API[56])
+#define PyArray_DescrFromScalar \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+        (*(PyArray_Descr * (*)(PyObject *)) \
+         PyArray_API[58])
+#define PyArray_Size \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[59])
+#define PyArray_Scalar \
+        (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[60])
+#define PyArray_FromScalar \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+         PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+        (*(void (*)(PyObject *, void *)) \
+         PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+        (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+         PyArray_API[63])
+#define PyArray_CastScalarDirect \
+        (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+         PyArray_API[64])
+#define PyArray_ScalarFromObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[65])
+#define PyArray_GetCastFunc \
+        (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+         PyArray_API[66])
+#define PyArray_FromDims \
+        (*(PyObject * (*)(int, int *, int)) \
+         PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+        (*(PyObject * (*)(int, int *, PyArray_Descr *, char *)) \
+         PyArray_API[68])
+#define PyArray_FromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[69])
+#define PyArray_EnsureArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[71])
+#define PyArray_FromFile \
+        (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[72])
+#define PyArray_FromString \
+        (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+         PyArray_API[73])
+#define PyArray_FromBuffer \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+         PyArray_API[74])
+#define PyArray_FromIter \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+         PyArray_API[75])
+#define PyArray_Return \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[76])
+#define PyArray_GetField \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[77])
+#define PyArray_SetField \
+        (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+         PyArray_API[78])
+#define PyArray_Byteswap \
+        (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+         PyArray_API[79])
+#define PyArray_Resize \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER)) \
+         PyArray_API[80])
+#define PyArray_MoveInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[81])
+#define PyArray_CopyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[82])
+#define PyArray_CopyAnyInto \
+        (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[83])
+#define PyArray_CopyObject \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[84])
+#define PyArray_NewCopy \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[85])
+#define PyArray_ToList \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[86])
+#define PyArray_ToString \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[87])
+#define PyArray_ToFile \
+        (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+         PyArray_API[88])
+#define PyArray_Dump \
+        (*(int (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[89])
+#define PyArray_Dumps \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[90])
+#define PyArray_ValidType \
+        (*(int (*)(int)) \
+         PyArray_API[91])
+#define PyArray_UpdateFlags \
+        (*(void (*)(PyArrayObject *, int)) \
+         PyArray_API[92])
+#define PyArray_New \
+        (*(PyObject * (*)(PyTypeObject *, int, npy_intp *, int, npy_intp *, void *, int, int, PyObject *)) \
+         PyArray_API[93])
+#define PyArray_NewFromDescr \
+        (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp *, npy_intp *, void *, int, PyObject *)) \
+         PyArray_API[94])
+#define PyArray_DescrNew \
+        (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+         PyArray_API[95])
+#define PyArray_DescrNewFromType \
+        (*(PyArray_Descr * (*)(int)) \
+         PyArray_API[96])
+#define PyArray_GetPriority \
+        (*(double (*)(PyObject *, double)) \
+         PyArray_API[97])
+#define PyArray_IterNew \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[98])
+#define PyArray_MultiIterNew \
+        (*(PyObject * (*)(int, ...)) \
+         PyArray_API[99])
+#define PyArray_PyIntAsInt \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+        (*(npy_intp (*)(PyObject *)) \
+         PyArray_API[101])
+#define PyArray_Broadcast \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[102])
+#define PyArray_FillObjectArray \
+        (*(void (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[103])
+#define PyArray_FillWithScalar \
+        (*(int (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[104])
+#define PyArray_CheckStrides \
+        (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)) \
+         PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+        (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+         PyArray_API[106])
+#define PyArray_IterAllButAxis \
+        (*(PyObject * (*)(PyObject *, int *)) \
+         PyArray_API[107])
+#define PyArray_CheckFromAny \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+         PyArray_API[108])
+#define PyArray_FromArray \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+         PyArray_API[109])
+#define PyArray_FromInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[110])
+#define PyArray_FromStructInterface \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[111])
+#define PyArray_FromArrayAttr \
+        (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+         PyArray_API[112])
+#define PyArray_ScalarKind \
+        (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+         PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+        (*(int (*)(int, int, NPY_SCALARKIND)) \
+         PyArray_API[114])
+#define PyArray_NewFlagsObject \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[115])
+#define PyArray_CanCastScalar \
+        (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+         PyArray_API[116])
+#define PyArray_CompareUCS4 \
+        (*(int (*)(npy_ucs4 *, npy_ucs4 *, register size_t)) \
+         PyArray_API[117])
+#define PyArray_RemoveSmallest \
+        (*(int (*)(PyArrayMultiIterObject *)) \
+         PyArray_API[118])
+#define PyArray_ElementStrides \
+        (*(int (*)(PyObject *)) \
+         PyArray_API[119])
+#define PyArray_Item_INCREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[120])
+#define PyArray_Item_XDECREF \
+        (*(void (*)(char *, PyArray_Descr *)) \
+         PyArray_API[121])
+#define PyArray_FieldNames \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[122])
+#define PyArray_Transpose \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+         PyArray_API[123])
+#define PyArray_TakeFrom \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[124])
+#define PyArray_PutTo \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+         PyArray_API[125])
+#define PyArray_PutMask \
+        (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+         PyArray_API[126])
+#define PyArray_Repeat \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+         PyArray_API[127])
+#define PyArray_Choose \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+         PyArray_API[128])
+#define PyArray_Sort \
+        (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[129])
+#define PyArray_ArgSort \
+        (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+         PyArray_API[130])
+#define PyArray_SearchSorted \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE)) \
+         PyArray_API[131])
+#define PyArray_ArgMax \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[132])
+#define PyArray_ArgMin \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[133])
+#define PyArray_Reshape \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+         PyArray_API[134])
+#define PyArray_Newshape \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+         PyArray_API[135])
+#define PyArray_Squeeze \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[136])
+#define PyArray_View \
+        (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+         PyArray_API[137])
+#define PyArray_SwapAxes \
+        (*(PyObject * (*)(PyArrayObject *, int, int)) \
+         PyArray_API[138])
+#define PyArray_Max \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[139])
+#define PyArray_Min \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[140])
+#define PyArray_Ptp \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[141])
+#define PyArray_Mean \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[142])
+#define PyArray_Trace \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+         PyArray_API[143])
+#define PyArray_Diagonal \
+        (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+         PyArray_API[144])
+#define PyArray_Clip \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+         PyArray_API[145])
+#define PyArray_Conjugate \
+        (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+         PyArray_API[146])
+#define PyArray_Nonzero \
+        (*(PyObject * (*)(PyArrayObject *)) \
+         PyArray_API[147])
+#define PyArray_Std \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+         PyArray_API[148])
+#define PyArray_Sum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[149])
+#define PyArray_CumSum \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[150])
+#define PyArray_Prod \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[151])
+#define PyArray_CumProd \
+        (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+         PyArray_API[152])
+#define PyArray_All \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[153])
+#define PyArray_Any \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[154])
+#define PyArray_Compress \
+        (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+         PyArray_API[155])
+#define PyArray_Flatten \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[156])
+#define PyArray_Ravel \
+        (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+         PyArray_API[157])
+#define PyArray_MultiplyList \
+        (*(npy_intp (*)(register npy_intp *, register int)) \
+         PyArray_API[158])
+#define PyArray_MultiplyIntList \
+        (*(int (*)(register int *, register int)) \
+         PyArray_API[159])
+#define PyArray_GetPtr \
+        (*(void * (*)(PyArrayObject *, register npy_intp*)) \
+         PyArray_API[160])
+#define PyArray_CompareLists \
+        (*(int (*)(npy_intp *, npy_intp *, int)) \
+         PyArray_API[161])
+#define PyArray_AsCArray \
+        (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+         PyArray_API[162])
+#define PyArray_As1D \
+        (*(int (*)(PyObject **, char **, int *, int)) \
+         PyArray_API[163])
+#define PyArray_As2D \
+        (*(int (*)(PyObject **, char ***, int *, int *, int)) \
+         PyArray_API[164])
+#define PyArray_Free \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[165])
+#define PyArray_Converter \
+        (*(int (*)(PyObject *, PyObject **)) \
+         PyArray_API[166])
+#define PyArray_IntpFromSequence \
+        (*(int (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[167])
+#define PyArray_Concatenate \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[168])
+#define PyArray_InnerProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[169])
+#define PyArray_MatrixProduct \
+        (*(PyObject * (*)(PyObject *, PyObject *)) \
+         PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+        (*(PyObject * (*)(PyObject *)) \
+         PyArray_API[171])
+#define PyArray_Correlate \
+        (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+         PyArray_API[172])
+#define PyArray_TypestrConvert \
+        (*(int (*)(int, int)) \
+         PyArray_API[173])
+#define PyArray_DescrConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[174])
+#define PyArray_DescrConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[175])
+#define PyArray_IntpConverter \
+        (*(int (*)(PyObject *, PyArray_Dims *)) \
+         PyArray_API[176])
+#define PyArray_BufferConverter \
+        (*(int (*)(PyObject *, PyArray_Chunk *)) \
+         PyArray_API[177])
+#define PyArray_AxisConverter \
+        (*(int (*)(PyObject *, int *)) \
+         PyArray_API[178])
+#define PyArray_BoolConverter \
+        (*(int (*)(PyObject *, npy_bool *)) \
+         PyArray_API[179])
+#define PyArray_ByteorderConverter \
+        (*(int (*)(PyObject *, char *)) \
+         PyArray_API[180])
+#define PyArray_OrderConverter \
+        (*(int (*)(PyObject *, NPY_ORDER *)) \
+         PyArray_API[181])
+#define PyArray_EquivTypes \
+        (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+         PyArray_API[182])
+#define PyArray_Zeros \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[183])
+#define PyArray_Empty \
+        (*(PyObject * (*)(int, npy_intp *, PyArray_Descr *, int)) \
+         PyArray_API[184])
+#define PyArray_Where \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+         PyArray_API[185])
+#define PyArray_Arange \
+        (*(PyObject * (*)(double, double, double, int)) \
+         PyArray_API[186])
+#define PyArray_ArangeObj \
+        (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+         PyArray_API[187])
+#define PyArray_SortkindConverter \
+        (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+         PyArray_API[188])
+#define PyArray_LexSort \
+        (*(PyObject * (*)(PyObject *, int)) \
+         PyArray_API[189])
+#define PyArray_Round \
+        (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+         PyArray_API[190])
+#define PyArray_EquivTypenums \
+        (*(unsigned char (*)(int, int)) \
+         PyArray_API[191])
+#define PyArray_RegisterDataType \
+        (*(int (*)(PyArray_Descr *)) \
+         PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+        (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+         PyArray_API[193])
+#define PyArray_RegisterCanCast \
+        (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+         PyArray_API[194])
+#define PyArray_InitArrFuncs \
+        (*(void (*)(PyArray_ArrFuncs *)) \
+         PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+        (*(PyObject * (*)(int, npy_intp *)) \
+         PyArray_API[196])
+#define PyArray_TypeNumFromName \
+        (*(int (*)(char *)) \
+         PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+        (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+         PyArray_API[198])
+#define PyArray_OutputConverter \
+        (*(int (*)(PyObject *, PyArrayObject **)) \
+         PyArray_API[199])
+#define PyArray_BroadcastToShape \
+        (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+         PyArray_API[200])
+#define _PyArray_SigintHandler \
+        (*(void (*)(int)) \
+         PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+        (*(void* (*)(void)) \
+         PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+        (*(int (*)(PyObject *, PyArray_Descr **)) \
+         PyArray_API[204])
+#define PyArray_SearchsideConverter \
+        (*(int (*)(PyObject *, void *)) \
+         PyArray_API[205])
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
+  PyObject *c_api = NULL;
+  if (numpy == NULL) return -1;
+  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+  if (c_api == NULL) {Py_DECREF(numpy); return -1;}
+  if (PyCObject_Check(c_api)) {
+      PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
+  }
+  Py_DECREF(c_api);
+  Py_DECREF(numpy);
+  if (PyArray_API == NULL) return -1;
+  /* Perform runtime check of C API version */
+  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+    PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+        "version %x of C-API but this version of numpy is %x", \
+        (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+    return -1;
+  }
+  return 0;
+}
+
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return; } }
+
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+
+#endif
+
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/__multiarray_api.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/__ufunc_api.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/__ufunc_api.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/__ufunc_api.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,203 @@
+
+#ifdef _UMATHMODULE
+
+static PyTypeObject PyUFunc_Type;
+
+static PyObject * PyUFunc_FromFuncAndData \
+       (PyUFuncGenericFunction *, void **, char *, int, int, int, int, char *, char *, int);
+static int PyUFunc_RegisterLoopForType \
+       (PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *);
+static int PyUFunc_GenericFunction \
+       (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+static void PyUFunc_f_f_As_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_d_d \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_f_f \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_g_g \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_F_F_As_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_F_F \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_D_D \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_G_G \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_O_O \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_ff_f_As_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_ff_f \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_dd_d \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_gg_g \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_FF_F_As_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_DD_D \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_FF_F \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_GG_G \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_OO_O \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_O_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_OO_O_method \
+       (char **, npy_intp *, npy_intp *, void *);
+static void PyUFunc_On_Om \
+       (char **, npy_intp *, npy_intp *, void *);
+static int PyUFunc_GetPyValues \
+       (char *, int *, int *, PyObject **);
+static int PyUFunc_checkfperr \
+       (int, PyObject *, int *);
+static void PyUFunc_clearfperr \
+       (void);
+static int PyUFunc_getfperr \
+       (void);
+static int PyUFunc_handlefperr \
+       (int, PyObject *, int, int *);
+static int PyUFunc_ReplaceLoopBySignature \
+       (PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *);
+
+#else
+
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+#else
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+void **PyUFunc_API;
+#else
+static void **PyUFunc_API=NULL;
+#endif
+#endif
+
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+
+#define PyUFunc_FromFuncAndData \
+        (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, char *, char *, int)) \
+         PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+        (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, int *, void *)) \
+         PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+        (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+         PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[4])
+#define PyUFunc_d_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[5])
+#define PyUFunc_f_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[6])
+#define PyUFunc_g_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[8])
+#define PyUFunc_F_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[9])
+#define PyUFunc_D_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[10])
+#define PyUFunc_G_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[11])
+#define PyUFunc_O_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[13])
+#define PyUFunc_ff_f \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[14])
+#define PyUFunc_dd_d \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[15])
+#define PyUFunc_gg_g \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[17])
+#define PyUFunc_DD_D \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[18])
+#define PyUFunc_FF_F \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[19])
+#define PyUFunc_GG_G \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[20])
+#define PyUFunc_OO_O \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[23])
+#define PyUFunc_On_Om \
+        (*(void (*)(char **, npy_intp *, npy_intp *, void *)) \
+         PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+        (*(int (*)(char *, int *, int *, PyObject **)) \
+         PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+        (*(int (*)(int, PyObject *, int *)) \
+         PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+        (*(void (*)(void)) \
+         PyUFunc_API[27])
+#define PyUFunc_getfperr \
+        (*(int (*)(void)) \
+         PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+        (*(int (*)(int, PyObject *, int, int *)) \
+         PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+        (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)) \
+         PyUFunc_API[30])
+
+static int
+_import_umath(void)
+{
+  PyObject *numpy = PyImport_ImportModule("numpy.core.umath");
+  PyObject *c_api = NULL;
+
+  if (numpy == NULL) return -1;
+  c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+  if (c_api == NULL) {Py_DECREF(numpy); return -1;}
+  if (PyCObject_Check(c_api)) {
+      PyUFunc_API = (void **)PyCObject_AsVoidPtr(c_api);
+  }
+  Py_DECREF(c_api);
+  Py_DECREF(numpy);
+  if (PyUFunc_API == NULL) return -1;
+  return 0;
+}
+
+#define import_umath() { if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); return; }}
+
+#define import_umath1(ret) { if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); return ret; }}
+
+#define import_umath2(msg, ret) { if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; }}
+
+#define import_ufunc() { if (_import_umath() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.umath failed to import"); }}
+
+
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/__ufunc_api.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/arrayobject.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/arrayobject.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/arrayobject.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,21 @@
+
+/* This expects the following variables to be defined (besides
+   the usual ones from pyconfig.h
+
+   SIZEOF_LONG_DOUBLE -- sizeof(long double) or sizeof(double) if no
+                         long double is present on platform.
+   CHAR_BIT       --     number of bits in a char (usually 8)
+                         (should be in limits.h)
+
+*/
+
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+#include "ndarrayobject.h"
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
+#endif
+
+#include "npy_interrupt.h"
+
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/arrayobject.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/arrayscalars.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/arrayscalars.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/arrayscalars.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,152 @@
+#ifndef _MULTIARRAYMODULE
+typedef struct {
+	PyObject_HEAD
+	npy_bool obval;
+} PyBoolScalarObject;
+#endif
+
+
+typedef struct {
+	PyObject_HEAD
+	signed char obval;
+} PyByteScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	short obval;
+} PyShortScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	int obval;
+} PyIntScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	long obval;
+} PyLongScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_longlong obval;
+} PyLongLongScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	unsigned char obval;
+} PyUByteScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	unsigned short obval;
+} PyUShortScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	unsigned int obval;
+} PyUIntScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	unsigned long obval;
+} PyULongScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_ulonglong obval;
+} PyULongLongScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	float obval;
+} PyFloatScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	double obval;
+} PyDoubleScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_longdouble obval;
+} PyLongDoubleScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_cfloat obval;
+} PyCFloatScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_cdouble obval;
+} PyCDoubleScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	PyObject * obval;
+} PyObjectScalarObject;
+
+
+typedef struct {
+	PyObject_HEAD
+	char obval;
+} PyScalarObject;
+
+#define PyStringScalarObject PyStringObject
+#define PyUnicodeScalarObject PyUnicodeObject
+
+typedef struct {
+	PyObject_VAR_HEAD
+	char *obval;
+	PyArray_Descr *descr;
+	int flags;
+	PyObject *base;
+} PyVoidScalarObject;
+
+/* Macros
+     Py<Cls><bitsize>ScalarObject
+     Py<Cls><bitsize>ArrType_Type
+   are defined in ndarrayobject.h
+*/
+
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+	((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i)			\
+	return Py_INCREF(PyArrayScalar_FromLong(i)), \
+		PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE		\
+	return Py_INCREF(PyArrayScalar_False),	\
+		PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE		\
+	return Py_INCREF(PyArrayScalar_True),	\
+		PyArrayScalar_True
+
+#define PyArrayScalar_New(cls) \
+	Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls)		\
+	((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+	PyArrayScalar_VAL(obj, cls) = val


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/arrayscalars.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/config.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/config.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/config.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,22 @@
+/* #define SIZEOF_SHORT 2 */
+/* #define SIZEOF_INT 4 */
+/* #define SIZEOF_LONG 4 */
+/* #define SIZEOF_FLOAT 4 */
+/* #define SIZEOF_DOUBLE 8 */
+#define SIZEOF_LONG_DOUBLE 12
+#define SIZEOF_PY_INTPTR_T 4
+/* #define SIZEOF_LONG_LONG 8 */
+#define SIZEOF_PY_LONG_LONG 8
+/* #define CHAR_BIT 8 */
+#define MATHLIB 
+#define HAVE_FLOAT_FUNCS
+#define HAVE_LOG1P
+#define HAVE_EXPM1
+#define HAVE_INVERSE_HYPERBOLIC
+#define HAVE_INVERSE_HYPERBOLIC_FLOAT
+#define HAVE_RINT
+#ifdef WITH_THREAD
+#define NPY_ALLOW_THREADS 1
+#else
+#define NPY_ALLOW_THREADS 0
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/config.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/control.py
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/control.py	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/control.py	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,51 @@
+import volumeInput as V
+import Segmenter as S
+image = V.getFilteredSlice('slice112.raw')
+sourceImage = image.copy()
+edges, objects = S.Sobel(image)
+S.GetShapeMask(edges, objects)
+S.GetVoxelMeasures(sourceImage, edges, objects)
+S.GetTextureMeasures(sourceImage, edges, objects)
+
+import volumeInput as V
+import Segmenter as S
+sourceImage, labeledMask, ROIList = S.SegmentRegions()
+
+
+
+image = S.GetSliceFromVolume()
+edges, objects = S.Canny(image)
+
+ShenCastanLow = 0.3
+b             = 0.5
+window        = 7
+lowThreshold  = 220 + 2048
+highThreshold = 600 + 2048
+edges, groups = S.ShenCastan(image, ShenCastanLow, b, window, lowThreshold, highThreshold)
+
+
+import Segmenter as S
+image, mask, list = S.SegmentRegions()
+
+
+import Segmenter as S
+regionMask, numberRegions = S.GrowRegions()
+regionMask.max()
+
+S.SaveSlice(regionMask, 'regionMask.raw')
+
+// for display of dumped .raw files using matplotlib
+
+
+import volumeInput as V
+rawslice = V.getFilteredSlice("source.raw", bytes=4)
+edgeslice = V.getFilteredSlice("labeledMask.raw", bytes=4)
+
+pylab.figure(1)
+pylab.title('raw Image')
+pylab.imshow(rawslice)
+pylab.figure(3)
+pylab.title('Edge Image')
+pylab.imshow(edgeslice)
+
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/control.py
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/ndImage_Segmenter_structs.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/ndImage_Segmenter_structs.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/ndImage_Segmenter_structs.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,155 @@
+#ifndef V1_STRUCTSH
+#define V1_STRUCTSH
+
+#define bool unsigned char
+
+typedef struct{
+    int x;
+    int y;
+}POINT;
+
+typedef struct{
+    int x;
+    int y;
+    int linkIndex;
+    bool haveLink;
+}bPOINT;
+
+typedef struct{
+    int left;
+    int right;
+    int top;
+    int bottom;
+}RECT;
+
+typedef struct{
+    char filterName[20];
+    float Mean;
+    float Variance;
+}tTEM;
+
+typedef struct{
+    int numberKernels;
+    int kernelLength;
+    int numberFilterLayers;
+    float lawsKernel[6][7];
+    char name[7];
+}LawsFilter7;
+
+typedef struct{
+    // filled in GetObjectStats 
+    int L;
+    int R;
+    int T;
+    int B;
+    int Label;
+    int Area;
+    float cX;
+    float cY;
+    // filled in BuildBoundary
+    int   curveClose;
+    float cXBoundary;
+    float cYBoundary;
+    float boundaryLength;
+    float minRadius;
+    float maxRadius;
+    float aveRadius;
+    float ratio;
+    float compactness;
+    // filled in VoxelMeasures
+    float voxelMean;
+    float voxelVar;
+    // filled in TextureMeasures
+    float TEM[20];
+}objStruct;
+
+typedef struct{
+    int numberPoints;
+    int curveClose;
+    int classify;
+    float boundaryLength;
+    float minRadius;
+    float maxRadius;
+    float aveRadius;
+    float ratio;
+    float compactness;
+    float voxelMean;
+    float voxelVar;
+    RECT rectangle;
+    POINT centroid;
+    bool isWithin;
+    bool closedCurve;
+    bool criticalSize;
+    int Label;
+}boundaryIndex;
+
+
+typedef struct{
+    POINT xy;
+}blobBoundary;
+
+
+//
+// prototypes
+//
+int NI_RegionGrow(int, int, int, int, int, int, int, double *, unsigned short *, int *);   
+int NI_TextureMeasures(int, int, int, int, double *, unsigned short *, objStruct objectMetrics[]);
+int NI_VoxelMeasures(int, int, int, int, double *, unsigned short *, objStruct objectMetrics[]);
+int NI_BuildBoundary(int, int, int, int, unsigned short *, objStruct objectMetrics[]);
+int NI_GetObjectStats(int, int, int, unsigned short *, objStruct objectMetrics[]);
+int NI_ThinFilter(int, int, int, int, unsigned short *, objStruct objectMetrics[]);
+int NI_SobelEdges(int, int, int, double, int, int, int, double, int, double *, unsigned short *, int *);  
+int NI_ShenCastanEdges(int, int, int, double, double, int, int, int, double *, unsigned short *, int *);
+int NI_CannyEdges(int, int, int, double, double, double, int, int, int, double, int,
+	          double *, unsigned short *, int *);
+
+void computeLaws(LawsFilter7, tTEM LawsFeatures[], RECT, int, int, int, int, unsigned char *, float *,
+	       	 unsigned short *, float *, double *);
+float lawsConvolution(float *, float *, float *, int);
+void initLaws(LawsFilter7*);
+void getVoxelMeasures(objStruct objectMetrics[], double *, unsigned short *, int, int, int);
+void getLawsTexture(LawsFilter7, tTEM LawsFeatures[], objStruct objectMetrics[], double *, unsigned short *, int, int, int);
+		      
+void morphoFilterBinaryImage(int, int, unsigned short *, int, int);
+void buildBinaryImage(int, int, double *, unsigned short *, int, int);
+void doRegionGrow(int, int, int, double *, unsigned short *, int, int, int, int);
+void buildBoundary(objStruct objectMetrics[], int, unsigned short *, int, int, int);
+void getBoundary(unsigned short *, unsigned char *, blobBoundary *, blobBoundary *, 
+	         boundaryIndex *, RECT, int, int, int, int, int, int);
+void doMorphology(unsigned char *, unsigned char *, unsigned char *, unsigned char *, int olapValuesC[],
+       	          int olapValuesO[], unsigned short cmask[11][11], unsigned short omask[11][11],
+	          RECT, int, int, int, int);
+void getCompactness(unsigned char *, RECT, int, int, float *, float);
+void OpenCloseFilter(int olapValues[], int, int, int, int, unsigned char *,  
+                     unsigned char *, unsigned short mask[11][11]);
+void trackBoundary(unsigned char *, blobBoundary lBoundary[], int, int, blobBoundary, int); 
+void getBoundaryMetrics(bPOINT *, float *, float *, float *, float *, float, float, int);
+void generateMask(unsigned char *, bPOINT *, int, int, int);
+void ThinningFilter(int, int, int, int J_mask[3][30], int K_mask[3][30], unsigned char *, 
+	            unsigned char *, unsigned char *, unsigned char *, unsigned char *, unsigned char *);
+void initThinFilter(int J_mask[3][30], int K_mask[3][30]);
+void Shen_Castan(double, double, int, int, int, int, int, double *, unsigned short *);
+void computeISEF(float *, float *, int, int, double);
+void ISEF_Horizontal(float *, float *, float *, float *, int, int, double);
+void ISEF_Vertical(float *, float *, float *, float *, int, int, double);
+void thresholdImage(float *, float *, int, int, int, int);
+void computeBandedLaplacian(float *, float *, float *, int, int);
+void getZeroCrossings(float *, float *, float *, int, int, int);
+float adaptiveGradient(float *, float *, int, int, int, int);
+void thresholdEdges(float *, unsigned short *, double, int, int);
+void estimateThreshold(float *, float *, float, int, int, float *);
+void doSobel(int, int, int, double, int, double *, unsigned short *);
+void DGFilters(int, int, int, double, int, float *, float *, double *, double *, float *, float *);
+void nonMaxSupress(int, int, float, float, double *, double *, int, float *, float *, float *);
+void edgeHysteresis(int, int, double, double, float *, float *);
+void edgeThreshold(int, int, double, float *, float *);
+int traceEdge(int, int, int, int, double, float *, float *);
+float magnitude(float, float);
+int ConnectedEdgePoints(int, int, unsigned short *);
+void doPreProcess(int, int, int, double *, double, int, int, int);
+void filter2D(int, int, int, int, int, float *, double *);
+void buildKernel(double, int, int, float *);
+
+
+
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/ndImage_Segmenter_structs.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/ndarrayobject.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/ndarrayobject.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/ndarrayobject.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,1995 @@
+/* DON'T INCLUDE THIS DIRECTLY.
+ */
+
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#ifdef __cplusplus
+#define CONFUSE_EMACS {
+#define CONFUSE_EMACS2 }
+extern "C" CONFUSE_EMACS
+#undef CONFUSE_EMACS
+#undef CONFUSE_EMACS2
+/* ... otherwise a semi-smart identer (like emacs) tries to indent
+       everything when you're typing */
+#endif
+/* This is auto-generated by the installer */
+#include "config.h"
+
+/* There are several places in the code where an array of dimensions is
+ * allocated statically.  This is the size of that static allocation.
+ *
+ * The array creation itself could have arbitrary dimensions but
+ * all the places where static allocation is used would need to
+ * be changed to dynamic (including inside of several structures)
+ */
+
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+
+        /* Helpful to distinguish what is installed */
+#define NPY_VERSION 0x01000009
+
+        /* Some platforms don't define bool, long long, or long double.
+           Handle that here.
+         */
+
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+#  ifdef _MSC_VER
+#    define NPY_LONGLONG_FMT         "I64d"
+#    define NPY_ULONGLONG_FMT        "I64u"
+#    define NPY_LONGLONG_SUFFIX(x)   (x##i64)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##Ui64)
+#  else
+        /* #define LONGLONG_FMT   "lld"      Another possible variant
+           #define ULONGLONG_FMT  "llu"
+
+           #define LONGLONG_FMT   "qd"   -- BSD perhaps?
+           #define ULONGLONG_FMT   "qu"
+        */
+#    define NPY_LONGLONG_FMT         "Ld"
+#    define NPY_ULONGLONG_FMT        "Lu"
+#    define NPY_LONGLONG_SUFFIX(x)   (x##LL)
+#    define NPY_ULONGLONG_SUFFIX(x)  (x##ULL)
+#  endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+#  define NPY_LONGLONG_SUFFIX(x)  (x##L)
+#  define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+#if SIZEOF_LONG_DOUBLE==SIZEOF_DOUBLE
+        typedef double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "g"
+#else
+        typedef long double npy_longdouble;
+        #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+/* These are for completeness */
+typedef float npy_float;
+typedef double npy_double;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+
+typedef struct { float real, imag; } npy_cfloat;
+typedef struct { double real, imag; } npy_cdouble;
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+
+enum NPY_TYPES {    NPY_BOOL=0,
+                    NPY_BYTE, NPY_UBYTE,
+                    NPY_SHORT, NPY_USHORT,
+                    NPY_INT, NPY_UINT,
+                    NPY_LONG, NPY_ULONG,
+                    NPY_LONGLONG, NPY_ULONGLONG,
+                    NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+                    NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+                    NPY_OBJECT=17,
+                    NPY_STRING, NPY_UNICODE,
+                    NPY_VOID,
+                    NPY_NTYPES,
+                    NPY_NOTYPE,
+                    NPY_CHAR,      /* special flag */
+                    NPY_USERDEF=256  /* leave room for characters */
+};
+
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+
+/* How many floating point types are there */
+#define NPY_NUM_FLOATTYPE 3
+
+/* We need to match npy_intp to a signed integer of the same size as
+   a pointer variable. npy_uintp to the equivalent unsigned integer
+*/
+
+
+/* These characters correspond to the array type and the
+   struct module */
+
+/*  except 'p' -- signed integer for pointer type */
+
+enum NPY_TYPECHAR { NPY_BOOLLTR = '?',
+                        NPY_BYTELTR = 'b',
+                        NPY_UBYTELTR = 'B',
+                        NPY_SHORTLTR = 'h',
+                        NPY_USHORTLTR = 'H',
+                        NPY_INTLTR = 'i',
+                        NPY_UINTLTR = 'I',
+                        NPY_LONGLTR = 'l',
+                        NPY_ULONGLTR = 'L',
+                        NPY_LONGLONGLTR = 'q',
+                        NPY_ULONGLONGLTR = 'Q',
+                        NPY_FLOATLTR = 'f',
+                        NPY_DOUBLELTR = 'd',
+                        NPY_LONGDOUBLELTR = 'g',
+                        NPY_CFLOATLTR = 'F',
+                        NPY_CDOUBLELTR = 'D',
+                        NPY_CLONGDOUBLELTR = 'G',
+                        NPY_OBJECTLTR = 'O',
+                        NPY_STRINGLTR = 'S',
+                        NPY_STRINGLTR2 = 'a',
+                        NPY_UNICODELTR = 'U',
+                        NPY_VOIDLTR = 'V',
+                        NPY_CHARLTR = 'c',
+
+                        /* No Descriptor, just a define -- this let's
+                         Python users specify an array of integers
+                         large enough to hold a pointer on the platform*/
+                        NPY_INTPLTR = 'p',
+                        NPY_UINTPLTR = 'P',
+
+                        NPY_GENBOOLLTR ='b',
+                        NPY_SIGNEDLTR = 'i',
+                        NPY_UNSIGNEDLTR = 'u',
+                        NPY_FLOATINGLTR = 'f',
+                        NPY_COMPLEXLTR = 'c'
+};
+
+typedef enum {
+        NPY_QUICKSORT=0,
+        NPY_HEAPSORT=1,
+        NPY_MERGESORT=2,
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_MERGESORT + 1)
+
+
+typedef enum {
+        NPY_SEARCHLEFT=0,
+        NPY_SEARCHRIGHT=1,
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+
+
+typedef enum {
+        NPY_NOSCALAR=-1,
+        NPY_BOOL_SCALAR,
+        NPY_INTPOS_SCALAR,
+        NPY_INTNEG_SCALAR,
+        NPY_FLOAT_SCALAR,
+        NPY_COMPLEX_SCALAR,
+        NPY_OBJECT_SCALAR,
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+
+typedef enum {
+        NPY_ANYORDER=-1,
+        NPY_CORDER=0,
+        NPY_FORTRANORDER=1
+} NPY_ORDER;
+
+
+typedef enum {
+        NPY_CLIP=0,
+        NPY_WRAP=1,
+        NPY_RAISE=2
+} NPY_CLIPMODE;
+
+        /* Define bit-width array types and typedefs */
+
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+        /* Need to find the number of bits for each type and
+           make definitions accordingly.
+
+           C states that sizeof(char) == 1 by definition
+
+           So, just using the sizeof keyword won't help.
+
+           It also looks like Python itself uses sizeof(char) quite a
+           bit, which by definition should be 1 all the time.
+
+           Idea: Make Use of CHAR_BIT which should tell us how many
+           BITS per CHARACTER
+        */
+
+        /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT   INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#endif
+#define NPY_MIN_INT   INT_MIN
+#define NPY_MAX_UINT  UINT_MAX
+#define NPY_MAX_LONG  LONG_MAX
+#define NPY_MIN_LONG  LONG_MIN
+#define NPY_MAX_ULONG  ULONG_MAX
+
+
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_FLOAT SIZEOF_FLOAT
+#define NPY_SIZEOF_DOUBLE SIZEOF_DOUBLE
+#define NPY_SIZEOF_LONGDOUBLE SIZEOF_LONG_DOUBLE
+#define NPY_SIZEOF_LONGLONG SIZEOF_LONG_LONG
+#define NPY_BITSOF_BOOL (sizeof(npy_bool)*CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_SHORT (SIZEOF_SHORT*CHAR_BIT)
+#define NPY_BITSOF_INT (SIZEOF_INT*CHAR_BIT)
+#define NPY_BITSOF_LONG (SIZEOF_LONG*CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG*CHAR_BIT)
+#define NPY_BITSOF_FLOAT (SIZEOF_FLOAT*CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (SIZEOF_DOUBLE*CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE*CHAR_BIT)
+
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+        typedef long npy_int8;
+        typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+        typedef long npy_int16;
+        typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+        typedef long npy_int32;
+        typedef unsigned long npy_uint32;
+        typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+        typedef long npy_int64;
+        typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+        typedef long npy_int128;
+        typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#endif
+
+#if NPY_BITSOF_LONGLONG == 8
+#  ifndef NPY_INT8
+#    define NPY_INT8 NPY_LONGLONG
+#    define NPY_UINT8 NPY_ULONGLONG
+        typedef npy_longlong npy_int8;
+        typedef npy_ulonglong npy_uint8;
+#    define PyInt8ScalarObject PyLongLongScalarObject
+#    define PyInt8ArrType_Type PyLongLongArrType_Type
+#    define PyUInt8ScalarObject PyULongLongScalarObject
+#    define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT8
+#  define NPY_MIN_LONGLONG NPY_MIN_INT8
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+#  ifndef NPY_INT16
+#    define NPY_INT16 NPY_LONGLONG
+#    define NPY_UINT16 NPY_ULONGLONG
+        typedef npy_longlong npy_int16;
+        typedef npy_ulonglong npy_uint16;
+#    define PyInt16ScalarObject PyLongLongScalarObject
+#    define PyInt16ArrType_Type PyLongLongArrType_Type
+#    define PyUInt16ScalarObject PyULongLongScalarObject
+#    define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT16
+#  define NPY_MIN_LONGLONG NPY_MIN_INT16
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+#  ifndef NPY_INT32
+#    define NPY_INT32 NPY_LONGLONG
+#    define NPY_UINT32 NPY_ULONGLONG
+        typedef npy_longlong npy_int32;
+        typedef npy_ulonglong npy_uint32;
+        typedef npy_ulonglong npy_ucs4;
+#    define PyInt32ScalarObject PyLongLongScalarObject
+#    define PyInt32ArrType_Type PyLongLongArrType_Type
+#    define PyUInt32ScalarObject PyULongLongScalarObject
+#    define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT32
+#  define NPY_MIN_LONGLONG NPY_MIN_INT32
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+#  ifndef NPY_INT64
+#    define NPY_INT64 NPY_LONGLONG
+#    define NPY_UINT64 NPY_ULONGLONG
+        typedef npy_longlong npy_int64;
+        typedef npy_ulonglong npy_uint64;
+#    define PyInt64ScalarObject PyLongLongScalarObject
+#    define PyInt64ArrType_Type PyLongLongArrType_Type
+#    define PyUInt64ScalarObject PyULongLongScalarObject
+#    define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT64
+#  define NPY_MIN_LONGLONG NPY_MIN_INT64
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+#  ifndef NPY_INT128
+#    define NPY_INT128 NPY_LONGLONG
+#    define NPY_UINT128 NPY_ULONGLONG
+        typedef npy_longlong npy_int128;
+        typedef npy_ulonglong npy_uint128;
+#    define PyInt128ScalarObject PyLongLongScalarObject
+#    define PyInt128ArrType_Type PyLongLongArrType_Type
+#    define PyUInt128ScalarObject PyULongLongScalarObject
+#    define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+#  endif
+#  define NPY_MAX_LONGLONG NPY_MAX_INT128
+#  define NPY_MIN_LONGLONG NPY_MIN_INT128
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+#  define NPY_INT256 NPY_LONGLONG
+#  define NPY_UINT256 NPY_ULONGLONG
+        typedef npy_longlong npy_int256;
+        typedef npy_ulonglong npy_uint256;
+#  define PyInt256ScalarObject PyLongLongScalarObject
+#  define PyInt256ArrType_Type PyLongLongArrType_Type
+#  define PyUInt256ScalarObject PyULongLongScalarObject
+#  define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+#  define NPY_MAX_LONGLONG NPY_MAX_INT256
+#  define NPY_MIN_LONGLONG NPY_MIN_INT256
+#  define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#endif
+
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+        typedef int npy_int8;
+        typedef unsigned int npy_uint8;
+#    define PyInt8ScalarObject PyIntScalarObject
+#    define PyInt8ArrType_Type PyIntArrType_Type
+#    define PyUInt8ScalarObject PyUIntScalarObject
+#    define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+        typedef int npy_int16;
+        typedef unsigned int npy_uint16;
+#    define PyInt16ScalarObject PyIntScalarObject
+#    define PyInt16ArrType_Type PyIntArrType_Type
+#    define PyUInt16ScalarObject PyIntUScalarObject
+#    define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+        typedef int npy_int32;
+        typedef unsigned int npy_uint32;
+        typedef unsigned int npy_ucs4;
+#    define PyInt32ScalarObject PyIntScalarObject
+#    define PyInt32ArrType_Type PyIntArrType_Type
+#    define PyUInt32ScalarObject PyUIntScalarObject
+#    define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+        typedef int npy_int64;
+        typedef unsigned int npy_uint64;
+#    define PyInt64ScalarObject PyIntScalarObject
+#    define PyInt64ArrType_Type PyIntArrType_Type
+#    define PyUInt64ScalarObject PyUIntScalarObject
+#    define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+#endif
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+        typedef int npy_int128;
+        typedef unsigned int npy_uint128;
+#    define PyInt128ScalarObject PyIntScalarObject
+#    define PyInt128ArrType_Type PyIntArrType_Type
+#    define PyUInt128ScalarObject PyUIntScalarObject
+#    define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#endif
+#endif
+
+#if NPY_BITSOF_SHORT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+        typedef short npy_int8;
+        typedef unsigned short npy_uint8;
+#    define PyInt8ScalarObject PyShortScalarObject
+#    define PyInt8ArrType_Type PyShortArrType_Type
+#    define PyUInt8ScalarObject PyUShortScalarObject
+#    define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+        typedef short npy_int16;
+        typedef unsigned short npy_uint16;
+#    define PyInt16ScalarObject PyShortScalarObject
+#    define PyInt16ArrType_Type PyShortArrType_Type
+#    define PyUInt16ScalarObject PyUShortScalarObject
+#    define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+        typedef short npy_int32;
+        typedef unsigned short npy_uint32;
+        typedef unsigned short npy_ucs4;
+#    define PyInt32ScalarObject PyShortScalarObject
+#    define PyInt32ArrType_Type PyShortArrType_Type
+#    define PyUInt32ScalarObject PyUShortScalarObject
+#    define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+        typedef short npy_int64;
+        typedef unsigned short npy_uint64;
+#    define PyInt64ScalarObject PyShortScalarObject
+#    define PyInt64ArrType_Type PyShortArrType_Type
+#    define PyUInt64ScalarObject PyUShortScalarObject
+#    define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#endif
+#elif NPY_BITSOF_SHORT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+        typedef short npy_int128;
+        typedef unsigned short npy_uint128;
+#    define PyInt128ScalarObject PyShortScalarObject
+#    define PyInt128ArrType_Type PyShortArrType_Type
+#    define PyUInt128ScalarObject PyUShortScalarObject
+#    define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_CHAR == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+        typedef signed char npy_int8;
+        typedef unsigned char npy_uint8;
+#    define PyInt8ScalarObject PyByteScalarObject
+#    define PyInt8ArrType_Type PyByteArrType_Type
+#    define PyUInt8ScalarObject PyUByteScalarObject
+#    define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+        typedef signed char npy_int16;
+        typedef unsigned char npy_uint16;
+#    define PyInt16ScalarObject PyByteScalarObject
+#    define PyInt16ArrType_Type PyByteArrType_Type
+#    define PyUInt16ScalarObject PyUByteScalarObject
+#    define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+        typedef signed char npy_int32;
+        typedef unsigned char npy_uint32;
+        typedef unsigned char npy_ucs4;
+#    define PyInt32ScalarObject PyByteScalarObject
+#    define PyInt32ArrType_Type PyByteArrType_Type
+#    define PyUInt32ScalarObject PyUByteScalarObject
+#    define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+        typedef signed char npy_int64;
+        typedef unsigned char npy_uint64;
+#    define PyInt64ScalarObject PyByteScalarObject
+#    define PyInt64ArrType_Type PyByteArrType_Type
+#    define PyUInt64ScalarObject PyUByteScalarObject
+#    define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#endif
+#elif NPY_BITSOF_CHAR == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+        typedef signed char npy_int128;
+        typedef unsigned char npy_uint128;
+#    define PyInt128ScalarObject PyByteScalarObject
+#    define PyInt128ArrType_Type PyByteArrType_Type
+#    define PyUInt128ScalarObject PyUByteScalarObject
+#    define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_DOUBLE == 16
+#ifndef NPY_FLOAT16
+#define NPY_FLOAT16 NPY_DOUBLE
+#define NPY_COMPLEX32 NPY_CDOUBLE
+        typedef  double npy_float16;
+        typedef npy_cdouble npy_complex32;
+#    define PyFloat16ScalarObject PyDoubleScalarObject
+#    define PyComplex32ScalarObject PyCDoubleScalarObject
+#    define PyFloat16ArrType_Type PyDoubleArrType_Type
+#    define PyComplex32ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT16_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX32_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+        typedef double npy_float32;
+        typedef npy_cdouble npy_complex64;
+#    define PyFloat32ScalarObject PyDoubleScalarObject
+#    define PyComplex64ScalarObject PyCDoubleScalarObject
+#    define PyFloat32ArrType_Type PyDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+        typedef double npy_float64;
+        typedef npy_cdouble npy_complex128;
+#    define PyFloat64ScalarObject PyDoubleScalarObject
+#    define PyComplex128ScalarObject PyCDoubleScalarObject
+#    define PyFloat64ArrType_Type PyDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+        typedef double npy_float80;
+        typedef npy_cdouble npy_complex160;
+#    define PyFloat80ScalarObject PyDoubleScalarObject
+#    define PyComplex160ScalarObject PyCDoubleScalarObject
+#    define PyFloat80ArrType_Type PyDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+        typedef double npy_float96;
+        typedef npy_cdouble npy_complex192;
+#    define PyFloat96ScalarObject PyDoubleScalarObject
+#    define PyComplex192ScalarObject PyCDoubleScalarObject
+#    define PyFloat96ArrType_Type PyDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+        typedef double npy_float128;
+        typedef npy_cdouble npy_complex256;
+#    define PyFloat128ScalarObject PyDoubleScalarObject
+#    define PyComplex256ScalarObject PyCDoubleScalarObject
+#    define PyFloat128ArrType_Type PyDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#endif
+#endif
+
+
+
+#if NPY_BITSOF_FLOAT == 16
+#ifndef NPY_FLOAT16
+#define NPY_FLOAT16 NPY_FLOAT
+#define NPY_COMPLEX32 NPY_CFLOAT
+        typedef float npy_float16;
+        typedef npy_cfloat npy_complex32;
+#    define PyFloat16ScalarObject PyFloatScalarObject
+#    define PyComplex32ScalarObject PyCFloatScalarObject
+#    define PyFloat16ArrType_Type PyFloatArrType_Type
+#    define PyComplex32ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT16_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX32_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+        typedef float npy_float32;
+        typedef npy_cfloat npy_complex64;
+#    define PyFloat32ScalarObject PyFloatScalarObject
+#    define PyComplex64ScalarObject PyCFloatScalarObject
+#    define PyFloat32ArrType_Type PyFloatArrType_Type
+#    define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+        typedef float npy_float64;
+        typedef npy_cfloat npy_complex128;
+#    define PyFloat64ScalarObject PyFloatScalarObject
+#    define PyComplex128ScalarObject PyCFloatScalarObject
+#    define PyFloat64ArrType_Type PyFloatArrType_Type
+#    define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+        typedef float npy_float80;
+        typedef npy_cfloat npy_complex160;
+#    define PyFloat80ScalarObject PyFloatScalarObject
+#    define PyComplex160ScalarObject PyCFloatScalarObject
+#    define PyFloat80ArrType_Type PyFloatArrType_Type
+#    define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+        typedef float npy_float96;
+        typedef npy_cfloat npy_complex192;
+#    define PyFloat96ScalarObject PyFloatScalarObject
+#    define PyComplex192ScalarObject PyCFloatScalarObject
+#    define PyFloat96ArrType_Type PyFloatArrType_Type
+#    define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#endif
+#elif NPY_BITSOF_FLOAT == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+        typedef float npy_float128;
+        typedef npy_cfloat npy_complex256;
+#    define PyFloat128ScalarObject PyFloatScalarObject
+#    define PyComplex256ScalarObject PyCFloatScalarObject
+#    define PyFloat128ArrType_Type PyFloatArrType_Type
+#    define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+#endif
+#endif
+
+
+#if NPY_BITSOF_LONGDOUBLE == 16
+#ifndef NPY_FLOAT16
+#define NPY_FLOAT16 NPY_LONGDOUBLE
+#define NPY_COMPLEX32 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float16;
+        typedef npy_clongdouble npy_complex32;
+#    define PyFloat16ScalarObject PyLongDoubleScalarObject
+#    define PyComplex32ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat16ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex32ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT16_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX32_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float32;
+        typedef npy_clongdouble npy_complex64;
+#    define PyFloat32ScalarObject PyLongDoubleScalarObject
+#    define PyComplex64ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float64;
+        typedef npy_clongdouble npy_complex128;
+#    define PyFloat64ScalarObject PyLongDoubleScalarObject
+#    define PyComplex128ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float80;
+        typedef npy_clongdouble npy_complex160;
+#    define PyFloat80ScalarObject PyLongDoubleScalarObject
+#    define PyComplex160ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float96;
+        typedef npy_clongdouble npy_complex192;
+#    define PyFloat96ScalarObject PyLongDoubleScalarObject
+#    define PyComplex192ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float128;
+        typedef npy_clongdouble npy_complex256;
+#    define PyFloat128ScalarObject PyLongDoubleScalarObject
+#    define PyComplex256ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#endif
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+        typedef npy_longdouble npy_float256;
+        typedef npy_clongdouble npy_complex512;
+#    define PyFloat256ScalarObject PyLongDoubleScalarObject
+#    define PyComplex512ScalarObject PyCLongDoubleScalarObject
+#    define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+#    define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+#endif
+
+/* End of typedefs for numarray style bit-width names */
+
+/* This is to typedef npy_intp to the appropriate pointer size for this
+ * platform.  Py_intptr_t, Py_uintptr_t are defined in pyport.h. */
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+#define NPY_SIZEOF_INTP SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP SIZEOF_PY_INTPTR_T
+
+#ifdef constchar
+#undef constchar
+#endif
+
+#if (PY_VERSION_HEX < 0x02050000)
+  #ifndef PY_SSIZE_T_MIN
+    typedef int Py_ssize_t;
+    #define PY_SSIZE_T_MAX INT_MAX
+    #define PY_SSIZE_T_MIN INT_MIN
+  #endif
+#define NPY_SSIZE_T_PYFMT "i"
+#undef PyIndex_Check
+#define constchar const char
+#define PyIndex_Check(op) 0
+#else
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+#endif
+
+#if SIZEOF_PY_INTPTR_T == SIZEOF_INT
+        #define NPY_INTP NPY_INT
+        #define NPY_UINTP NPY_UINT
+        #define PyIntpArrType_Type PyIntArrType_Type
+        #define PyUIntpArrType_Type PyUIntArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_INT
+        #define NPY_MIN_INTP NPY_MIN_INT
+        #define NPY_MAX_UINTP NPY_MAX_UINT
+        #define NPY_INTP_FMT "d"
+#elif SIZEOF_PY_INTPTR_T == SIZEOF_LONG
+        #define NPY_INTP NPY_LONG
+        #define NPY_UINTP NPY_ULONG
+        #define PyIntpArrType_Type PyLongArrType_Type
+        #define PyUIntpArrType_Type PyULongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONG
+        #define NPY_MIN_INTP MIN_LONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONG
+        #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (SIZEOF_PY_INTPTR_T == SIZEOF_LONG_LONG)
+        #define NPY_INTP NPY_LONGLONG
+        #define NPY_UINTP NPY_ULONGLONG
+        #define PyIntpArrType_Type PyLongLongArrType_Type
+        #define PyUIntpArrType_Type PyULongLongArrType_Type
+        #define NPY_MAX_INTP NPY_MAX_LONGLONG
+        #define NPY_MIN_INTP NPY_MIN_LONGLONG
+        #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+        #define NPY_INTP_FMT "Ld"
+#endif
+
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+
+  /* Macros to define how array, and dimension/strides data is
+     allocated.
+  */
+
+  /* Data buffer */
+#define PyDataMem_NEW(size) ((char *)malloc(size))
+#define PyDataMem_FREE(ptr)  free(ptr)
+#define PyDataMem_RENEW(ptr,size) ((char *)realloc(ptr,size))
+
+#define NPY_USE_PYMEM 1
+
+#if NPY_USE_PYMEM == 1
+#define PyArray_malloc PyMem_Malloc
+#define PyArray_free PyMem_Free
+#define PyArray_realloc PyMem_Realloc
+#else
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+#endif
+
+/* Dimensions and strides */
+#define PyDimMem_NEW(size)                                         \
+    ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+
+#define PyDimMem_RENEW(ptr,size)                                   \
+        ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+
+/* forward declaration */
+struct _PyArray_Descr;
+
+  /* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+                                     npy_intp, int, void *);
+
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+
+
+  /* These assume aligned and notswapped data -- a buffer will be
+      used before or contiguous data will be obtained
+  */
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+                               npy_intp, void *);
+
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+                                       void *);
+
+/* XXX the ignore argument should be removed next time the API version
+   is bumped. It used to be the separator. */
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+                               char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+                                  struct _PyArray_Descr *);
+
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+
+typedef int (PyArray_ScalarKindFunc)(void *);
+
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+
+typedef struct {
+        npy_intp *ptr;
+        int len;
+} PyArray_Dims;
+
+typedef struct {
+        /* Functions to cast to all other standard types*/
+        /* Can have some NULL entries */
+        PyArray_VectorUnaryFunc *cast[NPY_NTYPES];
+
+        /* The next four functions *cannot* be NULL */
+
+        /* Functions to get and set items with standard
+           Python types -- not array scalars */
+        PyArray_GetItemFunc *getitem;
+        PyArray_SetItemFunc *setitem;
+
+        /* Copy and/or swap data.  Memory areas may not overlap */
+        /*  Use memmove first if they might */
+        PyArray_CopySwapNFunc *copyswapn;
+        PyArray_CopySwapFunc *copyswap;
+
+        /* Function to compare items */
+        /* Can be NULL
+         */
+        PyArray_CompareFunc *compare;
+
+        /* Function to select largest
+           Can be NULL
+        */
+        PyArray_ArgFunc *argmax;
+
+        /* Function to compute dot product */
+        /* Can be NULL */
+        PyArray_DotFunc *dotfunc;
+
+        /* Function to scan an ASCII file and
+           place a single value plus possible separator
+           Can be NULL
+        */
+        PyArray_ScanFunc *scanfunc;
+
+        /* Function to read a single value from a string */
+        /* and adjust the pointer; Can be NULL */
+        PyArray_FromStrFunc *fromstr;
+
+        /* Function to determine if data is zero or not */
+        /* If NULL a default version is */
+        /* used at Registration time. */
+        PyArray_NonzeroFunc *nonzero;
+
+        /* Used for arange. Can be NULL.*/
+        PyArray_FillFunc *fill;
+
+        /* Function to fill arrays with scalar values
+         Can be NULL*/
+        PyArray_FillWithScalarFunc *fillwithscalar;
+
+        /* Sorting functions; Can be NULL*/
+        PyArray_SortFunc *sort[NPY_NSORTS];
+        PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+
+        /* Dictionary of additional casting functions
+           PyArray_VectorUnaryFuncs
+           which can be populated to support casting
+           to other registered types. Can be NULL*/
+        PyObject *castdict;
+
+        /* Functions useful for generalizing
+           the casting rules.  Can be NULL;
+        */
+        PyArray_ScalarKindFunc *scalarkind;
+        int **cancastscalarkindto;
+        int *cancastto;
+
+        PyArray_FastClipFunc *fastclip;
+} PyArray_ArrFuncs;
+
+#define NPY_ITEM_REFCOUNT   0x01  /* The item must be reference counted
+                                     when it is inserted or extracted. */
+#define NPY_ITEM_HASOBJECT  0x01  /* Same as needing REFCOUNT */
+
+#define NPY_LIST_PICKLE     0x02  /* Convert to list for pickling */
+#define NPY_ITEM_IS_POINTER 0x04  /* The item is a POINTER  */
+
+#define NPY_NEEDS_INIT      0x08  /* memory needs to be initialized
+                                     for this data-type */
+
+#define NPY_NEEDS_PYAPI     0x10  /* operations need Python C-API
+                                     so don't give-up thread. */
+
+#define NPY_USE_GETITEM     0x20  /* Use f.getitem when extracting elements
+                                     of this data-type */
+
+#define NPY_USE_SETITEM     0x40  /* Use f.setitem when setting creating
+                                     0-d array from this data-type.
+                                  */
+
+/* These are inherited for global data-type if any data-types in the field
+   have them */
+#define NPY_FROM_FIELDS    (NPY_NEEDS_INIT | NPY_LIST_PICKLE |             \
+                            NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM |       \
+                                NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+                                NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+
+#define PyDataType_FLAGCHK(dtype, flag)                                   \
+        (((dtype)->hasobject & (flag)) == (flag))
+
+#define PyDataType_REFCHK(dtype)                                          \
+        PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+
+/* Change dtype hasobject to 32-bit in 1.1 and change its name */
+typedef struct _PyArray_Descr {
+        PyObject_HEAD
+        PyTypeObject *typeobj;  /* the type object representing an
+                                   instance of this type -- should not
+                                   be two type_numbers with the same type
+                                   object. */
+        char kind;              /* kind for this type */
+        char type;              /* unique-character representing this type */
+        char byteorder;         /* '>' (big), '<' (little), '|'
+                                   (not-applicable), or '=' (native). */
+        char hasobject;         /* non-zero if it has object arrays
+                                   in fields */
+        int type_num;          /* number representing this type */
+        int elsize;             /* element size for this type */
+        int alignment;          /* alignment needed for this type */
+        struct _arr_descr                                       \
+        *subarray;              /* Non-NULL if this type is
+                                   is an array (C-contiguous)
+                                   of some other type
+                                */
+        PyObject *fields;       /* The fields dictionary for this type */
+                                /* For statically defined descr this
+                                   is always Py_None */
+
+        PyObject *names;        /* An ordered tuple of field names or NULL
+                                   if no fields are defined */
+
+        PyArray_ArrFuncs *f;     /* a table of functions specific for each
+                                    basic data descriptor */
+} PyArray_Descr;
+
+typedef struct _arr_descr {
+        PyArray_Descr *base;
+        PyObject *shape;       /* a tuple */
+} PyArray_ArrayDescr;
+
+/*
+  The main array object structure. It is recommended to use the macros
+  defined below (PyArray_DATA and friends) access fields here, instead
+  of the members themselves.
+ */
+
+typedef struct PyArrayObject {
+        PyObject_HEAD
+        char *data;             /* pointer to raw data buffer */
+        int nd;                 /* number of dimensions, also called ndim */
+        npy_intp *dimensions;       /* size in each dimension */
+        npy_intp *strides;          /* bytes to jump to get to the
+                                   next element in each dimension */
+        PyObject *base;         /* This object should be decref'd
+                                   upon deletion of array */
+                                /* For views it points to the original array */
+                                /* For creation from buffer object it points
+                                   to an object that shold be decref'd on
+                                   deletion */
+                                /* For UPDATEIFCOPY flag this is an array
+                                   to-be-updated upon deletion of this one */
+        PyArray_Descr *descr;   /* Pointer to type structure */
+        int flags;              /* Flags describing array -- see below*/
+        PyObject *weakreflist;  /* For weakreferences */
+} PyArrayObject;
+
+#define NPY_AO PyArrayObject
+
+#define fortran fortran_        /* For some compilers */
+
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+        PyObject_HEAD
+        PyObject *arr;
+        int flags;
+} PyArrayFlagsObject;
+
+/* Mirrors buffer object to ptr */
+
+typedef struct {
+        PyObject_HEAD
+        PyObject *base;
+        void *ptr;
+        npy_intp len;
+        int flags;
+} PyArray_Chunk;
+
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+
+/* Means c-style contiguous (last index varies the fastest). The
+   data elements right after each other. */
+#define NPY_CONTIGUOUS    0x0001
+/* set if array is a contiguous Fortran array: the first index
+   varies the fastest in memory (strides array is reverse of
+   C-contiguous array)*/
+#define NPY_FORTRAN       0x0002
+
+#define NPY_C_CONTIGUOUS NPY_CONTIGUOUS
+#define NPY_F_CONTIGUOUS NPY_FORTRAN
+
+/*
+  Note: all 0-d arrays are CONTIGUOUS and FORTRAN contiguous. If a
+   1-d array is CONTIGUOUS it is also FORTRAN contiguous
+*/
+
+/* If set, the array owns the data: it will be free'd when the array
+   is deleted. */
+#define NPY_OWNDATA       0x0004
+
+/* An array never has the next four set; they're only used as parameter
+   flags to the the various FromAny functions */
+
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_FORCECAST     0x0010
+
+/* Always copy the array. Returned arrays are always CONTIGUOUS, ALIGNED,
+   and WRITEABLE. */
+#define NPY_ENSURECOPY    0x0020
+
+/* Make sure the returned array is an ndarray or a bigndarray */
+#define NPY_ENSUREARRAY   0x0040
+
+/* Make sure that the strides are in units of the element size
+   Needed for some operations with record-arrays.
+*/
+#define NPY_ELEMENTSTRIDES 0x0080
+
+/* Array data is aligned on the appropiate memory address for the
+   type stored according to how the compiler would align things
+   (e.g., an array of integers (4 bytes each) starts on
+   a memory address that's a multiple of 4) */
+#define NPY_ALIGNED       0x0100
+/* Array data has the native endianness */
+#define NPY_NOTSWAPPED    0x0200
+/* Array data is writeable */
+#define NPY_WRITEABLE     0x0400
+/* If this flag is set, then base contains a pointer to an array of
+   the same size that should be updated with the current contents of
+   this array when this array is deallocated
+*/
+#define NPY_UPDATEIFCOPY  0x1000
+
+/* This flag is for the array interface */
+#define NPY_ARR_HAS_DESCR  0x0800
+
+
+#define NPY_BEHAVED (NPY_ALIGNED | NPY_WRITEABLE)
+#define NPY_BEHAVED_NS (NPY_ALIGNED | NPY_WRITEABLE | NPY_NOTSWAPPED)
+#define NPY_CARRAY (NPY_CONTIGUOUS | NPY_BEHAVED)
+#define NPY_CARRAY_RO (NPY_CONTIGUOUS | NPY_ALIGNED)
+#define NPY_FARRAY (NPY_FORTRAN | NPY_BEHAVED)
+#define NPY_FARRAY_RO (NPY_FORTRAN | NPY_ALIGNED)
+#define NPY_DEFAULT NPY_CARRAY
+#define NPY_IN_ARRAY NPY_CARRAY_RO
+#define NPY_OUT_ARRAY NPY_CARRAY
+#define NPY_INOUT_ARRAY (NPY_CARRAY | NPY_UPDATEIFCOPY)
+#define NPY_IN_FARRAY NPY_FARRAY_RO
+#define NPY_OUT_FARRAY NPY_FARRAY
+#define NPY_INOUT_FARRAY (NPY_FARRAY | NPY_UPDATEIFCOPY)
+
+#define NPY_UPDATE_ALL (NPY_CONTIGUOUS | NPY_FORTRAN | NPY_ALIGNED)
+
+
+/* Size of internal buffers used for alignment */
+/* Make BUFSIZE a multiple of sizeof(cdouble) -- ususally 16 */
+/* So that ufunc buffers are aligned */
+#define NPY_MIN_BUFSIZE ((int)sizeof(cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(cdouble))*1000000)
+#define NPY_BUFSIZE 10000
+/* #define NPY_BUFSIZE 80*/
+
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+
+/*
+ * C API:  consists of Macros and functions.  The MACROS are defined here.
+ */
+
+
+#define PyArray_CHKFLAGS(m, FLAGS)                              \
+        ((((PyArrayObject *)(m))->flags & (FLAGS)) == (FLAGS))
+
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ALIGNED)
+
+
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#define NPY_BEGIN_THREADS _save = PyEval_SaveThread();
+#define NPY_END_THREADS   if (_save) PyEval_RestoreThread(_save);
+
+#define NPY_BEGIN_THREADS_DESCR(dtype)                          \
+        if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI)))      \
+                NPY_BEGIN_THREADS
+
+#define NPY_END_THREADS_DESCR(dtype)                            \
+        if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI)))      \
+                NPY_END_THREADS
+
+#define NPY_ALLOW_C_API_DEF  PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API      __save__ = PyGILState_Ensure();
+#define NPY_DISABLE_C_API    PyGILState_Release(__save__);
+#else
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS_DEF
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+#endif
+
+typedef struct {
+        PyObject_HEAD
+        int               nd_m1;            /* number of dimensions - 1 */
+        npy_intp          index, size;
+        npy_intp          coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+        npy_intp          dims_m1[NPY_MAXDIMS];    /* ao->dimensions - 1 */
+        npy_intp          strides[NPY_MAXDIMS];    /* ao->strides or fake */
+        npy_intp          backstrides[NPY_MAXDIMS];/* how far to jump back */
+        npy_intp          factors[NPY_MAXDIMS];     /* shape factors */
+        PyArrayObject     *ao;
+        char              *dataptr;        /* pointer to current item*/
+        npy_bool          contiguous;
+} PyArrayIterObject;
+
+
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
+
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) {                                        \
+        _PyAIT(it)->index = 0;                                          \
+        _PyAIT(it)->dataptr = _PyAIT(it)->ao->data;                     \
+        memset(_PyAIT(it)->coordinates, 0,                              \
+	       (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp));                 \
+}
+
+#define _PyArray_ITER_NEXT1(it) {                                       \
+        (it)->dataptr += _PyAIT(it)->strides[0];                        \
+        (it)->coordinates[0]++;                                         \
+}
+
+#define _PyArray_ITER_NEXT2(it) {                                       \
+        if ((it)->coordinates[1] < (it)->dims_m1[1]) {                  \
+                (it)->coordinates[1]++;                                 \
+                (it)->dataptr += (it)->strides[1];                      \
+        }                                                               \
+        else {                                                          \
+                (it)->coordinates[1] = 0;                               \
+                (it)->coordinates[0]++;                                 \
+                (it)->dataptr += (it)->strides[0] -                     \
+                        (it)->backstrides[1];                           \
+        }                                                               \
+}
+
+#define _PyArray_ITER_NEXT3(it) {                                       \
+        if ((it)->coordinates[2] < (it)->dims_m1[2]) {                  \
+                (it)->coordinates[2]++;                                 \
+                (it)->dataptr += (it)->strides[2];                      \
+        }                                                               \
+        else {                                                          \
+                (it)->coordinates[2] = 0;                               \
+                (it)->dataptr -= (it)->backstrides[2];                  \
+                if ((it)->coordinates[1] < (it)->dims_m1[1]) {          \
+                        (it)->coordinates[1]++;                         \
+                        (it)->dataptr += (it)->strides[1];              \
+                }                                                       \
+                else {                                                  \
+                        (it)->coordinates[1] = 0;                       \
+                        (it)->coordinates[0]++;                         \
+                        (it)->dataptr += (it)->strides[0] -             \
+                                (it)->backstrides[1];                   \
+                }                                                       \
+        }                                                               \
+}
+
+#define PyArray_ITER_NEXT(it) {                                            \
+        _PyAIT(it)->index++;                                               \
+        if (_PyAIT(it)->nd_m1 == 0) {                                      \
+                _PyArray_ITER_NEXT1(_PyAIT(it));                           \
+        }                                                                  \
+        else if (_PyAIT(it)->contiguous)                                   \
+	        _PyAIT(it)->dataptr += _PyAIT(it)->ao->descr->elsize;      \
+        else if (_PyAIT(it)->nd_m1 == 1) {                                 \
+                _PyArray_ITER_NEXT2(_PyAIT(it));                           \
+        }                                                                  \
+        else {                                                             \
+                int __npy_i;                                               \
+                for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+                        if (_PyAIT(it)->coordinates[__npy_i] <             \
+                            _PyAIT(it)->dims_m1[__npy_i]) {                \
+                                _PyAIT(it)->coordinates[__npy_i]++;        \
+                                _PyAIT(it)->dataptr +=                     \
+                                        _PyAIT(it)->strides[__npy_i];      \
+                                break;                                     \
+                        }                                                  \
+                        else {                                             \
+                                _PyAIT(it)->coordinates[__npy_i] = 0;      \
+                                _PyAIT(it)->dataptr -=                     \
+                                        _PyAIT(it)->backstrides[__npy_i];  \
+                        }                                                  \
+                }                                                          \
+        }                                                                  \
+}
+
+#define PyArray_ITER_GOTO(it, destination) {                            \
+        int __npy_i;                                                    \
+        _PyAIT(it)->index = 0;                                          \
+        _PyAIT(it)->dataptr = _PyAIT(it)->ao->data;                     \
+        for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) {      \
+                if (destination[__npy_i] < 0) {                         \
+                        destination[__npy_i] +=                         \
+                                _PyAIT(it)->dims_m1[__npy_i]+1;         \
+                }                                                       \
+                _PyAIT(it)->dataptr += destination[__npy_i] *           \
+                        _PyAIT(it)->strides[__npy_i];                   \
+                _PyAIT(it)->coordinates[__npy_i] =                      \
+                        destination[__npy_i];                           \
+                _PyAIT(it)->index += destination[__npy_i] *             \
+                        ( __npy_i==_PyAIT(it)->nd_m1 ? 1 :              \
+                          _PyAIT(it)->dims_m1[__npy_i+1]+1) ;           \
+        }                                                               \
+}
+
+#define PyArray_ITER_GOTO1D(it, ind) {                                     \
+        int __npy_i;                                                       \
+        npy_intp __npy_ind = (npy_intp) (ind);                             \
+        if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size;                  \
+        _PyAIT(it)->index = __npy_ind;                                     \
+        if (_PyAIT(it)->nd_m1 == 0) {                                      \
+                _PyAIT(it)->dataptr = _PyAIT(it)->ao->data +               \
+                        __npy_ind * _PyAIT(it)->strides[0];                \
+        }                                                                  \
+        else if (_PyAIT(it)->contiguous)                                   \
+                _PyAIT(it)->dataptr = _PyAIT(it)->ao->data +               \
+                        __npy_ind * _PyAIT(it)->ao->descr->elsize;         \
+        else {                                                             \
+                _PyAIT(it)->dataptr = _PyAIT(it)->ao->data;                \
+                for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1;              \
+                     __npy_i++) {                                          \
+                        _PyAIT(it)->dataptr +=                             \
+                                (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+                                * _PyAIT(it)->strides[__npy_i];            \
+                        __npy_ind %= _PyAIT(it)->factors[__npy_i];         \
+                }                                                          \
+        }                                                                  \
+}
+
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+
+
+/*
+   Any object passed to PyArray_Broadcast must be binary compatible with
+   this structure.
+*/
+
+typedef struct {
+        PyObject_HEAD
+        int                  numiter;                 /* number of iters */
+        npy_intp             size;                    /* broadcasted size */
+        npy_intp             index;                   /* current index */
+        int                  nd;                      /* number of dims */
+        npy_intp             dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject    *iters[NPY_MAXARGS];     /* iterators */
+} PyArrayMultiIterObject;
+
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) {                                      \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index = 0;                                             \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;  __npy_mi++) {    \
+                PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]);           \
+        }                                                                     \
+}
+
+#define PyArray_MultiIter_NEXT(multi) {                                       \
+        int __npy_mi;                                                         \
+        _PyMIT(multi)->index++;                                               \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter;   __npy_mi++) {   \
+                PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]);            \
+        }                                                                     \
+}
+
+#define PyArray_MultiIter_GOTO(multi, dest) {                               \
+        int __npy_mi;                                                       \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {   \
+                PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest);    \
+        }                                                                   \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;              \
+}
+
+#define PyArray_MultiIter_GOTO1D(multi, ind) {                             \
+        int __npy_mi;                                                      \
+        for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) {  \
+                PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind);  \
+        }                                                                  \
+        _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index;             \
+}
+
+#define PyArray_MultiIter_DATA(multi, i)                \
+        ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+
+#define PyArray_MultiIter_NEXTi(multi, i)               \
+        PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+
+#define PyArray_MultiIter_NOTDONE(multi)                \
+        (_PyMIT(multi)->index < _PyMIT(multi)->size)
+
+/* Store the information needed for fancy-indexing over an array */
+
+typedef struct {
+        PyObject_HEAD
+        /* Multi-iterator portion --- needs to be present in this order to
+           work with PyArray_Broadcast */
+
+        int                   numiter;                 /* number of index-array
+                                                          iterators */
+        npy_intp              size;                    /* size of broadcasted
+                                                          result */
+        npy_intp              index;                   /* current index */
+        int                   nd;                      /* number of dims */
+        npy_intp              dimensions[NPY_MAXDIMS]; /* dimensions */
+        PyArrayIterObject     *iters[NPY_MAXDIMS];     /* index object
+                                                          iterators */
+        PyArrayIterObject     *ait;                    /* flat Iterator for
+                                                          underlying array */
+
+        /* flat iterator for subspace (when numiter < nd) */
+        PyArrayIterObject     *subspace;
+
+        /* if subspace iteration, then this is the array of
+           axes in the underlying array represented by the
+           index objects */
+        int                   iteraxes[NPY_MAXDIMS];
+        /* if subspace iteration, the these are the coordinates
+           to the start of the subspace.
+        */
+        npy_intp              bscoord[NPY_MAXDIMS];
+
+        PyObject              *indexobj;               /* creating obj */
+        int                   consec;
+        char                  *dataptr;
+
+} PyArrayMapIterObject;
+
+/* The default array type
+ */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+/* All sorts of useful ways to look into a PyArrayObject.
+   These are the recommended over casting to PyArrayObject and accessing
+   the members directly.
+ */
+
+#define PyArray_NDIM(obj) (((PyArrayObject *)(obj))->nd)
+#define PyArray_ISONESEGMENT(m) (PyArray_NDIM(m) == 0 ||                      \
+                                 PyArray_CHKFLAGS(m, NPY_CONTIGUOUS) ||       \
+                                 PyArray_CHKFLAGS(m, NPY_FORTRAN))
+
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_FORTRAN) &&             \
+                             (PyArray_NDIM(m) > 1))
+
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_FORTRAN) ?            \
+                              NPY_FORTRAN : 0))
+
+#define FORTRAN_IF PyArray_FORTRAN_IF
+#define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data))
+#define PyArray_BYTES(obj) (((PyArrayObject *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject *)(obj))->flags)
+#define PyArray_ITEMSIZE(obj) (((PyArrayObject *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) (((PyArrayObject *)(obj))->descr->type_num)
+
+#define PyArray_GETITEM(obj,itemptr)                                          \
+        ((PyArrayObject *)(obj))->descr->f->getitem((char *)(itemptr),        \
+                                                 (PyArrayObject *)(obj));
+
+#define PyArray_SETITEM(obj,itemptr,v)                                        \
+        ((PyArrayObject *)(obj))->descr->f->setitem((PyObject *)(v),          \
+                                                    (char *)(itemptr),        \
+                                                    (PyArrayObject *)(obj));
+
+
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) ||   \
+                                 ((type) == NPY_USHORT) ||     \
+                                 ((type) == NPY_UINT) ||       \
+                                 ((type) == NPY_ULONG) ||      \
+                                 ((type) == NPY_ULONGLONG))
+
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) ||      \
+                               ((type) == NPY_SHORT) ||        \
+                               ((type) == NPY_INT) ||          \
+                               ((type) == NPY_LONG) ||         \
+                               ((type) == NPY_LONGLONG))
+
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) &&     \
+                                ((type) <= NPY_ULONGLONG))
+
+#define PyTypeNum_ISFLOAT(type) (((type) >= NPY_FLOAT) &&      \
+                              ((type) <= NPY_LONGDOUBLE))
+
+#define PyTypeNum_ISNUMBER(type) ((type) <= NPY_CLONGDOUBLE)
+
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) ||    \
+                                  ((type) == NPY_UNICODE))
+
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) &&   \
+                                ((type) <= NPY_CLONGDOUBLE))
+
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) ||      \
+                                  ((type) == NPY_DOUBLE) ||    \
+                                  ((type) == NPY_CDOUBLE) ||   \
+                                  ((type) == NPY_BOOL) ||      \
+                                  ((type) == NPY_OBJECT ))
+
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) &&  \
+                                    ((type) <=NPY_VOID))
+
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+                                   ((type) < NPY_USERDEF+     \
+                                    NPY_NUMUSERTYPES))
+
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) ||  \
+                                    PyTypeNum_ISUSERDEF(type))
+
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+
+
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(_PyADt(obj))
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+
+#ifdef WORDS_BIGENDIAN
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#else
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#endif
+
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) &&       \
+                                    PyArray_ISNOTSWAPPED(m))
+
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ALIGNED)
+
+
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+
+
+/* This is the form of the struct that's returned pointed by the
+   PyCObject attribute of an array __array_struct__. See
+   http://numpy.scipy.org/array_interface.shtml for the full
+   documentation. */
+typedef struct {
+    int two;              /* contains the integer 2 as a sanity check */
+    int nd;               /* number of dimensions */
+    char typekind;        /* kind in array --- character code of typestr */
+    int itemsize;         /* size of each element */
+    int flags;            /* how should be data interpreted. Valid
+                             flags are CONTIGUOUS (1), FORTRAN (2),
+                             ALIGNED (0x100), NOTSWAPPED (0x200), and
+                             WRITEABLE (0x400).
+                             ARR_HAS_DESCR (0x800) states that arrdescr
+                                field is present in structure */
+    npy_intp *shape;          /* A length-nd array of shape information */
+    npy_intp *strides;        /* A length-nd array of stride information */
+    void *data;           /* A pointer to the first element of the array */
+    PyObject *descr;      /* A list of fields or NULL (ignored if flags
+                                does not have ARR_HAS_DESCR flag set) */
+} PyArrayInterface;
+
+
+/* Includes the "function" C-API -- these are all stored in a
+   list of pointers --- one for each file
+   The two lists are concatenated into one in multiarray.
+
+   They are available as import_array()
+*/
+
+#include "__multiarray_api.h"
+
+
+/* C-API that requries previous API to be defined */
+
+#define PyArray_DescrCheck(op) ((op)->ob_type == &PyArrayDescr_Type)
+
+#define PyArray_Check(op) ((op)->ob_type == &PyArray_Type ||                  \
+                           PyObject_TypeCheck(op, &PyArray_Type))
+
+#define PyArray_CheckExact(op) ((op)->ob_type == &PyArray_Type)
+
+#define PyArray_HasArrayInterfaceType(op, type, context, out)                 \
+        ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) ||    \
+         (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) ||          \
+         (((out)=PyArray_FromArrayAttr(op, type, context)) !=                 \
+          Py_NotImplemented))
+
+#define PyArray_HasArrayInterface(op, out)                                    \
+        PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && (PyArray_NDIM(op) == 0))
+
+#define PyArray_IsScalar(obj, cls)                                            \
+        (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) ||               \
+                                PyArray_IsZeroDim(m))
+
+#define PyArray_IsPythonNumber(obj)                                           \
+        (PyInt_Check(obj) || PyFloat_Check(obj) || PyComplex_Check(obj) ||    \
+         PyLong_Check(obj) || PyBool_Check(obj))
+
+#define PyArray_IsPythonScalar(obj)                                           \
+        (PyArray_IsPythonNumber(obj) || PyString_Check(obj) ||                \
+         PyUnicode_Check(obj))
+
+#define PyArray_IsAnyScalar(obj)                                              \
+        (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) ||           \
+                                     PyArray_CheckScalar(obj))
+
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ?                   \
+                                  Py_INCREF(m), (m) :                         \
+                                  (PyArrayObject *)(PyArray_Copy(m)))
+
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) &&   \
+                                  PyArray_CompareLists(PyArray_DIMS(a1),      \
+                                                       PyArray_DIMS(a2),      \
+                                                       PyArray_NDIM(a1)))
+
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags,   \
+                                                      NULL)
+
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m,                            \
+                                PyArray_DescrFromType(type), 0, 0, 0, NULL);
+
+#define PyArray_FROM_OTF(m, type, flags)                                      \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0,                 \
+                        (((flags) & NPY_ENSURECOPY) ?                         \
+                         ((flags) | NPY_DEFAULT) : (flags)), NULL)
+
+#define PyArray_FROMANY(m, type, min, max, flags)                             \
+        PyArray_FromAny(m, PyArray_DescrFromType(type), min, max,             \
+                        (((flags) & NPY_ENSURECOPY) ?                         \
+                         (flags) | NPY_DEFAULT : (flags)), NULL)
+
+#define PyArray_ZEROS(m, dims, type, fortran)                                 \
+        PyArray_Zeros(m, dims, PyArray_DescrFromType(type), fortran)
+
+#define PyArray_EMPTY(m, dims, type, fortran)                                 \
+        PyArray_Empty(m, dims, PyArray_DescrFromType(type), fortran)
+
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val,            \
+                                           PyArray_NBYTES(obj))
+
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2*SIZEOF_LONGDOUBLE)
+
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth)             \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth,           \
+                              max_depth, NPY_DEFAULT, NULL)
+
+#define PyArray_EquivArrTypes(a1, a2)                                         \
+        PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+
+#define PyArray_EquivByteorders(b1, b2)                                       \
+        (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+
+#define PyArray_SimpleNew(nd, dims, typenum)                                  \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data)                    \
+        PyArray_New(&PyArray_Type, nd, dims, typenum, NULL,                   \
+                    data, 0, NPY_CARRAY, NULL)
+
+#define PyArray_SimpleNewFromDescr(nd, dims, descr)                           \
+        PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims,                  \
+                             NULL, NULL, 0, NULL)
+
+#define PyArray_ToScalar(data, arr)                                           \
+        PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+
+
+/* These might be faster without the dereferencing of obj
+   going on inside -- of course an optimizing compiler should
+   inline the constants inside a for loop making it a moot point
+*/
+
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) +                \
+                                         (i)*PyArray_STRIDES(obj)[0]))
+
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) +             \
+                                            (i)*PyArray_STRIDES(obj)[0] +     \
+                                            (j)*PyArray_STRIDES(obj)[1]))
+
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) +          \
+                                            (i)*PyArray_STRIDES(obj)[0] +     \
+                                            (j)*PyArray_STRIDES(obj)[1] +     \
+                                            (k)*PyArray_STRIDES(obj)[2])) 
+
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) +       \
+                                            (i)*PyArray_STRIDES(obj)[0] +     \
+                                            (j)*PyArray_STRIDES(obj)[1] +     \
+                                            (k)*PyArray_STRIDES(obj)[2] +     \
+                                            (l)*PyArray_STRIDES(obj)[3]))
+
+#define PyArray_XDECREF_ERR(obj) \
+        if (obj && (PyArray_FLAGS(obj) & NPY_UPDATEIFCOPY)) {                 \
+                PyArray_FLAGS(PyArray_BASE(obj)) |= NPY_WRITEABLE;            \
+                PyArray_FLAGS(obj) &= ~NPY_UPDATEIFCOPY;                      \
+        }                                                                     \
+        Py_XDECREF(obj)
+
+#define PyArray_DESCR_REPLACE(descr) do {                                     \
+                PyArray_Descr *_new_;                                         \
+                _new_ = PyArray_DescrNew(descr);                              \
+                Py_XDECREF(descr);                                            \
+                descr = _new_;                                                \
+        } while(0)
+
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+
+#define PyArray_FromObject(op, type, min_depth, max_depth)                    \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth,           \
+                              max_depth, NPY_BEHAVED | NPY_ENSUREARRAY, NULL)
+
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth)          \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth,           \
+                              max_depth, NPY_DEFAULT | NPY_ENSUREARRAY, NULL)
+
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth)                \
+        PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth,           \
+                        max_depth, NPY_ENSURECOPY | NPY_DEFAULT |             \
+                        NPY_ENSUREARRAY, NULL)
+
+#define PyArray_Cast(mp, type_num)                                            \
+        PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+
+#define PyArray_Take(ap, items, axis)                                         \
+        PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+
+#define PyArray_Put(ap, items, values)                                        \
+        PyArray_PutTo(ap, items, values, NPY_RAISE)
+
+/* Compatibility with old Numeric stuff -- don't use in new code */
+
+#define PyArray_FromDimsAndData(nd, d, type, data)                            \
+        PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type),   \
+                                        data)
+
+#include "old_defines.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NPY_NDARRAYOBJECT_H */


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/ndarrayobject.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/noprefix.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/noprefix.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/noprefix.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,191 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+
+/* You can directly include noprefix.h as a backward
+compatibility measure*/
+#ifndef NPY_NO_PREFIX
+#include "ndarrayobject.h"
+#endif
+
+#define MAX_DIMS NPY_MAXDIMS
+
+#define longlong    npy_longlong
+#define ulonglong   npy_ulonglong
+#define Bool        npy_bool
+#define longdouble  npy_longdouble
+#define byte        npy_byte
+
+#ifndef _BSD_SOURCE
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#endif
+
+#define ubyte       npy_ubyte
+#define ushort      npy_ushort
+#define uint        npy_uint
+#define ulong       npy_ulong
+#define cfloat      npy_cfloat
+#define cdouble     npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8        npy_int8
+#define UInt8       npy_uint8
+#define Int16       npy_int16
+#define UInt16      npy_uint16
+#define Int32       npy_int32
+#define UInt32      npy_uint32
+#define Int64       npy_int64
+#define UInt64      npy_uint64
+#define Int128      npy_int128
+#define UInt128     npy_uint128
+#define Int256      npy_int256
+#define UInt256     npy_uint256
+#define Float16     npy_float16
+#define Complex32   npy_complex32
+#define Float32     npy_float32
+#define Complex64   npy_complex64
+#define Float64     npy_float64
+#define Complex128  npy_complex128
+#define Float80     npy_float80
+#define Complex160  npy_complex160
+#define Float96     npy_float96
+#define Complex192  npy_complex192
+#define Float128    npy_float128
+#define Complex256  npy_complex256
+#define intp        npy_intp
+#define uintp       npy_uintp
+
+#define SIZEOF_INTP NPY_SIZEOF_INTP
+#define SIZEOF_UINTP NPY_SIZEOF_UINTP
+
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX(x)
+
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT   NPY_MAX_INT
+#define MIN_INT   NPY_MIN_INT
+#define MAX_UINT  NPY_MAX_UINT
+#define MAX_LONG  NPY_MAX_LONG
+#define MIN_LONG  NPY_MIN_LONG
+#define MAX_ULONG  NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+
+#define SIZEOF_LONGDOUBLE NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_LONGLONG   NPY_SIZEOF_LONGLONG
+#define BITSOF_BOOL       NPY_BITSOF_BOOL
+#define BITSOF_CHAR       NPY_BITSOF_CHAR
+#define BITSOF_SHORT      NPY_BITSOF_SHORT
+#define BITSOF_INT        NPY_BITSOF_INT
+#define BITSOF_LONG       NPY_BITSOF_LONG
+#define BITSOF_LONGLONG   NPY_BITSOF_LONGLONG
+#define BITSOF_FLOAT      NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE     NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+
+#define PyArray_UCS4 npy_ucs4
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS     NPY_BEGIN_THREADS
+#define END_THREADS       NPY_END_THREADS
+#define ALLOW_C_API_DEF   NPY_ALLOW_C_API_DEF
+#define	ALLOW_C_API       NPY_ALLOW_C_API
+#define	DISABLE_C_API     NPY_DISABLE_C_API
+
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#endif
+
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#endif
+
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+
+#define CONTIGUOUS         NPY_CONTIGUOUS
+#define C_CONTIGUOUS       NPY_C_CONTIGUOUS
+#define FORTRAN            NPY_FORTRAN
+#define F_CONTIGUOUS       NPY_F_CONTIGUOUS
+#define OWNDATA            NPY_OWNDATA
+#define FORCECAST          NPY_FORCECAST
+#define ENSURECOPY         NPY_ENSURECOPY
+#define ENSUREARRAY        NPY_ENSUREARRAY
+#define ELEMENTSTRIDES     NPY_ELEMENTSTRIDES
+#define ALIGNED            NPY_ALIGNED
+#define NOTSWAPPED         NPY_NOTSWAPPED
+#define WRITEABLE          NPY_WRITEABLE
+#define UPDATEIFCOPY       NPY_UPDATEIFCOPY
+#define ARR_HAS_DESCR      NPY_ARR_HAS_DESCR
+#define BEHAVED            NPY_BEHAVED
+#define BEHAVED_NS         NPY_BEHAVED_NS
+#define CARRAY             NPY_CARRAY
+#define CARRAY_RO          NPY_CARRAY_RO
+#define FARRAY             NPY_FARRAY
+#define FARRAY_RO          NPY_FARRAY_RO
+#define DEFAULT            NPY_DEFAULT
+#define IN_ARRAY           NPY_IN_ARRAY
+#define OUT_ARRAY          NPY_OUT_ARRAY
+#define INOUT_ARRAY        NPY_INOUT_ARRAY
+#define IN_FARRAY          NPY_IN_FARRAY
+#define OUT_FARRAY         NPY_OUT_FARRAY
+#define INOUT_FARRAY       NPY_INOUT_FARRAY
+#define UPDATE_ALL         NPY_UPDATE_ALL
+
+#define OWN_DATA          NPY_OWNDATA
+#define BEHAVED_FLAGS     NPY_BEHAVED
+#define BEHAVED_FLAGS_NS  NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO   NPY_CARRAY_RO
+#define CARRAY_FLAGS      NPY_CARRAY
+#define FARRAY_FLAGS      NPY_FARRAY
+#define FARRAY_FLAGS_RO   NPY_FARRAY_RO
+#define DEFAULT_FLAGS     NPY_DEFAULT
+#define UPDATE_ALL_FLAGS  NPY_UPDATE_ALL_FLAGS
+
+#ifndef MIN
+#define MIN PyArray_MIN
+#endif
+#ifndef MAX
+#define MAX PyArray_MAX
+#endif
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
+
+#endif


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/noprefix.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/npy_interrupt.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/npy_interrupt.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/npy_interrupt.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,117 @@
+
+/* Signal handling:
+
+This header file defines macros that allow your code to handle
+interrupts received during processing.  Interrupts that
+could reasonably be handled:
+
+SIGINT, SIGABRT, SIGALRM, SIGSEGV
+
+****Warning***************
+
+Do not allow code that creates temporary memory or increases reference
+counts of Python objects to be interrupted unless you handle it
+differently.
+
+**************************
+
+The mechanism for handling interrupts is conceptually simple:
+
+  - replace the signal handler with our own home-grown version
+     and store the old one.
+  - run the code to be interrupted -- if an interrupt occurs
+     the handler should basically just cause a return to the
+     calling function for finish work.
+  - restore the old signal handler
+
+Of course, every code that allows interrupts must account for
+returning via the interrupt and handle clean-up correctly.  But,
+even still, the simple paradigm is complicated by at least three
+factors.
+
+ 1) platform portability (i.e. Microsoft says not to use longjmp
+     to return from signal handling.  They have a __try  and __except
+     extension to C instead but what about mingw?).
+
+ 2) how to handle threads: apparently whether signals are delivered to
+    every thread of the process or the "invoking" thread is platform
+    dependent. --- we don't handle threads for now.
+
+ 3) do we need to worry about re-entrance.  For now, assume the
+    code will not call-back into itself.
+
+Ideas:
+
+ 1) Start by implementing an approach that works on platforms that
+    can use setjmp and longjmp functionality and does nothing
+    on other platforms.
+
+ 2) Ignore threads --- i.e. do not mix interrupt handling and threads
+
+ 3) Add a default signal_handler function to the C-API but have the rest
+    use macros.
+
+
+Simple Interface:
+
+
+In your C-extension: around a block of code you want to be interruptable
+with a SIGINT
+
+NPY_SIGINT_ON
+[code]
+NPY_SIGINT_OFF
+
+In order for this to work correctly, the
+[code] block must not allocate any memory or alter the reference count of any
+Python objects.  In other words [code] must be interruptible so that continuation
+after NPY_SIGINT_OFF will only be "missing some computations"
+
+Interrupt handling does not work well with threads.
+
+*/
+
+/* Add signal handling macros
+   Make the global variable and signal handler part of the C-API
+*/
+
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+
+#ifndef NPY_NO_SIGNAL
+
+#include <setjmp.h>
+#include <signal.h>
+
+#ifndef sigsetjmp
+
+#define SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define SIGJMP_BUF jmp_buf
+
+#else
+
+#define SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define SIGJMP_BUF sigjmp_buf
+
+#endif
+
+#    define NPY_SIGINT_ON {                                             \
+                   PyOS_sighandler_t _npy_sig_save;                     \
+                   _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+                   if (SIGSETJMP(*((SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+                                 1) == 0) {                             \
+
+#    define NPY_SIGINT_OFF }                                      \
+        PyOS_setsig(SIGINT, _npy_sig_save);                       \
+        }
+
+#else /* NPY_NO_SIGNAL  */
+
+#  define NPY_SIGINT_ON
+#  define NPY_SIGINT_OFF
+
+#endif /* HAVE_SIGSETJMP */
+
+#endif /* NPY_INTERRUPT_H */


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/npy_interrupt.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/old_defines.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/old_defines.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/old_defines.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,169 @@
+#define NDARRAY_VERSION NPY_VERSION
+
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+
+#define PyArray_TYPES       NPY_TYPES
+#define PyArray_BOOL        NPY_BOOL
+#define PyArray_BYTE        NPY_BYTE
+#define PyArray_UBYTE       NPY_UBYTE
+#define PyArray_SHORT       NPY_SHORT
+#define PyArray_USHORT      NPY_USHORT
+#define PyArray_INT         NPY_INT
+#define PyArray_UINT        NPY_UINT
+#define PyArray_LONG        NPY_LONG
+#define PyArray_ULONG       NPY_ULONG
+#define PyArray_LONGLONG    NPY_LONGLONG
+#define PyArray_ULONGLONG   NPY_ULONGLONG
+#define PyArray_FLOAT       NPY_FLOAT
+#define PyArray_DOUBLE      NPY_DOUBLE
+#define PyArray_LONGDOUBLE  NPY_LONGDOUBLE
+#define PyArray_CFLOAT      NPY_CFLOAT
+#define PyArray_CDOUBLE     NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT      NPY_OBJECT
+#define PyArray_STRING      NPY_STRING
+#define PyArray_UNICODE     NPY_UNICODE
+#define PyArray_VOID        NPY_VOID
+#define PyArray_NTYPES      NPY_NTYPES
+#define PyArray_NOTYPE      NPY_NOTYPE
+#define PyArray_CHAR        NPY_CHAR
+#define PyArray_USERDEF     NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+
+#define PyArray_INTP        NPY_INTP
+#define PyArray_UINTP       NPY_UINTP
+
+#define PyArray_INT8    NPY_INT8
+#define PyArray_UINT8   NPY_UINT8
+#define PyArray_INT16   NPY_INT16
+#define PyArray_UINT16  NPY_UINT16
+#define PyArray_INT32   NPY_INT32
+#define PyArray_UINT32  NPY_UINT32
+
+#ifdef NPY_INT64
+#define PyArray_INT64   NPY_INT64
+#define PyArray_UINT64  NPY_UINT64
+#endif
+
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#endif
+
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16  NPY_FLOAT16
+#define PyArray_COMPLEX32  NPY_COMPLEX32
+#endif
+
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80  NPY_FLOAT80
+#define PyArray_COMPLEX160  NPY_COMPLEX160
+#endif
+
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96  NPY_FLOAT96
+#define PyArray_COMPLEX192  NPY_COMPLEX192
+#endif
+
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128  NPY_FLOAT128
+#define PyArray_COMPLEX256  NPY_COMPLEX256
+#endif
+
+#define PyArray_FLOAT32    NPY_FLOAT32
+#define PyArray_COMPLEX64  NPY_COMPLEX64
+#define PyArray_FLOAT64    NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+
+
+#define PyArray_TYPECHAR        NPY_TYPECHAR
+#define PyArray_BOOLLTR         NPY_BOOLLTR
+#define PyArray_BYTELTR         NPY_BYTELTR
+#define PyArray_UBYTELTR        NPY_UBYTELTR
+#define PyArray_SHORTLTR        NPY_SHORTLTR
+#define PyArray_USHORTLTR       NPY_USHORTLTR
+#define PyArray_INTLTR          NPY_INTLTR
+#define PyArray_UINTLTR         NPY_UINTLTR
+#define PyArray_LONGLTR         NPY_LONGLTR
+#define PyArray_ULONGLTR        NPY_ULONGLTR
+#define PyArray_LONGLONGLTR     NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR    NPY_ULONGLONGLTR
+#define PyArray_FLOATLTR        NPY_FLOATLTR
+#define PyArray_DOUBLELTR       NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR   NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR       NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR      NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR  NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR       NPY_OBJECTLTR
+#define PyArray_STRINGLTR       NPY_STRINGLTR
+#define PyArray_STRINGLTR2      NPY_STRINGLTR2
+#define PyArray_UNICODELTR      NPY_UNICODELTR
+#define PyArray_VOIDLTR         NPY_VOIDLTR
+#define PyArray_CHARLTR         NPY_CHARLTR
+#define PyArray_INTPLTR         NPY_INTPLTR
+#define PyArray_UINTPLTR        NPY_UINTPLTR
+#define PyArray_GENBOOLLTR      NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR       NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR     NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR     NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR      NPY_COMPLEXLTR
+
+#define PyArray_QUICKSORT   NPY_QUICKSORT
+#define PyArray_HEAPSORT    NPY_HEAPSORT
+#define PyArray_MERGESORT   NPY_MERGESORT
+#define PyArray_SORTKIND    NPY_SORTKIND
+#define PyArray_NSORTS      NPY_NSORTS
+
+#define PyArray_NOSCALAR       NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR    NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR  NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR  NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR   NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR  NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND     NPY_SCALARKIND
+#define PyArray_NSCALARKINDS   NPY_NSCALARKINDS
+
+#define PyArray_ANYORDER     NPY_ANYORDER
+#define PyArray_CORDER       NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER        NPY_ORDER
+
+#define PyDescr_ISBOOL      PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED  PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED    PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER   PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT     PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER    PyDataType_ISNUMBER
+#define PyDescr_ISSTRING    PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX   PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON    PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE  PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF   PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED  PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT    PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS   PyDataType_HASFIELDS
+
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+
+#define PyArray_RemoveLargest PyArray_RemoveSmallest


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/old_defines.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/oldnumeric.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/oldnumeric.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/oldnumeric.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,23 @@
+#include "arrayobject.h"
+
+#ifndef REFCOUNT
+#  define REFCOUNT NPY_REFCOUNT
+#  define MAX_ELSIZE 16
+#endif
+
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE PyArray_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define OWN_DATA NPY_OWNDATA
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/oldnumeric.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/setup.py
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/setup.py	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/setup.py	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,8 @@
+
+#!/usr/bin/env python
+
+from distutils.core import setup, Extension
+
+MOD = 'NDI_Segmenter'
+setup(name=MOD, ext_modules=[Extension(MOD, sources=['Segmenter_EXT.c', 'Segmenter_IMPL.c'])])
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/setup.py
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/slice112.raw
===================================================================
(Binary files differ)


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/slice112.raw
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Added: branches/ndimage_segmenter/scipy/NDISegmenter/testShenCastan.py
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/testShenCastan.py	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/testShenCastan.py	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,19 @@
+import numpy as N
+import volumeInput as V
+import EdgeFilters as E
+import edgeSegmenter as S
+
+slice = V.getFilteredSlice('slice112.raw')
+
+edges, groups = S.Canny(slice)
+
+ShenCastanLow = 0.3
+b             = 0.8
+window        = 7
+lowThreshold  = 220 + 2048
+highThreshold = 600 + 2048
+
+edges, groups = S.ShenCastan(slice)
+
+edges, groups = E.ShenCastanEdges(ShenCastanLow, b, window, lowThreshold, highThreshold, slice)
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/testShenCastan.py
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/ufuncobject.h
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/ufuncobject.h	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/ufuncobject.h	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,365 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *);
+
+typedef struct {
+	PyObject_HEAD
+	int nin, nout, nargs;
+	int identity;
+	PyUFuncGenericFunction *functions;
+	void **data;
+	int ntypes;
+	int check_return;
+	char *name, *types;
+	char *doc;
+        void *ptr;
+        PyObject *obj;
+	PyObject *userloops;
+} PyUFuncObject;
+
+#include "arrayobject.h"
+
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN   1
+#define UFUNC_ERR_RAISE  2
+#define UFUNC_ERR_CALL   3
+#define UFUNC_ERR_PRINT  4
+#define UFUNC_ERR_LOG    5
+
+	/* Python side integer mask */
+
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW     3
+#define UFUNC_SHIFT_UNDERFLOW    6
+#define UFUNC_SHIFT_INVALID      9
+
+
+/* platform-dependent code translates floating point
+   status to an integer sum of these values
+*/
+#define UFUNC_FPE_DIVIDEBYZERO  1
+#define UFUNC_FPE_OVERFLOW      2
+#define UFUNC_FPE_UNDERFLOW     4
+#define UFUNC_FPE_INVALID       8
+
+#define UFUNC_ERR_DEFAULT  0      /* Error mode that avoids look-up (no checking) */
+
+   /* Default user error mode */
+#define UFUNC_ERR_DEFAULT2                               \
+        (UFUNC_ERR_PRINT << UFUNC_SHIFT_DIVIDEBYZERO) +  \
+        (UFUNC_ERR_PRINT << UFUNC_SHIFT_OVERFLOW) +      \
+        (UFUNC_ERR_PRINT << UFUNC_SHIFT_INVALID)
+
+	/* Only internal -- not exported, yet*/
+typedef struct {
+	/* Multi-iterator portion --- needs to be present in this order
+	   to work with PyArray_Broadcast */
+	PyObject_HEAD
+	int  numiter;
+	npy_intp size;
+	npy_intp index;
+	int nd;
+	npy_intp dimensions[NPY_MAXDIMS];
+	PyArrayIterObject *iters[NPY_MAXARGS];
+        /*  End of Multi-iterator portion */
+
+	/* The ufunc */
+	PyUFuncObject *ufunc;
+
+	/* The error handling */
+	int errormask;         /* Integer showing desired error handling */
+	PyObject *errobj;      /* currently a tuple with
+				  (string, func or obj with write method or None)
+			       */
+        int first;
+
+	/* Specific function and data to use */
+	PyUFuncGenericFunction function;
+	void *funcdata;
+
+	/* Loop method */
+	int meth;
+
+	/* Whether we need to copy to a buffer or not.*/
+	int needbuffer[NPY_MAXARGS];
+	int leftover;
+	int ninnerloops;
+	int lastdim;
+
+	/* Whether or not to swap */
+	int swap[NPY_MAXARGS];
+
+	/* Buffers for the loop */
+	char *buffer[NPY_MAXARGS];
+	int bufsize;
+	npy_intp bufcnt;
+	char *dptr[NPY_MAXARGS];
+
+	/* For casting */
+	char *castbuf[NPY_MAXARGS];
+	PyArray_VectorUnaryFunc *cast[NPY_MAXARGS];
+
+	/* usually points to buffer but when a cast is to be
+	   done it switches for that argument to castbuf.
+	*/
+	char *bufptr[NPY_MAXARGS];
+
+	/* Steps filled in from iters or sizeof(item)
+	   depending on loop method.
+	*/
+	npy_intp steps[NPY_MAXARGS];
+
+        int obj;  /* This loop uses object arrays */
+        int notimplemented; /* The loop caused notimplemented */
+        int objfunc; /* This loop calls object functions
+                        (an inner-loop function with argument types */
+} PyUFuncLoopObject;
+
+/* Could make this more clever someday */
+#define UFUNC_MAXIDENTITY 32
+
+typedef struct {
+        PyObject_HEAD
+        PyArrayIterObject *it;
+        PyArrayObject *ret;
+	PyArrayIterObject *rit;   /* Needed for Accumulate */
+        int  outsize;
+	npy_intp  index;
+	npy_intp  size;
+        char idptr[UFUNC_MAXIDENTITY];
+
+	/* The ufunc */
+	PyUFuncObject *ufunc;
+
+	/* The error handling */
+	int errormask;
+	PyObject *errobj;
+        int first;
+
+        PyUFuncGenericFunction function;
+        void *funcdata;
+        int meth;
+        int swap;
+
+        char *buffer;
+        int bufsize;
+
+        char *castbuf;
+        PyArray_VectorUnaryFunc *cast;
+
+        char *bufptr[3];
+        npy_intp steps[3];
+
+        npy_intp N;
+        int  instrides;
+        int  insize;
+        char *inptr;
+
+        /* For copying small arrays */
+        PyObject *decref;
+
+        int obj;
+        int retbase;
+
+} PyUFuncReduceObject;
+
+
+#if NPY_ALLOW_THREADS
+#define NPY_LOOP_BEGIN_THREADS if (!(loop->obj)) {_save = PyEval_SaveThread();}
+#define NPY_LOOP_END_THREADS   if (!(loop->obj)) {PyEval_RestoreThread(_save);}
+#else
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+#endif
+
+#define PyUFunc_One 1
+#define PyUFunc_Zero 0
+#define PyUFunc_None -1
+
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+
+
+typedef struct {
+        int nin;
+        int nout;
+        PyObject *callable;
+} PyUFunc_PyFuncData;
+
+/* A linked-list of function information for
+   user-defined 1-d loops.
+ */
+typedef struct _loop1d_info {
+        PyUFuncGenericFunction func;
+        void *data;
+        int *arg_types;
+        struct _loop1d_info *next;
+} PyUFunc_Loop1d;
+
+
+#include "__ufunc_api.h"
+
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+
+#define UFUNC_CHECK_ERROR(arg)                                          \
+	if (((arg)->obj && PyErr_Occurred()) ||                         \
+            ((arg)->errormask &&                                        \
+             PyUFunc_checkfperr((arg)->errormask,                       \
+                                (arg)->errobj,                          \
+                                &(arg)->first)))                        \
+		goto fail
+
+/* This code checks the IEEE status flags in a platform-dependent way */
+/* Adapted from Numarray  */
+
+/*  OSF/Alpha (Tru64)  ---------------------------------------------*/
+#if defined(__osf__) && defined(__alpha)
+
+#include <machine/fpu.h>
+
+#define UFUNC_CHECK_STATUS(ret) {		\
+	unsigned long fpstatus;		        \
+						\
+	fpstatus = ieee_get_fp_control();				\
+	/* clear status bits as well as disable exception mode if on */ \
+	ieee_set_fp_control( 0 );					\
+	ret = ((IEEE_STATUS_DZE & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \
+		| ((IEEE_STATUS_OVF & fpstatus) ? UFUNC_FPE_OVERFLOW : 0) \
+		| ((IEEE_STATUS_UNF & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \
+		| ((IEEE_STATUS_INV & fpstatus) ? UFUNC_FPE_INVALID : 0); \
+	}
+
+/* MS Windows -----------------------------------------------------*/
+#elif defined(_MSC_VER)
+
+#include <float.h>
+
+#define UFUNC_CHECK_STATUS(ret) {		 \
+	int fpstatus = (int) _clearfp();			\
+									\
+	ret = ((SW_ZERODIVIDE & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0)	\
+		| ((SW_OVERFLOW & fpstatus) ? UFUNC_FPE_OVERFLOW : 0)	\
+		| ((SW_UNDERFLOW & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0)	\
+		| ((SW_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0);	\
+	}
+
+#define isnan(x) (_isnan((double)(x)))
+#define isinf(x) ((_fpclass((double)(x)) == _FPCLASS_PINF) ||	\
+		  (_fpclass((double)(x)) == _FPCLASS_NINF))
+#define isfinite(x) (_finite((double) x))
+
+/* Solaris --------------------------------------------------------*/
+/* --------ignoring SunOS ieee_flags approach, someone else can
+**         deal with that! */
+#elif defined(sun) || defined(__BSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+#include <ieeefp.h>
+
+#define UFUNC_CHECK_STATUS(ret) {				\
+	int fpstatus;						\
+								\
+	fpstatus = (int) fpgetsticky();					\
+	ret = ((FP_X_DZ  & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0)	\
+		| ((FP_X_OFL & fpstatus) ? UFUNC_FPE_OVERFLOW : 0)	\
+		| ((FP_X_UFL & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0)	\
+		| ((FP_X_INV & fpstatus) ? UFUNC_FPE_INVALID : 0);	\
+	(void) fpsetsticky(0);						\
+	}
+
+#elif defined(__GLIBC__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__MINGW32__)
+
+#if defined(__GLIBC__) || defined(__APPLE__) || defined(__MINGW32__)
+#include <fenv.h>
+#elif defined(__CYGWIN__)
+#include "fenv/fenv.c"
+#endif
+
+#define UFUNC_CHECK_STATUS(ret) {                                       \
+	int fpstatus = (int) fetestexcept(FE_DIVBYZERO | FE_OVERFLOW |	\
+					  FE_UNDERFLOW | FE_INVALID);	\
+	ret = ((FE_DIVBYZERO  & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \
+		| ((FE_OVERFLOW   & fpstatus) ? UFUNC_FPE_OVERFLOW : 0)	\
+		| ((FE_UNDERFLOW  & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \
+		| ((FE_INVALID    & fpstatus) ? UFUNC_FPE_INVALID : 0);	\
+	(void) feclearexcept(FE_DIVBYZERO | FE_OVERFLOW |		\
+			     FE_UNDERFLOW | FE_INVALID);		\
+}
+
+#define generate_divbyzero_error() feraiseexcept(FE_DIVBYZERO)
+#define generate_overflow_error() feraiseexcept(FE_OVERFLOW)
+
+#elif defined(_AIX)
+
+#include <float.h>
+#include <fpxcp.h>
+
+#define UFUNC_CHECK_STATUS(ret) { \
+	fpflag_t fpstatus; \
+                                                \
+	fpstatus = fp_read_flag(); \
+	ret = ((FP_DIV_BY_ZERO & fpstatus) ? UFUNC_FPE_DIVIDEBYZERO : 0) \
+		| ((FP_OVERFLOW & fpstatus) ? UFUNC_FPE_OVERFLOW : 0)	\
+		| ((FP_UNDERFLOW & fpstatus) ? UFUNC_FPE_UNDERFLOW : 0) \
+		| ((FP_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0); \
+	fp_swap_flag(0); \
+}
+
+#define generate_divbyzero_error() fp_raise_xcp(FP_DIV_BY_ZERO)
+#define generate_overflow_error() fp_raise_xcp(FP_OVERFLOW)
+
+#else
+
+#define NO_FLOATING_POINT_SUPPORT
+#define UFUNC_CHECK_STATUS(ret) { \
+    ret = 0;							     \
+  }
+
+#endif
+
+/* These should really be altered to just set the corresponding bit
+   in the floating point status flag.  Need to figure out how to do that
+   on all the platforms...
+*/
+
+#if !defined(generate_divbyzero_error)
+static int numeric_zero2 = 0;
+static void generate_divbyzero_error(void) {
+	double dummy;
+	dummy = 1./numeric_zero2;
+        if (dummy) /* to prevent optimizer from eliminating expression */
+	   return;
+	else /* should never be called */
+	   numeric_zero2 += 1;
+	return;
+}
+#endif
+
+#if !defined(generate_overflow_error)
+static double numeric_two = 2.0;
+static void generate_overflow_error(void) {
+	double dummy;
+	dummy = pow(numeric_two,1000);
+        if (dummy)
+           return;
+        else
+           numeric_two += 0.1;
+        return;
+	return;
+}
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_UFUNCOBJECT_H */


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/ufuncobject.h
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/ndimage_segmenter/scipy/NDISegmenter/volumeInput.py
===================================================================
--- branches/ndimage_segmenter/scipy/NDISegmenter/volumeInput.py	2007-11-02 19:51:44 UTC (rev 3491)
+++ branches/ndimage_segmenter/scipy/NDISegmenter/volumeInput.py	2007-11-02 20:09:04 UTC (rev 3492)
@@ -0,0 +1,85 @@
+import struct
+import numpy as N
+
+def getFilteredSlice(imageName='junk.raw', bytes=2, rows=512, columns=512):
+	image = open(imageName, 'rb')
+	slice = image.read(rows*columns*bytes)
+	if bytes == 2:
+		values = struct.unpack('h'*rows*columns, slice)
+	else:
+		values = struct.unpack('i'*rows*columns, slice)
+
+	ImageSlice = N.array(values, dtype=float).reshape(rows, columns)
+	return (ImageSlice)
+
+def getSlice(mySlice, rows=512, columns=512, bytes=2):
+	image = open('C:\PythonStuff\CardiacCT.vol', 'rb')
+	image.seek(mySlice*rows*columns*bytes)
+	slice = image.read(rows*columns*bytes)
+	values = struct.unpack('h'*rows*columns, slice)
+	ImageSlice = N.array(values, dtype=float).reshape(rows, columns)
+	return (ImageSlice+2048)
+
+def saveSlice(mySlice, filename='junk.raw', rows=512, columns=512, bytes=2):
+	# just save the slice to a fixed file
+	slice = mySlice.astype(int)
+	image = open(filename, 'wb')
+	image.write(slice)
+	image.close()
+	return
+
+
+def buildDGaussKernel(gWidth, sigma):
+
+	kernel  = zeros((1+2*(gWidth-1)), dtype=float)
+	indices = range(1, gWidth)  
+
+	i = 0
+	kernel[gWidth-1]  = math.exp(((-i*i)/(2.0 * sigma * sigma)))
+	kernel[gWidth-1] *= -(i / (sigma * sigma))
+	for i in indices:
+		kernel[gWidth-1+i]  = math.exp(((-i*i)/(2.0 * sigma * sigma)))
+		kernel[gWidth-1+i] *= -(i / (sigma * sigma))
+		kernel[gWidth-1-i]  = -kernel[gWidth-1+i]	# since using correlated1d that doesn't
+								# flip the kernel like in convolution
+
+	return kernel
+
+
+def build2DKernel(aperature, hiFilterCutoff):
+	rad = math.pi / 180.0
+	HalfFilterTaps = (aperature-1) / 2
+	kernel = zeros((aperature), dtype=float)
+
+	LC = 0.0
+	HC = hiFilterCutoff * rad 
+	t2 = 2.0 * math.pi
+	t1 = 2.0 * HalfFilterTaps + 1.0
+	indices = range(-HalfFilterTaps, HalfFilterTaps+1, 1)  
+	# indices   = arange(-HalfFilterTaps, HalfFilterTaps+1, 1)  
+	# indicesNZ = indices[indices.nonzero()]
+	# indicesP  = indices[indices>0]
+
+	j = 0
+	for i in indices:
+	    if i == 0:
+		tLOW  = LC
+	        tHIGH = HC
+	    else:
+		tLOW  = math.sin(i*LC)/i
+	        tHIGH = math.sin(i*HC)/i
+	    t3 = 0.54 + 0.46*(math.cos(i*t2/t1))
+	    t4 = t3*(tHIGH-tLOW)
+	    kernel[j] = t4
+	    j += 1
+
+	# normalize the kernel
+	sum = kernel.sum()
+	kernel /= sum
+
+	return kernel
+
+
+
+
+


Property changes on: branches/ndimage_segmenter/scipy/NDISegmenter/volumeInput.py
___________________________________________________________________
Name: svn:executable
   + *



More information about the Scipy-svn mailing list