Index: sansmodels/src/sans/models/c_models/COnionModel.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/COnionModel.cpp	(revision e096270047b0757e07e7187aa5de071c857a7e13)
+++ sansmodels/src/sans/models/c_models/COnionModel.cpp	(revision e096270047b0757e07e7187aa5de071c857a7e13)
@@ -0,0 +1,938 @@
+/**
+	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
+ */
+
+/** COnionModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY onion.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 "onion.h"
+}
+
+#include "models.hh"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * COnionModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    OnionModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} COnionModel;
+
+
+static void
+COnionModel_dealloc(COnionModel* self)
+{
+    Py_DECREF(self->params);
+    Py_DECREF(self->dispersion);
+    Py_DECREF(self->log);
+    delete self->model;
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+COnionModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    COnionModel *self;
+    
+    self = (COnionModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+COnionModel_init(COnionModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+        self->model = new OnionModel();
+        
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"thick_shell4",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"thick_shell5",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"thick_shell9",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"thick_shell7",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"A_shell10",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"thick_shell1",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"func_shell4",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"func_shell5",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"func_shell6",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"func_shell1",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"thick_shell10",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"func_shell3",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"rad_core",Py_BuildValue("d",200.00000000));
+        PyDict_SetItemString(self->params,"thick_shell3",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"func_shell8",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"func_shell9",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"sld_in_shell5",Py_BuildValue("d",0.00000370));
+        PyDict_SetItemString(self->params,"func_shell10",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"sld_in_shell4",Py_BuildValue("d",0.00000320));
+        PyDict_SetItemString(self->params,"sld_in_shell7",Py_BuildValue("d",0.00000470));
+        PyDict_SetItemString(self->params,"sld_out_shell9",Py_BuildValue("d",0.00000600));
+        PyDict_SetItemString(self->params,"sld_out_shell8",Py_BuildValue("d",0.00000550));
+        PyDict_SetItemString(self->params,"thick_shell6",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"sld_out_shell2",Py_BuildValue("d",0.00000250));
+        PyDict_SetItemString(self->params,"sld_in_shell9",Py_BuildValue("d",0.00000570));
+        PyDict_SetItemString(self->params,"sld_in_shell8",Py_BuildValue("d",0.00000520));
+        PyDict_SetItemString(self->params,"thick_shell2",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"sld_core",Py_BuildValue("d",0.00000100));
+        PyDict_SetItemString(self->params,"sld_out_shell1",Py_BuildValue("d",0.00000200));
+        PyDict_SetItemString(self->params,"sld_in_shell1",Py_BuildValue("d",0.00000170));
+        PyDict_SetItemString(self->params,"sld_out_shell3",Py_BuildValue("d",0.00000300));
+        PyDict_SetItemString(self->params,"sld_in_shell6",Py_BuildValue("d",0.00000420));
+        PyDict_SetItemString(self->params,"sld_out_shell5",Py_BuildValue("d",0.00000400));
+        PyDict_SetItemString(self->params,"sld_out_shell4",Py_BuildValue("d",0.00000350));
+        PyDict_SetItemString(self->params,"sld_in_shell3",Py_BuildValue("d",0.00000270));
+        PyDict_SetItemString(self->params,"sld_out_shell6",Py_BuildValue("d",0.00000450));
+        PyDict_SetItemString(self->params,"func_shell7",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"sld_out_shell7",Py_BuildValue("d",0.00000500));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.00000000));
+        PyDict_SetItemString(self->params,"n_shells",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"sld_in_shell2",Py_BuildValue("d",0.00000220));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.00000640));
+        PyDict_SetItemString(self->params,"func_shell2",Py_BuildValue("d",2.00000000));
+        PyDict_SetItemString(self->params,"thick_shell8",Py_BuildValue("d",50.00000000));
+        PyDict_SetItemString(self->params,"sld_out_shell10",Py_BuildValue("d",0.00000620));
+        PyDict_SetItemString(self->params,"sld_in_shell10",Py_BuildValue("d",0.00000600));
+        PyDict_SetItemString(self->params,"A_shell8",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell9",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell6",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell7",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell4",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell5",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell2",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell3",Py_BuildValue("d",1.00000000));
+        PyDict_SetItemString(self->params,"A_shell1",Py_BuildValue("d",1.00000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_core.dispersion->accept_as_source(visitor, self->model->rad_core.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_core", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell1.dispersion->accept_as_source(visitor, self->model->thick_shell1.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell1", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell2.dispersion->accept_as_source(visitor, self->model->thick_shell2.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell2", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell3.dispersion->accept_as_source(visitor, self->model->thick_shell3.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell3", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell4.dispersion->accept_as_source(visitor, self->model->thick_shell4.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell4", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell5.dispersion->accept_as_source(visitor, self->model->thick_shell5.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell5", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell6.dispersion->accept_as_source(visitor, self->model->thick_shell6.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell6", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell7.dispersion->accept_as_source(visitor, self->model->thick_shell7.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell7", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell8.dispersion->accept_as_source(visitor, self->model->thick_shell8.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell8", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell9.dispersion->accept_as_source(visitor, self->model->thick_shell9.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell9", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_shell10.dispersion->accept_as_source(visitor, self->model->thick_shell10.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_shell10", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef COnionModel_members[] = {
+    {"params", T_OBJECT, offsetof(COnionModel, params), 0,
+     "Parameters"},
+	{"dispersion", T_OBJECT, offsetof(COnionModel, dispersion), 0,
+	  "Dispersion parameters"},     
+    {"log", T_OBJECT, offsetof(COnionModel, log), 0,
+     "Log"},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double COnionModel_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(OnionModel* 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( OnionModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int i,j, x_len, y_len, dims[1];
+    //check validity of input vectors
+    if (x->nd != 1 || x->descr->type_num != PyArray_DOUBLE
+        || y->nd != 1 || y->descr->type_num != PyArray_DOUBLE
+        || y->dimensions[0] != 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[0]= x->dimensions[0];
+        y_len = dims[0]= y->dimensions[0];
+	    
+	    // Make a new double matrix of same dims
+        result=(PyArrayObject *) PyArray_FromDims(1,dims,NPY_DOUBLE);
+        if (result == NULL){
+	    const char * message= "Could not create result ";
+        PyErr_SetString(PyExc_RuntimeError , message);
+	    return NULL;
+	    }
+       
+        /* Do the calculation. */
+        for ( i=0; i< x_len; i++) {
+            double x_value = *(double *)(x->data + i*x->strides[0]);
+  		    double y_value = *(double *)(y->data + i*y->strides[0]);
+  			double *result_value = (double *)(result->data +
+  			      i*result->strides[0]);
+  			*result_value = (*model)(x_value, y_value);
+        }           
+        return PyArray_Return(result); 
+        
+        }else{
+		    PyErr_SetString(COnionModelError, 
+                   "COnionModel.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(COnionModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->thick_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell5") );
+    self->model->thick_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell9") );
+    self->model->thick_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell7") );
+    self->model->A_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell10") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->func_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell4") );
+    self->model->func_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell5") );
+    self->model->func_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell6") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell1") );
+    self->model->thick_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell10") );
+    self->model->func_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell3") );
+    self->model->rad_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->func_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell8") );
+    self->model->func_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell9") );
+    self->model->sld_in_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell5") );
+    self->model->func_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell10") );
+    self->model->sld_in_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell4") );
+    self->model->sld_in_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell7") );
+    self->model->sld_out_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell9") );
+    self->model->sld_out_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell8") );
+    self->model->thick_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell6") );
+    self->model->sld_out_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell2") );
+    self->model->sld_in_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell9") );
+    self->model->sld_in_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell8") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    self->model->sld_out_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell3") );
+    self->model->sld_in_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell6") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    self->model->sld_out_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell4") );
+    self->model->sld_in_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell3") );
+    self->model->sld_out_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell6") );
+    self->model->func_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell7") );
+    self->model->sld_out_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell7") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->n_shells = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_shells") );
+    self->model->sld_in_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell2") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell2") );
+    self->model->thick_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell8") );
+    self->model->sld_out_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell10") );
+    self->model->sld_in_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell10") );
+    self->model->A_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell8") );
+    self->model->A_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell9") );
+    self->model->A_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell6") );
+    self->model->A_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell7") );
+    self->model->A_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell4") );
+    self->model->A_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell5") );
+    self->model->A_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell2") );
+    self->model->A_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell3") );
+    self->model->A_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell1") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core");
+    self->model->rad_core.dispersion->accept_as_destination(visitor, self->model->rad_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell1");
+    self->model->thick_shell1.dispersion->accept_as_destination(visitor, self->model->thick_shell1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell2");
+    self->model->thick_shell2.dispersion->accept_as_destination(visitor, self->model->thick_shell2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell3");
+    self->model->thick_shell3.dispersion->accept_as_destination(visitor, self->model->thick_shell3.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell4");
+    self->model->thick_shell4.dispersion->accept_as_destination(visitor, self->model->thick_shell4.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell5");
+    self->model->thick_shell5.dispersion->accept_as_destination(visitor, self->model->thick_shell5.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell6");
+    self->model->thick_shell6.dispersion->accept_as_destination(visitor, self->model->thick_shell6.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell7");
+    self->model->thick_shell7.dispersion->accept_as_destination(visitor, self->model->thick_shell7.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell8");
+    self->model->thick_shell8.dispersion->accept_as_destination(visitor, self->model->thick_shell8.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell9");
+    self->model->thick_shell9.dispersion->accept_as_destination(visitor, self->model->thick_shell9.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell10");
+    self->model->thick_shell10.dispersion->accept_as_destination(visitor, self->model->thick_shell10.dispersion, disp_dict);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(COnionModelError, 
+	    	"COnionModel.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(COnionModelError, 
+                   "COnionModel.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(COnionModelError, 
+	    		"COnionModel.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(COnionModelError, 
+                   "COnionModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(COnionModelError, 
+                   "COnionModel.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(COnionModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->thick_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell5") );
+    self->model->thick_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell9") );
+    self->model->thick_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell7") );
+    self->model->A_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell10") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->func_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell4") );
+    self->model->func_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell5") );
+    self->model->func_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell6") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell1") );
+    self->model->thick_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell10") );
+    self->model->func_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell3") );
+    self->model->rad_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->func_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell8") );
+    self->model->func_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell9") );
+    self->model->sld_in_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell5") );
+    self->model->func_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell10") );
+    self->model->sld_in_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell4") );
+    self->model->sld_in_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell7") );
+    self->model->sld_out_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell9") );
+    self->model->sld_out_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell8") );
+    self->model->thick_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell6") );
+    self->model->sld_out_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell2") );
+    self->model->sld_in_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell9") );
+    self->model->sld_in_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell8") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    self->model->sld_out_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell3") );
+    self->model->sld_in_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell6") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    self->model->sld_out_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell4") );
+    self->model->sld_in_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell3") );
+    self->model->sld_out_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell6") );
+    self->model->func_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell7") );
+    self->model->sld_out_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell7") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->n_shells = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_shells") );
+    self->model->sld_in_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell2") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell2") );
+    self->model->thick_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell8") );
+    self->model->sld_out_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell10") );
+    self->model->sld_in_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell10") );
+    self->model->A_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell8") );
+    self->model->A_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell9") );
+    self->model->A_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell6") );
+    self->model->A_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell7") );
+    self->model->A_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell4") );
+    self->model->A_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell5") );
+    self->model->A_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell2") );
+    self->model->A_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell3") );
+    self->model->A_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell1") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core");
+    self->model->rad_core.dispersion->accept_as_destination(visitor, self->model->rad_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell1");
+    self->model->thick_shell1.dispersion->accept_as_destination(visitor, self->model->thick_shell1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell2");
+    self->model->thick_shell2.dispersion->accept_as_destination(visitor, self->model->thick_shell2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell3");
+    self->model->thick_shell3.dispersion->accept_as_destination(visitor, self->model->thick_shell3.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell4");
+    self->model->thick_shell4.dispersion->accept_as_destination(visitor, self->model->thick_shell4.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell5");
+    self->model->thick_shell5.dispersion->accept_as_destination(visitor, self->model->thick_shell5.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell6");
+    self->model->thick_shell6.dispersion->accept_as_destination(visitor, self->model->thick_shell6.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell7");
+    self->model->thick_shell7.dispersion->accept_as_destination(visitor, self->model->thick_shell7.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell8");
+    self->model->thick_shell8.dispersion->accept_as_destination(visitor, self->model->thick_shell8.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell9");
+    self->model->thick_shell9.dispersion->accept_as_destination(visitor, self->model->thick_shell9.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell10");
+    self->model->thick_shell10.dispersion->accept_as_destination(visitor, self->model->thick_shell10.dispersion, disp_dict);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(COnionModelError, 
+	    	"COnionModel.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(COnionModelError, 
+	    		"COnionModel.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 = COnionModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = COnionModel_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 = COnionModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(COnionModel *self) {
+
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->thick_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell5") );
+    self->model->thick_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell9") );
+    self->model->thick_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell7") );
+    self->model->A_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell10") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->func_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell4") );
+    self->model->func_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell5") );
+    self->model->func_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell6") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell1") );
+    self->model->thick_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell10") );
+    self->model->func_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell3") );
+    self->model->rad_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->func_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell8") );
+    self->model->func_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell9") );
+    self->model->sld_in_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell5") );
+    self->model->func_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell10") );
+    self->model->sld_in_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell4") );
+    self->model->sld_in_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell7") );
+    self->model->sld_out_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell9") );
+    self->model->sld_out_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell8") );
+    self->model->thick_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell6") );
+    self->model->sld_out_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell2") );
+    self->model->sld_in_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell9") );
+    self->model->sld_in_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell8") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    self->model->sld_out_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell3") );
+    self->model->sld_in_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell6") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    self->model->sld_out_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell4") );
+    self->model->sld_in_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell3") );
+    self->model->sld_out_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell6") );
+    self->model->func_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell7") );
+    self->model->sld_out_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell7") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->n_shells = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_shells") );
+    self->model->sld_in_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell2") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell2") );
+    self->model->thick_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell8") );
+    self->model->sld_out_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell10") );
+    self->model->sld_in_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell10") );
+    self->model->A_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell8") );
+    self->model->A_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell9") );
+    self->model->A_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell6") );
+    self->model->A_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell7") );
+    self->model->A_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell4") );
+    self->model->A_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell5") );
+    self->model->A_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell2") );
+    self->model->A_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell3") );
+    self->model->A_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell1") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core");
+    self->model->rad_core.dispersion->accept_as_destination(visitor, self->model->rad_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell1");
+    self->model->thick_shell1.dispersion->accept_as_destination(visitor, self->model->thick_shell1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell2");
+    self->model->thick_shell2.dispersion->accept_as_destination(visitor, self->model->thick_shell2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell3");
+    self->model->thick_shell3.dispersion->accept_as_destination(visitor, self->model->thick_shell3.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell4");
+    self->model->thick_shell4.dispersion->accept_as_destination(visitor, self->model->thick_shell4.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell5");
+    self->model->thick_shell5.dispersion->accept_as_destination(visitor, self->model->thick_shell5.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell6");
+    self->model->thick_shell6.dispersion->accept_as_destination(visitor, self->model->thick_shell6.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell7");
+    self->model->thick_shell7.dispersion->accept_as_destination(visitor, self->model->thick_shell7.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell8");
+    self->model->thick_shell8.dispersion->accept_as_destination(visitor, self->model->thick_shell8.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell9");
+    self->model->thick_shell9.dispersion->accept_as_destination(visitor, self->model->thick_shell9.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell10");
+    self->model->thick_shell10.dispersion->accept_as_destination(visitor, self->model->thick_shell10.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(COnionModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->thick_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell5") );
+    self->model->thick_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell9") );
+    self->model->thick_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell7") );
+    self->model->A_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell10") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->func_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell4") );
+    self->model->func_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell5") );
+    self->model->func_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell6") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell1") );
+    self->model->thick_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell10") );
+    self->model->func_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell3") );
+    self->model->rad_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->func_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell8") );
+    self->model->func_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell9") );
+    self->model->sld_in_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell5") );
+    self->model->func_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell10") );
+    self->model->sld_in_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell4") );
+    self->model->sld_in_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell7") );
+    self->model->sld_out_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell9") );
+    self->model->sld_out_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell8") );
+    self->model->thick_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell6") );
+    self->model->sld_out_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell2") );
+    self->model->sld_in_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell9") );
+    self->model->sld_in_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell8") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    self->model->sld_out_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell3") );
+    self->model->sld_in_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell6") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    self->model->sld_out_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell4") );
+    self->model->sld_in_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell3") );
+    self->model->sld_out_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell6") );
+    self->model->func_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell7") );
+    self->model->sld_out_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell7") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->n_shells = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_shells") );
+    self->model->sld_in_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell2") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_shell2") );
+    self->model->thick_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell8") );
+    self->model->sld_out_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell10") );
+    self->model->sld_in_shell10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell10") );
+    self->model->A_shell8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell8") );
+    self->model->A_shell9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell9") );
+    self->model->A_shell6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell6") );
+    self->model->A_shell7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell7") );
+    self->model->A_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell4") );
+    self->model->A_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell5") );
+    self->model->A_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell2") );
+    self->model->A_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell3") );
+    self->model->A_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "A_shell1") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core");
+    self->model->rad_core.dispersion->accept_as_destination(visitor, self->model->rad_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell1");
+    self->model->thick_shell1.dispersion->accept_as_destination(visitor, self->model->thick_shell1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell2");
+    self->model->thick_shell2.dispersion->accept_as_destination(visitor, self->model->thick_shell2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell3");
+    self->model->thick_shell3.dispersion->accept_as_destination(visitor, self->model->thick_shell3.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell4");
+    self->model->thick_shell4.dispersion->accept_as_destination(visitor, self->model->thick_shell4.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell5");
+    self->model->thick_shell5.dispersion->accept_as_destination(visitor, self->model->thick_shell5.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell6");
+    self->model->thick_shell6.dispersion->accept_as_destination(visitor, self->model->thick_shell6.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell7");
+    self->model->thick_shell7.dispersion->accept_as_destination(visitor, self->model->thick_shell7.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell8");
+    self->model->thick_shell8.dispersion->accept_as_destination(visitor, self->model->thick_shell8.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell9");
+    self->model->thick_shell9.dispersion->accept_as_destination(visitor, self->model->thick_shell9.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_shell10");
+    self->model->thick_shell10.dispersion->accept_as_destination(visitor, self->model->thick_shell10.dispersion, disp_dict);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(COnionModelError, 
+	    	"COnionModel.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(COnionModelError, 
+	    		"COnionModel.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 = COnionModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = COnionModel_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 = COnionModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(COnionModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(COnionModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(COnionModelError,
+	    	"COnionModel.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
+    if (!strcmp(par_name, "rad_core")) {
+        self->model->rad_core.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell1")) {
+        self->model->thick_shell1.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell2")) {
+        self->model->thick_shell2.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell3")) {
+        self->model->thick_shell3.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell4")) {
+        self->model->thick_shell4.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell5")) {
+        self->model->thick_shell5.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell6")) {
+        self->model->thick_shell6.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell7")) {
+        self->model->thick_shell7.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell8")) {
+        self->model->thick_shell8.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell9")) {
+        self->model->thick_shell9.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_shell10")) {
+        self->model->thick_shell10.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(COnionModelError,
+	    	"COnionModel.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 COnionModel_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"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+      
+    {"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 COnionModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "COnionModel",             /*tp_name*/
+    sizeof(COnionModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)COnionModel_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*/
+    "COnionModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    COnionModel_methods,             /* tp_methods */
+    COnionModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)COnionModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    COnionModel_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 addCOnionModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&COnionModelType) < 0)
+        return;
+
+    Py_INCREF(&COnionModelType);
+    PyModule_AddObject(module, "COnionModel", (PyObject *)&COnionModelType);
+    
+    d = PyModule_GetDict(module);
+    COnionModelError = PyErr_NewException("COnionModel.error", NULL, NULL);
+    PyDict_SetItemString(d, "COnionModelError", COnionModelError);
+}
+
Index: sansmodels/src/sans/models/c_models/c_models.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/c_models.cpp	(revision c724ccd87499a21402fee0d11d517066f99ddf9b)
+++ sansmodels/src/sans/models/c_models/c_models.cpp	(revision e096270047b0757e07e7187aa5de071c857a7e13)
@@ -15,4 +15,5 @@
 void addCParallelepipedModel(PyObject *module);
 void addCSphereModel(PyObject *module);
+void addCOnionModel(PyObject *module);
 void addCFuzzySphereModel(PyObject *module);
 void addCHardsphereStructure(PyObject *module);
@@ -222,4 +223,5 @@
 	addCEllipsoidModel(m);
 	addCSphereModel(m);
+	addCOnionModel(m);
 	addCFuzzySphereModel(m);
 	addCHardsphereStructure(m);
Index: sansmodels/src/sans/models/c_models/models.hh
===================================================================
--- sansmodels/src/sans/models/c_models/models.hh	(revision 13eb1c4b175eb150bd941382067266672545173d)
+++ sansmodels/src/sans/models/c_models/models.hh	(revision e096270047b0757e07e7187aa5de071c857a7e13)
@@ -75,4 +75,79 @@
 
 
+class OnionModel{
+public:
+	// Model parameters
+	Parameter n_shells;
+	Parameter scale;
+	Parameter rad_core;
+	Parameter sld_core;
+	Parameter sld_solv;
+	Parameter background;
+
+	Parameter sld_out_shell1;
+	Parameter sld_out_shell2;
+	Parameter sld_out_shell3;
+	Parameter sld_out_shell4;
+	Parameter sld_out_shell5;
+	Parameter sld_out_shell6;
+	Parameter sld_out_shell7;
+	Parameter sld_out_shell8;
+	Parameter sld_out_shell9;
+	Parameter sld_out_shell10;
+
+	Parameter sld_in_shell1;
+	Parameter sld_in_shell2;
+	Parameter sld_in_shell3;
+	Parameter sld_in_shell4;
+	Parameter sld_in_shell5;
+	Parameter sld_in_shell6;
+	Parameter sld_in_shell7;
+	Parameter sld_in_shell8;
+	Parameter sld_in_shell9;
+	Parameter sld_in_shell10;
+
+	Parameter A_shell1;
+	Parameter A_shell2;
+	Parameter A_shell3;
+	Parameter A_shell4;
+	Parameter A_shell5;
+	Parameter A_shell6;
+	Parameter A_shell7;
+	Parameter A_shell8;
+	Parameter A_shell9;
+	Parameter A_shell10;
+
+	Parameter thick_shell1;
+	Parameter thick_shell2;
+	Parameter thick_shell3;
+	Parameter thick_shell4;
+	Parameter thick_shell5;
+	Parameter thick_shell6;
+	Parameter thick_shell7;
+	Parameter thick_shell8;
+	Parameter thick_shell9;
+	Parameter thick_shell10;
+
+	Parameter func_shell1;
+	Parameter func_shell2;
+	Parameter func_shell3;
+	Parameter func_shell4;
+	Parameter func_shell5;
+	Parameter func_shell6;
+	Parameter func_shell7;
+	Parameter func_shell8;
+	Parameter func_shell9;
+	Parameter func_shell10;
+
+	// Constructor
+	OnionModel();
+
+	// Operators to get I(Q)
+	double operator()(double q);
+	double operator()(double qx, double qy);
+	double calculate_ER();
+	double evaluate_rphi(double q, double phi);
+};
+
 class SphereModel{
 public:
@@ -93,4 +168,5 @@
 	double evaluate_rphi(double q, double phi);
 };
+
 
 class FuzzySphereModel{
Index: sansmodels/src/sans/models/c_models/onion.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/onion.cpp	(revision e096270047b0757e07e7187aa5de071c857a7e13)
+++ sansmodels/src/sans/models/c_models/onion.cpp	(revision e096270047b0757e07e7187aa5de071c857a7e13)
@@ -0,0 +1,438 @@
+/**
+	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
+ */
+
+/**
+ * Scattering model classes
+ * The classes use the IGOR library found in
+ *   sansmodels/src/libigor
+ *
+ */
+
+#include <math.h>
+#include "models.hh"
+#include "parameters.hh"
+#include <stdio.h>
+using namespace std;
+
+extern "C" {
+	#include "onion.h"
+}
+
+OnionModel :: OnionModel() {
+	n_shells = Parameter(1.0);
+	scale = Parameter(1.0);
+	rad_core = Parameter(200.0);
+	sld_core = Parameter(1e-06);
+	sld_solv = Parameter(6.4e-06);
+    background = Parameter(0.0);
+
+
+    sld_out_shell1 = Parameter(1.0e-06);
+    sld_out_shell2 = Parameter(1.0e-06);
+    sld_out_shell3 = Parameter(1.0e-06);
+    sld_out_shell4 = Parameter(1.0e-06);
+    sld_out_shell5 = Parameter(1.0e-06);
+    sld_out_shell6 = Parameter(1.0e-06);
+    sld_out_shell7 = Parameter(1.0e-06);
+    sld_out_shell8 = Parameter(1.0e-06);
+    sld_out_shell9 = Parameter(1.0e-06);
+    sld_out_shell10 = Parameter(1.0e-06);
+
+
+    sld_in_shell1 = Parameter(2.3e-06);
+    sld_in_shell2 = Parameter(2.6e-06);
+    sld_in_shell3 = Parameter(2.9e-06);
+    sld_in_shell4 = Parameter(3.2e-06);
+    sld_in_shell5 = Parameter(3.5e-06);
+    sld_in_shell6 = Parameter(3.8e-06);
+    sld_in_shell7 = Parameter(4.1e-06);
+    sld_in_shell8 = Parameter(4.4e-06);
+    sld_in_shell9 = Parameter(4.7e-06);
+    sld_in_shell10 = Parameter(5.0e-06);
+
+
+    A_shell1 = Parameter(1.0);
+    A_shell2 = Parameter(1.0);
+    A_shell3 = Parameter(1.0);
+    A_shell4 = Parameter(1.0);
+    A_shell5 = Parameter(1.0);
+    A_shell6 = Parameter(1.0);
+    A_shell7 = Parameter(1.0);
+    A_shell8 = Parameter(1.0);
+    A_shell9 = Parameter(1.0);
+    A_shell10 = Parameter(1.0);
+
+
+    thick_shell1 = Parameter(50.0);
+    thick_shell2 = Parameter(50.0);
+    thick_shell3 = Parameter(50.0);
+    thick_shell4 = Parameter(50.0);
+    thick_shell5 = Parameter(50.0);
+    thick_shell6 = Parameter(50.0);
+    thick_shell7 = Parameter(50.0);
+    thick_shell8 = Parameter(50.0);
+    thick_shell9 = Parameter(50.0);
+    thick_shell10 = Parameter(50.0);
+
+
+    func_shell1 = Parameter(2);
+    func_shell2 = Parameter(2);
+    func_shell3 = Parameter(2);
+    func_shell4 = Parameter(2);
+    func_shell5 = Parameter(2);
+    func_shell6 = Parameter(2);
+    func_shell7 = Parameter(2);
+    func_shell8 = Parameter(2);
+    func_shell9 = Parameter(2);
+    func_shell10 = Parameter(2);
+
+}
+
+/**
+ * Function to evaluate 1D scattering function
+ * The NIST IGOR library is used for the actual calculation.
+ * @param q: q-value
+ * @return: function value
+ */
+double OnionModel :: operator()(double q) {
+	double dp[56];
+	// Fill parameter array for IGOR library
+	// Add the background after averaging
+	dp[0] = n_shells();
+	dp[1] = scale();
+	dp[2] = rad_core();
+	dp[3] = sld_core();
+	dp[4] = sld_solv();
+	dp[5] = 0.0;
+
+	dp[6] = sld_out_shell1();
+	dp[7] = sld_out_shell2();
+	dp[8] = sld_out_shell3();
+	dp[9] = sld_out_shell4();
+	dp[10] = sld_out_shell5();
+	dp[11] = sld_out_shell6();
+	dp[12] = sld_out_shell7();
+	dp[13] = sld_out_shell8();
+	dp[14] = sld_out_shell9();
+	dp[15] = sld_out_shell10();
+
+	dp[16] = sld_in_shell1();
+	dp[17] = sld_in_shell2();
+	dp[18] = sld_in_shell3();
+	dp[19] = sld_in_shell4();
+	dp[20] = sld_in_shell5();
+	dp[21] = sld_in_shell6();
+	dp[22] = sld_in_shell7();
+	dp[23] = sld_in_shell8();
+	dp[24] = sld_in_shell9();
+	dp[25] = sld_in_shell10();
+
+	dp[26] = A_shell1();
+	dp[27] = A_shell2();
+	dp[28] = A_shell3();
+	dp[29] = A_shell4();
+	dp[30] = A_shell5();
+	dp[31] = A_shell6();
+	dp[32] = A_shell7();
+	dp[33] = A_shell8();
+	dp[34] = A_shell9();
+	dp[35] = A_shell10();
+
+	dp[36] = thick_shell1();
+	dp[37] = thick_shell2();
+	dp[38] = thick_shell3();
+	dp[39] = thick_shell4();
+	dp[40] = thick_shell5();
+	dp[41] = thick_shell6();
+	dp[42] = thick_shell7();
+	dp[43] = thick_shell8();
+	dp[44] = thick_shell9();
+	dp[45] = thick_shell10();
+
+	dp[46] = func_shell1();
+	dp[47] = func_shell2();
+	dp[48] = func_shell3();
+	dp[49] = func_shell4();
+	dp[50] = func_shell5();
+	dp[51] = func_shell6();
+	dp[52] = func_shell7();
+	dp[53] = func_shell8();
+	dp[54] = func_shell9();
+	dp[55] = func_shell10();
+
+
+	// Get the dispersion points for the radius
+	vector<WeightPoint> weights_rad;
+	rad_core.get_weights(weights_rad);
+
+	// Get the dispersion points for the thick 1
+	vector<WeightPoint> weights_s1;
+	thick_shell1.get_weights(weights_s1);
+
+	// Get the dispersion points for the thick 2
+	vector<WeightPoint> weights_s2;
+	thick_shell2.get_weights(weights_s2);
+
+	// Get the dispersion points for the thick 3
+	vector<WeightPoint> weights_s3;
+	thick_shell3.get_weights(weights_s3);
+
+	// Get the dispersion points for the thick 4
+	vector<WeightPoint> weights_s4;
+	thick_shell4.get_weights(weights_s4);
+
+	// Get the dispersion points for the thick 5
+	vector<WeightPoint> weights_s5;
+	thick_shell5.get_weights(weights_s5);
+
+	// Get the dispersion points for the thick 6
+	vector<WeightPoint> weights_s6;
+	thick_shell6.get_weights(weights_s6);
+
+	// Get the dispersion points for the thick 7
+	vector<WeightPoint> weights_s7;
+	thick_shell7.get_weights(weights_s7);
+
+	// Get the dispersion points for the thick 8
+	vector<WeightPoint> weights_s8;
+	thick_shell8.get_weights(weights_s8);
+	// Get the dispersion points for the thick 9
+	vector<WeightPoint> weights_s9;
+	thick_shell9.get_weights(weights_s9);
+
+	// Get the dispersion points for the thick 10
+	vector<WeightPoint> weights_s10;
+	thick_shell10.get_weights(weights_s10);
+
+
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+	double vol = 0.0;
+
+	// Loop over radius weight points
+	for(int i=0; i<weights_rad.size(); i++) {
+		dp[2] = weights_rad[i].value;
+		// Loop over radius weight points
+		for(int j=0; j<weights_s1.size(); j++) {
+			dp[36] = weights_s1[j].value;
+			// Loop over radius weight points
+			for(int k=0; k<weights_s2.size(); k++) {
+				dp[37] = weights_s2[k].value;
+				// Loop over radius weight points
+				for(int l=0; l<weights_s3.size(); l++) {
+					dp[38] = weights_s3[l].value;
+					// Loop over radius weight points
+					for(int m=0; m<weights_s4.size(); m++) {
+						dp[39] = weights_s4[m].value;
+						for(int n=0; n<weights_s5.size(); n++) {
+							dp[40] = weights_s5[n].value;
+							for(int o=0; o<weights_s6.size(); o++) {
+								dp[41] = weights_s6[o].value;
+								for(int p=0; p<weights_s7.size(); p++) {
+									dp[42] = weights_s7[p].value;
+									for(int t=0; t<weights_s8.size(); t++) {
+										dp[43] = weights_s8[t].value;
+										for(int r=0; r<weights_s9.size(); r++) {
+											dp[44] = weights_s9[r].value;
+											for(int s=0; s<weights_s10.size(); s++) {
+												dp[45] = weights_s10[s].value;
+												//Un-normalize Shells by volume
+												sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight
+														*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight
+														*weights_s9[r].weight*weights_s10[s].weight
+														* so_kernel(dp,q) * pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value
+																+weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value
+																+weights_s9[r].value+weights_s10[s].value),3.0);
+												//Find average volume
+												vol += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight
+													*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight
+													*weights_s9[r].weight*weights_s10[s].weight
+													* pow((weights_rad[i].value+weights_s1[j].value+weights_s2[k].value+weights_s3[l].value+weights_s4[m].value
+															+weights_s5[n].value+weights_s6[o].value+weights_s7[p].value+weights_s8[t].value
+															+weights_s9[r].value+weights_s10[s].value),3.0);
+												norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight
+													*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight
+													*weights_s9[r].weight*weights_s10[s].weight;
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (vol != 0.0 && norm != 0.0) {
+		//Re-normalize by avg volume
+		sum = sum/(vol/norm);}
+
+	return sum/norm + background();
+}
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param q_x: value of Q along x
+ * @param q_y: value of Q along y
+ * @return: function value
+ */
+double OnionModel :: operator()(double qx, double qy) {
+	double q = sqrt(qx*qx + qy*qy);
+	return (*this).operator()(q);
+}
+
+/**
+ * Function to evaluate 2D scattering function
+ * @param pars: parameters of the sphere
+ * @param q: q-value
+ * @param phi: angle phi
+ * @return: function value
+ */
+double OnionModel :: evaluate_rphi(double q, double phi) {
+	return (*this).operator()(q);
+}
+
+/**
+ * Function to calculate effective radius
+ * @return: effective radius value
+ */
+double OnionModel :: calculate_ER() {
+	OnionParameters dp;
+	dp.rad_core = rad_core();
+	dp.thick_shell1 = thick_shell1();
+	dp.thick_shell2 = thick_shell2();
+	dp.thick_shell3 = thick_shell3();
+	dp.thick_shell4 = thick_shell4();
+	dp.thick_shell5 = thick_shell5();
+	dp.thick_shell6 = thick_shell6();
+	dp.thick_shell7 = thick_shell7();
+	dp.thick_shell8 = thick_shell8();
+	dp.thick_shell9 = thick_shell9();
+	dp.thick_shell10 = thick_shell10();
+
+
+	double rad_out = 0.0;
+	// Perform the computation, with all weight points
+	double sum = 0.0;
+	double norm = 0.0;
+
+	// Get the dispersion points for the radius
+	vector<WeightPoint> weights_rad;
+	rad_core.get_weights(weights_rad);
+
+	// Get the dispersion points for the thick 1
+	vector<WeightPoint> weights_s1;
+	thick_shell1.get_weights(weights_s1);
+
+	// Get the dispersion points for the thick 2
+	vector<WeightPoint> weights_s2;
+	thick_shell2.get_weights(weights_s2);
+
+	// Get the dispersion points for the thick 3
+	vector<WeightPoint> weights_s3;
+	thick_shell3.get_weights(weights_s3);
+
+	// Get the dispersion points for the thick 4
+	vector<WeightPoint> weights_s4;
+	thick_shell4.get_weights(weights_s4);
+	// Get the dispersion points for the thick 5
+	vector<WeightPoint> weights_s5;
+	thick_shell5.get_weights(weights_s5);
+
+	// Get the dispersion points for the thick 6
+	vector<WeightPoint> weights_s6;
+	thick_shell6.get_weights(weights_s6);
+
+	// Get the dispersion points for the thick 7
+	vector<WeightPoint> weights_s7;
+	thick_shell7.get_weights(weights_s7);
+
+	// Get the dispersion points for the thick 8
+	vector<WeightPoint> weights_s8;
+	thick_shell8.get_weights(weights_s8);
+	// Get the dispersion points for the thick 9
+	vector<WeightPoint> weights_s9;
+	thick_shell9.get_weights(weights_s9);
+
+	// Get the dispersion points for the thick 10
+	vector<WeightPoint> weights_s10;
+	thick_shell10.get_weights(weights_s10);
+
+
+	// Loop over radius weight points
+	for(int i=0; i<weights_rad.size(); i++) {
+		dp.rad_core = weights_rad[i].value;
+		// Loop over radius weight points
+		for(int j=0; j<weights_s1.size(); j++) {
+			dp.thick_shell1 = weights_s1[j].value;
+			// Loop over radius weight points
+			for(int k=0; k<weights_s2.size(); k++) {
+				dp.thick_shell2 = weights_s2[k].value;
+				// Loop over radius weight points
+				for(int l=0; l<weights_s3.size(); l++) {
+					dp.thick_shell3 = weights_s3[l].value;
+					// Loop over radius weight points
+					for(int m=0; m<weights_s4.size(); m++) {
+						dp.thick_shell4 = weights_s4[m].value;
+						// Loop over radius weight points
+						for(int n=0; j<weights_s5.size(); n++) {
+							dp.thick_shell5 = weights_s5[n].value;
+							// Loop over radius weight points
+							for(int o=0; k<weights_s6.size(); o++) {
+								dp.thick_shell6 = weights_s6[o].value;
+								// Loop over radius weight points
+								for(int p=0; l<weights_s7.size(); p++) {
+									dp.thick_shell7 = weights_s7[p].value;
+									// Loop over radius weight points
+									for(int t=0; m<weights_s8.size(); t++) {
+										dp.thick_shell8 = weights_s8[t].value;
+										// Loop over radius weight points
+										for(int r=0; l<weights_s9.size(); r++) {
+											dp.thick_shell8 = weights_s9[r].value;
+											// Loop over radius weight points
+											for(int s=0; m<weights_s10.size(); s++) {
+												dp.thick_shell10 = weights_s10[s].value;
+												//Un-normalize FourShell by volume
+												sum += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight*weights_s4[m].weight
+													*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight*weights_s8[t].weight
+													*weights_s9[r].weight*weights_s10[s].weight
+													* (dp.rad_core+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4+dp.thick_shell5
+															+dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10);
+												norm += weights_rad[i].weight*weights_s1[j].weight*weights_s2[k].weight*weights_s3[l].weight
+													*weights_s4[m].weight*weights_s5[n].weight*weights_s6[o].weight*weights_s7[p].weight
+													*weights_s8[t].weight*weights_s9[r].weight*weights_s10[s].weight;
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (norm != 0){
+		//return the averaged value
+		rad_out =  sum/norm;}
+	else{
+		//return normal value
+		rad_out = dp.rad_core+dp.thick_shell1+dp.thick_shell2+dp.thick_shell3+dp.thick_shell4
+					+dp.thick_shell5+dp.thick_shell6+dp.thick_shell7+dp.thick_shell8+dp.thick_shell9+dp.thick_shell10;}
+	return rad_out;
+}
