Index: sansmodels/src/sans/models/c_extensions/CBinaryHSModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CBinaryHSModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CBinaryHSModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,305 @@
+/** CBinaryHSModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY binaryHs.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "binaryHs.h"
+
+/// Error object for raised exceptions
+static PyObject * CBinaryHSModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	BinaryHSParameters model_pars;
+} CBinaryHSModel;
+
+
+static void
+CBinaryHSModel_dealloc(CBinaryHSModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CBinaryHSModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CBinaryHSModel *self;
+    
+    self = (CBinaryHSModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CBinaryHSModel_init(CBinaryHSModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"vol_frac_ls",Py_BuildValue("d",0.100000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"vol_frac_ss",Py_BuildValue("d",0.200000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"ls_sld",Py_BuildValue("d",0.000003));
+        PyDict_SetItemString(self->params,"ss_sld",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"s_radius",Py_BuildValue("d",25.000000));
+        PyDict_SetItemString(self->params,"l_radius",Py_BuildValue("d",100.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CBinaryHSModel_members[] = {
+    {"params", T_OBJECT, offsetof(CBinaryHSModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CBinaryHSModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CBinaryHSModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CBinaryHSModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model_pars.ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model_pars.s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model_pars.l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CBinaryHSModelError, 
+	    	"CBinaryHSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSModelError, 
+	    		"CBinaryHSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",binaryHs_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CBinaryHSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",binaryHs_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CBinaryHSModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model_pars.ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model_pars.s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model_pars.l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CBinaryHSModelError, 
+	    	"CBinaryHSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSModelError, 
+	    		"CBinaryHSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",binaryHs_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CBinaryHSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",binaryHs_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CBinaryHSModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CBinaryHSModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CBinaryHSModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CBinaryHSModel",             /*tp_name*/
+    sizeof(CBinaryHSModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CBinaryHSModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CBinaryHSModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CBinaryHSModel_methods,             /* tp_methods */
+    CBinaryHSModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CBinaryHSModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CBinaryHSModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCBinaryHSModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CBinaryHSModelType) < 0)
+        return;
+
+    Py_INCREF(&CBinaryHSModelType);
+    PyModule_AddObject(module, "CBinaryHSModel", (PyObject *)&CBinaryHSModelType);
+    
+    d = PyModule_GetDict(module);
+    CBinaryHSModelError = PyErr_NewException("CBinaryHSModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CBinaryHSModelError", CBinaryHSModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CBinaryHSPSF11Model.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CBinaryHSPSF11Model.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CBinaryHSPSF11Model.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,305 @@
+/** CBinaryHSPSF11Model
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY binaryHS_PSF11.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "binaryHS_PSF11.h"
+
+/// Error object for raised exceptions
+static PyObject * CBinaryHSPSF11ModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	BinaryHSPSF11Parameters model_pars;
+} CBinaryHSPSF11Model;
+
+
+static void
+CBinaryHSPSF11Model_dealloc(CBinaryHSPSF11Model* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CBinaryHSPSF11Model_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CBinaryHSPSF11Model *self;
+    
+    self = (CBinaryHSPSF11Model *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CBinaryHSPSF11Model_init(CBinaryHSPSF11Model *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"vol_frac_ls",Py_BuildValue("d",0.200000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"vol_frac_ss",Py_BuildValue("d",0.200000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"ls_sld",Py_BuildValue("d",0.000003));
+        PyDict_SetItemString(self->params,"ss_sld",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"s_radius",Py_BuildValue("d",25.000000));
+        PyDict_SetItemString(self->params,"l_radius",Py_BuildValue("d",160.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CBinaryHSPSF11Model_members[] = {
+    {"params", T_OBJECT, offsetof(CBinaryHSPSF11Model, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CBinaryHSPSF11Model, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CBinaryHSPSF11Model_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CBinaryHSPSF11Model *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model_pars.ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model_pars.s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model_pars.l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CBinaryHSPSF11ModelError, 
+	    	"CBinaryHSPSF11Model.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSPSF11ModelError, 
+	    		"CBinaryHSPSF11Model.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CBinaryHSPSF11Model_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CBinaryHSPSF11Model_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",binaryHS_PSF11_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CBinaryHSPSF11Model_readDouble(pars);		
+		
+		return Py_BuildValue("d",binaryHS_PSF11_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CBinaryHSPSF11Model *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model_pars.ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model_pars.s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model_pars.l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CBinaryHSPSF11ModelError, 
+	    	"CBinaryHSPSF11Model.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSPSF11ModelError, 
+	    		"CBinaryHSPSF11Model.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CBinaryHSPSF11Model_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CBinaryHSPSF11Model_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",binaryHS_PSF11_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CBinaryHSPSF11Model_readDouble(pars);		
+		
+		return Py_BuildValue("d",binaryHS_PSF11_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CBinaryHSPSF11Model *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CBinaryHSPSF11Model_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CBinaryHSPSF11ModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CBinaryHSPSF11Model",             /*tp_name*/
+    sizeof(CBinaryHSPSF11Model),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CBinaryHSPSF11Model_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CBinaryHSPSF11Model objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CBinaryHSPSF11Model_methods,             /* tp_methods */
+    CBinaryHSPSF11Model_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CBinaryHSPSF11Model_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CBinaryHSPSF11Model_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCBinaryHSPSF11Model(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CBinaryHSPSF11ModelType) < 0)
+        return;
+
+    Py_INCREF(&CBinaryHSPSF11ModelType);
+    PyModule_AddObject(module, "CBinaryHSPSF11Model", (PyObject *)&CBinaryHSPSF11ModelType);
+    
+    d = PyModule_GetDict(module);
+    CBinaryHSPSF11ModelError = PyErr_NewException("CBinaryHSPSF11Model.error", NULL, NULL);
+    PyDict_SetItemString(d, "CBinaryHSPSF11ModelError", CBinaryHSPSF11ModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CCoreShellEllipsoidModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CCoreShellEllipsoidModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CCoreShellEllipsoidModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,311 @@
+/** CCoreShellEllipsoidModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY spheroid.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "spheroid.h"
+
+/// Error object for raised exceptions
+static PyObject * CCoreShellEllipsoidModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	SpheroidParameters model_pars;
+} CCoreShellEllipsoidModel;
+
+
+static void
+CCoreShellEllipsoidModel_dealloc(CCoreShellEllipsoidModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CCoreShellEllipsoidModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreShellEllipsoidModel *self;
+    
+    self = (CCoreShellEllipsoidModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreShellEllipsoidModel_init(CCoreShellEllipsoidModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"polar_shell",Py_BuildValue("d",30.000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"equat_shell",Py_BuildValue("d",250.000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"equat_core",Py_BuildValue("d",200.000000));
+        PyDict_SetItemString(self->params,"polar_core",Py_BuildValue("d",20.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000001));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CCoreShellEllipsoidModel_members[] = {
+    {"params", T_OBJECT, offsetof(CCoreShellEllipsoidModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CCoreShellEllipsoidModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreShellEllipsoidModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CCoreShellEllipsoidModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model_pars.polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    	"CCoreShellEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    		"CCoreShellEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",spheroid_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CCoreShellEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",spheroid_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreShellEllipsoidModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model_pars.polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    	"CCoreShellEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    		"CCoreShellEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",spheroid_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CCoreShellEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",spheroid_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreShellEllipsoidModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CCoreShellEllipsoidModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CCoreShellEllipsoidModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreShellEllipsoidModel",             /*tp_name*/
+    sizeof(CCoreShellEllipsoidModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreShellEllipsoidModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CCoreShellEllipsoidModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreShellEllipsoidModel_methods,             /* tp_methods */
+    CCoreShellEllipsoidModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreShellEllipsoidModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreShellEllipsoidModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCCoreShellEllipsoidModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreShellEllipsoidModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreShellEllipsoidModelType);
+    PyModule_AddObject(module, "CCoreShellEllipsoidModel", (PyObject *)&CCoreShellEllipsoidModelType);
+    
+    d = PyModule_GetDict(module);
+    CCoreShellEllipsoidModelError = PyErr_NewException("CCoreShellEllipsoidModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CCoreShellEllipsoidModelError", CCoreShellEllipsoidModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CDiamCylFunc.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CDiamCylFunc.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CDiamCylFunc.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,287 @@
+/** CDiamCylFunc
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY DiamCyl.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "DiamCyl.h"
+
+/// Error object for raised exceptions
+static PyObject * CDiamCylFuncError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	DiamCyldParameters model_pars;
+} CDiamCylFunc;
+
+
+static void
+CDiamCylFunc_dealloc(CDiamCylFunc* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CDiamCylFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CDiamCylFunc *self;
+    
+    self = (CDiamCylFunc *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CDiamCylFunc_init(CDiamCylFunc *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CDiamCylFunc_members[] = {
+    {"params", T_OBJECT, offsetof(CDiamCylFunc, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CDiamCylFunc, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CDiamCylFunc_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CDiamCylFunc *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CDiamCylFuncError, 
+	    	"CDiamCylFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamCylFuncError, 
+	    		"CDiamCylFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",DiamCyl_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CDiamCylFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",DiamCyl_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CDiamCylFunc *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CDiamCylFuncError, 
+	    	"CDiamCylFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamCylFuncError, 
+	    		"CDiamCylFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",DiamCyl_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CDiamCylFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",DiamCyl_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CDiamCylFunc *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CDiamCylFunc_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CDiamCylFuncType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CDiamCylFunc",             /*tp_name*/
+    sizeof(CDiamCylFunc),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CDiamCylFunc_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CDiamCylFunc objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CDiamCylFunc_methods,             /* tp_methods */
+    CDiamCylFunc_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CDiamCylFunc_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CDiamCylFunc_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCDiamCylFunc(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CDiamCylFuncType) < 0)
+        return;
+
+    Py_INCREF(&CDiamCylFuncType);
+    PyModule_AddObject(module, "CDiamCylFunc", (PyObject *)&CDiamCylFuncType);
+    
+    d = PyModule_GetDict(module);
+    CDiamCylFuncError = PyErr_NewException("CDiamCylFunc.error", NULL, NULL);
+    PyDict_SetItemString(d, "CDiamCylFuncError", CDiamCylFuncError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CDiamEllipFunc.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CDiamEllipFunc.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CDiamEllipFunc.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,287 @@
+/** CDiamEllipFunc
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY DiamEllip.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "DiamEllip.h"
+
+/// Error object for raised exceptions
+static PyObject * CDiamEllipFuncError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	DiamEllipsParameters model_pars;
+} CDiamEllipFunc;
+
+
+static void
+CDiamEllipFunc_dealloc(CDiamEllipFunc* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CDiamEllipFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CDiamEllipFunc *self;
+    
+    self = (CDiamEllipFunc *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CDiamEllipFunc_init(CDiamEllipFunc *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"radius_b",Py_BuildValue("d",400.000000));
+        PyDict_SetItemString(self->params,"radius_a",Py_BuildValue("d",20.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CDiamEllipFunc_members[] = {
+    {"params", T_OBJECT, offsetof(CDiamEllipFunc, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CDiamEllipFunc, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CDiamEllipFunc_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CDiamEllipFunc *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model_pars.radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CDiamEllipFuncError, 
+	    	"CDiamEllipFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamEllipFuncError, 
+	    		"CDiamEllipFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",DiamEllip_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CDiamEllipFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",DiamEllip_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CDiamEllipFunc *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model_pars.radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CDiamEllipFuncError, 
+	    	"CDiamEllipFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamEllipFuncError, 
+	    		"CDiamEllipFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",DiamEllip_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CDiamEllipFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",DiamEllip_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CDiamEllipFunc *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CDiamEllipFunc_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CDiamEllipFuncType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CDiamEllipFunc",             /*tp_name*/
+    sizeof(CDiamEllipFunc),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CDiamEllipFunc_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CDiamEllipFunc objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CDiamEllipFunc_methods,             /* tp_methods */
+    CDiamEllipFunc_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CDiamEllipFunc_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CDiamEllipFunc_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCDiamEllipFunc(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CDiamEllipFuncType) < 0)
+        return;
+
+    Py_INCREF(&CDiamEllipFuncType);
+    PyModule_AddObject(module, "CDiamEllipFunc", (PyObject *)&CDiamEllipFuncType);
+    
+    d = PyModule_GetDict(module);
+    CDiamEllipFuncError = PyErr_NewException("CDiamEllipFunc.error", NULL, NULL);
+    PyDict_SetItemString(d, "CDiamEllipFuncError", CDiamEllipFuncError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CFlexibleCylinderModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CFlexibleCylinderModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CFlexibleCylinderModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,299 @@
+/** CFlexibleCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY flexible_cylinder.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "flexible_cylinder.h"
+
+/// Error object for raised exceptions
+static PyObject * CFlexibleCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	FlexibleCylinderParameters model_pars;
+} CFlexibleCylinderModel;
+
+
+static void
+CFlexibleCylinderModel_dealloc(CFlexibleCylinderModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CFlexibleCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFlexibleCylinderModel *self;
+    
+    self = (CFlexibleCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFlexibleCylinderModel_init(CFlexibleCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",1000.000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000100));
+        PyDict_SetItemString(self->params,"kuhn_length",Py_BuildValue("d",100.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000005));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CFlexibleCylinderModel_members[] = {
+    {"params", T_OBJECT, offsetof(CFlexibleCylinderModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CFlexibleCylinderModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFlexibleCylinderModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CFlexibleCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CFlexibleCylinderModelError, 
+	    	"CFlexibleCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CFlexibleCylinderModelError, 
+	    		"CFlexibleCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",flexible_cylinder_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CFlexibleCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",flexible_cylinder_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFlexibleCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CFlexibleCylinderModelError, 
+	    	"CFlexibleCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CFlexibleCylinderModelError, 
+	    		"CFlexibleCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",flexible_cylinder_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CFlexibleCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",flexible_cylinder_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CFlexibleCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CFlexibleCylinderModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CFlexibleCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFlexibleCylinderModel",             /*tp_name*/
+    sizeof(CFlexibleCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFlexibleCylinderModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CFlexibleCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFlexibleCylinderModel_methods,             /* tp_methods */
+    CFlexibleCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFlexibleCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFlexibleCylinderModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCFlexibleCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFlexibleCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CFlexibleCylinderModelType);
+    PyModule_AddObject(module, "CFlexibleCylinderModel", (PyObject *)&CFlexibleCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    CFlexibleCylinderModelError = PyErr_NewException("CFlexibleCylinderModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CFlexibleCylinderModelError", CFlexibleCylinderModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CHardsphereStructure.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CHardsphereStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CHardsphereStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,287 @@
+/** CHardsphereStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY Hardsphere.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "Hardsphere.h"
+
+/// Error object for raised exceptions
+static PyObject * CHardsphereStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	HardsphereParameters model_pars;
+} CHardsphereStructure;
+
+
+static void
+CHardsphereStructure_dealloc(CHardsphereStructure* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CHardsphereStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHardsphereStructure *self;
+    
+    self = (CHardsphereStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHardsphereStructure_init(CHardsphereStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",50.000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.200000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CHardsphereStructure_members[] = {
+    {"params", T_OBJECT, offsetof(CHardsphereStructure, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CHardsphereStructure, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHardsphereStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CHardsphereStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHardsphereStructureError, 
+	    	"CHardsphereStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHardsphereStructureError, 
+	    		"CHardsphereStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",Hardsphere_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHardsphereStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",Hardsphere_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHardsphereStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHardsphereStructureError, 
+	    	"CHardsphereStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHardsphereStructureError, 
+	    		"CHardsphereStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",Hardsphere_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHardsphereStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",Hardsphere_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CHardsphereStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CHardsphereStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CHardsphereStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHardsphereStructure",             /*tp_name*/
+    sizeof(CHardsphereStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHardsphereStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHardsphereStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHardsphereStructure_methods,             /* tp_methods */
+    CHardsphereStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHardsphereStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHardsphereStructure_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHardsphereStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHardsphereStructureType) < 0)
+        return;
+
+    Py_INCREF(&CHardsphereStructureType);
+    PyModule_AddObject(module, "CHardsphereStructure", (PyObject *)&CHardsphereStructureType);
+    
+    d = PyModule_GetDict(module);
+    CHardsphereStructureError = PyErr_NewException("CHardsphereStructure.error", NULL, NULL);
+    PyDict_SetItemString(d, "CHardsphereStructureError", CHardsphereStructureError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CHayterMSAStructure.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CHayterMSAStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CHayterMSAStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,299 @@
+/** CHayterMSAStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY HayterMSA.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "HayterMSA.h"
+
+/// Error object for raised exceptions
+static PyObject * CHayterMSAStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	HayterMSAParameters model_pars;
+} CHayterMSAStructure;
+
+
+static void
+CHayterMSAStructure_dealloc(CHayterMSAStructure* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CHayterMSAStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHayterMSAStructure *self;
+    
+    self = (CHayterMSAStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHayterMSAStructure_init(CHayterMSAStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"temperature",Py_BuildValue("d",318.160000));
+        PyDict_SetItemString(self->params,"saltconc",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"dielectconst",Py_BuildValue("d",71.080000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.019200));
+        PyDict_SetItemString(self->params,"charge",Py_BuildValue("d",19.000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.750000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CHayterMSAStructure_members[] = {
+    {"params", T_OBJECT, offsetof(CHayterMSAStructure, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CHayterMSAStructure, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHayterMSAStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CHayterMSAStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model_pars.saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model_pars.dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHayterMSAStructureError, 
+	    	"CHayterMSAStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHayterMSAStructureError, 
+	    		"CHayterMSAStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",HayterMSA_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHayterMSAStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",HayterMSA_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHayterMSAStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model_pars.saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model_pars.dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHayterMSAStructureError, 
+	    	"CHayterMSAStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHayterMSAStructureError, 
+	    		"CHayterMSAStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",HayterMSA_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHayterMSAStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",HayterMSA_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CHayterMSAStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CHayterMSAStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CHayterMSAStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHayterMSAStructure",             /*tp_name*/
+    sizeof(CHayterMSAStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHayterMSAStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHayterMSAStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHayterMSAStructure_methods,             /* tp_methods */
+    CHayterMSAStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHayterMSAStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHayterMSAStructure_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHayterMSAStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHayterMSAStructureType) < 0)
+        return;
+
+    Py_INCREF(&CHayterMSAStructureType);
+    PyModule_AddObject(module, "CHayterMSAStructure", (PyObject *)&CHayterMSAStructureType);
+    
+    d = PyModule_GetDict(module);
+    CHayterMSAStructureError = PyErr_NewException("CHayterMSAStructure.error", NULL, NULL);
+    PyDict_SetItemString(d, "CHayterMSAStructureError", CHayterMSAStructureError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CHollowCylinderModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CHollowCylinderModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CHollowCylinderModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,305 @@
+/** CHollowCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY hollow_cylinder.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "hollow_cylinder.h"
+
+/// Error object for raised exceptions
+static PyObject * CHollowCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	HollowCylinderParameters model_pars;
+} CHollowCylinderModel;
+
+
+static void
+CHollowCylinderModel_dealloc(CHollowCylinderModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CHollowCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHollowCylinderModel *self;
+    
+    self = (CHollowCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHollowCylinderModel_init(CHollowCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"core_radius",Py_BuildValue("d",20.000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",1.570000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.010000));
+        PyDict_SetItemString(self->params,"shell_radius",Py_BuildValue("d",30.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000005));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CHollowCylinderModel_members[] = {
+    {"params", T_OBJECT, offsetof(CHollowCylinderModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CHollowCylinderModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHollowCylinderModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CHollowCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_radius") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHollowCylinderModelError, 
+	    	"CHollowCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHollowCylinderModelError, 
+	    		"CHollowCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",hollow_cylinder_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHollowCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",hollow_cylinder_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHollowCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_radius") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CHollowCylinderModelError, 
+	    	"CHollowCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHollowCylinderModelError, 
+	    		"CHollowCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",hollow_cylinder_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHollowCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",hollow_cylinder_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CHollowCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CHollowCylinderModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CHollowCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHollowCylinderModel",             /*tp_name*/
+    sizeof(CHollowCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHollowCylinderModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHollowCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHollowCylinderModel_methods,             /* tp_methods */
+    CHollowCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHollowCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHollowCylinderModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHollowCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHollowCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CHollowCylinderModelType);
+    PyModule_AddObject(module, "CHollowCylinderModel", (PyObject *)&CHollowCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    CHollowCylinderModelError = PyErr_NewException("CHollowCylinderModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CHollowCylinderModelError", CHollowCylinderModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CLamellarFFHGModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CLamellarFFHGModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CLamellarFFHGModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,302 @@
+/** CLamellarFFHGModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY lamellarFF_HG.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "lamellarFF_HG.h"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarFFHGModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	LamellarFF_HGParameters model_pars;
+} CLamellarFFHGModel;
+
+
+static void
+CLamellarFFHGModel_dealloc(CLamellarFFHGModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CLamellarFFHGModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarFFHGModel *self;
+    
+    self = (CLamellarFFHGModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarFFHGModel_init(CLamellarFFHGModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"h_thickness",Py_BuildValue("d",10.000000));
+        PyDict_SetItemString(self->params,"sld_tail",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"t_length",Py_BuildValue("d",15.000000));
+        PyDict_SetItemString(self->params,"sld_head",Py_BuildValue("d",0.000003));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CLamellarFFHGModel_members[] = {
+    {"params", T_OBJECT, offsetof(CLamellarFFHGModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CLamellarFFHGModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarFFHGModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CLamellarFFHGModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model_pars.sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model_pars.sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarFFHGModelError, 
+	    	"CLamellarFFHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarFFHGModelError, 
+	    		"CLamellarFFHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",lamellarFF_HG_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarFFHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarFF_HG_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarFFHGModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model_pars.sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model_pars.sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarFFHGModelError, 
+	    	"CLamellarFFHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarFFHGModelError, 
+	    		"CLamellarFFHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",lamellarFF_HG_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarFFHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarFF_HG_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarFFHGModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CLamellarFFHGModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CLamellarFFHGModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarFFHGModel",             /*tp_name*/
+    sizeof(CLamellarFFHGModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarFFHGModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarFFHGModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarFFHGModel_methods,             /* tp_methods */
+    CLamellarFFHGModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarFFHGModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarFFHGModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarFFHGModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarFFHGModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarFFHGModelType);
+    PyModule_AddObject(module, "CLamellarFFHGModel", (PyObject *)&CLamellarFFHGModelType);
+    
+    d = PyModule_GetDict(module);
+    CLamellarFFHGModelError = PyErr_NewException("CLamellarFFHGModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarFFHGModelError", CLamellarFFHGModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CLamellarModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CLamellarModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CLamellarModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,296 @@
+/** CLamellarModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY lamellar.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "lamellar.h"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	LamellarParameters model_pars;
+} CLamellarModel;
+
+
+static void
+CLamellarModel_dealloc(CLamellarModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CLamellarModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarModel *self;
+    
+    self = (CLamellarModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarModel_init(CLamellarModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"sld_sol",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"bi_thick",Py_BuildValue("d",50.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"sld_bi",Py_BuildValue("d",0.000001));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CLamellarModel_members[] = {
+    {"params", T_OBJECT, offsetof(CLamellarModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CLamellarModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CLamellarModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarModelError, 
+	    	"CLamellarModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarModelError, 
+	    		"CLamellarModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",lamellar_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellar_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarModelError, 
+	    	"CLamellarModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarModelError, 
+	    		"CLamellarModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",lamellar_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellar_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CLamellarModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CLamellarModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarModel",             /*tp_name*/
+    sizeof(CLamellarModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarModel_methods,             /* tp_methods */
+    CLamellarModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarModelType);
+    PyModule_AddObject(module, "CLamellarModel", (PyObject *)&CLamellarModelType);
+    
+    d = PyModule_GetDict(module);
+    CLamellarModelError = PyErr_NewException("CLamellarModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarModelError", CLamellarModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CLamellarPSHGModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CLamellarPSHGModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CLamellarPSHGModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,311 @@
+/** CLamellarPSHGModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY lamellarPS_HG.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "lamellarPS_HG.h"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarPSHGModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	LamellarPSHGParameters model_pars;
+} CLamellarPSHGModel;
+
+
+static void
+CLamellarPSHGModel_dealloc(CLamellarPSHGModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CLamellarPSHGModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarPSHGModel *self;
+    
+    self = (CLamellarPSHGModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarPSHGModel_init(CLamellarPSHGModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"n_plates",Py_BuildValue("d",30.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"deltaT",Py_BuildValue("d",10.000000));
+        PyDict_SetItemString(self->params,"spacing",Py_BuildValue("d",40.000000));
+        PyDict_SetItemString(self->params,"sld_tail",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"caille",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"sld_head",Py_BuildValue("d",0.000002));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"deltaH",Py_BuildValue("d",2.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CLamellarPSHGModel_members[] = {
+    {"params", T_OBJECT, offsetof(CLamellarPSHGModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CLamellarPSHGModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarPSHGModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CLamellarPSHGModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model_pars.spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model_pars.sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model_pars.sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarPSHGModelError, 
+	    	"CLamellarPSHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSHGModelError, 
+	    		"CLamellarPSHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",lamellarPS_HG_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarPSHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarPS_HG_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarPSHGModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model_pars.spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model_pars.sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model_pars.sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarPSHGModelError, 
+	    	"CLamellarPSHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSHGModelError, 
+	    		"CLamellarPSHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",lamellarPS_HG_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarPSHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarPS_HG_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarPSHGModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CLamellarPSHGModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CLamellarPSHGModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarPSHGModel",             /*tp_name*/
+    sizeof(CLamellarPSHGModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarPSHGModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarPSHGModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarPSHGModel_methods,             /* tp_methods */
+    CLamellarPSHGModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarPSHGModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarPSHGModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarPSHGModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarPSHGModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarPSHGModelType);
+    PyModule_AddObject(module, "CLamellarPSHGModel", (PyObject *)&CLamellarPSHGModelType);
+    
+    d = PyModule_GetDict(module);
+    CLamellarPSHGModelError = PyErr_NewException("CLamellarPSHGModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarPSHGModelError", CLamellarPSHGModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CLamellarPSModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CLamellarPSModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CLamellarPSModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,302 @@
+/** CLamellarPSModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY lamellarPS.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "lamellarPS.h"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarPSModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	LamellarPSParameters model_pars;
+} CLamellarPSModel;
+
+
+static void
+CLamellarPSModel_dealloc(CLamellarPSModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CLamellarPSModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarPSModel *self;
+    
+    self = (CLamellarPSModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarPSModel_init(CLamellarPSModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"n_plates",Py_BuildValue("d",20.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"spacing",Py_BuildValue("d",400.000000));
+        PyDict_SetItemString(self->params,"caille",Py_BuildValue("d",0.100000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"delta",Py_BuildValue("d",30.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000005));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CLamellarPSModel_members[] = {
+    {"params", T_OBJECT, offsetof(CLamellarPSModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CLamellarPSModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarPSModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CLamellarPSModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model_pars.caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarPSModelError, 
+	    	"CLamellarPSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSModelError, 
+	    		"CLamellarPSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",lamellarPS_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarPSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarPS_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarPSModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model_pars.caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLamellarPSModelError, 
+	    	"CLamellarPSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSModelError, 
+	    		"CLamellarPSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",lamellarPS_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarPSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",lamellarPS_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarPSModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CLamellarPSModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CLamellarPSModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarPSModel",             /*tp_name*/
+    sizeof(CLamellarPSModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarPSModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarPSModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarPSModel_methods,             /* tp_methods */
+    CLamellarPSModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarPSModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarPSModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarPSModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarPSModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarPSModelType);
+    PyModule_AddObject(module, "CLamellarPSModel", (PyObject *)&CLamellarPSModelType);
+    
+    d = PyModule_GetDict(module);
+    CLamellarPSModelError = PyErr_NewException("CLamellarPSModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarPSModelError", CLamellarPSModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CMultiShellModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CMultiShellModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CMultiShellModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,305 @@
+/** CMultiShellModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY multishell.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "multishell.h"
+
+/// Error object for raised exceptions
+static PyObject * CMultiShellModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	MultiShellParameters model_pars;
+} CMultiShellModel;
+
+
+static void
+CMultiShellModel_dealloc(CMultiShellModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CMultiShellModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CMultiShellModel *self;
+    
+    self = (CMultiShellModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CMultiShellModel_init(CMultiShellModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"core_radius",Py_BuildValue("d",60.000000));
+        PyDict_SetItemString(self->params,"n_pairs",Py_BuildValue("d",2.000000));
+        PyDict_SetItemString(self->params,"w_thickness",Py_BuildValue("d",10.000000));
+        PyDict_SetItemString(self->params,"s_thickness",Py_BuildValue("d",10.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CMultiShellModel_members[] = {
+    {"params", T_OBJECT, offsetof(CMultiShellModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CMultiShellModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CMultiShellModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CMultiShellModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model_pars.w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model_pars.s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMultiShellModelError, 
+	    	"CMultiShellModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CMultiShellModelError, 
+	    		"CMultiShellModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",multishell_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CMultiShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",multishell_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CMultiShellModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model_pars.w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model_pars.s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMultiShellModelError, 
+	    	"CMultiShellModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CMultiShellModelError, 
+	    		"CMultiShellModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",multishell_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CMultiShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",multishell_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CMultiShellModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CMultiShellModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CMultiShellModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CMultiShellModel",             /*tp_name*/
+    sizeof(CMultiShellModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CMultiShellModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CMultiShellModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CMultiShellModel_methods,             /* tp_methods */
+    CMultiShellModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CMultiShellModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CMultiShellModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCMultiShellModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CMultiShellModelType) < 0)
+        return;
+
+    Py_INCREF(&CMultiShellModelType);
+    PyModule_AddObject(module, "CMultiShellModel", (PyObject *)&CMultiShellModelType);
+    
+    d = PyModule_GetDict(module);
+    CMultiShellModelError = PyErr_NewException("CMultiShellModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CMultiShellModelError", CMultiShellModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/COblateModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/COblateModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/COblateModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,311 @@
+/** COblateModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY oblate.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "oblate.h"
+
+/// Error object for raised exceptions
+static PyObject * COblateModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	OblateParameters model_pars;
+} COblateModel;
+
+
+static void
+COblateModel_dealloc(COblateModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+COblateModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    COblateModel *self;
+    
+    self = (COblateModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+COblateModel_init(COblateModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"major_core",Py_BuildValue("d",200.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"minor_core",Py_BuildValue("d",20.000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"major_shell",Py_BuildValue("d",250.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000001));
+        PyDict_SetItemString(self->params,"minor_shell",Py_BuildValue("d",30.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef COblateModel_members[] = {
+    {"params", T_OBJECT, offsetof(COblateModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(COblateModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double COblateModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(COblateModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.major_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_core") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.minor_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_core") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.major_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_shell") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+    self->model_pars.minor_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_shell") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(COblateModelError, 
+	    	"COblateModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(COblateModelError, 
+	    		"COblateModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = COblateModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = COblateModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",oblate_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = COblateModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",oblate_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(COblateModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.major_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_core") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.minor_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_core") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.major_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_shell") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+    self->model_pars.minor_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_shell") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(COblateModelError, 
+	    	"COblateModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(COblateModelError, 
+	    		"COblateModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = COblateModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = COblateModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",oblate_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = COblateModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",oblate_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(COblateModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef COblateModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject COblateModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "COblateModel",             /*tp_name*/
+    sizeof(COblateModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)COblateModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "COblateModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    COblateModel_methods,             /* tp_methods */
+    COblateModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)COblateModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    COblateModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCOblateModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&COblateModelType) < 0)
+        return;
+
+    Py_INCREF(&COblateModelType);
+    PyModule_AddObject(module, "COblateModel", (PyObject *)&COblateModelType);
+    
+    d = PyModule_GetDict(module);
+    COblateModelError = PyErr_NewException("COblateModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "COblateModelError", COblateModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CProlateModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CProlateModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CProlateModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,305 @@
+/** CProlateModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY prolate.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "prolate.h"
+
+/// Error object for raised exceptions
+static PyObject * CProlateModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	ProlateParameters model_pars;
+} CProlateModel;
+
+
+static void
+CProlateModel_dealloc(CProlateModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CProlateModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CProlateModel *self;
+    
+    self = (CProlateModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CProlateModel_init(CProlateModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"major_core",Py_BuildValue("d",100.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"minor_core",Py_BuildValue("d",50.000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"major_shell",Py_BuildValue("d",110.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000001));
+        PyDict_SetItemString(self->params,"minor_shell",Py_BuildValue("d",60.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CProlateModel_members[] = {
+    {"params", T_OBJECT, offsetof(CProlateModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CProlateModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CProlateModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CProlateModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.major_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_core") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.minor_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_core") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.major_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_shell") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+    self->model_pars.minor_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_shell") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CProlateModelError, 
+	    	"CProlateModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CProlateModelError, 
+	    		"CProlateModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CProlateModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CProlateModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",prolate_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CProlateModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",prolate_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CProlateModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.major_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_core") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.minor_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_core") );
+    self->model_pars.sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.major_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "major_shell") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+    self->model_pars.minor_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "minor_shell") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CProlateModelError, 
+	    	"CProlateModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CProlateModelError, 
+	    		"CProlateModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CProlateModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CProlateModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",prolate_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CProlateModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",prolate_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CProlateModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CProlateModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CProlateModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CProlateModel",             /*tp_name*/
+    sizeof(CProlateModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CProlateModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CProlateModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CProlateModel_methods,             /* tp_methods */
+    CProlateModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CProlateModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CProlateModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCProlateModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CProlateModelType) < 0)
+        return;
+
+    Py_INCREF(&CProlateModelType);
+    PyModule_AddObject(module, "CProlateModel", (PyObject *)&CProlateModelType);
+    
+    d = PyModule_GetDict(module);
+    CProlateModelError = PyErr_NewException("CProlateModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CProlateModelError", CProlateModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CSquareWellStructure.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CSquareWellStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CSquareWellStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,293 @@
+/** CSquareWellStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY SquareWell.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "SquareWell.h"
+
+/// Error object for raised exceptions
+static PyObject * CSquareWellStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	SquareWellParameters model_pars;
+} CSquareWellStructure;
+
+
+static void
+CSquareWellStructure_dealloc(CSquareWellStructure* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CSquareWellStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSquareWellStructure *self;
+    
+    self = (CSquareWellStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSquareWellStructure_init(CSquareWellStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",50.000000));
+        PyDict_SetItemString(self->params,"welldepth",Py_BuildValue("d",1.500000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.040000));
+        PyDict_SetItemString(self->params,"wellwidth",Py_BuildValue("d",1.200000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CSquareWellStructure_members[] = {
+    {"params", T_OBJECT, offsetof(CSquareWellStructure, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CSquareWellStructure, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSquareWellStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CSquareWellStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSquareWellStructureError, 
+	    	"CSquareWellStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSquareWellStructureError, 
+	    		"CSquareWellStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",SquareWell_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CSquareWellStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",SquareWell_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSquareWellStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSquareWellStructureError, 
+	    	"CSquareWellStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSquareWellStructureError, 
+	    		"CSquareWellStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",SquareWell_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CSquareWellStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",SquareWell_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CSquareWellStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CSquareWellStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CSquareWellStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSquareWellStructure",             /*tp_name*/
+    sizeof(CSquareWellStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSquareWellStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CSquareWellStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSquareWellStructure_methods,             /* tp_methods */
+    CSquareWellStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSquareWellStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSquareWellStructure_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCSquareWellStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSquareWellStructureType) < 0)
+        return;
+
+    Py_INCREF(&CSquareWellStructureType);
+    PyModule_AddObject(module, "CSquareWellStructure", (PyObject *)&CSquareWellStructureType);
+    
+    d = PyModule_GetDict(module);
+    CSquareWellStructureError = PyErr_NewException("CSquareWellStructure.error", NULL, NULL);
+    PyDict_SetItemString(d, "CSquareWellStructureError", CSquareWellStructureError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CStackedDisksModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CStackedDisksModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CStackedDisksModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,317 @@
+/** CStackedDisksModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY stacked_disks.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "stacked_disks.h"
+
+/// Error object for raised exceptions
+static PyObject * CStackedDisksModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	StackedDisksParameters model_pars;
+} CStackedDisksModel;
+
+
+static void
+CStackedDisksModel_dealloc(CStackedDisksModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CStackedDisksModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CStackedDisksModel *self;
+    
+    self = (CStackedDisksModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CStackedDisksModel_init(CStackedDisksModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000004));
+        PyDict_SetItemString(self->params,"core_thick",Py_BuildValue("d",10.000000));
+        PyDict_SetItemString(self->params,"layer_thick",Py_BuildValue("d",15.000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"layer_sld",Py_BuildValue("d",-0.000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000005));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",0.010000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",3000.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000));
+        PyDict_SetItemString(self->params,"sigma_d",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"n_stacking",Py_BuildValue("d",1.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CStackedDisksModel_members[] = {
+    {"params", T_OBJECT, offsetof(CStackedDisksModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CStackedDisksModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CStackedDisksModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CStackedDisksModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model_pars.layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model_pars.n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CStackedDisksModelError, 
+	    	"CStackedDisksModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStackedDisksModelError, 
+	    		"CStackedDisksModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",stacked_disks_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CStackedDisksModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",stacked_disks_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CStackedDisksModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model_pars.layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model_pars.n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CStackedDisksModelError, 
+	    	"CStackedDisksModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStackedDisksModelError, 
+	    		"CStackedDisksModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",stacked_disks_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CStackedDisksModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",stacked_disks_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CStackedDisksModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CStackedDisksModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CStackedDisksModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CStackedDisksModel",             /*tp_name*/
+    sizeof(CStackedDisksModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CStackedDisksModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CStackedDisksModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CStackedDisksModel_methods,             /* tp_methods */
+    CStackedDisksModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CStackedDisksModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CStackedDisksModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCStackedDisksModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CStackedDisksModelType) < 0)
+        return;
+
+    Py_INCREF(&CStackedDisksModelType);
+    PyModule_AddObject(module, "CStackedDisksModel", (PyObject *)&CStackedDisksModelType);
+    
+    d = PyModule_GetDict(module);
+    CStackedDisksModelError = PyErr_NewException("CStackedDisksModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CStackedDisksModelError", CStackedDisksModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CStickyHSStructure.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CStickyHSStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CStickyHSStructure.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,293 @@
+/** CStickyHSStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY StickyHS.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "StickyHS.h"
+
+/// Error object for raised exceptions
+static PyObject * CStickyHSStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	StickyHSParameters model_pars;
+} CStickyHSStructure;
+
+
+static void
+CStickyHSStructure_dealloc(CStickyHSStructure* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CStickyHSStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CStickyHSStructure *self;
+    
+    self = (CStickyHSStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CStickyHSStructure_init(CStickyHSStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",50.000000));
+        PyDict_SetItemString(self->params,"stickiness",Py_BuildValue("d",0.200000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.100000));
+        PyDict_SetItemString(self->params,"perturb",Py_BuildValue("d",0.050000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CStickyHSStructure_members[] = {
+    {"params", T_OBJECT, offsetof(CStickyHSStructure, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CStickyHSStructure, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CStickyHSStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CStickyHSStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CStickyHSStructureError, 
+	    	"CStickyHSStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStickyHSStructureError, 
+	    		"CStickyHSStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",StickyHS_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CStickyHSStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",StickyHS_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CStickyHSStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model_pars.stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model_pars.volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model_pars.perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CStickyHSStructureError, 
+	    	"CStickyHSStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStickyHSStructureError, 
+	    		"CStickyHSStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",StickyHS_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CStickyHSStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",StickyHS_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CStickyHSStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CStickyHSStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CStickyHSStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CStickyHSStructure",             /*tp_name*/
+    sizeof(CStickyHSStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CStickyHSStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CStickyHSStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CStickyHSStructure_methods,             /* tp_methods */
+    CStickyHSStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CStickyHSStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CStickyHSStructure_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCStickyHSStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CStickyHSStructureType) < 0)
+        return;
+
+    Py_INCREF(&CStickyHSStructureType);
+    PyModule_AddObject(module, "CStickyHSStructure", (PyObject *)&CStickyHSStructureType);
+    
+    d = PyModule_GetDict(module);
+    CStickyHSStructureError = PyErr_NewException("CStickyHSStructure.error", NULL, NULL);
+    PyDict_SetItemString(d, "CStickyHSStructureError", CStickyHSStructureError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CTriaxialEllipsoidModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CTriaxialEllipsoidModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CTriaxialEllipsoidModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,308 @@
+/** CTriaxialEllipsoidModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY triaxial_ellipsoid.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "triaxial_ellipsoid.h"
+
+/// Error object for raised exceptions
+static PyObject * CTriaxialEllipsoidModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	TriaxialEllipsoidParameters model_pars;
+} CTriaxialEllipsoidModel;
+
+
+static void
+CTriaxialEllipsoidModel_dealloc(CTriaxialEllipsoidModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CTriaxialEllipsoidModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CTriaxialEllipsoidModel *self;
+    
+    self = (CTriaxialEllipsoidModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CTriaxialEllipsoidModel_init(CTriaxialEllipsoidModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"axis_psi",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"semi_axisA",Py_BuildValue("d",35.000000));
+        PyDict_SetItemString(self->params,"semi_axisB",Py_BuildValue("d",100.000000));
+        PyDict_SetItemString(self->params,"semi_axisC",Py_BuildValue("d",400.000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"contrast",Py_BuildValue("d",0.000005));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CTriaxialEllipsoidModel_members[] = {
+    {"params", T_OBJECT, offsetof(CTriaxialEllipsoidModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CTriaxialEllipsoidModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CTriaxialEllipsoidModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CTriaxialEllipsoidModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model_pars.semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model_pars.semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    	"CTriaxialEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    		"CTriaxialEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",triaxial_ellipsoid_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CTriaxialEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",triaxial_ellipsoid_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CTriaxialEllipsoidModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model_pars.axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model_pars.semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model_pars.semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model_pars.semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model_pars.axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.contrast = PyFloat_AsDouble( PyDict_GetItemString(self->params, "contrast") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    	"CTriaxialEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    		"CTriaxialEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",triaxial_ellipsoid_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CTriaxialEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",triaxial_ellipsoid_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CTriaxialEllipsoidModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CTriaxialEllipsoidModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CTriaxialEllipsoidModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CTriaxialEllipsoidModel",             /*tp_name*/
+    sizeof(CTriaxialEllipsoidModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CTriaxialEllipsoidModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CTriaxialEllipsoidModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CTriaxialEllipsoidModel_methods,             /* tp_methods */
+    CTriaxialEllipsoidModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CTriaxialEllipsoidModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CTriaxialEllipsoidModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCTriaxialEllipsoidModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CTriaxialEllipsoidModelType) < 0)
+        return;
+
+    Py_INCREF(&CTriaxialEllipsoidModelType);
+    PyModule_AddObject(module, "CTriaxialEllipsoidModel", (PyObject *)&CTriaxialEllipsoidModelType);
+    
+    d = PyModule_GetDict(module);
+    CTriaxialEllipsoidModelError = PyErr_NewException("CTriaxialEllipsoidModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CTriaxialEllipsoidModelError", CTriaxialEllipsoidModelError);
+}
+
Index: sansmodels/src/sans/models/c_extensions/CVesicleModel.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CVesicleModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_extensions/CVesicleModel.c	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,299 @@
+/** CVesicleModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY vesicle.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "vesicle.h"
+
+/// Error object for raised exceptions
+static PyObject * CVesicleModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	VesicleParameters model_pars;
+} CVesicleModel;
+
+
+static void
+CVesicleModel_dealloc(CVesicleModel* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CVesicleModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CVesicleModel *self;
+    
+    self = (CVesicleModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CVesicleModel_init(CVesicleModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000006));
+        PyDict_SetItemString(self->params,"core_radius",Py_BuildValue("d",100.000000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",30.000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000000));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CVesicleModel_members[] = {
+    {"params", T_OBJECT, offsetof(CVesicleModel, params), 0,
+     "Parameters"},
+    {"log", T_OBJECT, offsetof(CVesicleModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CVesicleModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CVesicleModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CVesicleModelError, 
+	    	"CVesicleModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CVesicleModelError, 
+	    		"CVesicleModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",vesicle_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CVesicleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",vesicle_analytical_1D(&(self->model_pars),q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CVesicleModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	// Reader parameter dictionary
+    self->model_pars.core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model_pars.core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model_pars.thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model_pars.shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CVesicleModelError, 
+	    	"CVesicleModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CVesicleModelError, 
+	    		"CVesicleModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,1));
+		return Py_BuildValue("d",vesicle_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CVesicleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",vesicle_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CVesicleModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+static PyMethodDef CVesicleModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    //{"numerical_1D",      (PyCFunction)numerical_1D     , METH_VARARGS,
+    //  "Evaluate the 1D model at a given Q"},
+   {NULL}
+};
+
+static PyTypeObject CVesicleModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CVesicleModel",             /*tp_name*/
+    sizeof(CVesicleModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CVesicleModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CVesicleModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CVesicleModel_methods,             /* tp_methods */
+    CVesicleModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CVesicleModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CVesicleModel_new,                 /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+    {NULL} 
+};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCVesicleModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CVesicleModelType) < 0)
+        return;
+
+    Py_INCREF(&CVesicleModelType);
+    PyModule_AddObject(module, "CVesicleModel", (PyObject *)&CVesicleModelType);
+    
+    d = PyModule_GetDict(module);
+    CVesicleModelError = PyErr_NewException("CVesicleModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "CVesicleModelError", CVesicleModelError);
+}
+
Index: sansmodels/src/sans/models/c_models/CBinaryHSModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CBinaryHSModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CBinaryHSModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -204,6 +204,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -291,9 +291,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CBinaryHSModelError, 
+	}
+	PyErr_SetString(CBinaryHSModelError, 
                    "CBinaryHSModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CBinaryHSPSF11Model.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CBinaryHSPSF11Model.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CBinaryHSPSF11Model.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -204,6 +204,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -291,9 +291,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CBinaryHSPSF11ModelError, 
+	}
+	PyErr_SetString(CBinaryHSPSF11ModelError, 
                    "CBinaryHSPSF11Model.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CCoreShellCylinderModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CCoreShellCylinderModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CCoreShellCylinderModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -215,6 +215,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -310,9 +310,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CCoreShellCylinderModelError, 
+	}
+	PyErr_SetString(CCoreShellCylinderModelError, 
                    "CCoreShellCylinderModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CCoreShellEllipsoidModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CCoreShellEllipsoidModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CCoreShellEllipsoidModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -218,6 +218,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -315,9 +315,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CCoreShellEllipsoidModelError, 
+	}
+	PyErr_SetString(CCoreShellEllipsoidModelError, 
                    "CCoreShellEllipsoidModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CCoreShellModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CCoreShellModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CCoreShellModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -203,6 +203,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -289,9 +289,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CCoreShellModelError, 
+	}
+	PyErr_SetString(CCoreShellModelError, 
                    "CCoreShellModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CCylinderModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CCylinderModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CCylinderModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -209,6 +209,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -299,9 +299,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CCylinderModelError, 
+	}
+	PyErr_SetString(CCylinderModelError, 
                    "CCylinderModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CDiamCylFunc.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CDiamCylFunc.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CDiamCylFunc.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -198,6 +198,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -279,9 +279,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CDiamCylFuncError, 
+	}
+	PyErr_SetString(CDiamCylFuncError, 
                    "CDiamCylFunc.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CDiamEllipFunc.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CDiamEllipFunc.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CDiamEllipFunc.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -198,6 +198,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -279,9 +279,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CDiamEllipFuncError, 
+	}
+	PyErr_SetString(CDiamEllipFuncError, 
                    "CDiamEllipFunc.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CEllipsoidModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CEllipsoidModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CEllipsoidModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -209,6 +209,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -299,9 +299,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CEllipsoidModelError, 
+	}
+	PyErr_SetString(CEllipsoidModelError, 
                    "CEllipsoidModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CEllipticalCylinderModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CEllipticalCylinderModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CEllipticalCylinderModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -217,6 +217,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -313,9 +313,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CEllipticalCylinderModelError, 
+	}
+	PyErr_SetString(CEllipticalCylinderModelError, 
                    "CEllipticalCylinderModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CFlexibleCylinderModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CFlexibleCylinderModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CFlexibleCylinderModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -205,6 +205,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -292,9 +292,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CFlexibleCylinderModelError, 
+	}
+	PyErr_SetString(CFlexibleCylinderModelError, 
                    "CFlexibleCylinderModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CGaussian.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CGaussian.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CGaussian.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -193,6 +193,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -271,9 +271,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CGaussianError, 
+	}
+	PyErr_SetString(CGaussianError, 
                    "CGaussian.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CHardsphereStructure.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CHardsphereStructure.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CHardsphereStructure.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -195,6 +195,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -274,9 +274,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CHardsphereStructureError, 
+	}
+	PyErr_SetString(CHardsphereStructureError, 
                    "CHardsphereStructure.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CHayterMSAStructure.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CHayterMSAStructure.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CHayterMSAStructure.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -199,6 +199,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -282,9 +282,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CHayterMSAStructureError, 
+	}
+	PyErr_SetString(CHayterMSAStructureError, 
                    "CHayterMSAStructure.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CHollowCylinderModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CHollowCylinderModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CHollowCylinderModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -213,6 +213,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -306,9 +306,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CHollowCylinderModelError, 
+	}
+	PyErr_SetString(CHollowCylinderModelError, 
                    "CHollowCylinderModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLamellarFFHGModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLamellarFFHGModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLamellarFFHGModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -203,6 +203,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -289,9 +289,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLamellarFFHGModelError, 
+	}
+	PyErr_SetString(CLamellarFFHGModelError, 
                    "CLamellarFFHGModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLamellarModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLamellarModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLamellarModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -198,6 +198,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -280,9 +280,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLamellarModelError, 
+	}
+	PyErr_SetString(CLamellarModelError, 
                    "CLamellarModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLamellarPSHGModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLamellarPSHGModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLamellarPSHGModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -209,6 +209,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -300,9 +300,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLamellarPSHGModelError, 
+	}
+	PyErr_SetString(CLamellarPSHGModelError, 
                    "CLamellarPSHGModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLamellarPSModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -203,6 +203,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -289,9 +289,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLamellarPSModelError, 
+	}
+	PyErr_SetString(CLamellarPSModelError, 
                    "CLamellarPSModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLogNormal.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLogNormal.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLogNormal.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -193,6 +193,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -271,9 +271,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLogNormalError, 
+	}
+	PyErr_SetString(CLogNormalError, 
                    "CLogNormal.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CLorentzian.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CLorentzian.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CLorentzian.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -193,6 +193,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -271,9 +271,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CLorentzianError, 
+	}
+	PyErr_SetString(CLorentzianError, 
                    "CLorentzian.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CMultiShellModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CMultiShellModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CMultiShellModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -207,6 +207,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -296,9 +296,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CMultiShellModelError, 
+	}
+	PyErr_SetString(CMultiShellModelError, 
                    "CMultiShellModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/COblateModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/COblateModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/COblateModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -212,6 +212,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -305,9 +305,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(COblateModelError, 
+	}
+	PyErr_SetString(COblateModelError, 
                    "COblateModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CParallelepipedModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CParallelepipedModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CParallelepipedModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -217,6 +217,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -313,9 +313,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CParallelepipedModelError, 
+	}
+	PyErr_SetString(CParallelepipedModelError, 
                    "CParallelepipedModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CProlateModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CProlateModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CProlateModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -210,6 +210,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -301,9 +301,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CProlateModelError, 
+	}
+	PyErr_SetString(CProlateModelError, 
                    "CProlateModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CSchulz.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CSchulz.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
+++ sansmodels/src/sans/models/c_models/CSchulz.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -0,0 +1,504 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2008, University of Tennessee
+ */
+
+/** CSchulz
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY schulz.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ */
+#define NO_IMPORT_ARRAY
+#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_sans
+ 
+extern "C" {
+#include <Python.h>
+#include <arrayobject.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include "schulz.h"
+}
+
+#include "models.hh"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSchulzError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Schulz * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSchulz;
+
+
+static void
+CSchulz_dealloc(CSchulz* self)
+{
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CSchulz_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSchulz *self;
+    
+    self = (CSchulz *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSchulz_init(CSchulz *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+        self->model = new Schulz();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"sigma",Py_BuildValue("d",1.000000));
+        PyDict_SetItemString(self->params,"center",Py_BuildValue("d",0.000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CSchulz_members[] = {
+    {"params", T_OBJECT, offsetof(CSchulz, params), 0,
+     "Parameters"},
+	{"dispersion", T_OBJECT, offsetof(CSchulz, dispersion), 0,
+	  "Dispersion parameters"},     
+    {"log", T_OBJECT, offsetof(CSchulz, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSchulz_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(Schulz* model, PyArrayObject *q){
+    PyArrayObject *result;
+   
+    // Check validity of array q , q must be of dimension 1, an array of double
+    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE)
+    {
+        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num;
+        //PyErr_SetString(PyExc_ValueError , message);
+        return NULL;
+    }
+    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions), 
+										  PyArray_DOUBLE);
+	if (result == NULL) {
+        const char * message= "Could not create result ";
+        PyErr_SetString(PyExc_RuntimeError , message);
+		return NULL;
+	}
+	 for (int i = 0; i < q->dimensions[0]; i++){
+      double q_value  = *(double *)(q->data + i*q->strides[0]);
+      double *result_value = (double *)(result->data + i*result->strides[0]);
+      *result_value =(*model)(q_value);
+	}
+    return PyArray_Return(result); 
+ }
+
+ /**
+ * Function to call to evaluate model
+ * @param args: input numpy array  [x[],y[]]
+ * @return: numpy array object 
+ */
+ static PyObject * evaluateTwoDimXY( Schulz* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int i,j, x_len, y_len, dims[2];
+    //check validity of input vectors
+    if (x->nd != 2 || x->descr->type_num != PyArray_DOUBLE
+        || y->nd != 2 || y->descr->type_num != PyArray_DOUBLE
+        || y->dimensions[1] != x->dimensions[0]){
+        const char * message= "evaluateTwoDimXY  expect 2 numpy arrays";
+        PyErr_SetString(PyExc_ValueError , message); 
+        return NULL;
+    }
+   
+	if (PyArray_Check(x) && PyArray_Check(y)) {
+		
+	    x_len = dims[1]= x->dimensions[1];
+        y_len = dims[0]= y->dimensions[0];
+	    
+	    // Make a new double matrix of same dims
+        result=(PyArrayObject *) PyArray_FromDims(2,dims,NPY_DOUBLE);
+        if (result == NULL){
+	    const char * message= "Could not create result ";
+        PyErr_SetString(PyExc_RuntimeError , message);
+	    return NULL;
+	    }
+       
+        /* Do the calculation. */
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
+                double x_value = *(double *)(x->data + i*x->strides[1]);
+      		    double y_value = *(double *)(y->data + j*y->strides[0]);
+      			double *result_value = (double *)(result->data +
+      			      i*result->strides[1] + j*result->strides[0]);
+      			*result_value = (*model)(x_value, y_value);
+            }           
+        }
+        return PyArray_Return(result); 
+        
+        }else{
+		    PyErr_SetString(CSchulzError, 
+                   "CSchulz.evaluateTwoDimXY couldn't run.");
+	        return NULL;
+		}      	
+}
+/**
+ *  evalDistribution function evaluate a model function with input vector
+ *  @param args: input q as vector or [qx, qy] where qx, qy are vectors
+ *
+ */ 
+static PyObject * evalDistribution(CSchulz *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.evalDistribution expects a q value.");
+		return NULL;
+	}
+    // Check params
+	
+    if(PyArray_Check(pars)==1) {
+		
+	    // Length of list should 1 or 2
+	    npars = pars->nd; 
+	    if(npars==1) {
+	        // input is a numpy array
+	        if (PyArray_Check(pars)) {
+		        return evaluateOneDim(self->model, (PyArrayObject*)pars); 
+		    }
+		}else{
+		    PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution expect numpy array of one dimension.");
+	        return NULL;
+		}
+    }else if( PyList_Check(pars)==1) {
+    	// Length of list should be 2 for I(qx,qy)
+	    mpars = PyList_GET_SIZE(pars); 
+	    if(mpars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.evalDistribution expects a list of dimension 2.");
+	    	return NULL;
+	    }
+	     qx = PyList_GET_ITEM(pars,0);
+	     qy = PyList_GET_ITEM(pars,1);
+	     if (PyArray_Check(qx) && PyArray_Check(qy)) {
+	         return evaluateTwoDimXY(self->model, (PyArrayObject*)qx,
+		           (PyArrayObject*)qy);
+		 }else{
+		    PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution couln't be run.");
+	return NULL;
+	
+}
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CSchulz *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CSchulz_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSchulz_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSchulz *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CSchulz_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSchulz_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSchulz *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSchulz *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSchulzError,
+	    	"CSchulz.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CSchulzError,
+	    	"CSchulz.set_dispersion expects a valid parameter name.");
+		return NULL;
+	}
+
+	DispersionVisitor* visitor = new DispersionVisitor();
+	PyObject * disp_dict = PyDict_New();
+	dispersion->accept_as_source(visitor, dispersion, disp_dict);
+	PyDict_SetItemString(self->dispersion, par_name, disp_dict);
+    return Py_BuildValue("i",1);
+}
+
+
+static PyMethodDef CSchulz_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+      
+    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy vector "},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    {"set_dispersion",      (PyCFunction)set_dispersion     , METH_VARARGS,
+      "Set the dispersion model for a given parameter"},
+   {NULL}
+};
+
+static PyTypeObject CSchulzType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSchulz",             /*tp_name*/
+    sizeof(CSchulz),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSchulz_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CSchulz objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSchulz_methods,             /* tp_methods */
+    CSchulz_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSchulz_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSchulz_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCSchulz(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSchulzType) < 0)
+        return;
+
+    Py_INCREF(&CSchulzType);
+    PyModule_AddObject(module, "CSchulz", (PyObject *)&CSchulzType);
+    
+    d = PyModule_GetDict(module);
+    CSchulzError = PyErr_NewException("CSchulz.error", NULL, NULL);
+    PyDict_SetItemString(d, "CSchulzError", CSchulzError);
+}
+
Index: sansmodels/src/sans/models/c_models/CSphereModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CSphereModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CSphereModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -197,6 +197,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -278,9 +278,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CSphereModelError, 
+	}
+	PyErr_SetString(CSphereModelError, 
                    "CSphereModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CSquareWellStructure.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CSquareWellStructure.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CSquareWellStructure.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -197,6 +197,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -278,9 +278,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CSquareWellStructureError, 
+	}
+	PyErr_SetString(CSquareWellStructureError, 
                    "CSquareWellStructure.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CStackedDisksModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CStackedDisksModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CStackedDisksModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -217,6 +217,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -314,9 +314,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CStackedDisksModelError, 
+	}
+	PyErr_SetString(CStackedDisksModelError, 
                    "CStackedDisksModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CStickyHSStructure.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CStickyHSStructure.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CStickyHSStructure.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -197,6 +197,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -278,9 +278,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CStickyHSStructureError, 
+	}
+	PyErr_SetString(CStickyHSStructureError, 
                    "CStickyHSStructure.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CTriaxialEllipsoidModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CTriaxialEllipsoidModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CTriaxialEllipsoidModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -208,6 +208,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -298,9 +298,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CTriaxialEllipsoidModelError, 
+	}
+	PyErr_SetString(CTriaxialEllipsoidModelError, 
                    "CTriaxialEllipsoidModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/CVesicleModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/CVesicleModel.cpp	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/CVesicleModel.cpp	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -202,6 +202,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -287,9 +287,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString(CVesicleModelError, 
+	}
+	PyErr_SetString(CVesicleModelError, 
                    "CVesicleModel.evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
Index: sansmodels/src/sans/models/c_models/classTemplate.txt
===================================================================
--- sansmodels/src/sans/models/c_models/classTemplate.txt	(revision a8d6888a4aca60748f072915b7116a8daf50636b)
+++ sansmodels/src/sans/models/c_models/classTemplate.txt	(revision e0a8a3ccbb7fa14ab3d063bb6214bb4828593f76)
@@ -183,6 +183,6 @@
        
         /* Do the calculation. */
-        for ( i=0; i< x_len; i++) {
-            for ( j=0; j< y_len; j++) {
+        for ( j=0; j< y_len; j++) {
+            for ( i=0; i< x_len; i++) {
                 double x_value = *(double *)(x->data + i*x->strides[1]);
       		    double y_value = *(double *)(y->data + j*y->strides[0]);
@@ -254,9 +254,9 @@
 	        return NULL;
 	     }
-	}else{
-	    PyErr_SetString([PYTHONCLASS]Error, 
+	}
+	PyErr_SetString([PYTHONCLASS]Error, 
                    "[PYTHONCLASS].evalDistribution couln't be run.");
-	    return NULL;
-	}
+	return NULL;
+	
 }
 
