Index: sansmodels/src/sans/models/Schulz.py
===================================================================
--- sansmodels/src/sans/models/Schulz.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/Schulz.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+"""
+	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
+"""
+
+""" Provide functionality for a C extension model
+
+	WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ 	         DO NOT MODIFY THIS FILE, MODIFY ..\c_extensions\schulz.h
+ 	         AND RE-RUN THE GENERATOR SCRIPT
+
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans_extension.c_models import CSchulz
+import copy    
+    
+class Schulz(CSchulz, BaseComponent):
+    """ Class that evaluates a Schulz model. 
+    	This file was auto-generated from ..\c_extensions\schulz.h.
+    	Refer to that file and the structure it contains
+    	for details of the model.
+    	List of default parameters:
+         scale           = 1.0 
+         sigma           = 1.0 
+         center          = 0.0 
+
+    """
+        
+    def __init__(self):
+        """ Initialization """
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        CSchulz.__init__(self)
+        
+        ## Name of the model
+        self.name = "Schulz"
+        ## Model description
+        self.description =""" f(x)=scale * math.pow(z+1, z+1)*math.pow((R), z)*
+		math.exp(-R*(z+1))/(center*gamma(z+1)
+		z= math.pow[(1/(sigma/center),2]-1"""
+       
+		## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['sigma'] = ['', None, None]
+        self.details['center'] = ['', None, None]
+
+		## fittable parameters
+        self.fixed=[]
+        
+        ## parameters with orientation
+        self.orientation_params =[]
+   
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(Schulz())   
+   
+    def run(self, x = 0.0):
+        """ Evaluate the model
+            @param x: input q, or [q,phi]
+            @return: scattering function P(q)
+        """
+        
+        return CSchulz.run(self, x)
+   
+    def runXY(self, x = 0.0):
+        """ Evaluate the model in cartesian coordinates
+            @param x: input q, or [qx, qy]
+            @return: scattering function P(q)
+        """
+        
+        return CSchulz.runXY(self, x)
+        
+    def evalDistribition(self, x = []):
+        """ Evaluate the model in cartesian coordinates
+            @param x: input q[], or [qx[], qy[]]
+            @return: scattering function P(q[])
+        """
+        return CSchulz.evalDistribition(self, x)
+        
+    def set_dispersion(self, parameter, dispersion):
+        """
+            Set the dispersion object for a model parameter
+            @param parameter: name of the parameter [string]
+            @dispersion: dispersion object of type DispersionModel
+        """
+        return CSchulz.set_dispersion(self, parameter, dispersion.cdisp)
+        
+   
+# End of file
Index: sansmodels/src/sans/models/c_extensions/CSchulz.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/CSchulz.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/c_extensions/CSchulz.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,290 @@
+/** 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
+ *
+ * @author   M.Doucet / UTK
+ */
+ 
+#include <Python.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#include "schulz.h"
+
+/// Error object for raised exceptions
+static PyObject * CSchulzError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Log for unit testing
+    PyObject * log;
+    /// Model parameters
+	SchulzParameters model_pars;
+} 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();
+        
+        // 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));
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static PyMemberDef CSchulz_members[] = {
+    {"params", T_OBJECT, offsetof(CSchulz, params), 0,
+     "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 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_pars.scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model_pars.sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model_pars.center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// 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",schulz_analytical_2D(&(self->model_pars),q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",schulz_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(CSchulz *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.sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model_pars.center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// 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",schulz_analytical_2DXY(&(self->model_pars),qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",schulz_analytical_1D(&(self->model_pars),qx_value));
+	}	
+}
+
+static PyObject * reset(CSchulz *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+
+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"},
+    {"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 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_extensions/c_models.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/c_models.c	(revision 812b901e8b8451f555bc0649e5ee190827ff9130)
+++ sansmodels/src/sans/models/c_extensions/c_models.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -52,4 +52,6 @@
 	addDisperser(m);
 	addCGaussian(m);
+	addCSchulz(m);
+	addCLogNormal(m);
 	addCLorentzian(m);
 	addCHollowCylinderModel(m);
Index: sansmodels/src/sans/models/c_extensions/logNormal.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/logNormal.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/c_extensions/logNormal.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,58 @@
+/**
+ * log normal function
+ */
+
+#include "logNormal.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/**
+ * Function to evaluate 1D Log normal function.
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x)=scale * 1/(sigma*math.sqrt(2pi))e^(-1/2*((math.log(x)-mu)/sigma)^2)
+ * 
+ * @param pars: parameters of the log normal 
+ * @param x: x-value
+ * @return: function value
+ */
+double logNormal_analytical_1D(LogNormalParameters *pars, double x) {
+	double sigma2 = pow(pars->sigma, 2);	
+	return pars->scale / (x*sigma2) * exp( -pow((log(x) -pars->center), 2) / (2*sigma2));
+}
+
+/**
+ * Function to evaluate 2D log normal  function
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x,y) = LogNormal(x) * Lognormal(y)
+ * 
+ * where both Gaussians share the same parameters.
+ * 
+ * @param pars: parameters of the log normal 
+ * @param x: x-value
+ * @param y: y-value
+ * @return: function value
+ */
+double logNormal_analytical_2DXY(LogNormalParameters *pars, double x, double y) {
+    return logNormal_analytical_1D(pars, x) * logNormal_analytical_1D(pars, y);
+} 
+
+/**
+ * Function to evaluate 2D log normal  function
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x,y) = Lognormal(x) * Lognormal(y)
+ * 
+ * where both log normal s share the same parameters.
+ * 
+ * @param pars: parameters of the log normal
+ * @param length: length of the (x,y) vector
+ * @param phi: angle relative to x
+ * @return: function value
+ */
+double logNormal_analytical_2D(LogNormalParameters *pars, double length, double phi) {
+    return logNormal_analytical_2DXY(pars, length*cos(phi), length*sin(phi));
+} 
Index: sansmodels/src/sans/models/c_extensions/logNormal.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/logNormal.h	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/c_extensions/logNormal.h	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,31 @@
+#if !defined(logNormal_h)
+#define logNormal_h
+
+/** Structure definition for Gaussian parameters.
+ * The Log normal is normalized to the 'scale' parameter.
+ *  
+ * f(x)=scale * 1/(sigma*math.sqrt(2pi))e^(-1/2*((math.log(x)-mu)/sigma)^2)
+ *
+ * [PYTHONCLASS] = LogNormal
+ * [DESCRIPTION] = <text>f(x)=scale * 1/(sigma*math.sqrt(2pi))e^(-1/2*((math.log(x)-mu)/sigma)^2)</text>
+ */
+typedef struct {
+    /// Scale factor 
+    //  [DEFAULT]=scale=1.0
+    double scale;
+    /// Standard deviation
+    //  [DEFAULT]=sigma=1 
+    double sigma;
+    /// Center of the Log Normal distribution
+    //  [DEFAULT]=center=0.0 
+    double center;
+} LogNormalParameters;
+
+/// 1D scattering function
+double logNormal_analytical_1D(LogNormalParameters *pars, double x);
+
+/// 2D scattering function
+double logNormal_analytical_2D(LogNormalParameters *pars, double x, double phi);
+double logNormal_analytical_2DXY(LogNormalParameters *pars, double x, double y);
+
+#endif
Index: sansmodels/src/sans/models/c_extensions/schulz.c
===================================================================
--- sansmodels/src/sans/models/c_extensions/schulz.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/c_extensions/schulz.c	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,62 @@
+/**
+ * Schulz function
+ */
+
+#include "schulz.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/**
+ * Function to evaluate 1D Schulz function.
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x)=scale * math.pow(z+1, z+1)*math.pow((R), z)*
+ *					math.exp(-R*(z+1))/(center*gamma(z+1)
+ *		z= math.pow[(1/(sigma/center),2]-1
+ *		R= x/center
+ * @param pars: parameters of the schulz
+ * @param x: x-value
+ * @return: function value
+ */
+double schulz_analytical_1D(SchulzParameters *pars, double x) {
+	double z = pow(pars->center/ pars->sigma, 2)-1;	
+	double R= x/pars->center;
+	double zz= z+1;
+	return pars->scale * pow(zz,zz) * pow(R,z) * exp(-1*R*zz)/((pars->center) * tgamma(zz)) ;
+}
+
+/**
+ * Function to evaluate 2D schulz function
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x,y) = Schulz(x) * Schulz(y)
+ * 
+ * where both Shulzs share the same parameters.
+ * 
+ * @param pars: parameters of the schulz
+ * @param x: x-value
+ * @param y: y-value
+ * @return: function value
+ */
+double schulz_analytical_2DXY(SchulzParameters *pars, double x, double y) {
+    return schulz_analytical_1D(pars, x) * schulz_analytical_1D(pars, y);
+} 
+
+/**
+ * Function to evaluate 2D Schulz  function
+ * The function is normalized to the 'scale' parameter.
+ * 
+ * f(x,y) = Schulz(x) * Schulz(y)
+ * 
+ * where both Gaussians share the same parameters.
+ * 
+ * @param pars: parameters of the gaussian
+ * @param length: length of the (x,y) vector
+ * @param phi: angle relative to x
+ * @return: function value
+ */
+double schulz_analytical_2D(SchulzParameters *pars, double length, double phi) {
+    return schulz_analytical_2DXY(pars, length*cos(phi), length*sin(phi));
+} 
Index: sansmodels/src/sans/models/c_extensions/schulz.h
===================================================================
--- sansmodels/src/sans/models/c_extensions/schulz.h	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
+++ sansmodels/src/sans/models/c_extensions/schulz.h	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -0,0 +1,37 @@
+#if !defined(schulz_h)
+#define schulz_h
+
+/** Structure definition for Schulz parameters.
+ * The Schulz is normalized to the 'scale' parameter.
+ *  
+ * f(x)=scale * math.pow(z+1, z+1)*math.pow((R), z)*
+ *					math.exp(-R*(z+1))/(center*gamma(z+1)
+ *		z= math.pow[(1/(sigma/center),2]-1
+ *		R= x/center
+ * 
+ * [PYTHONCLASS] = Schulz
+ * [DESCRIPTION] = <text> f(x)=scale * math.pow(z+1, z+1)*math.pow((R), z)*
+ 					math.exp(-R*(z+1))/(center*gamma(z+1)
+ 		            z= math.pow[(1/(sigma/center),2]-1
+ 					R= x/center</text>
+ */
+typedef struct {
+    /// Scale factor 
+    //  [DEFAULT]=scale=1.0
+    double scale;
+    /// Standard deviation
+    //  [DEFAULT]=sigma=1 
+    double sigma;
+    /// Center of the Schulz distribution
+    //  [DEFAULT]=center=0.0 
+    double center;
+} SchulzParameters;
+
+/// 1D scattering function
+double schulz_analytical_1D(SchulzParameters *pars, double x);
+
+/// 2D scattering function
+double schulz_analytical_2D(SchulzParameters *pars, double x, double phi);
+double schulz_analytical_2DXY(SchulzParameters *pars, double x, double y);
+
+#endif
Index: sansmodels/src/sans/models/c_models/c_models.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/c_models.cpp	(revision 812b901e8b8451f555bc0649e5ee190827ff9130)
+++ sansmodels/src/sans/models/c_models/c_models.cpp	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -48,4 +48,6 @@
 	void addCGaussian(PyObject *module);
 	void addCLorentzian(PyObject *module);
+	void addCLogNormal(PyObject *module);
+	void addCSchulz(PyObject *module);
 }
 
@@ -69,4 +71,21 @@
 
 /**
+ * Delete a lognormal dispersion model object
+ */
+void del_lognormal_dispersion(void *ptr){
+	LogNormalDispersion * disp = static_cast<LogNormalDispersion *>(ptr);
+	delete disp;
+	return;
+}
+
+/**
+ * Create a lognormal dispersion model as a python object
+ */
+PyObject * new_lognormal_dispersion(PyObject *, PyObject *args) {
+	LogNormalDispersion *disp = new LogNormalDispersion();
+	return PyCObject_FromVoidPtr(disp, del_lognormal_dispersion);
+}
+
+/**
  * Delete a gaussian dispersion model object
  */
@@ -84,4 +103,21 @@
 	return PyCObject_FromVoidPtr(disp, del_gaussian_dispersion);
 }
+
+/**
+ * Delete a schulz dispersion model object
+ */
+void del_schulz_dispersion(void *ptr){
+	SchulzDispersion * disp = static_cast<SchulzDispersion *>(ptr);
+	delete disp;
+	return;
+}
+/**
+ * Create a schulz dispersion model as a python object
+ */
+PyObject * new_schulz_dispersion(PyObject *, PyObject *args) {
+	SchulzDispersion *disp = new SchulzDispersion();
+	return PyCObject_FromVoidPtr(disp, del_schulz_dispersion);
+}
+
 
 /**
@@ -147,4 +183,8 @@
 	{"new_gaussian_model",   (PyCFunction)new_gaussian_dispersion, METH_VARARGS,
 		  "Create a new GaussianDispersion object"},
+    {"new_lognormal_model",   (PyCFunction)new_lognormal_dispersion, METH_VARARGS,
+		  "Create a new LogNormalDispersion object"},
+    {"new_schulz_model",   (PyCFunction)new_schulz_dispersion, METH_VARARGS,
+		  "Create a new SchulzDispersion object"},
 	{"new_array_model",      (PyCFunction)new_array_dispersion  , METH_VARARGS,
 		  "Create a new ArrayDispersion object"},
@@ -194,7 +234,8 @@
 	addDisperser(m);
 	addCGaussian(m);
+	addCSchulz(m);
+	addCLogNormal(m);
 	addCLorentzian(m);
 	addCVesicleModel(m);
 
-
-}
+}
Index: sansmodels/src/sans/models/c_models/dispersion_visitor.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/dispersion_visitor.cpp	(revision fca6936ab3704433fa2327bcd55367e8ea28de72)
+++ sansmodels/src/sans/models/c_models/dispersion_visitor.cpp	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -25,4 +25,29 @@
 
 	PyDict_SetItemString(dict, "type",  Py_BuildValue("s", "gaussian"));
+    PyDict_SetItemString(dict, "npts",  Py_BuildValue("i", disp->npts));
+    PyDict_SetItemString(dict, "width", Py_BuildValue("d", disp->width));
+    PyDict_SetItemString(dict, "nsigmas", Py_BuildValue("i", disp->nsigmas));
+#endif
+}
+
+void DispersionVisitor:: lognormal_to_dict(void* dispersion, void* dictionary) {
+#ifndef __MODELS_STANDALONE__
+	LogNormalDispersion * disp = (LogNormalDispersion*)dispersion;
+	PyObject * dict = (PyObject*)dictionary;
+
+	PyDict_SetItemString(dict, "type",  Py_BuildValue("s", "lognormal"));
+    PyDict_SetItemString(dict, "npts",  Py_BuildValue("i", disp->npts));
+    PyDict_SetItemString(dict, "width", Py_BuildValue("d", disp->width));
+    PyDict_SetItemString(dict, "nsigmas", Py_BuildValue("i", disp->nsigmas));
+#endif
+}
+
+
+void DispersionVisitor:: schulz_to_dict(void* dispersion, void* dictionary) {
+#ifndef __MODELS_STANDALONE__
+	SchulzDispersion * disp = (SchulzDispersion*)dispersion;
+	PyObject * dict = (PyObject*)dictionary;
+
+	PyDict_SetItemString(dict, "type",  Py_BuildValue("s", "schulz"));
     PyDict_SetItemString(dict, "npts",  Py_BuildValue("i", disp->npts));
     PyDict_SetItemString(dict, "width", Py_BuildValue("d", disp->width));
@@ -61,3 +86,24 @@
 }
 
+void DispersionVisitor:: lognormal_from_dict(void* dispersion, void* dictionary) {
+#ifndef __MODELS_STANDALONE__
+	LogNormalDispersion * disp = (LogNormalDispersion*)dispersion;
+	PyObject * dict = (PyObject*)dictionary;
+
+	disp->npts    = PyInt_AsLong( PyDict_GetItemString(dict, "npts") );
+	disp->width   = PyFloat_AsDouble( PyDict_GetItemString(dict, "width") );
+	disp->nsigmas = PyFloat_AsDouble( PyDict_GetItemString(dict, "nsigmas") );
+#endif
+}
+void DispersionVisitor:: schulz_from_dict(void* dispersion, void* dictionary) {
+#ifndef __MODELS_STANDALONE__
+	SchulzDispersion * disp = (SchulzDispersion*)dispersion;
+	PyObject * dict = (PyObject*)dictionary;
+
+	disp->npts    = PyInt_AsLong( PyDict_GetItemString(dict, "npts") );
+	disp->width   = PyFloat_AsDouble( PyDict_GetItemString(dict, "width") );
+	disp->nsigmas = PyFloat_AsDouble( PyDict_GetItemString(dict, "nsigmas") );
+#endif
+}
+
 void DispersionVisitor:: array_from_dict(void* dispersion, void* dictionary) {}
Index: sansmodels/src/sans/models/c_models/dispersion_visitor.hh
===================================================================
--- sansmodels/src/sans/models/c_models/dispersion_visitor.hh	(revision fca6936ab3704433fa2327bcd55367e8ea28de72)
+++ sansmodels/src/sans/models/c_models/dispersion_visitor.hh	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -19,8 +19,12 @@
 	void dispersion_to_dict(void *, void *);
 	void gaussian_to_dict(void *, void *);
+	void lognormal_to_dict(void *, void *);
+	void schulz_to_dict(void*, void *);
 	void array_to_dict(void *, void *);
 
 	void dispersion_from_dict(void*, void *);
 	void gaussian_from_dict(void*, void *);
+	void lognormal_from_dict(void*, void *);
+	void schulz_from_dict(void*, void *);
 	void array_from_dict(void*, void *);
 
Index: sansmodels/src/sans/models/c_models/parameters.cpp
===================================================================
--- sansmodels/src/sans/models/c_models/parameters.cpp	(revision 07da7493b3fac0bc4aa288a1fd12e1d6d4d6b215)
+++ sansmodels/src/sans/models/c_models/parameters.cpp	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -136,4 +136,127 @@
 	}
 }
+
+
+/**
+ * LogNormal dispersion
+ */
+
+LogNormalDispersion :: LogNormalDispersion() {
+	npts  = 1;
+	width = 0.0;
+	nsigmas = 2;
+};
+
+void LogNormalDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
+	visitor->lognormal_to_dict(from, to);
+}
+void LogNormalDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
+	visitor->lognormal_from_dict(from, to);
+}
+
+double lognormal_weight(double mean, double sigma, double x) {
+	
+	double sigma2 = pow(sigma, 2);	
+	return 1/(x*sigma2) * exp( -pow((log(x) -mean), 2) / (2*sigma2));
+ 
+}
+
+/**
+ * Lognormal dispersion
+ * @param mean: mean value of the LogNormal
+ * @param sigma: standard deviation of the LogNormal
+ * @param x: value at which the LogNormal is evaluated
+ * @return: value of the LogNormal
+ */
+void LogNormalDispersion :: operator() (void *param, vector<WeightPoint> &weights){
+	// Check against zero width
+	if (width<=0) {
+		width = 0.0;
+		npts  = 1;
+		nsigmas = 3;
+	}
+
+	Parameter* par = (Parameter*)param;
+	double value = (*par)();
+
+	if (npts<2) {
+		weights.insert(weights.end(), WeightPoint(value, 1.0));
+	} else {
+		for(int i=0; i<npts; i++) {
+			// We cover n(nsigmas) times sigmas on each side of the mean
+			double val = value + width * (2.0*nsigmas*i/float(npts-1) - nsigmas);
+
+			if ( ((*par).has_min==false || val>(*par).min)
+			  && ((*par).has_max==false || val<(*par).max)  ) {
+				double _w = lognormal_weight(value, width, val);
+				weights.insert(weights.end(), WeightPoint(val, _w));
+			}
+		}
+	}
+}
+
+
+
+/**
+ * Schulz dispersion
+ */
+
+SchulzDispersion :: SchulzDispersion() {
+	npts  = 1;
+	width = 0.0;
+	nsigmas = 2;
+};
+
+void SchulzDispersion :: accept_as_source(DispersionVisitor* visitor, void* from, void* to) {
+	visitor->schulz_to_dict(from, to);
+}
+void SchulzDispersion :: accept_as_destination(DispersionVisitor* visitor, void* from, void* to) {
+	visitor->schulz_from_dict(from, to);
+}
+
+double schulz_weight(double mean, double sigma, double x) {
+	double vary, expo_value;
+    double z = pow(mean/ sigma, 2)-1;	
+	double R= x/mean;
+	double zz= z+1;
+	return  pow(zz,zz) * pow(R,z) * exp(-1*R*zz)/((mean) * tgamma(zz)) ;
+}
+
+/**
+ * Schulz dispersion
+ * @param mean: mean value of the Schulz
+ * @param sigma: standard deviation of the Schulz
+ * @param x: value at which the Schulz is evaluated
+ * @return: value of the Schulz
+ */
+void SchulzDispersion :: operator() (void *param, vector<WeightPoint> &weights){
+	// Check against zero width
+	if (width<=0) {
+		width = 0.0;
+		npts  = 1;
+		nsigmas = 3;
+	}
+
+	Parameter* par = (Parameter*)param;
+	double value = (*par)();
+
+	if (npts<2) {
+		weights.insert(weights.end(), WeightPoint(value, 1.0));
+	} else {
+		for(int i=0; i<npts; i++) {
+			// We cover n(nsigmas) times sigmas on each side of the mean
+			double val = value + width * (2.0*nsigmas*i/float(npts-1) - nsigmas);
+
+			if ( ((*par).has_min==false || val>(*par).min)
+			  && ((*par).has_max==false || val<(*par).max)  ) {
+				double _w = schulz_weight(value, width, val);
+				weights.insert(weights.end(), WeightPoint(val, _w));
+			}
+		}
+	}
+}
+
+
+
 
 /**
Index: sansmodels/src/sans/models/c_models/parameters.hh
===================================================================
--- sansmodels/src/sans/models/c_models/parameters.hh	(revision fca6936ab3704433fa2327bcd55367e8ea28de72)
+++ sansmodels/src/sans/models/c_models/parameters.hh	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -77,4 +77,33 @@
 
 /**
+ * Schulz dispersion model
+ */
+class SchulzDispersion: public DispersionModel {
+public:
+	/// Number of sigmas on each side of the mean
+	int nsigmas;
+
+	SchulzDispersion();
+	void operator()(void *, vector<WeightPoint>&);
+	void accept_as_source(DispersionVisitor*, void*, void*);
+	void accept_as_destination(DispersionVisitor*, void*, void*);
+};
+
+/**
+ * LogNormal dispersion model
+ */
+class LogNormalDispersion: public DispersionModel {
+public:
+	/// Number of sigmas on each side of the mean
+	int nsigmas;
+
+	LogNormalDispersion();
+	void operator()(void *, vector<WeightPoint>&);
+	void accept_as_source(DispersionVisitor*, void*, void*);
+	void accept_as_destination(DispersionVisitor*, void*, void*);
+};
+
+
+/**
  * Dispersion model based on arrays provided by the user
  */
Index: sansmodels/src/sans/models/dispersion_models.py
===================================================================
--- sansmodels/src/sans/models/dispersion_models.py	(revision 988130c6c44dbbe2fa0a64fe25885c9c67a14480)
+++ sansmodels/src/sans/models/dispersion_models.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -74,5 +74,37 @@
             Set the weights of an array dispersion
         """
-        message = "set_weights is not available for GaussiantDispersion.\n"
+        message = "set_weights is not available for GaussianDispersion.\n"
+        message += "  Solution: Use an ArrayDispersion object"
+        raise "RuntimeError", message
+    
+class SchulzDispersion(DispersionModel):
+    """
+        Python bridge class for a dispersion model based 
+        on a Schulz distribution.
+    """
+    def __init__(self):
+        self.cdisp = c_models.new_schulz_model()
+        
+    def set_weights(self, values, weights):
+        """
+            Set the weights of an array dispersion
+        """
+        message = "set_weights is not available for SchulzDispersion.\n"
+        message += "  Solution: Use an ArrayDispersion object"
+        raise "RuntimeError", message
+    
+class LogNormalDispersion(DispersionModel):
+    """
+        Python bridge class for a dispersion model based 
+        on a Log Normal distribution.
+    """
+    def __init__(self):
+        self.cdisp = c_models.new_lognormal_model()
+        
+    def set_weights(self, values, weights):
+        """
+            Set the weights of an array dispersion
+        """
+        message = "set_weights is not available for LogNormalDispersion.\n"
         message += "  Solution: Use an ArrayDispersion object"
         raise "RuntimeError", message
@@ -100,4 +132,5 @@
         c_models.set_dispersion_weights(self.cdisp, values, weights)
  
-models = {GaussianDispersion:"GaussianModel", ArrayDispersion:"MyModel"}       
+models = {GaussianDispersion:"GaussianModel", ArrayDispersion:"MyModel",
+          SchulzDispersion: "Schulz", LogNormalDispersion: "LogNormal"}       
         
Index: sansmodels/src/sans/models/test/utest_dispersity.py
===================================================================
--- sansmodels/src/sans/models/test/utest_dispersity.py	(revision 8809e4829d357a9366a256b3595b75252de8b2c2)
+++ sansmodels/src/sans/models/test/utest_dispersity.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -57,6 +57,34 @@
         
         new_model = self.model.clone()
+        print "gaussian",self.model.run(0.001)
         self.assertAlmostEqual(new_model.run(0.001), 4723.32213339, 3)
         self.assertAlmostEqual(new_model.runXY([0.001,0.001]), 4743.56, 2)
+        
+    def test_schulz_zero(self):
+        from sans.models.dispersion_models import SchulzDispersion
+        disp = SchulzDispersion()
+        self.model.set_dispersion('radius', disp)
+        self.model.dispersion['radius']['width'] = 5.0
+        #self.model.dispersion['radius']['width'] = 0.0
+        self.model.dispersion['radius']['npts'] = 100
+        #self.model.setParam('scale', 1.0)
+        self.model.setParam('scale', 10.0)
+        print "schulz",self.model.run(0.001), self.model.dispersion
+        self.assertAlmostEqual(self.model.run(0.001), 450.355, 3)
+        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 452.299, 3)
+        
+    def test_lognormal_zero(self):
+        from sans.models.dispersion_models import LogNormalDispersion
+        disp = LogNormalDispersion()
+        self.model.set_dispersion('radius', disp)
+        self.model.dispersion['radius']['width'] = 5.0
+        #self.model.dispersion['radius']['width'] = 0.0
+        self.model.dispersion['radius']['npts'] = 100
+        #self.model.setParam('scale', 1.0)
+        self.model.setParam('scale', 10.0)
+        print "model dispersion",self.model.dispersion
+        print "lognormal",self.model.run(0.001)
+        self.assertAlmostEqual(self.model.run(0.001), 450.355, 3)
+        self.assertAlmostEqual(self.model.runXY([0.001,0.001]), 452.299, 3)
         
     def test_gaussian_zero(self):
Index: sansmodels/src/sans/models/test/utest_models.py
===================================================================
--- sansmodels/src/sans/models/test/utest_models.py	(revision ae60f8613faa37cf4fa6112ca8cc43e854b4cdbd)
+++ sansmodels/src/sans/models/test/utest_models.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -24,9 +24,9 @@
     def test1D(self):
         """ Test 1D model for a sphere """
-        self.assertAlmostEqual(self.comp.run(1.0), 56.3878, 4)
+        self.assertAlmostEqual(self.comp.run(1.0), 5.6387e-5, 4)
         
     def test1D_2(self):
         """ Test 2D model for a sphere """
-        self.assertAlmostEqual(self.comp.run([1.0, 1.3]), 56.3878, 4)
+        self.assertAlmostEqual(self.comp.run([1.0, 1.3]), 5.63878e-5, 4)
 
 class TestCyl(unittest.TestCase):
Index: sansmodels/src/sans/models/test/utest_models_array.py
===================================================================
--- sansmodels/src/sans/models/test/utest_models_array.py	(revision 812b901e8b8451f555bc0649e5ee190827ff9130)
+++ sansmodels/src/sans/models/test/utest_models_array.py	(revision eba988511d86410985b5a1c35ce70dd3968132a8)
@@ -8,5 +8,5 @@
         
 class TestSphere(unittest.TestCase):
-    """ Unit tests for sphere model """
+    """ Unit tests for sphere model using evalDistribution function """
     
     def setUp(self):
@@ -18,7 +18,8 @@
     def test1D(self):
         """ Test 1D model for a sphere  with vector as input"""
-        answer=numpy.array([5.63877831e-05,2.57231782e-06,2.73704050e-07,2.54229069e-08])
+        answer = numpy.array([5.63877831e-05,2.57231782e-06,2.73704050e-07,2.54229069e-08])
        
-        testvector= self.comp.run(self.x)
+       
+        testvector= self.comp.evalDistribution(self.x)
        
         self.assertAlmostEqual(len(testvector),4)
@@ -33,8 +34,16 @@
         """ Test 2D model for a sphere for 2 scalar """
         self.assertAlmostEqual(self.comp.run([1.0, 1.3]), 56.3878e-06, 4)
-   
+        
+    def test1D_3(self):
+        """ Test 2D model for a Shpere for 2 vectors as input """
+        x= numpy.reshape(self.x, [len(self.x),1])
+        y= numpy.reshape(self.y, [1,len(self.y)])
+        vect = self.comp.evalDistribution([x,y])
+        self.assertAlmostEqual(vect[0][0],9.2985e-07, 4)
+        self.assertAlmostEqual(vect[len(self.x)-1][len(self.y)-1],1.3871e-08, 4)
+        
         
 class TestCylinder(unittest.TestCase):
-    """ Unit tests for sphere model """
+    """ Unit tests for Cylinder model using evalDistribution function """
     
     def setUp(self):
@@ -42,11 +51,12 @@
         self.comp = CylinderModel()
         self.x = numpy.array([1.0,2.0,3.0, 4.0])
-        self.y = numpy.array([1.0,2.0,3.0, 4.0])
+        self.y = self.x +1
         
     def test1D(self):
-        """ Test 1D model for a Cylinder  with vector as input"""
+        """ Test 1D model for a cylinder with vector as input"""
+        
         answer = numpy.array([1.98860592e-04,7.03686335e-05,2.89144683e-06,2.04282827e-06])
-        testvector= self.comp.run(self.x)
-       
+
+        testvector= self.comp.evalDistribution(self.x)
         self.assertAlmostEqual(len(testvector),4)
         for i in xrange(len(answer)):
@@ -54,40 +64,24 @@
        
     def test1D_1(self):
-        """ Test 2D model for a Cylinder with scalar as input"""
-        self.assertAlmostEqual(self.comp.run(1.0),1.9886e-04, 4)
+        """ Test 2D model for a cylinder  with scalar as input"""
+        self.assertAlmostEqual(self.comp.run(0.2), 0.041761386790780453, 4)
          
     def test1D_2(self):
-        """ Test 2D model for a Cylinder for 2 scalar """
-        self.assertAlmostEqual(self.comp.run([1.0, 1.3]), 56.3878e-06, 4)
+        """ Test 2D model of a cylinder """ 
+        self.comp.setParam('cyl_theta', 1.0)
+        self.comp.setParam('cyl_phi', 1.0)
+        self.assertAlmostEqual(self.comp.run([0.2, 2.5]), 
+                               0.038176446608393366, 4)
         
     def test1D_3(self):
-        """ Test 2D model for a Cylinder for 2 vectors as input """
-        ans_input = numpy.zeros(len(self.x))
-        temp_x = numpy.zeros(len(self.x))
-        temp_y = numpy.zeros(len(self.y))
+        """ Test 2D model for a cylinder for 2 vectors as input """
+        x= numpy.reshape(self.x, [len(self.x),1])
+        y= numpy.reshape(self.y, [1,len(self.y)])
+        vect = self.comp.evalDistribution([x,y])
+      
+        self.assertAlmostEqual(vect[0][0],5.06121018e-08,4)
+        self.assertAlmostEqual(vect[len(self.x)-1][len(self.y)-1],2.5978e-11, 4)
         
-        for i in xrange(len(self.x)):
-            qx = self.x[i]
-            qy = self.y[i]
-          
-            temp_x[i]= qx*math.cos(qy)
-            temp_y[i]= qx*math.sin(qy)
-            
-            value = math.sqrt(temp_x[i]*temp_x[i]+ temp_y[i]*temp_y[i] )#qx*qx +qy*qy)
-            ans_input[i]= value
-         
-        vect_runXY_qx_qy = self.comp.runXY([temp_x, temp_y])
-        vect_run_x_y = self.comp.run([self.x, self.y])
         
-        for i in xrange(len(vect_runXY_qx_qy)):
-            self.assertAlmostEqual(vect_runXY_qx_qy[i], vect_run_x_y[i])
-            
-        vect_run_x = self.comp.run(self.x)
-        vect_run_answer = self.comp.run(ans_input)
-        
-        for i in xrange(len(vect_run_x )):
-            self.assertAlmostEqual(vect_run_x [i], vect_run_answer[i])
-            
-
 
 if __name__ == '__main__':
