Index: src/sans/models/BCCrystalModel.py
===================================================================
--- src/sans/models/BCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/BCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,209 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\bcc.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CBCCrystalModel
+
+def create_BCCrystalModel():
+    """
+       Create a model instance
+    """
+    obj = BCCrystalModel()
+    # CBCCrystalModel.__init__(obj) is called by
+    # the BCCrystalModel constructor
+    return obj
+
+class BCCrystalModel(CBCCrystalModel, BaseComponent):
+    """ 
+    Class that evaluates a BCCrystalModel model. 
+    This file was auto-generated from src\sans\models\include\bcc.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         dnn             = 220.0 [A]
+         d_factor        = 0.06 
+         radius          = 40.0 [A]
+         sldSph          = 3e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         theta           = 0.0 [deg]
+         phi             = 0.0 [deg]
+         psi             = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CBCCrystalModel.__init__, (self,)) 
+
+        CBCCrystalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "BCCrystalModel"
+        ## Model description
+        self.description = """
+        P(q)=(scale/Vp)*V_lattice*P(q)*Z(q)+bkg where scale is the volume
+		fraction of sphere,
+		Vp = volume of the primary particle,
+		V_lattice = volume correction for
+		for the crystal structure,
+		P(q)= form factor of the sphere (normalized),
+		Z(q)= paracrystalline structure factor
+		for a face centered cubic structure.
+		[Body Centered Cubic ParaCrystal Model]
+		Parameters;
+		scale: volume fraction of spheres
+		bkg:background, R: radius of sphere
+		dnn: Nearest neighbor distance
+		d_factor: Paracrystal distortion factor
+		radius: radius of the spheres
+		sldSph: SLD of the sphere
+		sldSolv: SLD of the solvent
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['dnn'] = ['[A]', None, None]
+        self.details['d_factor'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['sldSph'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['theta'] = ['[deg]', None, None]
+        self.details['phi'] = ['[deg]', None, None]
+        self.details['psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'phi.width',
+                      'psi.width',
+                      'theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['phi',
+                                   'psi',
+                                   'theta',
+                                   'phi.width',
+                                   'psi.width',
+                                   'theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_BCCrystalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(BCCrystalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CBCCrystalModel.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 CBCCrystalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CBCCrystalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CBCCrystalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CBCCrystalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CBCCrystalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/BarBellModel.py
===================================================================
--- src/sans/models/BarBellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/BarBellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,206 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\barbell.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CBarBellModel
+
+def create_BarBellModel():
+    """
+       Create a model instance
+    """
+    obj = BarBellModel()
+    # CBarBellModel.__init__(obj) is called by
+    # the BarBellModel constructor
+    return obj
+
+class BarBellModel(CBarBellModel, BaseComponent):
+    """ 
+    Class that evaluates a BarBellModel model. 
+    This file was auto-generated from src\sans\models\include\barbell.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         rad_bar         = 20.0 [A]
+         len_bar         = 400.0 [A]
+         rad_bell        = 40.0 [A]
+         sld_barbell     = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         theta           = 0.0 [deg]
+         phi             = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CBarBellModel.__init__, (self,)) 
+
+        CBarBellModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "BarBellModel"
+        ## Model description
+        self.description = """
+        Calculates the scattering from a barbell-shaped cylinder. That is
+		a sphereocylinder with spherical end caps
+		that have a radius larger than that of
+		the cylinder and the center of the end cap
+		radius lies outside of the cylinder.
+		Note: As the length of cylinder(bar) -->0,
+		it becomes a dumbbell.
+		And when rad_bar = rad_bell,
+		it is a spherocylinder.
+		It must be that rad_bar <(=) rad_bell.
+		[Parameters];
+		scale: volume fraction of spheres,
+		background:incoherent background,
+		rad_bar: radius of the cylindrical bar,
+		len_bar: length of the cylindrical bar,
+		rad_bell: radius of the spherical bell,
+		sld_barbell: SLD of the barbell,
+		sld_solv: SLD of the solvent.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['rad_bar'] = ['[A]', None, None]
+        self.details['len_bar'] = ['[A]', None, None]
+        self.details['rad_bell'] = ['[A]', None, None]
+        self.details['sld_barbell'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['theta'] = ['[deg]', None, None]
+        self.details['phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['rad_bar.width',
+                      'len_bar',
+                      'rad_bell',
+                      'phi.width',
+                      'theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['phi',
+                                   'theta',
+                                   'phi.width',
+                                   'theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_BarBellModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(BarBellModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CBarBellModel.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 CBarBellModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CBarBellModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CBarBellModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CBarBellModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CBarBellModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/BinaryHSModel.py
===================================================================
--- src/sans/models/BinaryHSModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/BinaryHSModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,188 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\binaryHS.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CBinaryHSModel
+
+def create_BinaryHSModel():
+    """
+       Create a model instance
+    """
+    obj = BinaryHSModel()
+    # CBinaryHSModel.__init__(obj) is called by
+    # the BinaryHSModel constructor
+    return obj
+
+class BinaryHSModel(CBinaryHSModel, BaseComponent):
+    """ 
+    Class that evaluates a BinaryHSModel model. 
+    This file was auto-generated from src\sans\models\include\binaryHS.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         l_radius        = 100.0 [A]
+         s_radius        = 25.0 [A]
+         vol_frac_ls     = 0.1 
+         vol_frac_ss     = 0.2 
+         ls_sld          = 3.5e-06 [1/A^(2)]
+         ss_sld          = 5e-07 [1/A^(2)]
+         solvent_sld     = 6.36e-06 [1/A^(2)]
+         background      = 0.001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CBinaryHSModel.__init__, (self,)) 
+
+        CBinaryHSModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "BinaryHSModel"
+        ## Model description
+        self.description = """
+         Model parameters: l_radius : large radius of binary hard sphere
+		s_radius : small radius of binary hard sphere
+		vol_frac_ls : volume fraction of large spheres
+		vol_frac_ss : volume fraction of small spheres
+		ls_sld: large sphere  scattering length density
+		ss_sld: small sphere scattering length density
+		solvent_sld: solvent scattering length density
+		background: incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['l_radius'] = ['[A]', None, None]
+        self.details['s_radius'] = ['[A]', None, None]
+        self.details['vol_frac_ls'] = ['', None, None]
+        self.details['vol_frac_ss'] = ['', None, None]
+        self.details['ls_sld'] = ['[1/A^(2)]', None, None]
+        self.details['ss_sld'] = ['[1/A^(2)]', None, None]
+        self.details['solvent_sld'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['l_radius.width',
+                      's_radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_BinaryHSModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(BinaryHSModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CBinaryHSModel.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 CBinaryHSModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CBinaryHSModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CBinaryHSModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CBinaryHSModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CBinaryHSModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CSParallelepipedModel.py
===================================================================
--- src/sans/models/CSParallelepipedModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CSParallelepipedModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,219 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\csparallelepiped.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCSParallelepipedModel
+
+def create_CSParallelepipedModel():
+    """
+       Create a model instance
+    """
+    obj = CSParallelepipedModel()
+    # CCSParallelepipedModel.__init__(obj) is called by
+    # the CSParallelepipedModel constructor
+    return obj
+
+class CSParallelepipedModel(CCSParallelepipedModel, BaseComponent):
+    """ 
+    Class that evaluates a CSParallelepipedModel model. 
+    This file was auto-generated from src\sans\models\include\csparallelepiped.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         shortA          = 35.0 [A]
+         midB            = 75.0 [A]
+         longC           = 400.0 [A]
+         rimA            = 10.0 [A]
+         rimB            = 10.0 [A]
+         rimC            = 10.0 [A]
+         sld_rimA        = 2e-06 [1/A^(2)]
+         sld_rimB        = 4e-06 [1/A^(2)]
+         sld_rimC        = 2e-06 [1/A^(2)]
+         sld_pcore       = 1e-06 [1/A^(2)]
+         sld_solv        = 6e-06 [1/A^(2)]
+         background      = 0.06 [1/cm]
+         parallel_theta  = 0.0 [deg]
+         parallel_phi    = 0.0 [deg]
+         parallel_psi    = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCSParallelepipedModel.__init__, (self,)) 
+
+        CCSParallelepipedModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CSParallelepipedModel"
+        ## Model description
+        self.description = """
+         Form factor for a rectangular Shell. Below are the Parameters.
+		scale: scale factor
+		shortA: length of short edge  [A]
+		midB: length of another short edge [A]
+		longC: length of long edge  of the parallelepiped [A]
+		rimA: length of short edge  [A]
+		rimB: length of another short edge [A]
+		rimC: length of long edge  of the parallelepiped [A]
+		sld_rimA: sld of rimA [1/A^(2)]
+		sld_rimB: sld of rimB [1/A^(2)]
+		sld_rimC: sld of rimC [1/A^(2)]
+		sld_core: Pipe_sld [1/A^(2)]
+		sld_solv: solvent_sld [1/A^(2)]
+		background: incoherent Background [1/cm]
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['shortA'] = ['[A]', None, None]
+        self.details['midB'] = ['[A]', None, None]
+        self.details['longC'] = ['[A]', None, None]
+        self.details['rimA'] = ['[A]', None, None]
+        self.details['rimB'] = ['[A]', None, None]
+        self.details['rimC'] = ['[A]', None, None]
+        self.details['sld_rimA'] = ['[1/A^(2)]', None, None]
+        self.details['sld_rimB'] = ['[1/A^(2)]', None, None]
+        self.details['sld_rimC'] = ['[1/A^(2)]', None, None]
+        self.details['sld_pcore'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['parallel_theta'] = ['[deg]', None, None]
+        self.details['parallel_phi'] = ['[deg]', None, None]
+        self.details['parallel_psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['shortA.width',
+                      'midB.width',
+                      'longC.width',
+                      'parallel_phi.width',
+                      'parallel_psi.width',
+                      'parallel_theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['parallel_phi',
+                                   'parallel_psi',
+                                   'parallel_theta',
+                                   'parallel_phi.width',
+                                   'parallel_psi.width',
+                                   'parallel_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CSParallelepipedModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CSParallelepipedModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCSParallelepipedModel.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 CCSParallelepipedModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCSParallelepipedModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCSParallelepipedModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCSParallelepipedModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCSParallelepipedModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CappedCylinderModel.py
===================================================================
--- src/sans/models/CappedCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CappedCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,204 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\capcyl.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCappedCylinderModel
+
+def create_CappedCylinderModel():
+    """
+       Create a model instance
+    """
+    obj = CappedCylinderModel()
+    # CCappedCylinderModel.__init__(obj) is called by
+    # the CappedCylinderModel constructor
+    return obj
+
+class CappedCylinderModel(CCappedCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a CappedCylinderModel model. 
+    This file was auto-generated from src\sans\models\include\capcyl.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         rad_cyl         = 20.0 [A]
+         len_cyl         = 400.0 [A]
+         rad_cap         = 40.0 [A]
+         sld_capcyl      = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         theta           = 0.0 [deg]
+         phi             = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCappedCylinderModel.__init__, (self,)) 
+
+        CCappedCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CappedCylinderModel"
+        ## Model description
+        self.description = """
+        Calculates the scattering from a cylinder with spherical section end-caps.
+		That is, a sphereocylinder
+		with end caps that have a radius larger than
+		that of the cylinder and the center of the
+		end cap radius lies within the cylinder.
+		Note: As the length of cylinder -->0,
+		it becomes a ConvexLens.
+		It must be that rad_cyl <(=) rad_cap.
+		[Parameters];
+		scale: volume fraction of spheres,
+		background:incoherent background,
+		rad_cyl: radius of the cylinder,
+		len_cyl: length of the cylinder,
+		rad_cap: radius of the semi-spherical cap,
+		sld_capcyl: SLD of the capped cylinder,
+		sld_solv: SLD of the solvent.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['rad_cyl'] = ['[A]', None, None]
+        self.details['len_cyl'] = ['[A]', None, None]
+        self.details['rad_cap'] = ['[A]', None, None]
+        self.details['sld_capcyl'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['theta'] = ['[deg]', None, None]
+        self.details['phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['rad_cyl.width',
+                      'len_cyl',
+                      'rad_cap',
+                      'phi.width',
+                      'theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['phi',
+                                   'theta',
+                                   'phi.width',
+                                   'theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CappedCylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CappedCylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCappedCylinderModel.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 CCappedCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCappedCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCappedCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCappedCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCappedCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/Core2ndMomentModel.py
===================================================================
--- src/sans/models/Core2ndMomentModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/Core2ndMomentModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,192 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\coresecondmoment.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCore2ndMomentModel
+
+def create_Core2ndMomentModel():
+    """
+       Create a model instance
+    """
+    obj = Core2ndMomentModel()
+    # CCore2ndMomentModel.__init__(obj) is called by
+    # the Core2ndMomentModel constructor
+    return obj
+
+class Core2ndMomentModel(CCore2ndMomentModel, BaseComponent):
+    """ 
+    Class that evaluates a Core2ndMomentModel model. 
+    This file was auto-generated from src\sans\models\include\coresecondmoment.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         density_poly    = 0.7 [g/cm^(3)]
+         sld_poly        = 1.5e-06 [1/A^(2)]
+         radius_core     = 500.0 [A]
+         volf_cores      = 0.14 
+         ads_amount      = 1.9 [mg/m^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         second_moment   = 23.0 [A]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCore2ndMomentModel.__init__, (self,)) 
+
+        CCore2ndMomentModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "Core2ndMomentModel"
+        ## Model description
+        self.description = """
+        Calculate CoreSecondMoment Model
+		
+		scale:calibration factor,
+		density_poly: density of the layer
+		sld_poly: the SLD of the layer
+		volf_cores: volume fraction of cores
+		ads_amount: adsorbed amount
+		second_moment: second moment of the layer
+		sld_solv: the SLD of the solvent
+		background
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['density_poly'] = ['[g/cm^(3)]', None, None]
+        self.details['sld_poly'] = ['[1/A^(2)]', None, None]
+        self.details['radius_core'] = ['[A]', None, None]
+        self.details['volf_cores'] = ['', None, None]
+        self.details['ads_amount'] = ['[mg/m^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['second_moment'] = ['[A]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius_core.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_Core2ndMomentModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(Core2ndMomentModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCore2ndMomentModel.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 CCore2ndMomentModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCore2ndMomentModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCore2ndMomentModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCore2ndMomentModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCore2ndMomentModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CoreFourShellModel.py
===================================================================
--- src/sans/models/CoreFourShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CoreFourShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,263 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\corefourshell.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCoreFourShellModel
+
+def create_CoreFourShellModel():
+    """
+       Create a model instance
+    """
+    obj = CoreFourShellModel()
+    # CCoreFourShellModel.__init__(obj) is called by
+    # the CoreFourShellModel constructor
+    return obj
+
+class CoreFourShellModel(CCoreFourShellModel, BaseComponent):
+    """ 
+    Class that evaluates a CoreFourShellModel model. 
+    This file was auto-generated from src\sans\models\include\corefourshell.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         rad_core0       = 60.0 [A]
+         sld_core0       = 6.4e-06 [1/A^(2)]
+         thick_shell1    = 10.0 [A]
+         sld_shell1      = 1e-06 [1/A^(2)]
+         thick_shell2    = 10.0 [A]
+         sld_shell2      = 2e-06 [1/A^(2)]
+         thick_shell3    = 10.0 [A]
+         sld_shell3      = 3e-06 [1/A^(2)]
+         thick_shell4    = 10.0 [A]
+         sld_shell4      = 4e-06 [1/A^(2)]
+         sld_solv        = 6.4e-06 [1/A^(2)]
+         background      = 0.001 [1/cm]
+         M0_sld_shell1   = 0.0 [1/A^(2)]
+         M_theta_shell1  = 0.0 [deg]
+         M_phi_shell1    = 0.0 [deg]
+         M0_sld_shell2   = 0.0 [1/A^(2)]
+         M_theta_shell2  = 0.0 [deg]
+         M_phi_shell2    = 0.0 [deg]
+         M0_sld_shell3   = 0.0 [1/A^(2)]
+         M_theta_shell3  = 0.0 [deg]
+         M_phi_shell3    = 0.0 [deg]
+         M0_sld_shell4   = 0.0 [1/A^(2)]
+         M_theta_shell4  = 0.0 [deg]
+         M_phi_shell4    = 0.0 [deg]
+         M0_sld_core0    = 0.0 [1/A^(2)]
+         M_theta_core0   = 0.0 [deg]
+         M_phi_core0     = 0.0 [deg]
+         M0_sld_solv     = 0.0 [1/A^(2)]
+         M_theta_solv    = 0.0 [deg]
+         M_phi_solv      = 0.0 [deg]
+         Up_frac_i       = 0.5 [u/(u+d)]
+         Up_frac_f       = 0.5 [u/(u+d)]
+         Up_theta        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCoreFourShellModel.__init__, (self,)) 
+
+        CCoreFourShellModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CoreFourShellModel"
+        ## Model description
+        self.description = """
+         Calculates the scattering intensity from a core-4 shell structure.
+		scale = scale factor * volume fraction
+		rad_core0: the radius of the core
+		sld_core0: the SLD of the core
+		thick_shelli: the thickness of the i'th shell from the core
+		sld_shelli: the SLD of the i'th shell from the core
+		sld_solv: the SLD of the solvent
+		background: incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['rad_core0'] = ['[A]', None, None]
+        self.details['sld_core0'] = ['[1/A^(2)]', None, None]
+        self.details['thick_shell1'] = ['[A]', None, None]
+        self.details['sld_shell1'] = ['[1/A^(2)]', None, None]
+        self.details['thick_shell2'] = ['[A]', None, None]
+        self.details['sld_shell2'] = ['[1/A^(2)]', None, None]
+        self.details['thick_shell3'] = ['[A]', None, None]
+        self.details['sld_shell3'] = ['[1/A^(2)]', None, None]
+        self.details['thick_shell4'] = ['[A]', None, None]
+        self.details['sld_shell4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['M0_sld_shell1'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_shell1'] = ['[deg]', None, None]
+        self.details['M_phi_shell1'] = ['[deg]', None, None]
+        self.details['M0_sld_shell2'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_shell2'] = ['[deg]', None, None]
+        self.details['M_phi_shell2'] = ['[deg]', None, None]
+        self.details['M0_sld_shell3'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_shell3'] = ['[deg]', None, None]
+        self.details['M_phi_shell3'] = ['[deg]', None, None]
+        self.details['M0_sld_shell4'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_shell4'] = ['[deg]', None, None]
+        self.details['M_phi_shell4'] = ['[deg]', None, None]
+        self.details['M0_sld_core0'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_core0'] = ['[deg]', None, None]
+        self.details['M_phi_core0'] = ['[deg]', None, None]
+        self.details['M0_sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_solv'] = ['[deg]', None, None]
+        self.details['M_phi_solv'] = ['[deg]', None, None]
+        self.details['Up_frac_i'] = ['[u/(u+d)]', None, None]
+        self.details['Up_frac_f'] = ['[u/(u+d)]', None, None]
+        self.details['Up_theta'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['thick_shell4.width',
+                      'thick_shell1.width',
+                      'thick_shell2.width',
+                      'thick_shell3.width',
+                      'rad_core0.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['M0_sld_shell4',
+                                   'M_theta_shell4',
+                                   'M_phi_shell4',
+                                   'M0_sld_shell3',
+                                   'M_theta_shell3',
+                                   'M_phi_shell3',
+                                   'M0_sld_shell2',
+                                   'M_theta_shell2',
+                                   'M_phi_shell2',
+                                   'M0_sld_shell1',
+                                   'M_theta_shell1',
+                                   'M_phi_shell1',
+                                   'M0_sld_core0',
+                                   'M_theta_core0',
+                                   'M_phi_core0',
+                                   'M0_sld_solv',
+                                   'M_theta_solv',
+                                   'M_phi_solv',
+                                   'Up_frac_i',
+                                   'Up_frac_f',
+                                   'Up_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = ['M0_sld_shell4', 'M_theta_shell4', 'M_phi_shell4', 'M0_sld_shell3', 'M_theta_shell3', 'M_phi_shell3', 'M0_sld_shell2', 'M_theta_shell2', 'M_phi_shell2', 'M0_sld_shell1', 'M_theta_shell1', 'M_phi_shell1', 'M0_sld_core0', 'M_theta_core0', 'M_phi_core0', 'M0_sld_solv', 'M_theta_solv', 'M_phi_solv', 'Up_frac_i', 'Up_frac_f', 'Up_theta']
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CoreFourShellModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CoreFourShellModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCoreFourShellModel.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 CCoreFourShellModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCoreFourShellModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCoreFourShellModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCoreFourShellModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCoreFourShellModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CoreShellBicelleModel.py
===================================================================
--- src/sans/models/CoreShellBicelleModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CoreShellBicelleModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,219 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\core_shell_bicelle.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCoreShellBicelleModel
+
+def create_CoreShellBicelleModel():
+    """
+       Create a model instance
+    """
+    obj = CoreShellBicelleModel()
+    # CCoreShellBicelleModel.__init__(obj) is called by
+    # the CoreShellBicelleModel constructor
+    return obj
+
+class CoreShellBicelleModel(CCoreShellBicelleModel, BaseComponent):
+    """ 
+    Class that evaluates a CoreShellBicelleModel model. 
+    This file was auto-generated from src\sans\models\include\core_shell_bicelle.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 20.0 [A]
+         scale           = 1.0 
+         rim_thick       = 10.0 [A]
+         face_thick      = 10.0 [A]
+         length          = 400.0 [A]
+         core_sld        = 1e-06 [1/A^(2)]
+         face_sld        = 4e-06 [1/A^(2)]
+         rim_sld         = 4e-06 [1/A^(2)]
+         solvent_sld     = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         axis_theta      = 90.0 [deg]
+         axis_phi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCoreShellBicelleModel.__init__, (self,)) 
+
+        CCoreShellBicelleModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CoreShellBicelleModel"
+        ## Model description
+        self.description = """
+        P(q,alpha)= scale/Vs*f(q)^(2) + bkg,  where: f(q)= 2(core_sld
+		- solvant_sld)* Vc*sin[qLcos(alpha/2)]
+		/[qLcos(alpha/2)]*J1(qRsin(alpha))
+		/[qRsin(alpha)]+2(shell_sld-solvent_sld)
+		*Vs*sin[q(L+T)cos(alpha/2)][[q(L+T)
+		*cos(alpha/2)]*J1(q(R+T)sin(alpha))
+		/q(R+T)sin(alpha)]
+		
+		alpha:is the angle between the axis of
+		the cylinder and the q-vector
+		Vs: the volume of the outer shell
+		Vc: the volume of the core
+		L: the length of the core
+		shell_sld: the scattering length density
+		of the shell
+		solvent_sld: the scattering length density
+		of the solvent
+		bkg: the background
+		T: the thickness
+		R+T: is the outer radius
+		L+2T: The total length of the outershell
+		J1: the first order Bessel function
+		theta: axis_theta of the cylinder
+		phi: the axis_phi of the cylinder...
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['rim_thick'] = ['[A]', None, None]
+        self.details['face_thick'] = ['[A]', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['core_sld'] = ['[1/A^(2)]', None, None]
+        self.details['face_sld'] = ['[1/A^(2)]', None, None]
+        self.details['rim_sld'] = ['[1/A^(2)]', None, None]
+        self.details['solvent_sld'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['axis_phi.width',
+                      'axis_theta.width',
+                      'length.width',
+                      'radius.width',
+                      'rim_thick.width',
+                      'face_thick.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi',
+                                   'axis_theta',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CoreShellBicelleModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CoreShellBicelleModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCoreShellBicelleModel.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 CCoreShellBicelleModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCoreShellBicelleModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCoreShellBicelleModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCoreShellBicelleModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCoreShellBicelleModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CoreShellCylinderModel.py
===================================================================
--- src/sans/models/CoreShellCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CoreShellCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,215 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\core_shell_cylinder.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCoreShellCylinderModel
+
+def create_CoreShellCylinderModel():
+    """
+       Create a model instance
+    """
+    obj = CoreShellCylinderModel()
+    # CCoreShellCylinderModel.__init__(obj) is called by
+    # the CoreShellCylinderModel constructor
+    return obj
+
+class CoreShellCylinderModel(CCoreShellCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a CoreShellCylinderModel model. 
+    This file was auto-generated from src\sans\models\include\core_shell_cylinder.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 20.0 [A]
+         scale           = 1.0 
+         thickness       = 10.0 [A]
+         length          = 400.0 [A]
+         core_sld        = 1e-06 [1/A^(2)]
+         shell_sld       = 4e-06 [1/A^(2)]
+         solvent_sld     = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         axis_theta      = 90.0 [deg]
+         axis_phi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCoreShellCylinderModel.__init__, (self,)) 
+
+        CCoreShellCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CoreShellCylinderModel"
+        ## Model description
+        self.description = """
+        P(q,alpha)= scale/Vs*f(q)^(2) + bkg,
+		where: f(q)= 2(core_sld
+		- solvant_sld)* Vc*sin[qLcos(alpha/2)]
+		/[qLcos(alpha/2)]*J1(qRsin(alpha))
+		/[qRsin(alpha)]+2(shell_sld-solvent_sld)
+		*Vs*sin[q(L+T)cos(alpha/2)][[q(L+T)
+		*cos(alpha/2)]*J1(q(R+T)sin(alpha))
+		/q(R+T)sin(alpha)]
+		
+		alpha:is the angle between the axis of
+		the cylinder and the q-vector
+		Vs: the volume of the outer shell
+		Vc: the volume of the core
+		L: the length of the core
+		shell_sld: the scattering length density
+		of the shell
+		solvent_sld: the scattering length density
+		of the solvent
+		bkg: the background
+		T: the thickness
+		R+T: is the outer radius
+		L+2T: The total length of the outershell
+		J1: the first order Bessel function
+		theta: axis_theta of the cylinder
+		phi: the axis_phi of the cylinder...
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['thickness'] = ['[A]', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['core_sld'] = ['[1/A^(2)]', None, None]
+        self.details['shell_sld'] = ['[1/A^(2)]', None, None]
+        self.details['solvent_sld'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['axis_phi.width',
+                      'axis_theta.width',
+                      'length.width',
+                      'radius.width',
+                      'thickness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi',
+                                   'axis_theta',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CoreShellCylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CoreShellCylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCoreShellCylinderModel.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 CCoreShellCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCoreShellCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCoreShellCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCoreShellCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCoreShellCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CoreShellEllipsoidModel.py
===================================================================
--- src/sans/models/CoreShellEllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CoreShellEllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,213 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\spheroid.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCoreShellEllipsoidModel
+
+def create_CoreShellEllipsoidModel():
+    """
+       Create a model instance
+    """
+    obj = CoreShellEllipsoidModel()
+    # CCoreShellEllipsoidModel.__init__(obj) is called by
+    # the CoreShellEllipsoidModel constructor
+    return obj
+
+class CoreShellEllipsoidModel(CCoreShellEllipsoidModel, BaseComponent):
+    """ 
+    Class that evaluates a CoreShellEllipsoidModel model. 
+    This file was auto-generated from src\sans\models\include\spheroid.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         equat_core      = 200.0 [A]
+         polar_core      = 20.0 [A]
+         equat_shell     = 250.0 [A]
+         polar_shell     = 30.0 [A]
+         sld_core        = 2e-06 [1/A^(2)]
+         sld_shell       = 1e-06 [1/A^(2)]
+         sld_solvent     = 6.3e-06 [1/A^(2)]
+         background      = 0.001 [1/cm]
+         axis_theta      = 0.0 [deg]
+         axis_phi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCoreShellEllipsoidModel.__init__, (self,)) 
+
+        CCoreShellEllipsoidModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CoreShellEllipsoidModel"
+        ## Model description
+        self.description = """
+        [SpheroidCoreShellModel] Calculates the form factor for an spheroid
+		ellipsoid particle with a core_shell structure.
+		The form factor is averaged over all possible
+		orientations of the ellipsoid such that P(q)
+		= scale*<f^2>/Vol + bkg, where f is the
+		single particle scattering amplitude.
+		[Parameters]:
+		equat_core = equatorial radius of core,
+		polar_core = polar radius of core,
+		equat_shell = equatorial radius of shell,
+		polar_shell = polar radius (revolution axis) of shell,
+		sld_core = SLD_core
+		sld_shell = SLD_shell
+		sld_solvent = SLD_solvent
+		background = Incoherent bkg
+		scale =scale
+		Note:It is the users' responsibility to ensure
+		that shell radii are larger than core radii.
+		oblate: polar radius < equatorial radius
+		prolate :  polar radius > equatorial radius
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['equat_core'] = ['[A]', None, None]
+        self.details['polar_core'] = ['[A]', None, None]
+        self.details['equat_shell'] = ['[A]', None, None]
+        self.details['polar_shell'] = ['[A]', None, None]
+        self.details['sld_core'] = ['[1/A^(2)]', None, None]
+        self.details['sld_shell'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solvent'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['equat_core.width',
+                      'polar_core.width',
+                      'equat_shell.width',
+                      'polar_shell.width',
+                      'axis_phi.width',
+                      'axis_theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi',
+                                   'axis_theta',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CoreShellEllipsoidModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CoreShellEllipsoidModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCoreShellEllipsoidModel.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 CCoreShellEllipsoidModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCoreShellEllipsoidModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCoreShellEllipsoidModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCoreShellEllipsoidModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCoreShellEllipsoidModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CoreShellModel.py
===================================================================
--- src/sans/models/CoreShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CoreShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,223 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\core_shell.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCoreShellModel
+
+def create_CoreShellModel():
+    """
+       Create a model instance
+    """
+    obj = CoreShellModel()
+    # CCoreShellModel.__init__(obj) is called by
+    # the CoreShellModel constructor
+    return obj
+
+class CoreShellModel(CCoreShellModel, BaseComponent):
+    """ 
+    Class that evaluates a CoreShellModel model. 
+    This file was auto-generated from src\sans\models\include\core_shell.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 60.0 [A]
+         scale           = 1.0 
+         thickness       = 10.0 [A]
+         core_sld        = 1e-06 [1/A^(2)]
+         shell_sld       = 2e-06 [1/A^(2)]
+         solvent_sld     = 3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         M0_sld_shell    = 0.0 [1/A^(2)]
+         M_theta_shell   = 0.0 [deg]
+         M_phi_shell     = 0.0 [deg]
+         M0_sld_core     = 0.0 [1/A^(2)]
+         M_theta_core    = 0.0 [deg]
+         M_phi_core      = 0.0 [deg]
+         M0_sld_solv     = 0.0 [1/A^(2)]
+         M_theta_solv    = 0.0 [deg]
+         M_phi_solv      = 0.0 [deg]
+         Up_frac_i       = 0.5 [u/(u+d)]
+         Up_frac_f       = 0.5 [u/(u+d)]
+         Up_theta        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCoreShellModel.__init__, (self,)) 
+
+        CCoreShellModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CoreShellModel"
+        ## Model description
+        self.description = """
+        Form factor for a monodisperse spherical particle with particle
+		with a core-shell structure:
+		
+		The form factor is normalized by the
+		total particle volume.
+		
+		radius: core radius, thickness: shell thickness
+		
+		Ref: Guinier, A. and G. Fournet,
+		John Wiley and Sons, New York, 1955.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['thickness'] = ['[A]', None, None]
+        self.details['core_sld'] = ['[1/A^(2)]', None, None]
+        self.details['shell_sld'] = ['[1/A^(2)]', None, None]
+        self.details['solvent_sld'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['M0_sld_shell'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_shell'] = ['[deg]', None, None]
+        self.details['M_phi_shell'] = ['[deg]', None, None]
+        self.details['M0_sld_core'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_core'] = ['[deg]', None, None]
+        self.details['M_phi_core'] = ['[deg]', None, None]
+        self.details['M0_sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_solv'] = ['[deg]', None, None]
+        self.details['M_phi_solv'] = ['[deg]', None, None]
+        self.details['Up_frac_i'] = ['[u/(u+d)]', None, None]
+        self.details['Up_frac_f'] = ['[u/(u+d)]', None, None]
+        self.details['Up_theta'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['thickness.width',
+                      'radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['M0_sld_shell',
+                                   'M_theta_shell',
+                                   'M_phi_shell',
+                                   'M0_sld_core',
+                                   'M_theta_core',
+                                   'M_phi_core',
+                                   'M0_sld_solv',
+                                   'M_theta_solv',
+                                   'M_phi_solv',
+                                   'Up_frac_i',
+                                   'Up_frac_f',
+                                   'Up_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = ['M0_sld_shell', 'M_theta_shell', 'M_phi_shell', 'M0_sld_core', 'M_theta_core', 'M_phi_core', 'M0_sld_solv', 'M_theta_solv', 'M_phi_solv', 'Up_frac_i', 'Up_frac_f', 'Up_theta']
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CoreShellModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CoreShellModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCoreShellModel.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 CCoreShellModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCoreShellModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCoreShellModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCoreShellModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCoreShellModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/CylinderModel.py
===================================================================
--- src/sans/models/CylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/CylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,225 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\cylinder.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CCylinderModel
+
+def create_CylinderModel():
+    """
+       Create a model instance
+    """
+    obj = CylinderModel()
+    # CCylinderModel.__init__(obj) is called by
+    # the CylinderModel constructor
+    return obj
+
+class CylinderModel(CCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a CylinderModel model. 
+    This file was auto-generated from src\sans\models\include\cylinder.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 20.0 [A]
+         length          = 400.0 [A]
+         sldCyl          = 4e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         cyl_theta       = 60.0 [deg]
+         cyl_phi         = 60.0 [deg]
+         M0_sld_cyl      = 0.0 [1/A^(2)]
+         M_theta_cyl     = 0.0 [deg]
+         M_phi_cyl       = 0.0 [deg]
+         M0_sld_solv     = 0.0 [1/A^(2)]
+         M_theta_solv    = 0.0 [deg]
+         M_phi_solv      = 0.0 [deg]
+         Up_frac_i       = 0.5 [u/(u+d)]
+         Up_frac_f       = 0.5 [u/(u+d)]
+         Up_theta        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CCylinderModel.__init__, (self,)) 
+
+        CCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "CylinderModel"
+        ## Model description
+        self.description = """
+         f(q)= 2*(sldCyl - sldSolv)*V*sin(qLcos(alpha/2))
+		/[qLcos(alpha/2)]*J1(qRsin(alpha/2))/[qRsin(alpha)]
+		
+		P(q,alpha)= scale/V*f(q)^(2)+bkg
+		V: Volume of the cylinder
+		R: Radius of the cylinder
+		L: Length of the cylinder
+		J1: The bessel function
+		alpha: angle betweenthe axis of the
+		cylinder and the q-vector for 1D
+		:the ouput is P(q)=scale/V*integral
+		from pi/2 to zero of...
+		f(q)^(2)*sin(alpha)*dalpha+ bkg
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['sldCyl'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['cyl_theta'] = ['[deg]', None, None]
+        self.details['cyl_phi'] = ['[deg]', None, None]
+        self.details['M0_sld_cyl'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_cyl'] = ['[deg]', None, None]
+        self.details['M_phi_cyl'] = ['[deg]', None, None]
+        self.details['M0_sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_solv'] = ['[deg]', None, None]
+        self.details['M_phi_solv'] = ['[deg]', None, None]
+        self.details['Up_frac_i'] = ['[u/(u+d)]', None, None]
+        self.details['Up_frac_f'] = ['[u/(u+d)]', None, None]
+        self.details['Up_theta'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['cyl_phi.width',
+                      'cyl_theta.width',
+                      'length.width',
+                      'radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['cyl_phi',
+                                   'cyl_theta',
+                                   'cyl_phi.width',
+                                   'cyl_theta.width',
+                                   'M0_sld_cyl',
+                                   'M_theta_cyl',
+                                   'M_phi_cyl',
+                                   'M0_sld_solv',
+                                   'M_theta_solv',
+                                   'M_phi_solv',
+                                   'Up_frac_i',
+                                   'Up_frac_f',
+                                   'Up_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = ['M0_sld_cyl', 'M_theta_cyl', 'M_phi_cyl', 'M0_sld_solv', 'M_theta_solv', 'M_phi_solv', 'Up_frac_i', 'Up_frac_f', 'Up_theta']
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_CylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(CylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CCylinderModel.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 CCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/DABModel.py
===================================================================
--- src/sans/models/DABModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/DABModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,171 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\dabmodel.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CDABModel
+
+def create_DABModel():
+    """
+       Create a model instance
+    """
+    obj = DABModel()
+    # CDABModel.__init__(obj) is called by
+    # the DABModel constructor
+    return obj
+
+class DABModel(CDABModel, BaseComponent):
+    """ 
+    Class that evaluates a DABModel model. 
+    This file was auto-generated from src\sans\models\include\dabmodel.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         length          = 50.0 [A]
+         scale           = 1.0 
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CDABModel.__init__, (self,)) 
+
+        CDABModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "DABModel"
+        ## Model description
+        self.description = """
+        Provide F(x) = scale/( 1 + (x*L)^2 )^(2) + background
+		DAB (Debye Anderson Brumberger) function as a BaseComponent model
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['length'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_DABModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(DABModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CDABModel.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 CDABModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CDABModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CDABModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CDABModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CDABModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/DiamCylFunc.py
===================================================================
--- src/sans/models/DiamCylFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/DiamCylFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,172 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\DiamCyl.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CDiamCylFunc
+
+def create_DiamCylFunc():
+    """
+       Create a model instance
+    """
+    obj = DiamCylFunc()
+    # CDiamCylFunc.__init__(obj) is called by
+    # the DiamCylFunc constructor
+    return obj
+
+class DiamCylFunc(CDiamCylFunc, BaseComponent):
+    """ 
+    Class that evaluates a DiamCylFunc model. 
+    This file was auto-generated from src\sans\models\include\DiamCyl.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 20.0 A
+         length          = 400.0 A
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CDiamCylFunc.__init__, (self,)) 
+
+        CDiamCylFunc.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "DiamCylFunc"
+        ## Model description
+        self.description = """
+        To calculate the 2nd virial coefficient for
+		the non-spherical object, then find the
+		radius of sphere that has this value of
+		virial coefficient.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['A', None, None]
+        self.details['length'] = ['A', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'length.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_DiamCylFunc, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(DiamCylFunc())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CDiamCylFunc.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 CDiamCylFunc.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CDiamCylFunc.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CDiamCylFunc.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CDiamCylFunc.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CDiamCylFunc.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/DiamEllipFunc.py
===================================================================
--- src/sans/models/DiamEllipFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/DiamEllipFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,176 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\DiamEllip.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CDiamEllipFunc
+
+def create_DiamEllipFunc():
+    """
+       Create a model instance
+    """
+    obj = DiamEllipFunc()
+    # CDiamEllipFunc.__init__(obj) is called by
+    # the DiamEllipFunc constructor
+    return obj
+
+class DiamEllipFunc(CDiamEllipFunc, BaseComponent):
+    """ 
+    Class that evaluates a DiamEllipFunc model. 
+    This file was auto-generated from src\sans\models\include\DiamEllip.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius_a        = 20.0 A
+         radius_b        = 400.0 A
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CDiamEllipFunc.__init__, (self,)) 
+
+        CDiamEllipFunc.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "DiamEllipFunc"
+        ## Model description
+        self.description = """
+        To calculate the 2nd virial coefficient for
+		the non-spherical object, then find the
+		radius of sphere that has this value of
+		virial coefficient:
+		radius_a = polar radius,
+		radius_b = equatorial radius;
+		radius_a > radius_b: Prolate spheroid,
+		radius_a < radius_b: Oblate spheroid.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius_a'] = ['A', None, None]
+        self.details['radius_b'] = ['A', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius_a.width',
+                      'radius_b.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_DiamEllipFunc, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(DiamEllipFunc())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CDiamEllipFunc.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 CDiamEllipFunc.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CDiamEllipFunc.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CDiamEllipFunc.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CDiamEllipFunc.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CDiamEllipFunc.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/EllipsoidModel.py
===================================================================
--- src/sans/models/EllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/EllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,204 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\ellipsoid.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CEllipsoidModel
+
+def create_EllipsoidModel():
+    """
+       Create a model instance
+    """
+    obj = EllipsoidModel()
+    # CEllipsoidModel.__init__(obj) is called by
+    # the EllipsoidModel constructor
+    return obj
+
+class EllipsoidModel(CEllipsoidModel, BaseComponent):
+    """ 
+    Class that evaluates a EllipsoidModel model. 
+    This file was auto-generated from src\sans\models\include\ellipsoid.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius_a        = 20.0 [A]
+         scale           = 1.0 
+         radius_b        = 400.0 [A]
+         sldEll          = 4e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         axis_theta      = 90.0 [deg]
+         axis_phi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CEllipsoidModel.__init__, (self,)) 
+
+        CEllipsoidModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "EllipsoidModel"
+        ## Model description
+        self.description = """
+        "P(q.alpha)= scale*f(q)^(2)+ bkg, where f(q)= 3*(sld_ell
+		- sld_solvent)*V*[sin(q*r(Ra,Rb,alpha))
+		-q*r*cos(qr(Ra,Rb,alpha))]
+		/[qr(Ra,Rb,alpha)]^(3)"
+		
+		r(Ra,Rb,alpha)= [Rb^(2)*(sin(alpha))^(2)
+		+ Ra^(2)*(cos(alpha))^(2)]^(1/2)
+		
+		scatter_sld: SLD of the scatter
+		solvent_sld: SLD of the solvent
+		sldEll: SLD of ellipsoid
+		sldSolv: SLD of solvent
+		V: volune of the Eliipsoid
+		Ra: radius along the rotation axis
+		of the Ellipsoid
+		Rb: radius perpendicular to the
+		rotation axis of the ellipsoid
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius_a'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['radius_b'] = ['[A]', None, None]
+        self.details['sldEll'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['axis_phi.width',
+                      'axis_theta.width',
+                      'radius_a.width',
+                      'radius_b.width',
+                      'length.width',
+                      'r_minor.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi.width',
+                                   'axis_theta.width',
+                                   'axis_phi',
+                                   'axis_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_EllipsoidModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(EllipsoidModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CEllipsoidModel.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 CEllipsoidModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CEllipsoidModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CEllipsoidModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CEllipsoidModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CEllipsoidModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/EllipticalCylinderModel.py
===================================================================
--- src/sans/models/EllipticalCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/EllipticalCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,199 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\elliptical_cylinder.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CEllipticalCylinderModel
+
+def create_EllipticalCylinderModel():
+    """
+       Create a model instance
+    """
+    obj = EllipticalCylinderModel()
+    # CEllipticalCylinderModel.__init__(obj) is called by
+    # the EllipticalCylinderModel constructor
+    return obj
+
+class EllipticalCylinderModel(CEllipticalCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a EllipticalCylinderModel model. 
+    This file was auto-generated from src\sans\models\include\elliptical_cylinder.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         r_minor         = 20.0 [A]
+         scale           = 1.0 
+         r_ratio         = 1.5 
+         length          = 400.0 [A]
+         sldCyl          = 4e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         cyl_theta       = 90.0 [deg]
+         cyl_phi         = 0.0 [deg]
+         cyl_psi         = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CEllipticalCylinderModel.__init__, (self,)) 
+
+        CEllipticalCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "EllipticalCylinderModel"
+        ## Model description
+        self.description = """
+         Model parameters: r_minor = the radius of minor axis of the cross section
+		r_ratio = the ratio of (r_major /r_minor >= 1)
+		length = the length of the cylinder
+		sldCyl = SLD of the cylinder
+		sldSolv = SLD of solvent -
+		background = incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['r_minor'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['r_ratio'] = ['', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['sldCyl'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['cyl_theta'] = ['[deg]', None, None]
+        self.details['cyl_phi'] = ['[deg]', None, None]
+        self.details['cyl_psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['cyl_phi.width',
+                      'cyl_theta.width',
+                      'cyl_psi.width',
+                      'length.width',
+                      'r_minor.width',
+                      'r_ratio.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['cyl_phi',
+                                   'cyl_theta',
+                                   'cyl_psi',
+                                   'cyl_phi.width',
+                                   'cyl_theta.width',
+                                   'cyl_psi.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_EllipticalCylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(EllipticalCylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CEllipticalCylinderModel.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 CEllipticalCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CEllipticalCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CEllipticalCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CEllipticalCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CEllipticalCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FCCrystalModel.py
===================================================================
--- src/sans/models/FCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,209 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\fcc.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFCCrystalModel
+
+def create_FCCrystalModel():
+    """
+       Create a model instance
+    """
+    obj = FCCrystalModel()
+    # CFCCrystalModel.__init__(obj) is called by
+    # the FCCrystalModel constructor
+    return obj
+
+class FCCrystalModel(CFCCrystalModel, BaseComponent):
+    """ 
+    Class that evaluates a FCCrystalModel model. 
+    This file was auto-generated from src\sans\models\include\fcc.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         dnn             = 220.0 [A]
+         d_factor        = 0.06 
+         radius          = 40.0 [A]
+         sldSph          = 3e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         theta           = 0.0 [deg]
+         phi             = 0.0 [deg]
+         psi             = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFCCrystalModel.__init__, (self,)) 
+
+        CFCCrystalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FCCrystalModel"
+        ## Model description
+        self.description = """
+        P(q)=(scale/Vp)*V_lattice*P(q)*Z(q)+bkg where scale is the volume
+		fraction of sphere,
+		Vp = volume of the primary particle,
+		V_lattice = volume correction for
+		for the crystal structure,
+		P(q)= form factor of the sphere (normalized),
+		Z(q)= paracrystalline structure factor
+		for a face centered cubic structure.
+		[Face Centered Cubic ParaCrystal Model]
+		Parameters;
+		scale: volume fraction of spheres
+		bkg:background, R: radius of sphere
+		dnn: Nearest neighbor distance
+		d_factor: Paracrystal distortion factor
+		radius: radius of the spheres
+		sldSph: SLD of the sphere
+		sldSolv: SLD of the solvent
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['dnn'] = ['[A]', None, None]
+        self.details['d_factor'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['sldSph'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['theta'] = ['[deg]', None, None]
+        self.details['phi'] = ['[deg]', None, None]
+        self.details['psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'phi.width',
+                      'psi.width',
+                      'theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['phi',
+                                   'psi',
+                                   'theta',
+                                   'phi.width',
+                                   'psi.width',
+                                   'theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FCCrystalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FCCrystalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFCCrystalModel.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 CFCCrystalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFCCrystalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFCCrystalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFCCrystalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFCCrystalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FlexCylEllipXModel.py
===================================================================
--- src/sans/models/FlexCylEllipXModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FlexCylEllipXModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,186 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\flexcyl_ellipX.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFlexCylEllipXModel
+
+def create_FlexCylEllipXModel():
+    """
+       Create a model instance
+    """
+    obj = FlexCylEllipXModel()
+    # CFlexCylEllipXModel.__init__(obj) is called by
+    # the FlexCylEllipXModel constructor
+    return obj
+
+class FlexCylEllipXModel(CFlexCylEllipXModel, BaseComponent):
+    """ 
+    Class that evaluates a FlexCylEllipXModel model. 
+    This file was auto-generated from src\sans\models\include\flexcyl_ellipX.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         length          = 1000.0 [A]
+         kuhn_length     = 100.0 [A]
+         radius          = 20.0 [A]
+         axis_ratio      = 1.5 
+         sldCyl          = 1e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFlexCylEllipXModel.__init__, (self,)) 
+
+        CFlexCylEllipXModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FlexCylEllipXModel"
+        ## Model description
+        self.description = """
+         Note : scale and contrast=sldCyl-sldSolv are both multiplicative factors in the
+		model and are perfectly correlated. One or
+		both of these parameters must be held fixed
+		during model fitting.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['kuhn_length'] = ['[A]', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['axis_ratio'] = ['', None, None]
+        self.details['sldCyl'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['length.width',
+                      'kuhn_length.width',
+                      'radius.width',
+                      'axis_ratio.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FlexCylEllipXModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FlexCylEllipXModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFlexCylEllipXModel.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 CFlexCylEllipXModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFlexCylEllipXModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFlexCylEllipXModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFlexCylEllipXModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFlexCylEllipXModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FlexibleCylinderModel.py
===================================================================
--- src/sans/models/FlexibleCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FlexibleCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,183 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\flexible_cylinder.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFlexibleCylinderModel
+
+def create_FlexibleCylinderModel():
+    """
+       Create a model instance
+    """
+    obj = FlexibleCylinderModel()
+    # CFlexibleCylinderModel.__init__(obj) is called by
+    # the FlexibleCylinderModel constructor
+    return obj
+
+class FlexibleCylinderModel(CFlexibleCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a FlexibleCylinderModel model. 
+    This file was auto-generated from src\sans\models\include\flexible_cylinder.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         length          = 1000.0 [A]
+         kuhn_length     = 100.0 [A]
+         radius          = 20.0 [A]
+         sldCyl          = 1e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFlexibleCylinderModel.__init__, (self,)) 
+
+        CFlexibleCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FlexibleCylinderModel"
+        ## Model description
+        self.description = """
+         Note : scale and contrast=sldCyl-sldSolv are both multiplicative factors in the
+		model and are perfectly correlated. One or
+		both of these parameters must be held fixed
+		during model fitting.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['kuhn_length'] = ['[A]', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['sldCyl'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['length.width',
+                      'kuhn_length.width',
+                      'radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FlexibleCylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FlexibleCylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFlexibleCylinderModel.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 CFlexibleCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFlexibleCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFlexibleCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFlexibleCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFlexibleCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FractalModel.py
===================================================================
--- src/sans/models/FractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,188 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\fractal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFractalModel
+
+def create_FractalModel():
+    """
+       Create a model instance
+    """
+    obj = FractalModel()
+    # CFractalModel.__init__(obj) is called by
+    # the FractalModel constructor
+    return obj
+
+class FractalModel(CFractalModel, BaseComponent):
+    """ 
+    Class that evaluates a FractalModel model. 
+    This file was auto-generated from src\sans\models\include\fractal.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 5.0 [A]
+         scale           = 0.05 
+         fractal_dim     = 2.0 
+         cor_length      = 100.0 [A]
+         sldBlock        = 2e-06 [1/A^(2)]
+         sldSolv         = 6.35e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFractalModel.__init__, (self,)) 
+
+        CFractalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FractalModel"
+        ## Model description
+        self.description = """
+         The scattering intensity  I(x) = P(|x|)*S(|x|) + background, where
+		p(x)= scale * V * delta^(2)* F(x*radius)^(2)
+		F(x) = 3*[sin(x)-x cos(x)]/x**3
+		where delta = sldBlock -sldSolv.
+		scale        =  scale factor * Volume fraction
+		radius       =  Block radius
+		fractal_dim  =  Fractal dimension
+		cor_length  =  Correlation Length
+		sldBlock    =  SDL block
+		sldSolv  =  SDL solvent
+		background   =  background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['fractal_dim'] = ['', None, None]
+        self.details['cor_length'] = ['[A]', None, None]
+        self.details['sldBlock'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FractalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FractalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFractalModel.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 CFractalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFractalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFractalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFractalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFractalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FractalO_Z.py
===================================================================
--- src/sans/models/FractalO_Z.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FractalO_Z.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,178 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\FractalQtoN.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFractalO_Z
+
+def create_FractalO_Z():
+    """
+       Create a model instance
+    """
+    obj = FractalO_Z()
+    # CFractalO_Z.__init__(obj) is called by
+    # the FractalO_Z constructor
+    return obj
+
+class FractalO_Z(CFractalO_Z, BaseComponent):
+    """ 
+    Class that evaluates a FractalO_Z model. 
+    This file was auto-generated from src\sans\models\include\FractalQtoN.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 10000.0 
+         m_fractal       = 1.8 
+         cluster_rg      = 3520.0 
+         s_fractal       = 2.5 
+         primary_rg      = 82.0 
+         background      = 0.01 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFractalO_Z.__init__, (self,)) 
+
+        CFractalO_Z.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FractalO_Z"
+        ## Model description
+        self.description = """
+        Structure factor for interacting particles:
+		Schmidt J Appl Cryst (1991), 24, 414-435 See equation (19)
+		Hurd; Schaefer; Martin, Phys Rev A (1987), 35, 2361-2364 See equation (2).
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['m_fractal'] = ['', None, None]
+        self.details['cluster_rg'] = ['', None, None]
+        self.details['s_fractal'] = ['', None, None]
+        self.details['primary_rg'] = ['', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FractalO_Z, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FractalO_Z())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFractalO_Z.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 CFractalO_Z.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFractalO_Z.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFractalO_Z.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFractalO_Z.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFractalO_Z.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/FuzzySphereModel.py
===================================================================
--- src/sans/models/FuzzySphereModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/FuzzySphereModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,186 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\fuzzysphere.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CFuzzySphereModel
+
+def create_FuzzySphereModel():
+    """
+       Create a model instance
+    """
+    obj = FuzzySphereModel()
+    # CFuzzySphereModel.__init__(obj) is called by
+    # the FuzzySphereModel constructor
+    return obj
+
+class FuzzySphereModel(CFuzzySphereModel, BaseComponent):
+    """ 
+    Class that evaluates a FuzzySphereModel model. 
+    This file was auto-generated from src\sans\models\include\fuzzysphere.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         radius          = 60.0 [A]
+         scale           = 0.01 
+         fuzziness       = 10.0 [A]
+         sldSph          = 1e-06 [1/A^(2)]
+         sldSolv         = 3e-06 [1/A^(2)]
+         background      = 0.001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CFuzzySphereModel.__init__, (self,)) 
+
+        CFuzzySphereModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "FuzzySphereModel"
+        ## Model description
+        self.description = """
+        
+		scale: scale factor times volume fraction,
+		or just volume fraction for absolute scale data
+		radius: radius of the solid sphere
+		fuzziness = the STD of the height of fuzzy interfacial
+		thickness (ie., so-called interfacial roughness)
+		sldSph: the SLD of the sphere
+		sldSolv: the SLD of the solvent
+		background: incoherent background
+		Note: By definition, this function works only when fuzziness << radius.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['radius'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['fuzziness'] = ['[A]', None, None]
+        self.details['sldSph'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'fuzziness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_FuzzySphereModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(FuzzySphereModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CFuzzySphereModel.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 CFuzzySphereModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CFuzzySphereModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CFuzzySphereModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CFuzzySphereModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CFuzzySphereModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/Gaussian.py
===================================================================
--- src/sans/models/Gaussian.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/Gaussian.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,170 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\gaussian.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CGaussian
+
+def create_Gaussian():
+    """
+       Create a model instance
+    """
+    obj = Gaussian()
+    # CGaussian.__init__(obj) is called by
+    # the Gaussian constructor
+    return obj
+
+class Gaussian(CGaussian, BaseComponent):
+    """ 
+    Class that evaluates a Gaussian model. 
+    This file was auto-generated from src\sans\models\include\gaussian.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, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CGaussian.__init__, (self,)) 
+
+        CGaussian.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "Gaussian"
+        ## Model description
+        self.description = """
+        f(x)=scale * 1/(sigma^2*2pi)e^(-(x-mu)^2/2sigma^2)
+        """
+       
+        ## 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 = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_Gaussian, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(Gaussian())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CGaussian.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 CGaussian.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CGaussian.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CGaussian.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CGaussian.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CGaussian.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/GelFitModel.py
===================================================================
--- src/sans/models/GelFitModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/GelFitModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,181 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\GelFit.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CGelFitModel
+
+def create_GelFitModel():
+    """
+       Create a model instance
+    """
+    obj = GelFitModel()
+    # CGelFitModel.__init__(obj) is called by
+    # the GelFitModel constructor
+    return obj
+
+class GelFitModel(CGelFitModel, BaseComponent):
+    """ 
+    Class that evaluates a GelFitModel model. 
+    This file was auto-generated from src\sans\models\include\GelFit.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         lScale          = 3.5 
+         gScale          = 1.7 
+         zeta            = 16.0 
+         radius          = 104.0 
+         scale           = 2.0 
+         background      = 0.01 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CGelFitModel.__init__, (self,)) 
+
+        CGelFitModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "GelFitModel"
+        ## Model description
+        self.description = """
+        Structure factor for interacting particles:                   .
+		Shibayama-Geissler Two-Length Scale Fit for Gels
+		(GelFit)
+		
+		Sibayama; Tanaka; Han J Chem Phys(1992), 97(9), 6829-6841
+		Mallam; Horkay; Hecht; Rennie; Geissler, Macromol(1991), 24, 543
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['lScale'] = ['', None, None]
+        self.details['gScale'] = ['', None, None]
+        self.details['zeta'] = ['', None, None]
+        self.details['radius'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_GelFitModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(GelFitModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CGelFitModel.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 CGelFitModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CGelFitModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CGelFitModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CGelFitModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CGelFitModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/HardsphereStructure.py
===================================================================
--- src/sans/models/HardsphereStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/HardsphereStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,179 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\Hardsphere.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CHardsphereStructure
+
+def create_HardsphereStructure():
+    """
+       Create a model instance
+    """
+    obj = HardsphereStructure()
+    # CHardsphereStructure.__init__(obj) is called by
+    # the HardsphereStructure constructor
+    return obj
+
+class HardsphereStructure(CHardsphereStructure, BaseComponent):
+    """ 
+    Class that evaluates a HardsphereStructure model. 
+    This file was auto-generated from src\sans\models\include\Hardsphere.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         effect_radius   = 50.0 [A]
+         volfraction     = 0.2 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CHardsphereStructure.__init__, (self,)) 
+
+        CHardsphereStructure.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "HardsphereStructure"
+        ## Model description
+        self.description = """
+        Structure factor for interacting particles:                   .
+		
+		The interparticle potential is
+		
+		U(r)= inf   , r < 2R
+		= 0     , r >= 2R
+		
+		R: effective radius of the Hardsphere particle
+		V:The volume fraction
+		
+		Ref: Percus., J. K.,etc., J. Phy.
+		Rev. 1958, 110, 1.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['effect_radius'] = ['[A]', None, None]
+        self.details['volfraction'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['effect_radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_HardsphereStructure, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(HardsphereStructure())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CHardsphereStructure.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 CHardsphereStructure.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CHardsphereStructure.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CHardsphereStructure.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CHardsphereStructure.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CHardsphereStructure.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/HayterMSAStructure.py
===================================================================
--- src/sans/models/HayterMSAStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/HayterMSAStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,189 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\HayterMSA.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CHayterMSAStructure
+
+def create_HayterMSAStructure():
+    """
+       Create a model instance
+    """
+    obj = HayterMSAStructure()
+    # CHayterMSAStructure.__init__(obj) is called by
+    # the HayterMSAStructure constructor
+    return obj
+
+class HayterMSAStructure(CHayterMSAStructure, BaseComponent):
+    """ 
+    Class that evaluates a HayterMSAStructure model. 
+    This file was auto-generated from src\sans\models\include\HayterMSA.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         effect_radius   = 20.75 [A]
+         charge          = 19.0 
+         volfraction     = 0.0192 
+         temperature     = 318.16 [K]
+         saltconc        = 0.0 [M]
+         dielectconst    = 71.08 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CHayterMSAStructure.__init__, (self,)) 
+
+        CHayterMSAStructure.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "HayterMSAStructure"
+        ## Model description
+        self.description = """
+        To calculate the structure factor (the Fourier transform of the
+		pair correlation function g(r)) for a system of
+		charged, spheroidal objects in a dielectric
+		medium.
+		When combined with an appropriate form
+		factor, this allows for inclusion of
+		the interparticle interference effects
+		due to screened coulomb repulsion between
+		charged particles.
+		(Note: charge > 0 required.)
+		
+		Ref: JP Hansen and JB Hayter, Molecular
+		Physics 46, 651-656 (1982).
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['effect_radius'] = ['[A]', None, None]
+        self.details['charge'] = ['', None, None]
+        self.details['volfraction'] = ['', None, None]
+        self.details['temperature'] = ['[K]', None, None]
+        self.details['saltconc'] = ['[M]', None, None]
+        self.details['dielectconst'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['effect_radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_HayterMSAStructure, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(HayterMSAStructure())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CHayterMSAStructure.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 CHayterMSAStructure.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CHayterMSAStructure.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CHayterMSAStructure.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CHayterMSAStructure.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CHayterMSAStructure.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/HollowCylinderModel.py
===================================================================
--- src/sans/models/HollowCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/HollowCylinderModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,195 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\hollow_cylinder.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CHollowCylinderModel
+
+def create_HollowCylinderModel():
+    """
+       Create a model instance
+    """
+    obj = HollowCylinderModel()
+    # CHollowCylinderModel.__init__(obj) is called by
+    # the HollowCylinderModel constructor
+    return obj
+
+class HollowCylinderModel(CHollowCylinderModel, BaseComponent):
+    """ 
+    Class that evaluates a HollowCylinderModel model. 
+    This file was auto-generated from src\sans\models\include\hollow_cylinder.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         core_radius     = 20.0 [A]
+         radius          = 30.0 [A]
+         length          = 400.0 [A]
+         sldCyl          = 6.3e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.01 [1/cm]
+         axis_theta      = 90.0 [deg]
+         axis_phi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CHollowCylinderModel.__init__, (self,)) 
+
+        CHollowCylinderModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "HollowCylinderModel"
+        ## Model description
+        self.description = """
+         P(q) = scale*<f*f>/Vol + bkg, where f is the scattering amplitude.
+		core_radius = the radius of core
+		radius = the radius of shell
+		length = the total length of the cylinder
+		sldCyl = SLD of the shell
+		sldSolv = SLD of the solvent
+		background = incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['core_radius'] = ['[A]', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['length'] = ['[A]', None, None]
+        self.details['sldCyl'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['axis_phi.width',
+                      'axis_theta.width',
+                      'length.width',
+                      'core_radius.width',
+                      'radius']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi',
+                                   'axis_theta',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_HollowCylinderModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(HollowCylinderModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CHollowCylinderModel.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 CHollowCylinderModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CHollowCylinderModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CHollowCylinderModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CHollowCylinderModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CHollowCylinderModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LamellarFFHGModel.py
===================================================================
--- src/sans/models/LamellarFFHGModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LamellarFFHGModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,186 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lamellarFF_HG.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLamellarFFHGModel
+
+def create_LamellarFFHGModel():
+    """
+       Create a model instance
+    """
+    obj = LamellarFFHGModel()
+    # CLamellarFFHGModel.__init__(obj) is called by
+    # the LamellarFFHGModel constructor
+    return obj
+
+class LamellarFFHGModel(CLamellarFFHGModel, BaseComponent):
+    """ 
+    Class that evaluates a LamellarFFHGModel model. 
+    This file was auto-generated from src\sans\models\include\lamellarFF_HG.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         t_length        = 15.0 [A]
+         h_thickness     = 10.0 [A]
+         sld_tail        = 4e-07 [1/A^(2)]
+         sld_head        = 3e-06 [1/A^(2)]
+         sld_solvent     = 6e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLamellarFFHGModel.__init__, (self,)) 
+
+        CLamellarFFHGModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LamellarFFHGModel"
+        ## Model description
+        self.description = """
+         Parameters: t_length = tail length, h_thickness = head thickness,
+		scale = Scale factor,
+		background = incoherent Background
+		sld_tail = tail scattering length density ,
+		sld_solvent = solvent scattering length density.
+		NOTE: The total bilayer thickness
+		= 2(h_thickness+ t_length).
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['t_length'] = ['[A]', None, None]
+        self.details['h_thickness'] = ['[A]', None, None]
+        self.details['sld_tail'] = ['[1/A^(2)]', None, None]
+        self.details['sld_head'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solvent'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['t_length.width',
+                      'h_thickness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LamellarFFHGModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LamellarFFHGModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLamellarFFHGModel.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 CLamellarFFHGModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLamellarFFHGModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLamellarFFHGModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLamellarFFHGModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLamellarFFHGModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LamellarModel.py
===================================================================
--- src/sans/models/LamellarModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LamellarModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,182 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lamellar.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLamellarModel
+
+def create_LamellarModel():
+    """
+       Create a model instance
+    """
+    obj = LamellarModel()
+    # CLamellarModel.__init__(obj) is called by
+    # the LamellarModel constructor
+    return obj
+
+class LamellarModel(CLamellarModel, BaseComponent):
+    """ 
+    Class that evaluates a LamellarModel model. 
+    This file was auto-generated from src\sans\models\include\lamellar.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         bi_thick        = 50.0 [A]
+         sld_bi          = 1e-06 [1/A^(2)]
+         sld_sol         = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLamellarModel.__init__, (self,)) 
+
+        CLamellarModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LamellarModel"
+        ## Model description
+        self.description = """
+        [Dilute Lamellar Form Factor](from a lyotropic lamellar phase)
+		I(q)= 2*pi*P(q)/(delta *q^(2)), where
+		P(q)=2*(contrast/q)^(2)*(1-cos(q*delta))^(2))
+		bi_thick = bilayer thickness
+		sld_bi = SLD of bilayer
+		sld_sol = SLD of solvent
+		background = Incoherent background
+		scale = scale factor
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['bi_thick'] = ['[A]', None, None]
+        self.details['sld_bi'] = ['[1/A^(2)]', None, None]
+        self.details['sld_sol'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LamellarModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LamellarModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLamellarModel.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 CLamellarModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLamellarModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLamellarModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLamellarModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLamellarModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LamellarPCrystalModel.py
===================================================================
--- src/sans/models/LamellarPCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LamellarPCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,190 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lamellarPC.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLamellarPCrystalModel
+
+def create_LamellarPCrystalModel():
+    """
+       Create a model instance
+    """
+    obj = LamellarPCrystalModel()
+    # CLamellarPCrystalModel.__init__(obj) is called by
+    # the LamellarPCrystalModel constructor
+    return obj
+
+class LamellarPCrystalModel(CLamellarPCrystalModel, BaseComponent):
+    """ 
+    Class that evaluates a LamellarPCrystalModel model. 
+    This file was auto-generated from src\sans\models\include\lamellarPC.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         thickness       = 33.0 [A]
+         Nlayers         = 20.0 
+         spacing         = 250.0 [A]
+         pd_spacing      = 0.0 
+         sld_layer       = 1e-06 [1/A^(2)]
+         sld_solvent     = 6.34e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLamellarPCrystalModel.__init__, (self,)) 
+
+        CLamellarPCrystalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LamellarPCrystalModel"
+        ## Model description
+        self.description = """
+        [Lamellar ParaCrystal Model] Parameter Definitions: scale = scale factor,
+		background = incoherent background
+		thickness = lamellar thickness,
+		sld_layer = layer scattering length density ,
+		sld_solvent = solvent scattering length density.
+		Nlayers = no. of lamellar layers
+		spacing = spacing between layers
+		pd_spacing = polydispersity of spacing
+		Note: This model can be used for large
+		multilamellar vesicles.
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['thickness'] = ['[A]', None, None]
+        self.details['Nlayers'] = ['', None, None]
+        self.details['spacing'] = ['[A]', None, None]
+        self.details['pd_spacing'] = ['', None, None]
+        self.details['sld_layer'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solvent'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['thickness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LamellarPCrystalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LamellarPCrystalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLamellarPCrystalModel.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 CLamellarPCrystalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLamellarPCrystalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLamellarPCrystalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLamellarPCrystalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLamellarPCrystalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LamellarPSHGModel.py
===================================================================
--- src/sans/models/LamellarPSHGModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LamellarPSHGModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,204 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lamellarPS_HG.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLamellarPSHGModel
+
+def create_LamellarPSHGModel():
+    """
+       Create a model instance
+    """
+    obj = LamellarPSHGModel()
+    # CLamellarPSHGModel.__init__(obj) is called by
+    # the LamellarPSHGModel constructor
+    return obj
+
+class LamellarPSHGModel(CLamellarPSHGModel, BaseComponent):
+    """ 
+    Class that evaluates a LamellarPSHGModel model. 
+    This file was auto-generated from src\sans\models\include\lamellarPS_HG.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         spacing         = 40.0 [A]
+         deltaT          = 10.0 [A]
+         deltaH          = 2.0 [A]
+         sld_tail        = 4e-07 [1/A^(2)]
+         sld_head        = 2e-06 [1/A^(2)]
+         sld_solvent     = 6e-06 [1/A^(2)]
+         n_plates        = 30.0 
+         caille          = 0.001 
+         background      = 0.001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLamellarPSHGModel.__init__, (self,)) 
+
+        CLamellarPSHGModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LamellarPSHGModel"
+        ## Model description
+        self.description = """
+        [Concentrated Lamellar (head+tail) Form Factor]: Calculates the
+		intensity from a lyotropic lamellar phase.
+		The intensity (form factor and structure factor)
+		calculated is for lamellae of two-layer scattering
+		length density that are randomly distributed in
+		solution (a powder average). The scattering
+		length density of the tail region, headgroup
+		region, and solvent are taken to be different.
+		The model can also be applied to large,
+		multi-lamellar vesicles.
+		No resolution smeared version is included
+		in the structure factor of this model.
+		*Parameters: spacing = repeat spacing,
+		deltaT = tail length,
+		deltaH = headgroup thickness,
+		n_plates = # of Lamellar plates
+		caille = Caille parameter (<0.8 or <1)
+		background = incoherent bgd
+		scale = scale factor ...
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['spacing'] = ['[A]', None, None]
+        self.details['deltaT'] = ['[A]', None, None]
+        self.details['deltaH'] = ['[A]', None, None]
+        self.details['sld_tail'] = ['[1/A^(2)]', None, None]
+        self.details['sld_head'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solvent'] = ['[1/A^(2)]', None, None]
+        self.details['n_plates'] = ['', None, None]
+        self.details['caille'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['deltaT.width',
+                      'deltaH.width',
+                      'spacing.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LamellarPSHGModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LamellarPSHGModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLamellarPSHGModel.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 CLamellarPSHGModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLamellarPSHGModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLamellarPSHGModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLamellarPSHGModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLamellarPSHGModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LamellarPSModel.py
===================================================================
--- src/sans/models/LamellarPSModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LamellarPSModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,199 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lamellarPS.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLamellarPSModel
+
+def create_LamellarPSModel():
+    """
+       Create a model instance
+    """
+    obj = LamellarPSModel()
+    # CLamellarPSModel.__init__(obj) is called by
+    # the LamellarPSModel constructor
+    return obj
+
+class LamellarPSModel(CLamellarPSModel, BaseComponent):
+    """ 
+    Class that evaluates a LamellarPSModel model. 
+    This file was auto-generated from src\sans\models\include\lamellarPS.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         spacing         = 400.0 [A]
+         delta           = 30.0 [A]
+         sld_bi          = 6.3e-06 [1/A^(2)]
+         sld_sol         = 1e-06 [1/A^(2)]
+         n_plates        = 20.0 
+         caille          = 0.1 
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLamellarPSModel.__init__, (self,)) 
+
+        CLamellarPSModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LamellarPSModel"
+        ## Model description
+        self.description = """
+        [Concentrated Lamellar Form Factor] Calculates the scattered
+		intensity from a lyotropic lamellar phase.
+		The intensity (form factor and structure
+		factor)calculated is for lamellae of
+		uniform scattering length density that
+		are randomly distributed in solution
+		(a powder average). The lamellae thickness
+		is polydisperse. The model can also
+		be applied to large, multi-lamellar vesicles.
+		No resolution smeared version is included
+		in the structure factor of this model.
+		*Parameters: spacing = repeat spacing,
+		delta = bilayer thickness,
+		sld_bi = SLD_bilayer
+		sld_sol = SLD_solvent
+		n_plate = # of Lamellar plates
+		caille = Caille parameter (<0.8 or <1)
+		background = incoherent bgd
+		scale = scale factor
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['spacing'] = ['[A]', None, None]
+        self.details['delta'] = ['[A]', None, None]
+        self.details['sld_bi'] = ['[1/A^(2)]', None, None]
+        self.details['sld_sol'] = ['[1/A^(2)]', None, None]
+        self.details['n_plates'] = ['', None, None]
+        self.details['caille'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['delta.width',
+                      'spacing.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LamellarPSModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LamellarPSModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLamellarPSModel.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 CLamellarPSModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLamellarPSModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLamellarPSModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLamellarPSModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLamellarPSModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LinearPearlsModel.py
===================================================================
--- src/sans/models/LinearPearlsModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LinearPearlsModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,202 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\linearpearls.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLinearPearlsModel
+
+def create_LinearPearlsModel():
+    """
+       Create a model instance
+    """
+    obj = LinearPearlsModel()
+    # CLinearPearlsModel.__init__(obj) is called by
+    # the LinearPearlsModel constructor
+    return obj
+
+class LinearPearlsModel(CLinearPearlsModel, BaseComponent):
+    """ 
+    Class that evaluates a LinearPearlsModel model. 
+    This file was auto-generated from src\sans\models\include\linearpearls.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 80.0 [A]
+         edge_separation = 350.0 [A]
+         num_pearls      = 3.0 
+         sld_pearl       = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 
+         scale           = 1.0 
+         radius          = 80.0 [A]
+         edge_separation = 350.0 [A]
+         num_pearls      = 3.0 
+         sld_pearl       = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLinearPearlsModel.__init__, (self,)) 
+
+        CLinearPearlsModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LinearPearlsModel"
+        ## Model description
+        self.description = """
+        Calculate form factor for Pearl Necklace Model
+		[Macromol. 1996, 29, 2974-2979]
+		Parameters:
+		background:background
+		scale: scale factor
+		sld_pearl: the SLD of the pearl spheres
+		sld_solv: the SLD of the solvent
+		num_pearls: number of the pearls
+		radius: the radius of a pearl
+		edge_separation: the length of string segment; surface to surface
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['edge_separation'] = ['[A]', None, None]
+        self.details['num_pearls'] = ['', None, None]
+        self.details['sld_pearl'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['edge_separation'] = ['[A]', None, None]
+        self.details['num_pearls'] = ['', None, None]
+        self.details['sld_pearl'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'edge_separation.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LinearPearlsModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LinearPearlsModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLinearPearlsModel.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 CLinearPearlsModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLinearPearlsModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLinearPearlsModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLinearPearlsModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLinearPearlsModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/LogNormal.py
===================================================================
--- src/sans/models/LogNormal.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/LogNormal.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,170 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\logNormal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLogNormal
+
+def create_LogNormal():
+    """
+       Create a model instance
+    """
+    obj = LogNormal()
+    # CLogNormal.__init__(obj) is called by
+    # the LogNormal constructor
+    return obj
+
+class LogNormal(CLogNormal, BaseComponent):
+    """ 
+    Class that evaluates a LogNormal model. 
+    This file was auto-generated from src\sans\models\include\logNormal.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, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLogNormal.__init__, (self,)) 
+
+        CLogNormal.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "LogNormal"
+        ## Model description
+        self.description = """
+        f(x)=scale * 1/(sigma*math.sqrt(2pi))e^(-1/2*((math.log(x)-mu)/sigma)^2)
+        """
+       
+        ## 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 = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_LogNormal, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(LogNormal())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLogNormal.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 CLogNormal.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLogNormal.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLogNormal.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLogNormal.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLogNormal.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/Lorentzian.py
===================================================================
--- src/sans/models/Lorentzian.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/Lorentzian.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,170 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\lorentzian.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CLorentzian
+
+def create_Lorentzian():
+    """
+       Create a model instance
+    """
+    obj = Lorentzian()
+    # CLorentzian.__init__(obj) is called by
+    # the Lorentzian constructor
+    return obj
+
+class Lorentzian(CLorentzian, BaseComponent):
+    """ 
+    Class that evaluates a Lorentzian model. 
+    This file was auto-generated from src\sans\models\include\lorentzian.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         gamma           = 1.0 
+         center          = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CLorentzian.__init__, (self,)) 
+
+        CLorentzian.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "Lorentzian"
+        ## Model description
+        self.description = """
+        f(x)=scale * 1/pi 0.5gamma / [ (x-x_0)^2 + (0.5gamma)^2 ]
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['gamma'] = ['', None, None]
+        self.details['center'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_Lorentzian, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(Lorentzian())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CLorentzian.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 CLorentzian.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CLorentzian.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CLorentzian.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CLorentzian.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CLorentzian.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/MassFractalModel.py
===================================================================
--- src/sans/models/MassFractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/MassFractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,187 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\massfractal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CMassFractalModel
+
+def create_MassFractalModel():
+    """
+       Create a model instance
+    """
+    obj = MassFractalModel()
+    # CMassFractalModel.__init__(obj) is called by
+    # the MassFractalModel constructor
+    return obj
+
+class MassFractalModel(CMassFractalModel, BaseComponent):
+    """ 
+    Class that evaluates a MassFractalModel model. 
+    This file was auto-generated from src\sans\models\include\massfractal.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 10.0 [A]
+         mass_dim        = 1.9 
+         co_length       = 100.0 [A]
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CMassFractalModel.__init__, (self,)) 
+
+        CMassFractalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "MassFractalModel"
+        ## Model description
+        self.description = """
+         The scattering intensity  I(x) = scale*P(x)*S(x) + background, where
+		scale = scale_factor  * V * delta^(2)
+		p(x)=  F(x*radius)^(2)
+		F(x) = 3*[sin(x)-x cos(x)]/x**3
+		S(x) = [(gamma(Dm-1)*colength^(Dm-1)*[1+(x^2*colength^2)]^((1-Dm)/2)
+		* sin[(Dm-1)*arctan(x*colength)])/x]
+		where delta = sldParticle -sldSolv.
+		radius       =  Particle radius
+		mass_dim  =  Mass fractal dimension
+		co_length  =  Cut-off length
+		background   =  background
+		Ref.:Mildner, Hall,J Phys D Appl Phys(1986), 9, 1535-1545
+		Note I: This model is valid for 1<mass_dim<6.
+		Note II: This model is not in absolute scale.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['mass_dim'] = ['', None, None]
+        self.details['co_length'] = ['[A]', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_MassFractalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(MassFractalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CMassFractalModel.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 CMassFractalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CMassFractalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CMassFractalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CMassFractalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CMassFractalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/MassSurfaceFractal.py
===================================================================
--- src/sans/models/MassSurfaceFractal.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/MassSurfaceFractal.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,188 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\masssurfacefractal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CMassSurfaceFractal
+
+def create_MassSurfaceFractal():
+    """
+       Create a model instance
+    """
+    obj = MassSurfaceFractal()
+    # CMassSurfaceFractal.__init__(obj) is called by
+    # the MassSurfaceFractal constructor
+    return obj
+
+class MassSurfaceFractal(CMassSurfaceFractal, BaseComponent):
+    """ 
+    Class that evaluates a MassSurfaceFractal model. 
+    This file was auto-generated from src\sans\models\include\masssurfacefractal.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         mass_dim        = 1.8 
+         surface_dim     = 2.3 
+         cluster_rg      = 86.7 [A]
+         primary_rg      = 4000.0 [A]
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CMassSurfaceFractal.__init__, (self,)) 
+
+        CMassSurfaceFractal.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "MassSurfaceFractal"
+        ## Model description
+        self.description = """
+         The scattering intensity  I(x) = scale*P(x) + background,
+		p(x)= {[1+(x^2*a)]^(Dm/2) * [1+(x^2*b)]^(6-Ds-Dm)/2}^(-1)
+		a = Rg^2/(3*Dm/2)
+		b = rg^2/(3*(6-Ds-Dm)/2)
+		scale        =  scale factor * N*Volume^2*contrast^2
+		mass_dim       =  Dm (mass fractal dimension)
+		surface_dim  =  Ds
+		cluster_rg  =  Rg
+		primary_rg    =  rg
+		background   =  background
+		Ref: Schmidt, J Appl Cryst, eq(19), (1991), 24, 414-435
+		: Hurd, Schaefer, Martin, Phys Rev A, eq(2),(1987),35, 2361-2364
+		Note that 0 < Ds< 6 and 0 < Dm < 6.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['mass_dim'] = ['', None, None]
+        self.details['surface_dim'] = ['', None, None]
+        self.details['cluster_rg'] = ['[A]', None, None]
+        self.details['primary_rg'] = ['[A]', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_MassSurfaceFractal, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(MassSurfaceFractal())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CMassSurfaceFractal.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 CMassSurfaceFractal.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CMassSurfaceFractal.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CMassSurfaceFractal.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CMassSurfaceFractal.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CMassSurfaceFractal.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/MultiShellModel.py
===================================================================
--- src/sans/models/MultiShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/MultiShellModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,190 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\multishell.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CMultiShellModel
+
+def create_MultiShellModel():
+    """
+       Create a model instance
+    """
+    obj = MultiShellModel()
+    # CMultiShellModel.__init__(obj) is called by
+    # the MultiShellModel constructor
+    return obj
+
+class MultiShellModel(CMultiShellModel, BaseComponent):
+    """ 
+    Class that evaluates a MultiShellModel model. 
+    This file was auto-generated from src\sans\models\include\multishell.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         core_radius     = 60.0 [A]
+         s_thickness     = 10.0 [A]
+         w_thickness     = 10.0 [A]
+         core_sld        = 6.4e-06 [1/A^(2)]
+         shell_sld       = 4e-07 [1/A^(2)]
+         n_pairs         = 2.0 
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CMultiShellModel.__init__, (self,)) 
+
+        CMultiShellModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "MultiShellModel"
+        ## Model description
+        self.description = """
+         MultiShell (Sphere) Model (or Multilamellar Vesicles): Model parameters;
+		scale : scale factor
+		core_radius : Core radius of the multishell
+		s_thickness: shell thickness
+		w_thickness: water thickness
+		core_sld: core scattering length density
+		shell_sld: shell scattering length density
+		n_pairs:number of pairs of water/shell
+		background: incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['core_radius'] = ['[A]', None, None]
+        self.details['s_thickness'] = ['[A]', None, None]
+        self.details['w_thickness'] = ['[A]', None, None]
+        self.details['core_sld'] = ['[1/A^(2)]', None, None]
+        self.details['shell_sld'] = ['[1/A^(2)]', None, None]
+        self.details['n_pairs'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['core_radius.width',
+                      's_thickness.width',
+                      'w_thickness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_MultiShellModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(MultiShellModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CMultiShellModel.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 CMultiShellModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CMultiShellModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CMultiShellModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CMultiShellModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CMultiShellModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/OnionModel.py
===================================================================
--- src/sans/models/OnionModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/OnionModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,308 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\onion.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import COnionModel
+
+def create_OnionModel():
+    """
+       Create a model instance
+    """
+    obj = OnionModel()
+    # COnionModel.__init__(obj) is called by
+    # the OnionModel constructor
+    return obj
+
+class OnionModel(COnionModel, BaseComponent):
+    """ 
+    Class that evaluates a OnionModel model. 
+    This file was auto-generated from src\sans\models\include\onion.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         n_shells        = 1.0 
+         scale           = 1.0 
+         rad_core0       = 200.0 [A]
+         sld_core0       = 1e-06 [1/A^(2)]
+         sld_solv        = 6.4e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         sld_out_shell1  = 2e-06 [1/A^(2)]
+         sld_out_shell2  = 2.5e-06 [1/A^(2)]
+         sld_out_shell3  = 3e-06 [1/A^(2)]
+         sld_out_shell4  = 3.5e-06 [1/A^(2)]
+         sld_out_shell5  = 4e-06 [1/A^(2)]
+         sld_out_shell6  = 4.5e-06 [1/A^(2)]
+         sld_out_shell7  = 5e-06 [1/A^(2)]
+         sld_out_shell8  = 5.5e-06 [1/A^(2)]
+         sld_out_shell9  = 6e-06 [1/A^(2)]
+         sld_out_shell10 = 6.2e-06 [1/A^(2)]
+         sld_in_shell1   = 1.7e-06 [1/A^(2)]
+         sld_in_shell2   = 2.2e-06 [1/A^(2)]
+         sld_in_shell3   = 2.7e-06 [1/A^(2)]
+         sld_in_shell4   = 3.2e-06 [1/A^(2)]
+         sld_in_shell5   = 3.7e-06 [1/A^(2)]
+         sld_in_shell6   = 4.2e-06 [1/A^(2)]
+         sld_in_shell7   = 4.7e-06 [1/A^(2)]
+         sld_in_shell8   = 5.2e-06 [1/A^(2)]
+         sld_in_shell9   = 5.7e-06 [1/A^(2)]
+         sld_in_shell10  = 6e-06 [1/A^(2)]
+         A_shell1        = 1.0 
+         A_shell2        = 1.0 
+         A_shell3        = 1.0 
+         A_shell4        = 1.0 
+         A_shell5        = 1.0 
+         A_shell6        = 1.0 
+         A_shell7        = 1.0 
+         A_shell8        = 1.0 
+         A_shell9        = 1.0 
+         A_shell10       = 1.0 
+         thick_shell1    = 50.0 [A]
+         thick_shell2    = 50.0 [A]
+         thick_shell3    = 50.0 [A]
+         thick_shell4    = 50.0 [A]
+         thick_shell5    = 50.0 [A]
+         thick_shell6    = 50.0 [A]
+         thick_shell7    = 50.0 [A]
+         thick_shell8    = 50.0 [A]
+         thick_shell9    = 50.0 [A]
+         thick_shell10   = 50.0 [A]
+         func_shell1     = 2.0 
+         func_shell2     = 2.0 
+         func_shell3     = 2.0 
+         func_shell4     = 2.0 
+         func_shell5     = 2.0 
+         func_shell6     = 2.0 
+         func_shell7     = 2.0 
+         func_shell8     = 2.0 
+         func_shell9     = 2.0 
+         func_shell10    = 2.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(COnionModel.__init__, (self,)) 
+
+        COnionModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "OnionModel"
+        ## Model description
+        self.description = """
+        Form factor of mutishells normalized by the volume. Here each shell is described
+		by an exponential function;
+		I)
+		For A_shell != 0,
+		f(r) = B*exp(A_shell*(r-r_in)/thick_shell)+C
+		where
+		B=(sld_out-sld_in)/(exp(A_shell)-1)
+		C=sld_in-B.
+		Note that in the above case,
+		the function becomes a linear function
+		as A_shell --> 0+ or 0-.
+		II)
+		For the exact point of A_shell == 0,
+		f(r) = sld_in ,i.e., it crosses over flat function
+		Note that the 'sld_out' becaomes NULL in this case.
+		
+		background:background,
+		rad_core0: radius of sphere(core)
+		thick_shell#:the thickness of the shell#
+		sld_core0: the SLD of the sphere
+		sld_solv: the SLD of the solvent
+		sld_shell: the SLD of the shell#
+		A_shell#: the coefficient in the exponential function
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['n_shells'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['rad_core0'] = ['[A]', None, None]
+        self.details['sld_core0'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['sld_out_shell1'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell2'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell3'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell5'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell6'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell7'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell8'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell9'] = ['[1/A^(2)]', None, None]
+        self.details['sld_out_shell10'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell1'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell2'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell3'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell5'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell6'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell7'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell8'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell9'] = ['[1/A^(2)]', None, None]
+        self.details['sld_in_shell10'] = ['[1/A^(2)]', None, None]
+        self.details['A_shell1'] = ['', None, None]
+        self.details['A_shell2'] = ['', None, None]
+        self.details['A_shell3'] = ['', None, None]
+        self.details['A_shell4'] = ['', None, None]
+        self.details['A_shell5'] = ['', None, None]
+        self.details['A_shell6'] = ['', None, None]
+        self.details['A_shell7'] = ['', None, None]
+        self.details['A_shell8'] = ['', None, None]
+        self.details['A_shell9'] = ['', None, None]
+        self.details['A_shell10'] = ['', None, None]
+        self.details['thick_shell1'] = ['[A]', None, None]
+        self.details['thick_shell2'] = ['[A]', None, None]
+        self.details['thick_shell3'] = ['[A]', None, None]
+        self.details['thick_shell4'] = ['[A]', None, None]
+        self.details['thick_shell5'] = ['[A]', None, None]
+        self.details['thick_shell6'] = ['[A]', None, None]
+        self.details['thick_shell7'] = ['[A]', None, None]
+        self.details['thick_shell8'] = ['[A]', None, None]
+        self.details['thick_shell9'] = ['[A]', None, None]
+        self.details['thick_shell10'] = ['[A]', None, None]
+        self.details['func_shell1'] = ['', None, None]
+        self.details['func_shell2'] = ['', None, None]
+        self.details['func_shell3'] = ['', None, None]
+        self.details['func_shell4'] = ['', None, None]
+        self.details['func_shell5'] = ['', None, None]
+        self.details['func_shell6'] = ['', None, None]
+        self.details['func_shell7'] = ['', None, None]
+        self.details['func_shell8'] = ['', None, None]
+        self.details['func_shell9'] = ['', None, None]
+        self.details['func_shell10'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['rad_core0.width',
+                      'thick_shell1.width',
+                      'thick_shell2.width',
+                      'thick_shell3.width',
+                      'thick_shell4.width',
+                      'thick_shell5.width',
+                      'thick_shell6.width',
+                      'thick_shell7.width',
+                      'thick_shell8.width',
+                      'thick_shell9.width',
+                      'thick_shell10.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_OnionModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(OnionModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return COnionModel.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 COnionModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return COnionModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return COnionModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return COnionModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return COnionModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/ParallelepipedModel.py
===================================================================
--- src/sans/models/ParallelepipedModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/ParallelepipedModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,229 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\parallelepiped.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CParallelepipedModel
+
+def create_ParallelepipedModel():
+    """
+       Create a model instance
+    """
+    obj = ParallelepipedModel()
+    # CParallelepipedModel.__init__(obj) is called by
+    # the ParallelepipedModel constructor
+    return obj
+
+class ParallelepipedModel(CParallelepipedModel, BaseComponent):
+    """ 
+    Class that evaluates a ParallelepipedModel model. 
+    This file was auto-generated from src\sans\models\include\parallelepiped.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         short_a         = 35.0 [A]
+         short_b         = 75.0 [A]
+         long_c          = 400.0 [A]
+         sldPipe         = 6.3e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         parallel_theta  = 0.0 [deg]
+         parallel_phi    = 0.0 [deg]
+         parallel_psi    = 0.0 [deg]
+         M0_sld_pipe     = 0.0 [1/A^(2)]
+         M_theta_pipe    = 0.0 [deg]
+         M_phi_pipe      = 0.0 [deg]
+         M0_sld_solv     = 0.0 [1/A^(2)]
+         M_theta_solv    = 0.0 [deg]
+         M_phi_solv      = 0.0 [deg]
+         Up_frac_i       = 0.5 [u/(u+d)]
+         Up_frac_f       = 0.5 [u/(u+d)]
+         Up_theta        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CParallelepipedModel.__init__, (self,)) 
+
+        CParallelepipedModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "ParallelepipedModel"
+        ## Model description
+        self.description = """
+         Form factor for a rectangular solid with uniform scattering length density.
+		
+		scale:Scale factor
+		short_a: length of short edge  [A]
+		short_b: length of another short edge [A]
+		long_c: length of long edge  of the parallelepiped [A]
+		sldPipe: Pipe_sld
+		sldSolv: solvent_sld
+		background:Incoherent Background [1/cm]
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['short_a'] = ['[A]', None, None]
+        self.details['short_b'] = ['[A]', None, None]
+        self.details['long_c'] = ['[A]', None, None]
+        self.details['sldPipe'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['parallel_theta'] = ['[deg]', None, None]
+        self.details['parallel_phi'] = ['[deg]', None, None]
+        self.details['parallel_psi'] = ['[deg]', None, None]
+        self.details['M0_sld_pipe'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_pipe'] = ['[deg]', None, None]
+        self.details['M_phi_pipe'] = ['[deg]', None, None]
+        self.details['M0_sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_solv'] = ['[deg]', None, None]
+        self.details['M_phi_solv'] = ['[deg]', None, None]
+        self.details['Up_frac_i'] = ['[u/(u+d)]', None, None]
+        self.details['Up_frac_f'] = ['[u/(u+d)]', None, None]
+        self.details['Up_theta'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['short_a.width',
+                      'short_b.width',
+                      'long_c.width',
+                      'parallel_phi.width',
+                      'parallel_psi.width',
+                      'parallel_theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['parallel_phi',
+                                   'parallel_psi',
+                                   'parallel_theta',
+                                   'parallel_phi.width',
+                                   'parallel_psi.width',
+                                   'parallel_theta.width',
+                                   'M0_sld_pipe',
+                                   'M_theta_pipe',
+                                   'M_phi_pipe',
+                                   'M0_sld_solv',
+                                   'M_theta_solv',
+                                   'M_phi_solv',
+                                   'Up_frac_i',
+                                   'Up_frac_f',
+                                   'Up_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = ['M0_sld_pipe', 'M_theta_pipe', 'M_phi_pipe', 'M0_sld_solv', 'M_theta_solv', 'M_phi_solv', 'Up_frac_i', 'Up_frac_f', 'Up_theta']
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_ParallelepipedModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(ParallelepipedModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CParallelepipedModel.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 CParallelepipedModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CParallelepipedModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CParallelepipedModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CParallelepipedModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CParallelepipedModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/PearlNecklaceModel.py
===================================================================
--- src/sans/models/PearlNecklaceModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/PearlNecklaceModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,212 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\pearlnecklace.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CPearlNecklaceModel
+
+def create_PearlNecklaceModel():
+    """
+       Create a model instance
+    """
+    obj = PearlNecklaceModel()
+    # CPearlNecklaceModel.__init__(obj) is called by
+    # the PearlNecklaceModel constructor
+    return obj
+
+class PearlNecklaceModel(CPearlNecklaceModel, BaseComponent):
+    """ 
+    Class that evaluates a PearlNecklaceModel model. 
+    This file was auto-generated from src\sans\models\include\pearlnecklace.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 80.0 [A]
+         edge_separation = 350.0 [A]
+         thick_string    = 2.5 [A]
+         num_pearls      = 3.0 
+         sld_pearl       = 1e-06 [1/A^(2)]
+         sld_string      = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 
+         scale           = 1.0 
+         radius          = 80.0 [A]
+         edge_separation = 350.0 [A]
+         thick_string    = 2.5 [A]
+         num_pearls      = 3.0 
+         sld_pearl       = 1e-06 [1/A^(2)]
+         sld_string      = 1e-06 [1/A^(2)]
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CPearlNecklaceModel.__init__, (self,)) 
+
+        CPearlNecklaceModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "PearlNecklaceModel"
+        ## Model description
+        self.description = """
+        Calculate form factor for Pearl Necklace Model
+		[Macromol. Symp. 2004, 211, 25-42]
+		Parameters:
+		background:background
+		scale: scale factor
+		sld_pearl: the SLD of the pearl spheres
+		sld_string: the SLD of the strings
+		sld_solv: the SLD of the solvent
+		num_pearls: number of the pearls
+		radius: the radius of a pearl
+		edge_separation: the length of string segment; surface to surface
+		thick_string: thickness (ie, diameter) of the string
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['edge_separation'] = ['[A]', None, None]
+        self.details['thick_string'] = ['[A]', None, None]
+        self.details['num_pearls'] = ['', None, None]
+        self.details['sld_pearl'] = ['[1/A^(2)]', None, None]
+        self.details['sld_string'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['edge_separation'] = ['[A]', None, None]
+        self.details['thick_string'] = ['[A]', None, None]
+        self.details['num_pearls'] = ['', None, None]
+        self.details['sld_pearl'] = ['[1/A^(2)]', None, None]
+        self.details['sld_string'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'edge_separation.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_PearlNecklaceModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(PearlNecklaceModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CPearlNecklaceModel.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 CPearlNecklaceModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CPearlNecklaceModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CPearlNecklaceModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CPearlNecklaceModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CPearlNecklaceModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/Poly_GaussCoil.py
===================================================================
--- src/sans/models/Poly_GaussCoil.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/Poly_GaussCoil.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,179 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\polygausscoil.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CPoly_GaussCoil
+
+def create_Poly_GaussCoil():
+    """
+       Create a model instance
+    """
+    obj = Poly_GaussCoil()
+    # CPoly_GaussCoil.__init__(obj) is called by
+    # the Poly_GaussCoil constructor
+    return obj
+
+class Poly_GaussCoil(CPoly_GaussCoil, BaseComponent):
+    """ 
+    Class that evaluates a Poly_GaussCoil model. 
+    This file was auto-generated from src\sans\models\include\polygausscoil.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         rg              = 60.0 [A]
+         scale           = 1.0 
+         poly_m          = 2.0 [Mw/Mn]
+         background      = 0.001 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CPoly_GaussCoil.__init__, (self,)) 
+
+        CPoly_GaussCoil.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "Poly_GaussCoil"
+        ## Model description
+        self.description = """
+        I(q)=(scale)*2*[(1+U*x)^(-1/U)+x-1]/[(1+U)*x^2] + background
+		where x = [rg^2*q^2]
+		and the polydispersity is
+		U = [M_w/M_n]-1.
+		scale = scale factor * volume fraction
+		rg = radius of gyration
+		poly_m = polydispersity of molecular weight
+		background = incoherent background
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['rg'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['poly_m'] = ['[Mw/Mn]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_Poly_GaussCoil, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(Poly_GaussCoil())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CPoly_GaussCoil.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 CPoly_GaussCoil.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CPoly_GaussCoil.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CPoly_GaussCoil.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CPoly_GaussCoil.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CPoly_GaussCoil.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/PringlesModel.py
===================================================================
--- src/sans/models/PringlesModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/PringlesModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,183 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\pringles.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CPringlesModel
+
+def create_PringlesModel():
+    """
+       Create a model instance
+    """
+    obj = PringlesModel()
+    # CPringlesModel.__init__(obj) is called by
+    # the PringlesModel constructor
+    return obj
+
+class PringlesModel(CPringlesModel, BaseComponent):
+    """ 
+    Class that evaluates a PringlesModel model. 
+    This file was auto-generated from src\sans\models\include\pringles.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 60.0 [A]
+         thickness       = 10.0 [A]
+         alpha           = 0.001 [rad]
+         beta            = 0.02 [rad]
+         sld_pringle     = 1e-06 [A^(-2)]
+         sld_solvent     = 6.35e-06 [A^(-2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CPringlesModel.__init__, (self,)) 
+
+        CPringlesModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "PringlesModel"
+        ## Model description
+        self.description = """
+         Pringles model for K Edler. Represents a disc that is bent in two directions. 
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['thickness'] = ['[A]', None, None]
+        self.details['alpha'] = ['[rad]', None, None]
+        self.details['beta'] = ['[rad]', None, None]
+        self.details['sld_pringle'] = ['[A^(-2)]', None, None]
+        self.details['sld_solvent'] = ['[A^(-2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'thickness.width',
+                      'alpha.width',
+                      'beta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_PringlesModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(PringlesModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CPringlesModel.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 CPringlesModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CPringlesModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CPringlesModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CPringlesModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CPringlesModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/RPAModel.py
===================================================================
--- src/sans/models/RPAModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/RPAModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,254 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\rpa.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CRPAModel
+
+def create_RPAModel():
+    """
+       Create a model instance
+    """
+    obj = RPAModel()
+    # CRPAModel.__init__(obj) is called by
+    # the RPAModel constructor
+    return obj
+
+class RPAModel(CRPAModel, BaseComponent):
+    """ 
+    Class that evaluates a RPAModel model. 
+    This file was auto-generated from src\sans\models\include\rpa.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         lcase_n         = 0.0 
+         ba              = 5.0 
+         bb              = 5.0 
+         bc              = 5.0 
+         bd              = 5.0 
+         Kab             = -0.0004 
+         Kac             = -0.0004 
+         Kad             = -0.0004 
+         Kbc             = -0.0004 
+         Kbd             = -0.0004 
+         Kcd             = -0.0004 
+         scale           = 1.0 
+         background      = 0.0 [1/cm]
+         Na              = 1000.0 
+         Phia            = 0.25 
+         va              = 100.0 
+         La              = 1e-12 
+         Nb              = 1000.0 
+         Phib            = 0.25 
+         vb              = 100.0 
+         Lb              = 1e-12 
+         Nc              = 1000.0 
+         Phic            = 0.25 
+         vc              = 100.0 
+         Lc              = 1e-12 
+         Nd              = 1000.0 
+         Phid            = 0.25 
+         vd              = 100.0 
+         Ld              = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CRPAModel.__init__, (self,)) 
+
+        CRPAModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "RPAModel"
+        ## Model description
+        self.description = """
+          THIS FORMALISM APPLIES TO MULTICOMPONENT POLYMER MIXTURES IN THE
+		HOMOGENEOUS (MIXED) PHASE REGION ONLY.;
+		CASE 0: C/D BINARY MIXTURE OF HOMOPOLYMERS
+		CASE 1: C-D DIBLOCK COPOLYMER
+		CASE 2: B/C/D TERNARY MIXTURE OF HOMOPOLYMERS
+		CASE 3: B/C-D MIXTURE OF HOMOPOLYMER B AND
+		DIBLOCK COPOLYMER C-D
+		CASE 4: B-C-D TRIBLOCK COPOLYMER
+		CASE 5: A/B/C/D QUATERNARY MIXTURE OF HOMOPOLYMERS
+		CASE 6: A/B/C-D MIXTURE OF TWO HOMOPOLYMERS A/B
+		AND A DIBLOCK C-D
+		CASE 7: A/B-C-D MIXTURE OF A HOMOPOLYMER A AND A
+		TRIBLOCK B-C-D
+		CASE 8: A-B/C-D MIXTURE OF TWO DIBLOCK COPOLYMERS
+		A-B AND C-D
+		CASE 9: A-B-C-D FOUR-BLOCK COPOLYMER
+		See details in the model function help
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['lcase_n'] = ['', None, None]
+        self.details['ba'] = ['', None, None]
+        self.details['bb'] = ['', None, None]
+        self.details['bc'] = ['', None, None]
+        self.details['bd'] = ['', None, None]
+        self.details['Kab'] = ['', None, None]
+        self.details['Kac'] = ['', None, None]
+        self.details['Kad'] = ['', None, None]
+        self.details['Kbc'] = ['', None, None]
+        self.details['Kbd'] = ['', None, None]
+        self.details['Kcd'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['Na'] = ['', None, None]
+        self.details['Phia'] = ['', None, None]
+        self.details['va'] = ['', None, None]
+        self.details['La'] = ['', None, None]
+        self.details['Nb'] = ['', None, None]
+        self.details['Phib'] = ['', None, None]
+        self.details['vb'] = ['', None, None]
+        self.details['Lb'] = ['', None, None]
+        self.details['Nc'] = ['', None, None]
+        self.details['Phic'] = ['', None, None]
+        self.details['vc'] = ['', None, None]
+        self.details['Lc'] = ['', None, None]
+        self.details['Nd'] = ['', None, None]
+        self.details['Phid'] = ['', None, None]
+        self.details['vd'] = ['', None, None]
+        self.details['Ld'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = ['lcase_n',
+                             'Na',
+                             'Phia',
+                             'va',
+                             'La',
+                             'Nb',
+                             'Phib',
+                             'vb',
+                             'Lb',
+                             'Nc',
+                             'Phic',
+                             'vc',
+                             'Lc',
+                             'Nd',
+                             'Phid',
+                             'vd',
+                             'Ld']
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_RPAModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(RPAModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CRPAModel.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 CRPAModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CRPAModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CRPAModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CRPAModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CRPAModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/RaspBerryModel.py
===================================================================
--- src/sans/models/RaspBerryModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/RaspBerryModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,195 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\raspberry.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CRaspBerryModel
+
+def create_RaspBerryModel():
+    """
+       Create a model instance
+    """
+    obj = RaspBerryModel()
+    # CRaspBerryModel.__init__(obj) is called by
+    # the RaspBerryModel constructor
+    return obj
+
+class RaspBerryModel(CRaspBerryModel, BaseComponent):
+    """ 
+    Class that evaluates a RaspBerryModel model. 
+    This file was auto-generated from src\sans\models\include\raspberry.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         volf_Lsph       = 0.05 
+         radius_Lsph     = 5000.0 [A]
+         sld_Lsph        = -4e-07 [1/A^(2)]
+         volf_Ssph       = 0.005 
+         radius_Ssph     = 100.0 [A]
+         surfrac_Ssph    = 0.4 
+         sld_Ssph        = 3.5e-06 [1/A^(2)]
+         delta_Ssph      = 0.0 
+         sld_solv        = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CRaspBerryModel.__init__, (self,)) 
+
+        CRaspBerryModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "RaspBerryModel"
+        ## Model description
+        self.description = """
+         RaspBerryModel:
+		volf_Lsph = volume fraction large spheres
+		radius_Lsph = radius large sphere (A)
+		sld_Lsph = sld large sphere (A-2)
+		volf_Ssph = volume fraction small spheres
+		radius_Ssph = radius small sphere (A)
+		surfrac_Ssph = fraction of small spheres at surface
+		sld_Ssph = sld small sphere
+		delta_Ssph = small sphere penetration (A)
+		sld_solv   = sld solvent
+		background = background (cm-1)
+		Ref: J. coll. inter. sci. (2010) vol. 343 (1) pp. 36-41.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['volf_Lsph'] = ['', None, None]
+        self.details['radius_Lsph'] = ['[A]', None, None]
+        self.details['sld_Lsph'] = ['[1/A^(2)]', None, None]
+        self.details['volf_Ssph'] = ['', None, None]
+        self.details['radius_Ssph'] = ['[A]', None, None]
+        self.details['surfrac_Ssph'] = ['', None, None]
+        self.details['sld_Ssph'] = ['[1/A^(2)]', None, None]
+        self.details['delta_Ssph'] = ['', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius_Lsph.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_RaspBerryModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(RaspBerryModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CRaspBerryModel.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 CRaspBerryModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CRaspBerryModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CRaspBerryModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CRaspBerryModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CRaspBerryModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/ReflAdvModel.py
===================================================================
--- src/sans/models/ReflAdvModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/ReflAdvModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,334 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\refl_adv.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CReflAdvModel
+
+def create_ReflAdvModel():
+    """
+       Create a model instance
+    """
+    obj = ReflAdvModel()
+    # CReflAdvModel.__init__(obj) is called by
+    # the ReflAdvModel constructor
+    return obj
+
+class ReflAdvModel(CReflAdvModel, BaseComponent):
+    """ 
+    Class that evaluates a ReflAdvModel model. 
+    This file was auto-generated from src\sans\models\include\refl_adv.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         n_layers        = 1.0 
+         scale           = 1.0 
+         thick_inter0    = 50.0 [A]
+         func_inter0     = 0.0 
+         sld_bottom0     = 2.07e-06 [1/A^(2)]
+         sld_medium      = 1e-06 [1/A^(2)]
+         background      = 0.0 
+         sld_flat1       = 4e-06 [1/A^(2)]
+         sld_flat2       = 3.5e-06 [1/A^(2)]
+         sld_flat3       = 4e-06 [1/A^(2)]
+         sld_flat4       = 3.5e-06 [1/A^(2)]
+         sld_flat5       = 4e-06 [1/A^(2)]
+         sld_flat6       = 3.5e-06 [1/A^(2)]
+         sld_flat7       = 4e-06 [1/A^(2)]
+         sld_flat8       = 3.5e-06 [1/A^(2)]
+         sld_flat9       = 4e-06 [1/A^(2)]
+         sld_flat10      = 3.5e-06 [1/A^(2)]
+         thick_inter1    = 50.0 [A]
+         thick_inter2    = 50.0 [A]
+         thick_inter3    = 50.0 [A]
+         thick_inter4    = 50.0 [A]
+         thick_inter5    = 50.0 [A]
+         thick_inter6    = 50.0 [A]
+         thick_inter7    = 50.0 [A]
+         thick_inter8    = 50.0 [A]
+         thick_inter9    = 50.0 [A]
+         thick_inter10   = 50.0 [A]
+         thick_flat1     = 100.0 [A]
+         thick_flat2     = 100.0 [A]
+         thick_flat3     = 100.0 [A]
+         thick_flat4     = 100.0 [A]
+         thick_flat5     = 100.0 [A]
+         thick_flat6     = 100.0 [A]
+         thick_flat7     = 100.0 [A]
+         thick_flat8     = 100.0 [A]
+         thick_flat9     = 100.0 [A]
+         thick_flat10    = 100.0 [A]
+         func_inter1     = 0.0 
+         func_inter2     = 0.0 
+         func_inter3     = 0.0 
+         func_inter4     = 0.0 
+         func_inter5     = 0.0 
+         func_inter6     = 0.0 
+         func_inter7     = 0.0 
+         func_inter8     = 0.0 
+         func_inter9     = 0.0 
+         func_inter10    = 0.0 
+         sldIM_flat1     = 0.0 [1/A^(2)]
+         sldIM_flat2     = 0.0 [1/A^(2)]
+         sldIM_flat3     = 0.0 [1/A^(2)]
+         sldIM_flat4     = 0.0 [1/A^(2)]
+         sldIM_flat5     = 0.0 [1/A^(2)]
+         sldIM_flat6     = 0.0 [1/A^(2)]
+         sldIM_flat7     = 0.0 [1/A^(2)]
+         sldIM_flat8     = 0.0 [1/A^(2)]
+         sldIM_flat9     = 0.0 [1/A^(2)]
+         sldIM_flat10    = 0.0 [1/A^(2)]
+         nu_inter1       = 2.5 
+         nu_inter2       = 2.5 
+         nu_inter3       = 2.5 
+         nu_inter4       = 2.5 
+         nu_inter5       = 2.5 
+         nu_inter6       = 2.5 
+         nu_inter7       = 2.5 
+         nu_inter8       = 2.5 
+         nu_inter9       = 2.5 
+         nu_inter10      = 2.5 
+         sldIM_sub0      = 0.0 
+         sldIM_medium    = 0.0 
+         npts_inter      = 21.0 
+         nu_inter0       = 2.5 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CReflAdvModel.__init__, (self,)) 
+
+        CReflAdvModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "ReflAdvModel"
+        ## Model description
+        self.description = """
+        Calculate neutron reflectivity using the Parratt iterative formula
+		Parameters:
+		background:background
+		scale: scale factor
+		sld_bottom0: the SLD of the substrate
+		sld_medium: the SLD of the incident medium
+		or superstrate
+		sld_flatN: the SLD of the flat region of
+		the N'th layer
+		thick_flatN: the thickness of the flat
+		region of the N'th layer
+		func_interN: the function used to describe
+		the interface of the N'th layer
+		nu_interN: the coefficient for the func_interN
+		thick_interN: the thickness of the interface
+		of the N'th layer
+		Note: the layer number starts to increase
+		from the bottom (substrate) to the top.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['n_layers'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['thick_inter0'] = ['[A]', None, None]
+        self.details['func_inter0'] = ['', None, None]
+        self.details['sld_bottom0'] = ['[1/A^(2)]', None, None]
+        self.details['sld_medium'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+        self.details['sld_flat1'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat2'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat3'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat5'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat6'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat7'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat8'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat9'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat10'] = ['[1/A^(2)]', None, None]
+        self.details['thick_inter1'] = ['[A]', None, None]
+        self.details['thick_inter2'] = ['[A]', None, None]
+        self.details['thick_inter3'] = ['[A]', None, None]
+        self.details['thick_inter4'] = ['[A]', None, None]
+        self.details['thick_inter5'] = ['[A]', None, None]
+        self.details['thick_inter6'] = ['[A]', None, None]
+        self.details['thick_inter7'] = ['[A]', None, None]
+        self.details['thick_inter8'] = ['[A]', None, None]
+        self.details['thick_inter9'] = ['[A]', None, None]
+        self.details['thick_inter10'] = ['[A]', None, None]
+        self.details['thick_flat1'] = ['[A]', None, None]
+        self.details['thick_flat2'] = ['[A]', None, None]
+        self.details['thick_flat3'] = ['[A]', None, None]
+        self.details['thick_flat4'] = ['[A]', None, None]
+        self.details['thick_flat5'] = ['[A]', None, None]
+        self.details['thick_flat6'] = ['[A]', None, None]
+        self.details['thick_flat7'] = ['[A]', None, None]
+        self.details['thick_flat8'] = ['[A]', None, None]
+        self.details['thick_flat9'] = ['[A]', None, None]
+        self.details['thick_flat10'] = ['[A]', None, None]
+        self.details['func_inter1'] = ['', None, None]
+        self.details['func_inter2'] = ['', None, None]
+        self.details['func_inter3'] = ['', None, None]
+        self.details['func_inter4'] = ['', None, None]
+        self.details['func_inter5'] = ['', None, None]
+        self.details['func_inter6'] = ['', None, None]
+        self.details['func_inter7'] = ['', None, None]
+        self.details['func_inter8'] = ['', None, None]
+        self.details['func_inter9'] = ['', None, None]
+        self.details['func_inter10'] = ['', None, None]
+        self.details['sldIM_flat1'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat2'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat3'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat4'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat5'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat6'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat7'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat8'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat9'] = ['[1/A^(2)]', None, None]
+        self.details['sldIM_flat10'] = ['[1/A^(2)]', None, None]
+        self.details['nu_inter1'] = ['', None, None]
+        self.details['nu_inter2'] = ['', None, None]
+        self.details['nu_inter3'] = ['', None, None]
+        self.details['nu_inter4'] = ['', None, None]
+        self.details['nu_inter5'] = ['', None, None]
+        self.details['nu_inter6'] = ['', None, None]
+        self.details['nu_inter7'] = ['', None, None]
+        self.details['nu_inter8'] = ['', None, None]
+        self.details['nu_inter9'] = ['', None, None]
+        self.details['nu_inter10'] = ['', None, None]
+        self.details['sldIM_sub0'] = ['', None, None]
+        self.details['sldIM_medium'] = ['', None, None]
+        self.details['npts_inter'] = ['', None, None]
+        self.details['nu_inter0'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = ['n_layers',
+                             'func_inter0',
+                             'func_inter1',
+                             'func_inter2',
+                             'func_inter3',
+                             'func_inter4',
+                             'func_inter5',
+                             'func_inter5',
+                             'func_inter7',
+                             'func_inter8',
+                             'func_inter9',
+                             'func_inter10']
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_ReflAdvModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(ReflAdvModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CReflAdvModel.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 CReflAdvModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CReflAdvModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CReflAdvModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CReflAdvModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CReflAdvModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/ReflModel.py
===================================================================
--- src/sans/models/ReflModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/ReflModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,285 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\refl.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CReflModel
+
+def create_ReflModel():
+    """
+       Create a model instance
+    """
+    obj = ReflModel()
+    # CReflModel.__init__(obj) is called by
+    # the ReflModel constructor
+    return obj
+
+class ReflModel(CReflModel, BaseComponent):
+    """ 
+    Class that evaluates a ReflModel model. 
+    This file was auto-generated from src\sans\models\include\refl.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         n_layers        = 1.0 
+         scale           = 1.0 
+         thick_inter0    = 1.0 [A]
+         func_inter0     = 0.0 
+         sld_bottom0     = 2.07e-06 [1/A^(2)]
+         sld_medium      = 1e-06 [1/A^(2)]
+         background      = 0.0 
+         sld_flat1       = 4e-06 [1/A^(2)]
+         sld_flat2       = 3.5e-06 [1/A^(2)]
+         sld_flat3       = 4e-06 [1/A^(2)]
+         sld_flat4       = 3.5e-06 [1/A^(2)]
+         sld_flat5       = 4e-06 [1/A^(2)]
+         sld_flat6       = 3.5e-06 [1/A^(2)]
+         sld_flat7       = 4e-06 [1/A^(2)]
+         sld_flat8       = 3.5e-06 [1/A^(2)]
+         sld_flat9       = 4e-06 [1/A^(2)]
+         sld_flat10      = 3.5e-06 [1/A^(2)]
+         thick_inter1    = 1.0 [A]
+         thick_inter2    = 1.0 [A]
+         thick_inter3    = 1.0 [A]
+         thick_inter4    = 1.0 [A]
+         thick_inter5    = 1.0 [A]
+         thick_inter6    = 1.0 [A]
+         thick_inter7    = 1.0 [A]
+         thick_inter8    = 1.0 [A]
+         thick_inter9    = 1.0 [A]
+         thick_inter10   = 1.0 [A]
+         thick_flat1     = 10.0 [A]
+         thick_flat2     = 100.0 [A]
+         thick_flat3     = 100.0 [A]
+         thick_flat4     = 100.0 [A]
+         thick_flat5     = 100.0 [A]
+         thick_flat6     = 100.0 [A]
+         thick_flat7     = 100.0 [A]
+         thick_flat8     = 100.0 [A]
+         thick_flat9     = 100.0 [A]
+         thick_flat10    = 100.0 [A]
+         func_inter1     = 0.0 
+         func_inter2     = 0.0 
+         func_inter3     = 0.0 
+         func_inter4     = 0.0 
+         func_inter5     = 0.0 
+         func_inter6     = 0.0 
+         func_inter7     = 0.0 
+         func_inter8     = 0.0 
+         func_inter9     = 0.0 
+         func_inter10    = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CReflModel.__init__, (self,)) 
+
+        CReflModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "ReflModel"
+        ## Model description
+        self.description = """
+        Calculate neutron reflectivity using the Parratt iterative formula
+		Parameters:
+		background:background
+		scale: scale factor
+		sld_bottom0: the SLD of the substrate
+		sld_medium: the SLD of the incident medium
+		or superstrate
+		sld_flatN: the SLD of the flat region of
+		the N'th layer
+		thick_flatN: the thickness of the flat
+		region of the N'th layer
+		func_interN: the function used to describe
+		the interface of the N'th layer
+		thick_interN: the thickness of the interface
+		of the N'th layer
+		Note: the layer number starts to increase
+		from the bottom (substrate) to the top.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['n_layers'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['thick_inter0'] = ['[A]', None, None]
+        self.details['func_inter0'] = ['', None, None]
+        self.details['sld_bottom0'] = ['[1/A^(2)]', None, None]
+        self.details['sld_medium'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+        self.details['sld_flat1'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat2'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat3'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat5'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat6'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat7'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat8'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat9'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat10'] = ['[1/A^(2)]', None, None]
+        self.details['thick_inter1'] = ['[A]', None, None]
+        self.details['thick_inter2'] = ['[A]', None, None]
+        self.details['thick_inter3'] = ['[A]', None, None]
+        self.details['thick_inter4'] = ['[A]', None, None]
+        self.details['thick_inter5'] = ['[A]', None, None]
+        self.details['thick_inter6'] = ['[A]', None, None]
+        self.details['thick_inter7'] = ['[A]', None, None]
+        self.details['thick_inter8'] = ['[A]', None, None]
+        self.details['thick_inter9'] = ['[A]', None, None]
+        self.details['thick_inter10'] = ['[A]', None, None]
+        self.details['thick_flat1'] = ['[A]', None, None]
+        self.details['thick_flat2'] = ['[A]', None, None]
+        self.details['thick_flat3'] = ['[A]', None, None]
+        self.details['thick_flat4'] = ['[A]', None, None]
+        self.details['thick_flat5'] = ['[A]', None, None]
+        self.details['thick_flat6'] = ['[A]', None, None]
+        self.details['thick_flat7'] = ['[A]', None, None]
+        self.details['thick_flat8'] = ['[A]', None, None]
+        self.details['thick_flat9'] = ['[A]', None, None]
+        self.details['thick_flat10'] = ['[A]', None, None]
+        self.details['func_inter1'] = ['', None, None]
+        self.details['func_inter2'] = ['', None, None]
+        self.details['func_inter3'] = ['', None, None]
+        self.details['func_inter4'] = ['', None, None]
+        self.details['func_inter5'] = ['', None, None]
+        self.details['func_inter6'] = ['', None, None]
+        self.details['func_inter7'] = ['', None, None]
+        self.details['func_inter8'] = ['', None, None]
+        self.details['func_inter9'] = ['', None, None]
+        self.details['func_inter10'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = ['n_layers',
+                             'func_inter0',
+                             'func_inter1',
+                             'func_inter2',
+                             'func_inter3',
+                             'func_inter4',
+                             'func_inter5',
+                             'func_inter5',
+                             'func_inter7',
+                             'func_inter8',
+                             'func_inter9',
+                             'func_inter10']
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_ReflModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(ReflModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CReflModel.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 CReflModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CReflModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CReflModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CReflModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CReflModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SCCrystalModel.py
===================================================================
--- src/sans/models/SCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SCCrystalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,209 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\sc.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSCCrystalModel
+
+def create_SCCrystalModel():
+    """
+       Create a model instance
+    """
+    obj = SCCrystalModel()
+    # CSCCrystalModel.__init__(obj) is called by
+    # the SCCrystalModel constructor
+    return obj
+
+class SCCrystalModel(CSCCrystalModel, BaseComponent):
+    """ 
+    Class that evaluates a SCCrystalModel model. 
+    This file was auto-generated from src\sans\models\include\sc.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         dnn             = 220.0 [A]
+         d_factor        = 0.06 
+         radius          = 40.0 [A]
+         sldSph          = 3e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         theta           = 0.0 [deg]
+         phi             = 0.0 [deg]
+         psi             = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSCCrystalModel.__init__, (self,)) 
+
+        CSCCrystalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SCCrystalModel"
+        ## Model description
+        self.description = """
+        P(q)=(scale/Vp)*V_lattice*P(q)*Z(q)+bkg where scale is the volume
+		fraction of sphere,
+		Vp = volume of the primary particle,
+		V_lattice = volume correction for
+		for the crystal structure,
+		P(q)= form factor of the sphere (normalized),
+		Z(q)= paracrystalline structure factor
+		for a simple cubic structure.
+		[Simple Cubic ParaCrystal Model]
+		Parameters;
+		scale: volume fraction of spheres
+		bkg:background, R: radius of sphere
+		dnn: Nearest neighbor distance
+		d_factor: Paracrystal distortion factor
+		radius: radius of the spheres
+		sldSph: SLD of the sphere
+		sldSolv: SLD of the solvent
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['dnn'] = ['[A]', None, None]
+        self.details['d_factor'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['sldSph'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['theta'] = ['[deg]', None, None]
+        self.details['phi'] = ['[deg]', None, None]
+        self.details['psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'phi.width',
+                      'psi.width',
+                      'theta.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['phi',
+                                   'psi',
+                                   'theta',
+                                   'phi.width',
+                                   'psi.width',
+                                   'theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SCCrystalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SCCrystalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSCCrystalModel.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 CSCCrystalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSCCrystalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSCCrystalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSCCrystalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSCCrystalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SLDCalFunc.py
===================================================================
--- src/sans/models/SLDCalFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SLDCalFunc.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,176 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\sld_cal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSLDCalFunc
+
+def create_SLDCalFunc():
+    """
+       Create a model instance
+    """
+    obj = SLDCalFunc()
+    # CSLDCalFunc.__init__(obj) is called by
+    # the SLDCalFunc constructor
+    return obj
+
+class SLDCalFunc(CSLDCalFunc, BaseComponent):
+    """ 
+    Class that evaluates a SLDCalFunc model. 
+    This file was auto-generated from src\sans\models\include\sld_cal.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         fun_type        = 0.0 
+         npts_inter      = 21.0 
+         shell_num       = 0.0 
+         nu_inter        = 2.5 
+         sld_left        = 0.0 [1/A^(2)]
+         sld_right       = 0.0 [1/A^(2)]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSLDCalFunc.__init__, (self,)) 
+
+        CSLDCalFunc.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SLDCalFunc"
+        ## Model description
+        self.description = """
+        To calculate sld values
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['fun_type'] = ['', None, None]
+        self.details['npts_inter'] = ['', None, None]
+        self.details['shell_num'] = ['', None, None]
+        self.details['nu_inter'] = ['', None, None]
+        self.details['sld_left'] = ['[1/A^(2)]', None, None]
+        self.details['sld_right'] = ['[1/A^(2)]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['</text>']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SLDCalFunc, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SLDCalFunc())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSLDCalFunc.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 CSLDCalFunc.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSLDCalFunc.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSLDCalFunc.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSLDCalFunc.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSLDCalFunc.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/Schulz.py
===================================================================
--- src/sans/models/Schulz.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/Schulz.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,172 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\schulz.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSchulz
+
+def create_Schulz():
+    """
+       Create a model instance
+    """
+    obj = Schulz()
+    # CSchulz.__init__(obj) is called by
+    # the Schulz constructor
+    return obj
+
+class Schulz(CSchulz, BaseComponent):
+    """ 
+    Class that evaluates a Schulz model. 
+    This file was auto-generated from src\sans\models\include\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, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSchulz.__init__, (self,)) 
+
+        CSchulz.__init__(self)
+        self.is_multifunc = False
+		        
+        ## 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 = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_Schulz, tuple(), state, None, None)
+        
+    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 evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSchulz.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSchulz.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSchulz.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSchulz.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SphereModel.py
===================================================================
--- src/sans/models/SphereModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SphereModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,207 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\sphere.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSphereModel
+
+def create_SphereModel():
+    """
+       Create a model instance
+    """
+    obj = SphereModel()
+    # CSphereModel.__init__(obj) is called by
+    # the SphereModel constructor
+    return obj
+
+class SphereModel(CSphereModel, BaseComponent):
+    """ 
+    Class that evaluates a SphereModel model. 
+    This file was auto-generated from src\sans\models\include\sphere.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 60.0 [A]
+         sldSph          = 2e-06 [1/A^(2)]
+         sldSolv         = 1e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         M0_sld_sph      = 0.0 [1/A^(2)]
+         M_theta_sph     = 0.0 [deg]
+         M_phi_sph       = 0.0 [deg]
+         M0_sld_solv     = 0.0 [1/A^(2)]
+         M_theta_solv    = 0.0 [deg]
+         M_phi_solv      = 0.0 [deg]
+         Up_frac_i       = 0.5 [u/(u+d)]
+         Up_frac_f       = 0.5 [u/(u+d)]
+         Up_theta        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSphereModel.__init__, (self,)) 
+
+        CSphereModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SphereModel"
+        ## Model description
+        self.description = """
+        P(q)=(scale/V)*[3V(sldSph-sldSolv)*(sin(qR)-qRcos(qR))
+		/(qR)^3]^(2)+bkg
+		
+		bkg:background, R: radius of sphere
+		V:The volume of the scatter
+		sldSph: the SLD of the sphere
+		sldSolv: the SLD of the solvent
+		
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['sldSph'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['M0_sld_sph'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_sph'] = ['[deg]', None, None]
+        self.details['M_phi_sph'] = ['[deg]', None, None]
+        self.details['M0_sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['M_theta_solv'] = ['[deg]', None, None]
+        self.details['M_phi_solv'] = ['[deg]', None, None]
+        self.details['Up_frac_i'] = ['[u/(u+d)]', None, None]
+        self.details['Up_frac_f'] = ['[u/(u+d)]', None, None]
+        self.details['Up_theta'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['M0_sld_sph',
+                                   'M_theta_sph',
+                                   'M_phi_sph',
+                                   'M0_sld_solv',
+                                   'M_theta_solv',
+                                   'M_phi_solv',
+                                   'Up_frac_i',
+                                   'Up_frac_f',
+                                   'Up_theta']
+
+        ## parameters with magnetism
+        self.magnetic_params = ['M0_sld_sph', 'M_theta_sph', 'M_phi_sph', 'M0_sld_solv', 'M_theta_solv', 'M_phi_solv', 'Up_frac_i', 'Up_frac_f', 'Up_theta']
+
+        self.category = "Shapes & Spheres"
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SphereModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SphereModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSphereModel.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 CSphereModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSphereModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSphereModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSphereModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSphereModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SphereSLDModel.py
===================================================================
--- src/sans/models/SphereSLDModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SphereSLDModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,313 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\spheresld.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSphereSLDModel
+
+def create_SphereSLDModel():
+    """
+       Create a model instance
+    """
+    obj = SphereSLDModel()
+    # CSphereSLDModel.__init__(obj) is called by
+    # the SphereSLDModel constructor
+    return obj
+
+class SphereSLDModel(CSphereSLDModel, BaseComponent):
+    """ 
+    Class that evaluates a SphereSLDModel model. 
+    This file was auto-generated from src\sans\models\include\spheresld.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         n_shells        = 1.0 
+         scale           = 1.0 
+         thick_inter0    = 50.0 [A]
+         func_inter0     = 0.0 
+         sld_core0       = 2.07e-06 [1/A^(2)]
+         sld_solv        = 1e-06 [1/A^(2)]
+         background      = 0.0 
+         sld_flat1       = 4e-06 [1/A^(2)]
+         sld_flat2       = 3.5e-06 [1/A^(2)]
+         sld_flat3       = 4e-06 [1/A^(2)]
+         sld_flat4       = 3.5e-06 [1/A^(2)]
+         sld_flat5       = 4e-06 [1/A^(2)]
+         sld_flat6       = 3.5e-06 [1/A^(2)]
+         sld_flat7       = 4e-06 [1/A^(2)]
+         sld_flat8       = 3.5e-06 [1/A^(2)]
+         sld_flat9       = 4e-06 [1/A^(2)]
+         sld_flat10      = 3.5e-06 [1/A^(2)]
+         thick_inter1    = 50.0 [A]
+         thick_inter2    = 50.0 [A]
+         thick_inter3    = 50.0 [A]
+         thick_inter4    = 50.0 [A]
+         thick_inter5    = 50.0 [A]
+         thick_inter6    = 50.0 [A]
+         thick_inter7    = 50.0 [A]
+         thick_inter8    = 50.0 [A]
+         thick_inter9    = 50.0 [A]
+         thick_inter10   = 50.0 [A]
+         thick_flat1     = 100.0 [A]
+         thick_flat2     = 100.0 [A]
+         thick_flat3     = 100.0 [A]
+         thick_flat4     = 100.0 [A]
+         thick_flat5     = 100.0 [A]
+         thick_flat6     = 100.0 [A]
+         thick_flat7     = 100.0 [A]
+         thick_flat8     = 100.0 [A]
+         thick_flat9     = 100.0 [A]
+         thick_flat10    = 100.0 [A]
+         func_inter1     = 0.0 
+         func_inter2     = 0.0 
+         func_inter3     = 0.0 
+         func_inter4     = 0.0 
+         func_inter5     = 0.0 
+         func_inter6     = 0.0 
+         func_inter7     = 0.0 
+         func_inter8     = 0.0 
+         func_inter9     = 0.0 
+         func_inter10    = 0.0 
+         nu_inter1       = 2.5 
+         nu_inter2       = 2.5 
+         nu_inter3       = 2.5 
+         nu_inter4       = 2.5 
+         nu_inter5       = 2.5 
+         nu_inter6       = 2.5 
+         nu_inter7       = 2.5 
+         nu_inter8       = 2.5 
+         nu_inter9       = 2.5 
+         nu_inter10      = 2.5 
+         npts_inter      = 35.0 
+         nu_inter0       = 2.5 
+         rad_core0       = 50.0 [A]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSphereSLDModel.__init__, (self,)) 
+
+        CSphereSLDModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SphereSLDModel"
+        ## Model description
+        self.description = """
+        Calculate neutron reflectivity using the Parratt iterative formula
+		Parameters:
+		background:background
+		scale: scale factor
+		sld_core0: the SLD of the substrate
+		sld_solv: the SLD of the incident medium
+		or superstrate
+		sld_flatN: the SLD of the flat region of
+		the N'th layer
+		thick_flatN: the thickness of the flat
+		region of the N'th layer
+		func_interN: the function used to describe
+		the interface of the N'th layer
+		nu_interN: the coefficient for the func_interN
+		thick_interN: the thickness of the interface
+		of the N'th layer
+		Note: the layer number starts to increase
+		from the bottom (substrate) to the top.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['n_shells'] = ['', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['thick_inter0'] = ['[A]', None, None]
+        self.details['func_inter0'] = ['', None, None]
+        self.details['sld_core0'] = ['[1/A^(2)]', None, None]
+        self.details['sld_solv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['', None, None]
+        self.details['sld_flat1'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat2'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat3'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat4'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat5'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat6'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat7'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat8'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat9'] = ['[1/A^(2)]', None, None]
+        self.details['sld_flat10'] = ['[1/A^(2)]', None, None]
+        self.details['thick_inter1'] = ['[A]', None, None]
+        self.details['thick_inter2'] = ['[A]', None, None]
+        self.details['thick_inter3'] = ['[A]', None, None]
+        self.details['thick_inter4'] = ['[A]', None, None]
+        self.details['thick_inter5'] = ['[A]', None, None]
+        self.details['thick_inter6'] = ['[A]', None, None]
+        self.details['thick_inter7'] = ['[A]', None, None]
+        self.details['thick_inter8'] = ['[A]', None, None]
+        self.details['thick_inter9'] = ['[A]', None, None]
+        self.details['thick_inter10'] = ['[A]', None, None]
+        self.details['thick_flat1'] = ['[A]', None, None]
+        self.details['thick_flat2'] = ['[A]', None, None]
+        self.details['thick_flat3'] = ['[A]', None, None]
+        self.details['thick_flat4'] = ['[A]', None, None]
+        self.details['thick_flat5'] = ['[A]', None, None]
+        self.details['thick_flat6'] = ['[A]', None, None]
+        self.details['thick_flat7'] = ['[A]', None, None]
+        self.details['thick_flat8'] = ['[A]', None, None]
+        self.details['thick_flat9'] = ['[A]', None, None]
+        self.details['thick_flat10'] = ['[A]', None, None]
+        self.details['func_inter1'] = ['', None, None]
+        self.details['func_inter2'] = ['', None, None]
+        self.details['func_inter3'] = ['', None, None]
+        self.details['func_inter4'] = ['', None, None]
+        self.details['func_inter5'] = ['', None, None]
+        self.details['func_inter6'] = ['', None, None]
+        self.details['func_inter7'] = ['', None, None]
+        self.details['func_inter8'] = ['', None, None]
+        self.details['func_inter9'] = ['', None, None]
+        self.details['func_inter10'] = ['', None, None]
+        self.details['nu_inter1'] = ['', None, None]
+        self.details['nu_inter2'] = ['', None, None]
+        self.details['nu_inter3'] = ['', None, None]
+        self.details['nu_inter4'] = ['', None, None]
+        self.details['nu_inter5'] = ['', None, None]
+        self.details['nu_inter6'] = ['', None, None]
+        self.details['nu_inter7'] = ['', None, None]
+        self.details['nu_inter8'] = ['', None, None]
+        self.details['nu_inter9'] = ['', None, None]
+        self.details['nu_inter10'] = ['', None, None]
+        self.details['npts_inter'] = ['', None, None]
+        self.details['nu_inter0'] = ['', None, None]
+        self.details['rad_core0'] = ['[A]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['rad_core0.width',
+                      'thick_inter0.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = ['n_shells',
+                             'func_inter0',
+                             'func_inter1',
+                             'func_inter2',
+                             'func_inter3',
+                             'func_inter4',
+                             'func_inter5',
+                             'func_inter5',
+                             'func_inter7',
+                             'func_inter8',
+                             'func_inter9',
+                             'func_inter10']
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SphereSLDModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SphereSLDModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSphereSLDModel.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 CSphereSLDModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSphereSLDModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSphereSLDModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSphereSLDModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSphereSLDModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SquareWellStructure.py
===================================================================
--- src/sans/models/SquareWellStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SquareWellStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,187 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\SquareWell.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSquareWellStructure
+
+def create_SquareWellStructure():
+    """
+       Create a model instance
+    """
+    obj = SquareWellStructure()
+    # CSquareWellStructure.__init__(obj) is called by
+    # the SquareWellStructure constructor
+    return obj
+
+class SquareWellStructure(CSquareWellStructure, BaseComponent):
+    """ 
+    Class that evaluates a SquareWellStructure model. 
+    This file was auto-generated from src\sans\models\include\SquareWell.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         effect_radius   = 50.0 [A]
+         volfraction     = 0.04 
+         welldepth       = 1.5 [kT]
+         wellwidth       = 1.2 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSquareWellStructure.__init__, (self,)) 
+
+        CSquareWellStructure.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SquareWellStructure"
+        ## Model description
+        self.description = """
+         Structure Factor for interacting particles:             .
+		
+		The interaction potential is
+		
+		U(r)= inf   , r < 2R
+		= -d    , 2R <= r <=2Rw
+		= 0     , r >= 2Rw
+		
+		R: effective radius (A)of the particle
+		v: volume fraction
+		d: well depth
+		w: well width; multiples of the
+		particle diameter
+		
+		Ref: Sharma, R. V.; Sharma,
+		K. C., Physica, 1977, 89A, 213.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['effect_radius'] = ['[A]', None, None]
+        self.details['volfraction'] = ['', None, None]
+        self.details['welldepth'] = ['[kT]', None, None]
+        self.details['wellwidth'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['effect_radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SquareWellStructure, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SquareWellStructure())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSquareWellStructure.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 CSquareWellStructure.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSquareWellStructure.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSquareWellStructure.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSquareWellStructure.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSquareWellStructure.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/StackedDisksModel.py
===================================================================
--- src/sans/models/StackedDisksModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/StackedDisksModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,203 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\stacked_disks.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CStackedDisksModel
+
+def create_StackedDisksModel():
+    """
+       Create a model instance
+    """
+    obj = StackedDisksModel()
+    # CStackedDisksModel.__init__(obj) is called by
+    # the StackedDisksModel constructor
+    return obj
+
+class StackedDisksModel(CStackedDisksModel, BaseComponent):
+    """ 
+    Class that evaluates a StackedDisksModel model. 
+    This file was auto-generated from src\sans\models\include\stacked_disks.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 0.01 
+         core_thick      = 10.0 [A]
+         radius          = 3000.0 [A]
+         layer_thick     = 15.0 [A]
+         core_sld        = 4e-06 [1/A^(2)]
+         layer_sld       = -4e-07 [1/A^(2)]
+         solvent_sld     = 5e-06 [1/A^(2)]
+         n_stacking      = 1.0 
+         sigma_d         = 0.0 
+         background      = 0.001 [1/cm]
+         axis_theta      = 0.0 [rad]
+         axis_phi        = 0.0 [rad]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CStackedDisksModel.__init__, (self,)) 
+
+        CStackedDisksModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "StackedDisksModel"
+        ## Model description
+        self.description = """
+         One layer of disk consists of a core, a top layer, and a bottom layer.
+		radius =  the radius of the disk
+		core_thick = thickness of the core
+		layer_thick = thickness of a layer
+		core_sld = the SLD of the core
+		layer_sld = the SLD of the layers
+		n_stacking = the number of the disks
+		sigma_d =  Gaussian STD of d-spacing
+		solvent_sld = the SLD of the solvent
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['core_thick'] = ['[A]', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['layer_thick'] = ['[A]', None, None]
+        self.details['core_sld'] = ['[1/A^(2)]', None, None]
+        self.details['layer_sld'] = ['[1/A^(2)]', None, None]
+        self.details['solvent_sld'] = ['[1/A^(2)]', None, None]
+        self.details['n_stacking'] = ['', None, None]
+        self.details['sigma_d'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[rad]', None, None]
+        self.details['axis_phi'] = ['[rad]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['core_thick.width',
+                      'layer_thick.width',
+                      'radius.width',
+                      'axis_theta.width',
+                      'axis_phi.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_phi',
+                                   'axis_theta',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_StackedDisksModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(StackedDisksModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CStackedDisksModel.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 CStackedDisksModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CStackedDisksModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CStackedDisksModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CStackedDisksModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CStackedDisksModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/StarPolymer.py
===================================================================
--- src/sans/models/StarPolymer.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/StarPolymer.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,179 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\starpolymer.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CStarPolymer
+
+def create_StarPolymer():
+    """
+       Create a model instance
+    """
+    obj = StarPolymer()
+    # CStarPolymer.__init__(obj) is called by
+    # the StarPolymer constructor
+    return obj
+
+class StarPolymer(CStarPolymer, BaseComponent):
+    """ 
+    Class that evaluates a StarPolymer model. 
+    This file was auto-generated from src\sans\models\include\starpolymer.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         arms            = 3.0 
+         R2              = 100.0 [A]
+         scale           = 1.0 
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CStarPolymer.__init__, (self,)) 
+
+        CStarPolymer.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "StarPolymer"
+        ## Model description
+        self.description = """
+          Scattering model class for 'Star polymer with Gaussian statistics'
+		with
+		P(q) = 2/{fv^2} * (v - (1-exp(-v)) + {f-1}/2 * (1-exp(-v))^2)
+		where
+		- v = u^2f/(3f-2)
+		- u = <R_g^2>q^2, where <R_g^2> is the ensemble average radius of
+		giration squared of an arm
+		- f is the number of arms on the star
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['arms'] = ['', None, None]
+        self.details['R2'] = ['[A]', None, None]
+        self.details['scale'] = ['', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_StarPolymer, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(StarPolymer())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CStarPolymer.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 CStarPolymer.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CStarPolymer.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CStarPolymer.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CStarPolymer.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CStarPolymer.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/StickyHSStructure.py
===================================================================
--- src/sans/models/StickyHSStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/StickyHSStructure.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,187 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\StickyHS.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CStickyHSStructure
+
+def create_StickyHSStructure():
+    """
+       Create a model instance
+    """
+    obj = StickyHSStructure()
+    # CStickyHSStructure.__init__(obj) is called by
+    # the StickyHSStructure constructor
+    return obj
+
+class StickyHSStructure(CStickyHSStructure, BaseComponent):
+    """ 
+    Class that evaluates a StickyHSStructure model. 
+    This file was auto-generated from src\sans\models\include\StickyHS.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         effect_radius   = 50.0 [A]
+         volfraction     = 0.1 
+         perturb         = 0.05 
+         stickiness      = 0.2 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CStickyHSStructure.__init__, (self,)) 
+
+        CStickyHSStructure.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "StickyHSStructure"
+        ## Model description
+        self.description = """
+         Structure Factor for interacting particles:                               .
+		
+		The interaction potential is
+		
+		U(r)= inf , r < 2R
+		= -Uo  , 2R < r < 2R + w
+		= 0   , r >= 2R +w
+		
+		R: effective radius of the hardsphere
+		stickiness = [exp(Uo/kT)]/(12*perturb)
+		perturb = w/(w+ 2R) , 0.01 =< w <= 0.1
+		w: The width of the square well ,w > 0
+		v: The volume fraction , v > 0
+		
+		Ref: Menon, S. V. G.,et.al., J. Chem.
+		Phys., 1991, 95(12), 9186-9190.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['effect_radius'] = ['[A]', None, None]
+        self.details['volfraction'] = ['', None, None]
+        self.details['perturb'] = ['', None, None]
+        self.details['stickiness'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = ['effect_radius.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_StickyHSStructure, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(StickyHSStructure())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CStickyHSStructure.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 CStickyHSStructure.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CStickyHSStructure.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CStickyHSStructure.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CStickyHSStructure.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CStickyHSStructure.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/SurfaceFractalModel.py
===================================================================
--- src/sans/models/SurfaceFractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/SurfaceFractalModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,187 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\surfacefractal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CSurfaceFractalModel
+
+def create_SurfaceFractalModel():
+    """
+       Create a model instance
+    """
+    obj = SurfaceFractalModel()
+    # CSurfaceFractalModel.__init__(obj) is called by
+    # the SurfaceFractalModel constructor
+    return obj
+
+class SurfaceFractalModel(CSurfaceFractalModel, BaseComponent):
+    """ 
+    Class that evaluates a SurfaceFractalModel model. 
+    This file was auto-generated from src\sans\models\include\surfacefractal.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 10.0 [A]
+         surface_dim     = 2.0 
+         co_length       = 500.0 [A]
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CSurfaceFractalModel.__init__, (self,)) 
+
+        CSurfaceFractalModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "SurfaceFractalModel"
+        ## Model description
+        self.description = """
+         The scattering intensity  I(x) = scale*P(x)*S(x) + background, where
+		scale = scale_factor  * V * delta^(2)
+		p(x)=  F(x*radius)^(2)
+		F(x) = 3*[sin(x)-x cos(x)]/x**3
+		S(x) = [(gamma(5-Ds)*colength^(5-Ds)*[1+(x^2*colength^2)]^((Ds-5)/2)
+		* sin[(Ds-5)*arctan(x*colength)])/x]
+		where delta = sldParticle -sldSolv.
+		radius       =  Particle radius
+		surface_dim  =  Surface fractal dimension (Ds)
+		co_length  =  Cut-off length
+		background   =  background
+		Ref.:Mildner, Hall,J Phys D Appl Phys(1986), 19, 1535-1545
+		Note I: This model is valid for 1<surface_dim<3 with limited q range.
+		Note II: This model is not in absolute scale.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['surface_dim'] = ['', None, None]
+        self.details['co_length'] = ['[A]', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_SurfaceFractalModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SurfaceFractalModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CSurfaceFractalModel.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 CSurfaceFractalModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CSurfaceFractalModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CSurfaceFractalModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CSurfaceFractalModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CSurfaceFractalModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/TeubnerStreyModel.py
===================================================================
--- src/sans/models/TeubnerStreyModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/TeubnerStreyModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,172 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\teubner_strey.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CTeubnerStreyModel
+
+def create_TeubnerStreyModel():
+    """
+       Create a model instance
+    """
+    obj = TeubnerStreyModel()
+    # CTeubnerStreyModel.__init__(obj) is called by
+    # the TeubnerStreyModel constructor
+    return obj
+
+class TeubnerStreyModel(CTeubnerStreyModel, BaseComponent):
+    """ 
+    Class that evaluates a TeubnerStreyModel model. 
+    This file was auto-generated from src\sans\models\include\teubner_strey.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 0.1 
+         c1              = -30.0 
+         c2              = 5000.0 
+         background      = 0.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CTeubnerStreyModel.__init__, (self,)) 
+
+        CTeubnerStreyModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "TeubnerStreyModel"
+        ## Model description
+        self.description = """
+        F(x) = 1/( scale + c1*(x)^(2)+  c2*(x)^(4)) + bkd 
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['c1'] = ['', None, None]
+        self.details['c2'] = ['', None, None]
+        self.details['background'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_TeubnerStreyModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(TeubnerStreyModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CTeubnerStreyModel.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 CTeubnerStreyModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CTeubnerStreyModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CTeubnerStreyModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CTeubnerStreyModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CTeubnerStreyModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/TriaxialEllipsoidModel.py
===================================================================
--- src/sans/models/TriaxialEllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/TriaxialEllipsoidModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,196 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\triaxial_ellipsoid.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CTriaxialEllipsoidModel
+
+def create_TriaxialEllipsoidModel():
+    """
+       Create a model instance
+    """
+    obj = TriaxialEllipsoidModel()
+    # CTriaxialEllipsoidModel.__init__(obj) is called by
+    # the TriaxialEllipsoidModel constructor
+    return obj
+
+class TriaxialEllipsoidModel(CTriaxialEllipsoidModel, BaseComponent):
+    """ 
+    Class that evaluates a TriaxialEllipsoidModel model. 
+    This file was auto-generated from src\sans\models\include\triaxial_ellipsoid.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         semi_axisA      = 35.0 [A]
+         semi_axisB      = 100.0 [A]
+         semi_axisC      = 400.0 [A]
+         sldEll          = 1e-06 [1/A^(2)]
+         sldSolv         = 6.3e-06 [1/A^(2)]
+         background      = 0.0 [1/cm]
+         axis_theta      = 57.325 [deg]
+         axis_phi        = 57.325 [deg]
+         axis_psi        = 0.0 [deg]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CTriaxialEllipsoidModel.__init__, (self,)) 
+
+        CTriaxialEllipsoidModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "TriaxialEllipsoidModel"
+        ## Model description
+        self.description = """
+        Note: During fitting ensure that the inequality A<B<C is not
+		violated. Otherwise the calculation will
+		not be correct.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['semi_axisA'] = ['[A]', None, None]
+        self.details['semi_axisB'] = ['[A]', None, None]
+        self.details['semi_axisC'] = ['[A]', None, None]
+        self.details['sldEll'] = ['[1/A^(2)]', None, None]
+        self.details['sldSolv'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+        self.details['axis_theta'] = ['[deg]', None, None]
+        self.details['axis_phi'] = ['[deg]', None, None]
+        self.details['axis_psi'] = ['[deg]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['axis_psi.width',
+                      'axis_phi.width',
+                      'axis_theta.width',
+                      'semi_axisA.width',
+                      'semi_axisB.width',
+                      'semi_axisC.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = ['axis_psi',
+                                   'axis_phi',
+                                   'axis_theta',
+                                   'axis_psi.width',
+                                   'axis_phi.width',
+                                   'axis_theta.width']
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_TriaxialEllipsoidModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(TriaxialEllipsoidModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CTriaxialEllipsoidModel.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 CTriaxialEllipsoidModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CTriaxialEllipsoidModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CTriaxialEllipsoidModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CTriaxialEllipsoidModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CTriaxialEllipsoidModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/TwoYukawaModel.py
===================================================================
--- src/sans/models/TwoYukawaModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/TwoYukawaModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,185 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\TwoYukawa.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CTwoYukawaModel
+
+def create_TwoYukawaModel():
+    """
+       Create a model instance
+    """
+    obj = TwoYukawaModel()
+    # CTwoYukawaModel.__init__(obj) is called by
+    # the TwoYukawaModel constructor
+    return obj
+
+class TwoYukawaModel(CTwoYukawaModel, BaseComponent):
+    """ 
+    Class that evaluates a TwoYukawaModel model. 
+    This file was auto-generated from src\sans\models\include\TwoYukawa.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         volfraction     = 0.2 
+         effect_radius   = 50.0 [A]
+         scale_K1        = 6.0 
+         decayConst_Z1   = 10.0 
+         scale_K2        = -1.0 
+         decayConst_Z2   = 2.0 
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CTwoYukawaModel.__init__, (self,)) 
+
+        CTwoYukawaModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "TwoYukawaModel"
+        ## Model description
+        self.description = """
+        Structure factor for interacting particles:                   .
+		
+		Calculates the structure factor, S(q), for a monodisperse spherical particle interacting
+		through a two-Yukawa potential. The Mean Spherical Approximation is used as the
+		closure to solve the Ornstein-Zernicke equations.
+		
+		The function calculated is S(q), based on the solution of the Ornstein-Zernicke equations
+		using the Two-Yukawa potential (in its scaled form, r=r/diam):
+		
+		Radius is that of the hard core. The returned value is dimensionless.
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['volfraction'] = ['', None, None]
+        self.details['effect_radius'] = ['[A]', None, None]
+        self.details['scale_K1'] = ['', None, None]
+        self.details['decayConst_Z1'] = ['', None, None]
+        self.details['scale_K2'] = ['', None, None]
+        self.details['decayConst_Z2'] = ['', None, None]
+
+        ## fittable parameters
+        self.fixed = []
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_TwoYukawaModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(TwoYukawaModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CTwoYukawaModel.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 CTwoYukawaModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CTwoYukawaModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CTwoYukawaModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CTwoYukawaModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CTwoYukawaModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/VesicleModel.py
===================================================================
--- src/sans/models/VesicleModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/VesicleModel.py	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,182 @@
+##############################################################################
+# 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-2011, University of Tennessee
+##############################################################################
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY
+            src\sans\models\include\vesicle.h
+         AND RE-RUN THE GENERATOR SCRIPT
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans.models.sans_extension.c_models import CVesicleModel
+
+def create_VesicleModel():
+    """
+       Create a model instance
+    """
+    obj = VesicleModel()
+    # CVesicleModel.__init__(obj) is called by
+    # the VesicleModel constructor
+    return obj
+
+class VesicleModel(CVesicleModel, BaseComponent):
+    """ 
+    Class that evaluates a VesicleModel model. 
+    This file was auto-generated from src\sans\models\include\vesicle.h.
+    Refer to that file and the structure it contains
+    for details of the model.
+    List of default parameters:
+         scale           = 1.0 
+         radius          = 100.0 [A]
+         thickness       = 30.0 [A]
+         solv_sld        = 6.36e-06 [1/A^(2)]
+         shell_sld       = 5e-07 [1/A^(2)]
+         background      = 0.0 [1/cm]
+
+    """
+        
+    def __init__(self, multfactor=1):
+        """ Initialization """
+        self.__dict__ = {}
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        #apply(CVesicleModel.__init__, (self,)) 
+
+        CVesicleModel.__init__(self)
+        self.is_multifunc = False
+		        
+        ## Name of the model
+        self.name = "VesicleModel"
+        ## Model description
+        self.description = """
+        Model parameters:    radius : the core radius of the vesicle
+		thickness: the shell thickness
+		core_sld: the core SLD
+		shell_sld: the shell SLD
+		background: incoherent background
+		scale : scale factor
+        """
+       
+        ## Parameter details [units, min, max]
+        self.details = {}
+        self.details['scale'] = ['', None, None]
+        self.details['radius'] = ['[A]', None, None]
+        self.details['thickness'] = ['[A]', None, None]
+        self.details['solv_sld'] = ['[1/A^(2)]', None, None]
+        self.details['shell_sld'] = ['[1/A^(2)]', None, None]
+        self.details['background'] = ['[1/cm]', None, None]
+
+        ## fittable parameters
+        self.fixed = ['radius.width',
+                      'thickness.width']
+        
+        ## non-fittable parameters
+        self.non_fittable = []
+        
+        ## parameters with orientation
+        self.orientation_params = []
+
+        ## parameters with magnetism
+        self.magnetic_params = []
+
+        self.category = None
+        self.multiplicity_info = None
+        
+    def __setstate__(self, state):
+        """
+        restore the state of a model from pickle
+        """
+        self.__dict__, self.params, self.dispersion = state
+        
+    def __reduce_ex__(self, proto):
+        """
+        Overwrite the __reduce_ex__ of PyTypeObject *type call in the init of 
+        c model.
+        """
+        state = (self.__dict__, self.params, self.dispersion)
+        return (create_VesicleModel, tuple(), state, None, None)
+        
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(VesicleModel())   
+       	
+    def run(self, x=0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+        return CVesicleModel.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 CVesicleModel.runXY(self, x)
+        
+    def evalDistribution(self, x):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        :param x: input q[], or [qx[], qy[]]
+        
+        :return: scattering function P(q[])
+        
+        """
+        return CVesicleModel.evalDistribution(self, x)
+        
+    def calculate_ER(self):
+        """ 
+        Calculate the effective radius for P(q)*S(q)
+        
+        :return: the value of the effective radius
+        
+        """       
+        return CVesicleModel.calculate_ER(self)
+        
+    def calculate_VR(self):
+        """ 
+        Calculate the volf ratio for P(q)*S(q)
+        
+        :return: the value of the volf ratio
+        
+        """       
+        return CVesicleModel.calculate_VR(self)
+              
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        :param parameter: name of the parameter [string]
+        :param dispersion: dispersion object of type DispersionModel
+        
+        """
+        return CVesicleModel.set_dispersion(self,
+               parameter, dispersion.cdisp)
+        
+   
+# End of file
+
Index: src/sans/models/c_extension/c_models/c_models.cpp
===================================================================
--- src/sans/models/c_extension/c_models/c_models.cpp	(revision 230f479e04002ef42bafef9a227d586459b717c1)
+++ src/sans/models/c_extension/c_models/c_models.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -12,66 +12,66 @@
 
  // adding generated code 
+void addCBarBellModel(PyObject *module); 
+void addCBCCrystalModel(PyObject *module); 
+void addCBinaryHSModel(PyObject *module); 
+void addCCappedCylinderModel(PyObject *module); 
+void addCCoreFourShellModel(PyObject *module); 
+void addCCore2ndMomentModel(PyObject *module); 
+void addCCoreShellModel(PyObject *module); 
+void addCCoreShellBicelleModel(PyObject *module); 
+void addCCoreShellCylinderModel(PyObject *module); 
+void addCCSParallelepipedModel(PyObject *module); 
+void addCCylinderModel(PyObject *module); 
+void addCDABModel(PyObject *module); 
+void addCDiamCylFunc(PyObject *module); 
+void addCDiamEllipFunc(PyObject *module); 
+void addCEllipsoidModel(PyObject *module); 
+void addCEllipticalCylinderModel(PyObject *module); 
+void addCFCCrystalModel(PyObject *module); 
+void addCFlexCylEllipXModel(PyObject *module); 
+void addCFlexibleCylinderModel(PyObject *module); 
+void addCFractalModel(PyObject *module); 
+void addCFractalO_Z(PyObject *module); 
+void addCFuzzySphereModel(PyObject *module); 
+void addCGaussian(PyObject *module); 
+void addCGelFitModel(PyObject *module); 
+void addCHardsphereStructure(PyObject *module); 
+void addCHayterMSAStructure(PyObject *module); 
+void addCHollowCylinderModel(PyObject *module); 
+void addCLamellarModel(PyObject *module); 
+void addCLamellarFFHGModel(PyObject *module); 
+void addCLamellarPCrystalModel(PyObject *module); 
+void addCLamellarPSModel(PyObject *module); 
+void addCLamellarPSHGModel(PyObject *module); 
 void addCLinearPearlsModel(PyObject *module); 
+void addCLogNormal(PyObject *module); 
+void addCLorentzian(PyObject *module); 
+void addCMassFractalModel(PyObject *module); 
+void addCMassSurfaceFractal(PyObject *module); 
+void addCMultiShellModel(PyObject *module); 
+void addCOnionModel(PyObject *module); 
+void addCParallelepipedModel(PyObject *module); 
+void addCPearlNecklaceModel(PyObject *module); 
+void addCPoly_GaussCoil(PyObject *module); 
+void addCPringlesModel(PyObject *module); 
 void addCRaspBerryModel(PyObject *module); 
-void addCCore2ndMomentModel(PyObject *module); 
+void addCReflModel(PyObject *module); 
+void addCReflAdvModel(PyObject *module); 
+void addCRPAModel(PyObject *module); 
+void addCSCCrystalModel(PyObject *module); 
+void addCSchulz(PyObject *module); 
+void addCSLDCalFunc(PyObject *module); 
+void addCSphereModel(PyObject *module); 
+void addCSphereSLDModel(PyObject *module); 
+void addCCoreShellEllipsoidModel(PyObject *module); 
+void addCSquareWellStructure(PyObject *module); 
 void addCStackedDisksModel(PyObject *module); 
-void addCCoreShellCylinderModel(PyObject *module); 
-void addCReflModel(PyObject *module); 
-void addCSphereSLDModel(PyObject *module); 
-void addCFractalModel(PyObject *module); 
-void addCLogNormal(PyObject *module); 
-void addCPringlesModel(PyObject *module); 
-void addCCappedCylinderModel(PyObject *module); 
-void addCLorentzian(PyObject *module); 
-void addCBCCrystalModel(PyObject *module); 
-void addCPearlNecklaceModel(PyObject *module); 
-void addCSCCrystalModel(PyObject *module); 
-void addCGaussian(PyObject *module); 
-void addCLamellarModel(PyObject *module); 
-void addCLamellarPCrystalModel(PyObject *module); 
-void addCMassFractalModel(PyObject *module); 
-void addCPoly_GaussCoil(PyObject *module); 
+void addCStarPolymer(PyObject *module); 
+void addCStickyHSStructure(PyObject *module); 
+void addCSurfaceFractalModel(PyObject *module); 
 void addCTeubnerStreyModel(PyObject *module); 
-void addCOnionModel(PyObject *module); 
-void addCHollowCylinderModel(PyObject *module); 
 void addCTriaxialEllipsoidModel(PyObject *module); 
-void addCEllipticalCylinderModel(PyObject *module); 
-void addCSchulz(PyObject *module); 
-void addCLamellarPSHGModel(PyObject *module); 
-void addCDABModel(PyObject *module); 
-void addCStarPolymer(PyObject *module); 
-void addCFuzzySphereModel(PyObject *module); 
-void addCParallelepipedModel(PyObject *module); 
-void addCMassSurfaceFractal(PyObject *module); 
+void addCTwoYukawaModel(PyObject *module); 
 void addCVesicleModel(PyObject *module); 
-void addCGelFitModel(PyObject *module); 
-void addCCoreShellEllipsoidModel(PyObject *module); 
-void addCRPAModel(PyObject *module); 
-void addCHayterMSAStructure(PyObject *module); 
-void addCCSParallelepipedModel(PyObject *module); 
-void addCFractalO_Z(PyObject *module); 
-void addCMultiShellModel(PyObject *module); 
-void addCLamellarPSModel(PyObject *module); 
-void addCEllipsoidModel(PyObject *module); 
-void addCTwoYukawaModel(PyObject *module); 
-void addCDiamEllipFunc(PyObject *module); 
-void addCHardsphereStructure(PyObject *module); 
-void addCLamellarFFHGModel(PyObject *module); 
-void addCCoreShellBicelleModel(PyObject *module); 
-void addCFCCrystalModel(PyObject *module); 
-void addCFlexibleCylinderModel(PyObject *module); 
-void addCSurfaceFractalModel(PyObject *module); 
-void addCDiamCylFunc(PyObject *module); 
-void addCCoreFourShellModel(PyObject *module); 
-void addCStickyHSStructure(PyObject *module); 
-void addCReflAdvModel(PyObject *module); 
-void addCSphereModel(PyObject *module); 
-void addCFlexCylEllipXModel(PyObject *module); 
-void addCSquareWellStructure(PyObject *module); 
-void addCSLDCalFunc(PyObject *module); 
-void addCCoreShellModel(PyObject *module); 
-void addCBarBellModel(PyObject *module); 
-void addCBinaryHSModel(PyObject *module); 
-void addCCylinderModel(PyObject *module); 
  // end generated code 
 
@@ -260,66 +260,66 @@
 
  // adding generated code 
+addCBarBellModel(m); 
+addCBCCrystalModel(m); 
+addCBinaryHSModel(m); 
+addCCappedCylinderModel(m); 
+addCCoreFourShellModel(m); 
+addCCore2ndMomentModel(m); 
+addCCoreShellModel(m); 
+addCCoreShellBicelleModel(m); 
+addCCoreShellCylinderModel(m); 
+addCCSParallelepipedModel(m); 
+addCCylinderModel(m); 
+addCDABModel(m); 
+addCDiamCylFunc(m); 
+addCDiamEllipFunc(m); 
+addCEllipsoidModel(m); 
+addCEllipticalCylinderModel(m); 
+addCFCCrystalModel(m); 
+addCFlexCylEllipXModel(m); 
+addCFlexibleCylinderModel(m); 
+addCFractalModel(m); 
+addCFractalO_Z(m); 
+addCFuzzySphereModel(m); 
+addCGaussian(m); 
+addCGelFitModel(m); 
+addCHardsphereStructure(m); 
+addCHayterMSAStructure(m); 
+addCHollowCylinderModel(m); 
+addCLamellarModel(m); 
+addCLamellarFFHGModel(m); 
+addCLamellarPCrystalModel(m); 
+addCLamellarPSModel(m); 
+addCLamellarPSHGModel(m); 
 addCLinearPearlsModel(m); 
+addCLogNormal(m); 
+addCLorentzian(m); 
+addCMassFractalModel(m); 
+addCMassSurfaceFractal(m); 
+addCMultiShellModel(m); 
+addCOnionModel(m); 
+addCParallelepipedModel(m); 
+addCPearlNecklaceModel(m); 
+addCPoly_GaussCoil(m); 
+addCPringlesModel(m); 
 addCRaspBerryModel(m); 
-addCCore2ndMomentModel(m); 
+addCReflModel(m); 
+addCReflAdvModel(m); 
+addCRPAModel(m); 
+addCSCCrystalModel(m); 
+addCSchulz(m); 
+addCSLDCalFunc(m); 
+addCSphereModel(m); 
+addCSphereSLDModel(m); 
+addCCoreShellEllipsoidModel(m); 
+addCSquareWellStructure(m); 
 addCStackedDisksModel(m); 
-addCCoreShellCylinderModel(m); 
-addCReflModel(m); 
-addCSphereSLDModel(m); 
-addCFractalModel(m); 
-addCLogNormal(m); 
-addCPringlesModel(m); 
-addCCappedCylinderModel(m); 
-addCLorentzian(m); 
-addCBCCrystalModel(m); 
-addCPearlNecklaceModel(m); 
-addCSCCrystalModel(m); 
-addCGaussian(m); 
-addCLamellarModel(m); 
-addCLamellarPCrystalModel(m); 
-addCMassFractalModel(m); 
-addCPoly_GaussCoil(m); 
+addCStarPolymer(m); 
+addCStickyHSStructure(m); 
+addCSurfaceFractalModel(m); 
 addCTeubnerStreyModel(m); 
-addCOnionModel(m); 
-addCHollowCylinderModel(m); 
 addCTriaxialEllipsoidModel(m); 
-addCEllipticalCylinderModel(m); 
-addCSchulz(m); 
-addCLamellarPSHGModel(m); 
-addCDABModel(m); 
-addCStarPolymer(m); 
-addCFuzzySphereModel(m); 
-addCParallelepipedModel(m); 
-addCMassSurfaceFractal(m); 
+addCTwoYukawaModel(m); 
 addCVesicleModel(m); 
-addCGelFitModel(m); 
-addCCoreShellEllipsoidModel(m); 
-addCRPAModel(m); 
-addCHayterMSAStructure(m); 
-addCCSParallelepipedModel(m); 
-addCFractalO_Z(m); 
-addCMultiShellModel(m); 
-addCLamellarPSModel(m); 
-addCEllipsoidModel(m); 
-addCTwoYukawaModel(m); 
-addCDiamEllipFunc(m); 
-addCHardsphereStructure(m); 
-addCLamellarFFHGModel(m); 
-addCCoreShellBicelleModel(m); 
-addCFCCrystalModel(m); 
-addCFlexibleCylinderModel(m); 
-addCSurfaceFractalModel(m); 
-addCDiamCylFunc(m); 
-addCCoreFourShellModel(m); 
-addCStickyHSStructure(m); 
-addCReflAdvModel(m); 
-addCSphereModel(m); 
-addCFlexCylEllipXModel(m); 
-addCSquareWellStructure(m); 
-addCSLDCalFunc(m); 
-addCCoreShellModel(m); 
-addCBarBellModel(m); 
-addCBinaryHSModel(m); 
-addCCylinderModel(m); 
 addDisperser(m); 
 
Index: src/sans/models/c_extension/python_wrapper/generated/CBCCrystalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CBCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CBCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,657 @@
+/**
+	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
+ */
+
+/** CBCCrystalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\bcc.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 "bcc.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CBCCrystalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    BCCrystalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CBCCrystalModel;
+
+
+static void
+CBCCrystalModel_dealloc(CBCCrystalModel* 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 *
+CBCCrystalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CBCCrystalModel *self;
+    
+    self = (CBCCrystalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CBCCrystalModel_init(CBCCrystalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new BCCrystalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"dnn",Py_BuildValue("d",220.000000000000));
+        PyDict_SetItemString(self->params,"sldSph",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"d_factor",Py_BuildValue("d",0.060000000000));
+        PyDict_SetItemString(self->params,"psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->phi.dispersion->accept_as_source(visitor, self->model->phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->psi.dispersion->accept_as_source(visitor, self->model->psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "psi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->theta.dispersion->accept_as_source(visitor, self->model->theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CBCCrystalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CBCCrystalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CBCCrystalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CBCCrystalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CBCCrystalModel_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(BCCrystalModel* 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;
+	}
+#pragma omp parallel for
+	 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( BCCrystalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CBCCrystalModelError, 
+                   "CBCCrystalModel.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(CBCCrystalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBCCrystalModelError, 
+	    	"CBCCrystalModel.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(CBCCrystalModelError, 
+                   "CBCCrystalModel.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(CBCCrystalModelError, 
+	    		"CBCCrystalModel.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(CBCCrystalModelError, 
+                   "CBCCrystalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CBCCrystalModelError, 
+                   "CBCCrystalModel.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(CBCCrystalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBCCrystalModelError, 
+	    	"CBCCrystalModel.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(CBCCrystalModelError, 
+	    		"CBCCrystalModel.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 = CBCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CBCCrystalModel_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 = CBCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CBCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CBCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CBCCrystalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBCCrystalModelError, 
+	    	"CBCCrystalModel.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(CBCCrystalModelError, 
+	    		"CBCCrystalModel.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 = CBCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CBCCrystalModel_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 = CBCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CBCCrystalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CBCCrystalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CBCCrystalModelError,
+	    	"CBCCrystalModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "phi")) {
+        self->model->phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "psi")) {
+        self->model->psi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "theta")) {
+        self->model->theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CBCCrystalModelError,
+	    	"CBCCrystalModel.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 CBCCrystalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CBCCrystalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CBCCrystalModel",             /*tp_name*/
+    sizeof(CBCCrystalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CBCCrystalModel_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*/
+    "CBCCrystalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CBCCrystalModel_methods,             /* tp_methods */
+    CBCCrystalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CBCCrystalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CBCCrystalModel_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 addCBCCrystalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CBCCrystalModelType) < 0)
+        return;
+
+    Py_INCREF(&CBCCrystalModelType);
+    PyModule_AddObject(module, "CBCCrystalModel", (PyObject *)&CBCCrystalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CBCCrystalModel.error";
+    CBCCrystalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CBCCrystalModelError", CBCCrystalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CBarBellModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CBarBellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CBarBellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,666 @@
+/**
+	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
+ */
+
+/** CBarBellModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\barbell.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 "barbell.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CBarBellModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    BarBellModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CBarBellModel;
+
+
+static void
+CBarBellModel_dealloc(CBarBellModel* 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 *
+CBarBellModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CBarBellModel *self;
+    
+    self = (CBarBellModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CBarBellModel_init(CBarBellModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new BarBellModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_barbell",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"len_bar",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"rad_bell",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"rad_bar",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_bar.dispersion->accept_as_source(visitor, self->model->rad_bar.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_bar", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->len_bar.dispersion->accept_as_source(visitor, self->model->len_bar.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "len_bar", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->rad_bell.dispersion->accept_as_source(visitor, self->model->rad_bell.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_bell", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->phi.dispersion->accept_as_source(visitor, self->model->phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->theta.dispersion->accept_as_source(visitor, self->model->theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CBarBellModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CBarBellModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CBarBellModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CBarBellModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CBarBellModel_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(BarBellModel* 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;
+	}
+#pragma omp parallel for
+	 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( BarBellModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CBarBellModelError, 
+                   "CBarBellModel.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(CBarBellModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_barbell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_barbell") );
+    self->model->len_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_bar") );
+    self->model->rad_bell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bell") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bar") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bar");
+    self->model->rad_bar.dispersion->accept_as_destination(visitor, self->model->rad_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_bar");
+    self->model->len_bar.dispersion->accept_as_destination(visitor, self->model->len_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bell");
+    self->model->rad_bell.dispersion->accept_as_destination(visitor, self->model->rad_bell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBarBellModelError, 
+	    	"CBarBellModel.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(CBarBellModelError, 
+                   "CBarBellModel.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(CBarBellModelError, 
+	    		"CBarBellModel.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(CBarBellModelError, 
+                   "CBarBellModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CBarBellModelError, 
+                   "CBarBellModel.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(CBarBellModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_barbell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_barbell") );
+    self->model->len_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_bar") );
+    self->model->rad_bell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bell") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bar") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bar");
+    self->model->rad_bar.dispersion->accept_as_destination(visitor, self->model->rad_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_bar");
+    self->model->len_bar.dispersion->accept_as_destination(visitor, self->model->len_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bell");
+    self->model->rad_bell.dispersion->accept_as_destination(visitor, self->model->rad_bell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBarBellModelError, 
+	    	"CBarBellModel.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(CBarBellModelError, 
+	    		"CBarBellModel.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 = CBarBellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CBarBellModel_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 = CBarBellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CBarBellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_barbell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_barbell") );
+    self->model->len_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_bar") );
+    self->model->rad_bell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bell") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bar") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bar");
+    self->model->rad_bar.dispersion->accept_as_destination(visitor, self->model->rad_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_bar");
+    self->model->len_bar.dispersion->accept_as_destination(visitor, self->model->len_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bell");
+    self->model->rad_bell.dispersion->accept_as_destination(visitor, self->model->rad_bell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CBarBellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_barbell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_barbell") );
+    self->model->len_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_bar") );
+    self->model->rad_bell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bell") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bar") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bar");
+    self->model->rad_bar.dispersion->accept_as_destination(visitor, self->model->rad_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_bar");
+    self->model->len_bar.dispersion->accept_as_destination(visitor, self->model->len_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bell");
+    self->model->rad_bell.dispersion->accept_as_destination(visitor, self->model->rad_bell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CBarBellModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_barbell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_barbell") );
+    self->model->len_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_bar") );
+    self->model->rad_bell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bell") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_bar = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_bar") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bar");
+    self->model->rad_bar.dispersion->accept_as_destination(visitor, self->model->rad_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_bar");
+    self->model->len_bar.dispersion->accept_as_destination(visitor, self->model->len_bar.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_bell");
+    self->model->rad_bell.dispersion->accept_as_destination(visitor, self->model->rad_bell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CBarBellModelError, 
+	    	"CBarBellModel.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(CBarBellModelError, 
+	    		"CBarBellModel.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 = CBarBellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CBarBellModel_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 = CBarBellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CBarBellModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CBarBellModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CBarBellModelError,
+	    	"CBarBellModel.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_bar")) {
+        self->model->rad_bar.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "len_bar")) {
+        self->model->len_bar.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "rad_bell")) {
+        self->model->rad_bell.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "phi")) {
+        self->model->phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "theta")) {
+        self->model->theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CBarBellModelError,
+	    	"CBarBellModel.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 CBarBellModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CBarBellModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CBarBellModel",             /*tp_name*/
+    sizeof(CBarBellModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CBarBellModel_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*/
+    "CBarBellModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CBarBellModel_methods,             /* tp_methods */
+    CBarBellModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CBarBellModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CBarBellModel_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 addCBarBellModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CBarBellModelType) < 0)
+        return;
+
+    Py_INCREF(&CBarBellModelType);
+    PyModule_AddObject(module, "CBarBellModel", (PyObject *)&CBarBellModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CBarBellModel.error";
+    CBarBellModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CBarBellModelError", CBarBellModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CBinaryHSModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CBinaryHSModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CBinaryHSModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,615 @@
+/**
+	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
+ */
+
+/** CBinaryHSModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\binaryHS.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 "binaryHS.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CBinaryHSModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    BinaryHSModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CBinaryHSModel;
+
+
+static void
+CBinaryHSModel_dealloc(CBinaryHSModel* 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 *
+CBinaryHSModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CBinaryHSModel *self;
+    
+    self = (CBinaryHSModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CBinaryHSModel_init(CBinaryHSModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new BinaryHSModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"vol_frac_ls",Py_BuildValue("d",0.100000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"vol_frac_ss",Py_BuildValue("d",0.200000000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000006360000));
+        PyDict_SetItemString(self->params,"ls_sld",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"ss_sld",Py_BuildValue("d",0.000000500000));
+        PyDict_SetItemString(self->params,"s_radius",Py_BuildValue("d",25.000000000000));
+        PyDict_SetItemString(self->params,"l_radius",Py_BuildValue("d",100.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->l_radius.dispersion->accept_as_source(visitor, self->model->l_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "l_radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->s_radius.dispersion->accept_as_source(visitor, self->model->s_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "s_radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CBinaryHSModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CBinaryHSModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CBinaryHSModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CBinaryHSModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CBinaryHSModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(BinaryHSModel* 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;
+	}
+#pragma omp parallel for
+	 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( BinaryHSModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CBinaryHSModelError, 
+                   "CBinaryHSModel.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(CBinaryHSModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model->ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model->s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model->l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "l_radius");
+    self->model->l_radius.dispersion->accept_as_destination(visitor, self->model->l_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_radius");
+    self->model->s_radius.dispersion->accept_as_destination(visitor, self->model->s_radius.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(CBinaryHSModelError, 
+	    	"CBinaryHSModel.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(CBinaryHSModelError, 
+                   "CBinaryHSModel.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(CBinaryHSModelError, 
+	    		"CBinaryHSModel.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(CBinaryHSModelError, 
+                   "CBinaryHSModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CBinaryHSModelError, 
+                   "CBinaryHSModel.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(CBinaryHSModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model->ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model->s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model->l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "l_radius");
+    self->model->l_radius.dispersion->accept_as_destination(visitor, self->model->l_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_radius");
+    self->model->s_radius.dispersion->accept_as_destination(visitor, self->model->s_radius.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(CBinaryHSModelError, 
+	    	"CBinaryHSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSModelError, 
+	    		"CBinaryHSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CBinaryHSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CBinaryHSModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model->ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model->s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model->l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "l_radius");
+    self->model->l_radius.dispersion->accept_as_destination(visitor, self->model->l_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_radius");
+    self->model->s_radius.dispersion->accept_as_destination(visitor, self->model->s_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CBinaryHSModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model->ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model->s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model->l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "l_radius");
+    self->model->l_radius.dispersion->accept_as_destination(visitor, self->model->l_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_radius");
+    self->model->s_radius.dispersion->accept_as_destination(visitor, self->model->s_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CBinaryHSModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->vol_frac_ls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ls") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->vol_frac_ss = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vol_frac_ss") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->ls_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ls_sld") );
+    self->model->ss_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ss_sld") );
+    self->model->s_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_radius") );
+    self->model->l_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "l_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "l_radius");
+    self->model->l_radius.dispersion->accept_as_destination(visitor, self->model->l_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_radius");
+    self->model->s_radius.dispersion->accept_as_destination(visitor, self->model->s_radius.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(CBinaryHSModelError, 
+	    	"CBinaryHSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CBinaryHSModelError, 
+	    		"CBinaryHSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CBinaryHSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CBinaryHSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CBinaryHSModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CBinaryHSModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CBinaryHSModelError,
+	    	"CBinaryHSModel.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, "l_radius")) {
+        self->model->l_radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "s_radius")) {
+        self->model->s_radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CBinaryHSModelError,
+	    	"CBinaryHSModel.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 CBinaryHSModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CBinaryHSModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CBinaryHSModel",             /*tp_name*/
+    sizeof(CBinaryHSModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CBinaryHSModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CBinaryHSModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CBinaryHSModel_methods,             /* tp_methods */
+    CBinaryHSModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CBinaryHSModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CBinaryHSModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCBinaryHSModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CBinaryHSModelType) < 0)
+        return;
+
+    Py_INCREF(&CBinaryHSModelType);
+    PyModule_AddObject(module, "CBinaryHSModel", (PyObject *)&CBinaryHSModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CBinaryHSModel.error";
+    CBinaryHSModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CBinaryHSModelError", CBinaryHSModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCSParallelepipedModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCSParallelepipedModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCSParallelepipedModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,723 @@
+/**
+	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
+ */
+
+/** CCSParallelepipedModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\csparallelepiped.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 "csparallelepiped.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCSParallelepipedModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CSParallelepipedModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCSParallelepipedModel;
+
+
+static void
+CCSParallelepipedModel_dealloc(CCSParallelepipedModel* 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 *
+CCSParallelepipedModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCSParallelepipedModel *self;
+    
+    self = (CCSParallelepipedModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCSParallelepipedModel_init(CCSParallelepipedModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CSParallelepipedModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"sld_rimB",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_rimC",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.060000000000));
+        PyDict_SetItemString(self->params,"parallel_psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"midB",Py_BuildValue("d",75.000000000000));
+        PyDict_SetItemString(self->params,"parallel_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"parallel_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_pcore",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"sld_rimA",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"shortA",Py_BuildValue("d",35.000000000000));
+        PyDict_SetItemString(self->params,"rimB",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"rimC",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"longC",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006000000));
+        PyDict_SetItemString(self->params,"rimA",Py_BuildValue("d",10.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->shortA.dispersion->accept_as_source(visitor, self->model->shortA.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "shortA", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->midB.dispersion->accept_as_source(visitor, self->model->midB.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "midB", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->longC.dispersion->accept_as_source(visitor, self->model->longC.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "longC", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_phi.dispersion->accept_as_source(visitor, self->model->parallel_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_psi.dispersion->accept_as_source(visitor, self->model->parallel_psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_psi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_theta.dispersion->accept_as_source(visitor, self->model->parallel_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCSParallelepipedModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCSParallelepipedModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCSParallelepipedModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCSParallelepipedModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCSParallelepipedModel_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(CSParallelepipedModel* 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;
+	}
+#pragma omp parallel for
+	 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( CSParallelepipedModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCSParallelepipedModelError, 
+                   "CCSParallelepipedModel.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(CCSParallelepipedModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimB") );
+    self->model->sld_rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimC") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->midB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "midB") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->sld_pcore = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pcore") );
+    self->model->sld_rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimA") );
+    self->model->shortA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shortA") );
+    self->model->rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimB") );
+    self->model->rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimC") );
+    self->model->longC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longC") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimA") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "shortA");
+    self->model->shortA.dispersion->accept_as_destination(visitor, self->model->shortA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "midB");
+    self->model->midB.dispersion->accept_as_destination(visitor, self->model->midB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "longC");
+    self->model->longC.dispersion->accept_as_destination(visitor, self->model->longC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CCSParallelepipedModelError, 
+	    	"CCSParallelepipedModel.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(CCSParallelepipedModelError, 
+                   "CCSParallelepipedModel.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(CCSParallelepipedModelError, 
+	    		"CCSParallelepipedModel.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(CCSParallelepipedModelError, 
+                   "CCSParallelepipedModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCSParallelepipedModelError, 
+                   "CCSParallelepipedModel.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(CCSParallelepipedModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimB") );
+    self->model->sld_rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimC") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->midB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "midB") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->sld_pcore = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pcore") );
+    self->model->sld_rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimA") );
+    self->model->shortA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shortA") );
+    self->model->rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimB") );
+    self->model->rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimC") );
+    self->model->longC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longC") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimA") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "shortA");
+    self->model->shortA.dispersion->accept_as_destination(visitor, self->model->shortA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "midB");
+    self->model->midB.dispersion->accept_as_destination(visitor, self->model->midB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "longC");
+    self->model->longC.dispersion->accept_as_destination(visitor, self->model->longC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CCSParallelepipedModelError, 
+	    	"CCSParallelepipedModel.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(CCSParallelepipedModelError, 
+	    		"CCSParallelepipedModel.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 = CCSParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCSParallelepipedModel_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 = CCSParallelepipedModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCSParallelepipedModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimB") );
+    self->model->sld_rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimC") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->midB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "midB") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->sld_pcore = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pcore") );
+    self->model->sld_rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimA") );
+    self->model->shortA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shortA") );
+    self->model->rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimB") );
+    self->model->rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimC") );
+    self->model->longC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longC") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimA") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "shortA");
+    self->model->shortA.dispersion->accept_as_destination(visitor, self->model->shortA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "midB");
+    self->model->midB.dispersion->accept_as_destination(visitor, self->model->midB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "longC");
+    self->model->longC.dispersion->accept_as_destination(visitor, self->model->longC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCSParallelepipedModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimB") );
+    self->model->sld_rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimC") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->midB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "midB") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->sld_pcore = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pcore") );
+    self->model->sld_rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimA") );
+    self->model->shortA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shortA") );
+    self->model->rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimB") );
+    self->model->rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimC") );
+    self->model->longC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longC") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimA") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "shortA");
+    self->model->shortA.dispersion->accept_as_destination(visitor, self->model->shortA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "midB");
+    self->model->midB.dispersion->accept_as_destination(visitor, self->model->midB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "longC");
+    self->model->longC.dispersion->accept_as_destination(visitor, self->model->longC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCSParallelepipedModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimB") );
+    self->model->sld_rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimC") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->midB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "midB") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->sld_pcore = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pcore") );
+    self->model->sld_rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_rimA") );
+    self->model->shortA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shortA") );
+    self->model->rimB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimB") );
+    self->model->rimC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimC") );
+    self->model->longC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "longC") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rimA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rimA") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "shortA");
+    self->model->shortA.dispersion->accept_as_destination(visitor, self->model->shortA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "midB");
+    self->model->midB.dispersion->accept_as_destination(visitor, self->model->midB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "longC");
+    self->model->longC.dispersion->accept_as_destination(visitor, self->model->longC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CCSParallelepipedModelError, 
+	    	"CCSParallelepipedModel.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(CCSParallelepipedModelError, 
+	    		"CCSParallelepipedModel.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 = CCSParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCSParallelepipedModel_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 = CCSParallelepipedModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCSParallelepipedModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCSParallelepipedModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCSParallelepipedModelError,
+	    	"CCSParallelepipedModel.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, "shortA")) {
+        self->model->shortA.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "midB")) {
+        self->model->midB.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "longC")) {
+        self->model->longC.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_phi")) {
+        self->model->parallel_phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_psi")) {
+        self->model->parallel_psi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_theta")) {
+        self->model->parallel_theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCSParallelepipedModelError,
+	    	"CCSParallelepipedModel.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 CCSParallelepipedModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCSParallelepipedModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCSParallelepipedModel",             /*tp_name*/
+    sizeof(CCSParallelepipedModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCSParallelepipedModel_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*/
+    "CCSParallelepipedModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCSParallelepipedModel_methods,             /* tp_methods */
+    CCSParallelepipedModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCSParallelepipedModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCSParallelepipedModel_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 addCCSParallelepipedModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCSParallelepipedModelType) < 0)
+        return;
+
+    Py_INCREF(&CCSParallelepipedModelType);
+    PyModule_AddObject(module, "CCSParallelepipedModel", (PyObject *)&CCSParallelepipedModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCSParallelepipedModel.error";
+    CCSParallelepipedModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCSParallelepipedModelError", CCSParallelepipedModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCappedCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCappedCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCappedCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,666 @@
+/**
+	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
+ */
+
+/** CCappedCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\capcyl.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 "capcyl.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCappedCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CappedCylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCappedCylinderModel;
+
+
+static void
+CCappedCylinderModel_dealloc(CCappedCylinderModel* 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 *
+CCappedCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCappedCylinderModel *self;
+    
+    self = (CCappedCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCappedCylinderModel_init(CCappedCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CappedCylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"len_cyl",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"sld_capcyl",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"rad_cap",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"rad_cyl",Py_BuildValue("d",20.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_cyl.dispersion->accept_as_source(visitor, self->model->rad_cyl.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_cyl", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->len_cyl.dispersion->accept_as_source(visitor, self->model->len_cyl.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "len_cyl", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->rad_cap.dispersion->accept_as_source(visitor, self->model->rad_cap.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_cap", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->phi.dispersion->accept_as_source(visitor, self->model->phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->theta.dispersion->accept_as_source(visitor, self->model->theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCappedCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCappedCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCappedCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCappedCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCappedCylinderModel_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(CappedCylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( CappedCylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCappedCylinderModelError, 
+                   "CCappedCylinderModel.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(CCappedCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->len_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_cyl") );
+    self->model->sld_capcyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_capcyl") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_cap = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cap") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rad_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cyl") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cyl");
+    self->model->rad_cyl.dispersion->accept_as_destination(visitor, self->model->rad_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_cyl");
+    self->model->len_cyl.dispersion->accept_as_destination(visitor, self->model->len_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cap");
+    self->model->rad_cap.dispersion->accept_as_destination(visitor, self->model->rad_cap.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CCappedCylinderModelError, 
+	    	"CCappedCylinderModel.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(CCappedCylinderModelError, 
+                   "CCappedCylinderModel.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(CCappedCylinderModelError, 
+	    		"CCappedCylinderModel.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(CCappedCylinderModelError, 
+                   "CCappedCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCappedCylinderModelError, 
+                   "CCappedCylinderModel.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(CCappedCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->len_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_cyl") );
+    self->model->sld_capcyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_capcyl") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_cap = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cap") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rad_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cyl") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cyl");
+    self->model->rad_cyl.dispersion->accept_as_destination(visitor, self->model->rad_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_cyl");
+    self->model->len_cyl.dispersion->accept_as_destination(visitor, self->model->len_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cap");
+    self->model->rad_cap.dispersion->accept_as_destination(visitor, self->model->rad_cap.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CCappedCylinderModelError, 
+	    	"CCappedCylinderModel.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(CCappedCylinderModelError, 
+	    		"CCappedCylinderModel.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 = CCappedCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCappedCylinderModel_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 = CCappedCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCappedCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->len_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_cyl") );
+    self->model->sld_capcyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_capcyl") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_cap = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cap") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rad_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cyl") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cyl");
+    self->model->rad_cyl.dispersion->accept_as_destination(visitor, self->model->rad_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_cyl");
+    self->model->len_cyl.dispersion->accept_as_destination(visitor, self->model->len_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cap");
+    self->model->rad_cap.dispersion->accept_as_destination(visitor, self->model->rad_cap.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCappedCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->len_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_cyl") );
+    self->model->sld_capcyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_capcyl") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_cap = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cap") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rad_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cyl") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cyl");
+    self->model->rad_cyl.dispersion->accept_as_destination(visitor, self->model->rad_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_cyl");
+    self->model->len_cyl.dispersion->accept_as_destination(visitor, self->model->len_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cap");
+    self->model->rad_cap.dispersion->accept_as_destination(visitor, self->model->rad_cap.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCappedCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->len_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "len_cyl") );
+    self->model->sld_capcyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_capcyl") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->rad_cap = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cap") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->rad_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_cyl") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cyl");
+    self->model->rad_cyl.dispersion->accept_as_destination(visitor, self->model->rad_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "len_cyl");
+    self->model->len_cyl.dispersion->accept_as_destination(visitor, self->model->len_cyl.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_cap");
+    self->model->rad_cap.dispersion->accept_as_destination(visitor, self->model->rad_cap.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CCappedCylinderModelError, 
+	    	"CCappedCylinderModel.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(CCappedCylinderModelError, 
+	    		"CCappedCylinderModel.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 = CCappedCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCappedCylinderModel_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 = CCappedCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCappedCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCappedCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCappedCylinderModelError,
+	    	"CCappedCylinderModel.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_cyl")) {
+        self->model->rad_cyl.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "len_cyl")) {
+        self->model->len_cyl.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "rad_cap")) {
+        self->model->rad_cap.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "phi")) {
+        self->model->phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "theta")) {
+        self->model->theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCappedCylinderModelError,
+	    	"CCappedCylinderModel.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 CCappedCylinderModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCappedCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCappedCylinderModel",             /*tp_name*/
+    sizeof(CCappedCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCappedCylinderModel_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*/
+    "CCappedCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCappedCylinderModel_methods,             /* tp_methods */
+    CCappedCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCappedCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCappedCylinderModel_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 addCCappedCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCappedCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CCappedCylinderModelType);
+    PyModule_AddObject(module, "CCappedCylinderModel", (PyObject *)&CCappedCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCappedCylinderModel.error";
+    CCappedCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCappedCylinderModelError", CCappedCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCore2ndMomentModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCore2ndMomentModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCore2ndMomentModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,606 @@
+/**
+	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
+ */
+
+/** CCore2ndMomentModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\coresecondmoment.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 "coresecondmoment.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCore2ndMomentModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Core2ndMomentModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCore2ndMomentModel;
+
+
+static void
+CCore2ndMomentModel_dealloc(CCore2ndMomentModel* 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 *
+CCore2ndMomentModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCore2ndMomentModel *self;
+    
+    self = (CCore2ndMomentModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCore2ndMomentModel_init(CCore2ndMomentModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new Core2ndMomentModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"second_moment",Py_BuildValue("d",23.000000000000));
+        PyDict_SetItemString(self->params,"density_poly",Py_BuildValue("d",0.700000000000));
+        PyDict_SetItemString(self->params,"ads_amount",Py_BuildValue("d",1.900000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"volf_cores",Py_BuildValue("d",0.140000000000));
+        PyDict_SetItemString(self->params,"radius_core",Py_BuildValue("d",500.000000000000));
+        PyDict_SetItemString(self->params,"sld_poly",Py_BuildValue("d",0.000001500000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius_core.dispersion->accept_as_source(visitor, self->model->radius_core.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_core", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCore2ndMomentModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCore2ndMomentModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCore2ndMomentModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCore2ndMomentModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCore2ndMomentModel_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(Core2ndMomentModel* 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;
+	}
+#pragma omp parallel for
+	 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( Core2ndMomentModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCore2ndMomentModelError, 
+                   "CCore2ndMomentModel.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(CCore2ndMomentModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->second_moment = PyFloat_AsDouble( PyDict_GetItemString(self->params, "second_moment") );
+    self->model->density_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "density_poly") );
+    self->model->ads_amount = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ads_amount") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->volf_cores = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_cores") );
+    self->model->radius_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_core") );
+    self->model->sld_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_poly") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_core");
+    self->model->radius_core.dispersion->accept_as_destination(visitor, self->model->radius_core.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(CCore2ndMomentModelError, 
+	    	"CCore2ndMomentModel.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(CCore2ndMomentModelError, 
+                   "CCore2ndMomentModel.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(CCore2ndMomentModelError, 
+	    		"CCore2ndMomentModel.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(CCore2ndMomentModelError, 
+                   "CCore2ndMomentModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCore2ndMomentModelError, 
+                   "CCore2ndMomentModel.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(CCore2ndMomentModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->second_moment = PyFloat_AsDouble( PyDict_GetItemString(self->params, "second_moment") );
+    self->model->density_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "density_poly") );
+    self->model->ads_amount = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ads_amount") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->volf_cores = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_cores") );
+    self->model->radius_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_core") );
+    self->model->sld_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_poly") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_core");
+    self->model->radius_core.dispersion->accept_as_destination(visitor, self->model->radius_core.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(CCore2ndMomentModelError, 
+	    	"CCore2ndMomentModel.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(CCore2ndMomentModelError, 
+	    		"CCore2ndMomentModel.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 = CCore2ndMomentModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCore2ndMomentModel_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 = CCore2ndMomentModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCore2ndMomentModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->second_moment = PyFloat_AsDouble( PyDict_GetItemString(self->params, "second_moment") );
+    self->model->density_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "density_poly") );
+    self->model->ads_amount = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ads_amount") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->volf_cores = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_cores") );
+    self->model->radius_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_core") );
+    self->model->sld_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_poly") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_core");
+    self->model->radius_core.dispersion->accept_as_destination(visitor, self->model->radius_core.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCore2ndMomentModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->second_moment = PyFloat_AsDouble( PyDict_GetItemString(self->params, "second_moment") );
+    self->model->density_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "density_poly") );
+    self->model->ads_amount = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ads_amount") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->volf_cores = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_cores") );
+    self->model->radius_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_core") );
+    self->model->sld_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_poly") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_core");
+    self->model->radius_core.dispersion->accept_as_destination(visitor, self->model->radius_core.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCore2ndMomentModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->second_moment = PyFloat_AsDouble( PyDict_GetItemString(self->params, "second_moment") );
+    self->model->density_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "density_poly") );
+    self->model->ads_amount = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ads_amount") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->volf_cores = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_cores") );
+    self->model->radius_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_core") );
+    self->model->sld_poly = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_poly") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_core");
+    self->model->radius_core.dispersion->accept_as_destination(visitor, self->model->radius_core.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(CCore2ndMomentModelError, 
+	    	"CCore2ndMomentModel.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(CCore2ndMomentModelError, 
+	    		"CCore2ndMomentModel.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 = CCore2ndMomentModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCore2ndMomentModel_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 = CCore2ndMomentModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCore2ndMomentModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCore2ndMomentModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCore2ndMomentModelError,
+	    	"CCore2ndMomentModel.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, "radius_core")) {
+        self->model->radius_core.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCore2ndMomentModelError,
+	    	"CCore2ndMomentModel.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 CCore2ndMomentModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCore2ndMomentModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCore2ndMomentModel",             /*tp_name*/
+    sizeof(CCore2ndMomentModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCore2ndMomentModel_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*/
+    "CCore2ndMomentModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCore2ndMomentModel_methods,             /* tp_methods */
+    CCore2ndMomentModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCore2ndMomentModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCore2ndMomentModel_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 addCCore2ndMomentModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCore2ndMomentModelType) < 0)
+        return;
+
+    Py_INCREF(&CCore2ndMomentModelType);
+    PyModule_AddObject(module, "CCore2ndMomentModel", (PyObject *)&CCore2ndMomentModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCore2ndMomentModel.error";
+    CCore2ndMomentModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCore2ndMomentModelError", CCore2ndMomentModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCoreFourShellModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCoreFourShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCoreFourShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,816 @@
+/**
+	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
+ */
+
+/** CCoreFourShellModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\corefourshell.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 "corefourshell.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCoreFourShellModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CoreFourShellModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCoreFourShellModel;
+
+
+static void
+CCoreFourShellModel_dealloc(CCoreFourShellModel* 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 *
+CCoreFourShellModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreFourShellModel *self;
+    
+    self = (CCoreFourShellModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreFourShellModel_init(CCoreFourShellModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CoreFourShellModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"sld_core0",Py_BuildValue("d",0.000006400000));
+        PyDict_SetItemString(self->params,"Up_frac_i",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"Up_frac_f",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"rad_core0",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"sld_shell3",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"Up_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell3",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_core0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_core0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell4",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"sld_shell4",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_shell2",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"thick_shell1",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell2",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"sld_shell1",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"M_theta_core0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"M0_sld_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_shell3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_shell2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_shell1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006400000));
+        PyDict_SetItemString(self->params,"M_theta_shell4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_shell2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_shell3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_shell1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_shell4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_shell4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_shell3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_shell2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_shell1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_solv",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_core0.dispersion->accept_as_source(visitor, self->model->rad_core0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_core0", 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);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCoreFourShellModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCoreFourShellModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCoreFourShellModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCoreFourShellModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreFourShellModel_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(CoreFourShellModel* 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;
+	}
+#pragma omp parallel for
+	 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( CoreFourShellModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCoreFourShellModelError, 
+                   "CCoreFourShellModel.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(CCoreFourShellModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell3") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->M_phi_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core0") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core0") );
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell4") );
+    self->model->sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell2") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell1") );
+    self->model->M_theta_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core0") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell3") );
+    self->model->M_theta_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell2") );
+    self->model->M_theta_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell1") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->M_theta_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell4") );
+    self->model->M_phi_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell2") );
+    self->model->M_phi_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell3") );
+    self->model->M_phi_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell1") );
+    self->model->M_phi_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell4") );
+    self->model->M0_sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell4") );
+    self->model->M0_sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell3") );
+    self->model->M0_sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell2") );
+    self->model->M0_sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell1") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CCoreFourShellModelError, 
+	    	"CCoreFourShellModel.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(CCoreFourShellModelError, 
+                   "CCoreFourShellModel.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(CCoreFourShellModelError, 
+	    		"CCoreFourShellModel.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(CCoreFourShellModelError, 
+                   "CCoreFourShellModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCoreFourShellModelError, 
+                   "CCoreFourShellModel.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(CCoreFourShellModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell3") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->M_phi_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core0") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core0") );
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell4") );
+    self->model->sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell2") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell1") );
+    self->model->M_theta_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core0") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell3") );
+    self->model->M_theta_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell2") );
+    self->model->M_theta_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell1") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->M_theta_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell4") );
+    self->model->M_phi_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell2") );
+    self->model->M_phi_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell3") );
+    self->model->M_phi_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell1") );
+    self->model->M_phi_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell4") );
+    self->model->M0_sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell4") );
+    self->model->M0_sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell3") );
+    self->model->M0_sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell2") );
+    self->model->M0_sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell1") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CCoreFourShellModelError, 
+	    	"CCoreFourShellModel.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(CCoreFourShellModelError, 
+	    		"CCoreFourShellModel.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 = CCoreFourShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreFourShellModel_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 = CCoreFourShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCoreFourShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell3") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->M_phi_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core0") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core0") );
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell4") );
+    self->model->sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell2") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell1") );
+    self->model->M_theta_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core0") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell3") );
+    self->model->M_theta_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell2") );
+    self->model->M_theta_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell1") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->M_theta_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell4") );
+    self->model->M_phi_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell2") );
+    self->model->M_phi_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell3") );
+    self->model->M_phi_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell1") );
+    self->model->M_phi_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell4") );
+    self->model->M0_sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell4") );
+    self->model->M0_sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell3") );
+    self->model->M0_sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell2") );
+    self->model->M0_sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell1") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCoreFourShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell3") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->M_phi_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core0") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core0") );
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell4") );
+    self->model->sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell2") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell1") );
+    self->model->M_theta_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core0") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell3") );
+    self->model->M_theta_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell2") );
+    self->model->M_theta_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell1") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->M_theta_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell4") );
+    self->model->M_phi_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell2") );
+    self->model->M_phi_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell3") );
+    self->model->M_phi_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell1") );
+    self->model->M_phi_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell4") );
+    self->model->M0_sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell4") );
+    self->model->M0_sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell3") );
+    self->model->M0_sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell2") );
+    self->model->M0_sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell1") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreFourShellModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell3") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->M_phi_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core0") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core0") );
+    self->model->thick_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell4") );
+    self->model->sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell4") );
+    self->model->sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell2") );
+    self->model->thick_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell1") );
+    self->model->thick_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell2") );
+    self->model->sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell1") );
+    self->model->M_theta_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core0") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell3") );
+    self->model->M_theta_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell2") );
+    self->model->M_theta_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell1") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->M_theta_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell4") );
+    self->model->M_phi_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell2") );
+    self->model->M_phi_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell3") );
+    self->model->M_phi_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell1") );
+    self->model->M_phi_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell4") );
+    self->model->M0_sld_shell4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell4") );
+    self->model->M0_sld_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell3") );
+    self->model->M0_sld_shell2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell2") );
+    self->model->M0_sld_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell1") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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);
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CCoreFourShellModelError, 
+	    	"CCoreFourShellModel.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(CCoreFourShellModelError, 
+	    		"CCoreFourShellModel.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 = CCoreFourShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreFourShellModel_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 = CCoreFourShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreFourShellModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCoreFourShellModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCoreFourShellModelError,
+	    	"CCoreFourShellModel.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_core0")) {
+        self->model->rad_core0.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 {
+	    PyErr_SetString(CCoreFourShellModelError,
+	    	"CCoreFourShellModel.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 CCoreFourShellModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCoreFourShellModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreFourShellModel",             /*tp_name*/
+    sizeof(CCoreFourShellModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreFourShellModel_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*/
+    "CCoreFourShellModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreFourShellModel_methods,             /* tp_methods */
+    CCoreFourShellModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreFourShellModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreFourShellModel_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 addCCoreFourShellModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreFourShellModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreFourShellModelType);
+    PyModule_AddObject(module, "CCoreFourShellModel", (PyObject *)&CCoreFourShellModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCoreFourShellModel.error";
+    CCoreFourShellModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCoreFourShellModelError", CCoreFourShellModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCoreShellBicelleModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCoreShellBicelleModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCoreShellBicelleModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,699 @@
+/**
+	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
+ */
+
+/** CCoreShellBicelleModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\core_shell_bicelle.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 "core_shell_bicelle.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCoreShellBicelleModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CoreShellBicelleModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCoreShellBicelleModel;
+
+
+static void
+CCoreShellBicelleModel_dealloc(CCoreShellBicelleModel* 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 *
+CCoreShellBicelleModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreShellBicelleModel *self;
+    
+    self = (CCoreShellBicelleModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreShellBicelleModel_init(CCoreShellBicelleModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CoreShellBicelleModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"rim_sld",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"face_sld",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"face_thick",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",90.000000000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"rim_thick",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->rim_thick.dispersion->accept_as_source(visitor, self->model->rim_thick.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rim_thick", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->face_thick.dispersion->accept_as_source(visitor, self->model->face_thick.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "face_thick", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCoreShellBicelleModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCoreShellBicelleModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCoreShellBicelleModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCoreShellBicelleModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreShellBicelleModel_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(CoreShellBicelleModel* 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;
+	}
+#pragma omp parallel for
+	 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( CoreShellBicelleModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCoreShellBicelleModelError, 
+                   "CCoreShellBicelleModel.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(CCoreShellBicelleModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->rim_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->face_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_sld") );
+    self->model->face_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->rim_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_thick") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rim_thick");
+    self->model->rim_thick.dispersion->accept_as_destination(visitor, self->model->rim_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "face_thick");
+    self->model->face_thick.dispersion->accept_as_destination(visitor, self->model->face_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellBicelleModelError, 
+	    	"CCoreShellBicelleModel.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(CCoreShellBicelleModelError, 
+                   "CCoreShellBicelleModel.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(CCoreShellBicelleModelError, 
+	    		"CCoreShellBicelleModel.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(CCoreShellBicelleModelError, 
+                   "CCoreShellBicelleModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCoreShellBicelleModelError, 
+                   "CCoreShellBicelleModel.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(CCoreShellBicelleModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->rim_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->face_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_sld") );
+    self->model->face_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->rim_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_thick") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rim_thick");
+    self->model->rim_thick.dispersion->accept_as_destination(visitor, self->model->rim_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "face_thick");
+    self->model->face_thick.dispersion->accept_as_destination(visitor, self->model->face_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellBicelleModelError, 
+	    	"CCoreShellBicelleModel.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(CCoreShellBicelleModelError, 
+	    		"CCoreShellBicelleModel.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 = CCoreShellBicelleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreShellBicelleModel_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 = CCoreShellBicelleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCoreShellBicelleModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->rim_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->face_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_sld") );
+    self->model->face_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->rim_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_thick") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rim_thick");
+    self->model->rim_thick.dispersion->accept_as_destination(visitor, self->model->rim_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "face_thick");
+    self->model->face_thick.dispersion->accept_as_destination(visitor, self->model->face_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCoreShellBicelleModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->rim_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->face_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_sld") );
+    self->model->face_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->rim_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_thick") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rim_thick");
+    self->model->rim_thick.dispersion->accept_as_destination(visitor, self->model->rim_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "face_thick");
+    self->model->face_thick.dispersion->accept_as_destination(visitor, self->model->face_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreShellBicelleModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->rim_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->face_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_sld") );
+    self->model->face_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "face_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->rim_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rim_thick") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "rim_thick");
+    self->model->rim_thick.dispersion->accept_as_destination(visitor, self->model->rim_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "face_thick");
+    self->model->face_thick.dispersion->accept_as_destination(visitor, self->model->face_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellBicelleModelError, 
+	    	"CCoreShellBicelleModel.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(CCoreShellBicelleModelError, 
+	    		"CCoreShellBicelleModel.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 = CCoreShellBicelleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreShellBicelleModel_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 = CCoreShellBicelleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreShellBicelleModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCoreShellBicelleModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCoreShellBicelleModelError,
+	    	"CCoreShellBicelleModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "rim_thick")) {
+        self->model->rim_thick.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "face_thick")) {
+        self->model->face_thick.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCoreShellBicelleModelError,
+	    	"CCoreShellBicelleModel.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 CCoreShellBicelleModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCoreShellBicelleModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreShellBicelleModel",             /*tp_name*/
+    sizeof(CCoreShellBicelleModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreShellBicelleModel_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*/
+    "CCoreShellBicelleModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreShellBicelleModel_methods,             /* tp_methods */
+    CCoreShellBicelleModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreShellBicelleModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreShellBicelleModel_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 addCCoreShellBicelleModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreShellBicelleModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreShellBicelleModelType);
+    PyModule_AddObject(module, "CCoreShellBicelleModel", (PyObject *)&CCoreShellBicelleModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCoreShellBicelleModel.error";
+    CCoreShellBicelleModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCoreShellBicelleModelError", CCoreShellBicelleModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCoreShellCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCoreShellCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCoreShellCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,672 @@
+/**
+	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
+ */
+
+/** CCoreShellCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\core_shell_cylinder.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 "core_shell_cylinder.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCoreShellCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CoreShellCylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCoreShellCylinderModel;
+
+
+static void
+CCoreShellCylinderModel_dealloc(CCoreShellCylinderModel* 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 *
+CCoreShellCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreShellCylinderModel *self;
+    
+    self = (CCoreShellCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreShellCylinderModel_init(CCoreShellCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CoreShellCylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",90.000000000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000004000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thickness.dispersion->accept_as_source(visitor, self->model->thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thickness", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCoreShellCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCoreShellCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCoreShellCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCoreShellCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreShellCylinderModel_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(CoreShellCylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( CoreShellCylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCoreShellCylinderModelError, 
+                   "CCoreShellCylinderModel.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(CCoreShellCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellCylinderModelError, 
+	    	"CCoreShellCylinderModel.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(CCoreShellCylinderModelError, 
+                   "CCoreShellCylinderModel.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(CCoreShellCylinderModelError, 
+	    		"CCoreShellCylinderModel.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(CCoreShellCylinderModelError, 
+                   "CCoreShellCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCoreShellCylinderModelError, 
+                   "CCoreShellCylinderModel.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(CCoreShellCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellCylinderModelError, 
+	    	"CCoreShellCylinderModel.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(CCoreShellCylinderModelError, 
+	    		"CCoreShellCylinderModel.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 = CCoreShellCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreShellCylinderModel_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 = CCoreShellCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCoreShellCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCoreShellCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreShellCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CCoreShellCylinderModelError, 
+	    	"CCoreShellCylinderModel.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(CCoreShellCylinderModelError, 
+	    		"CCoreShellCylinderModel.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 = CCoreShellCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreShellCylinderModel_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 = CCoreShellCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreShellCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCoreShellCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCoreShellCylinderModelError,
+	    	"CCoreShellCylinderModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thickness")) {
+        self->model->thickness.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCoreShellCylinderModelError,
+	    	"CCoreShellCylinderModel.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 CCoreShellCylinderModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCoreShellCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreShellCylinderModel",             /*tp_name*/
+    sizeof(CCoreShellCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreShellCylinderModel_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*/
+    "CCoreShellCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreShellCylinderModel_methods,             /* tp_methods */
+    CCoreShellCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreShellCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreShellCylinderModel_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 addCCoreShellCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreShellCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreShellCylinderModelType);
+    PyModule_AddObject(module, "CCoreShellCylinderModel", (PyObject *)&CCoreShellCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCoreShellCylinderModel.error";
+    CCoreShellCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCoreShellCylinderModelError", CCoreShellCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCoreShellEllipsoidModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCoreShellEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCoreShellEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,693 @@
+/**
+	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
+ */
+
+/** CCoreShellEllipsoidModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\spheroid.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 "spheroid.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCoreShellEllipsoidModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CoreShellEllipsoidModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCoreShellEllipsoidModel;
+
+
+static void
+CCoreShellEllipsoidModel_dealloc(CCoreShellEllipsoidModel* 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 *
+CCoreShellEllipsoidModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreShellEllipsoidModel *self;
+    
+    self = (CCoreShellEllipsoidModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreShellEllipsoidModel_init(CCoreShellEllipsoidModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CoreShellEllipsoidModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_core",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"polar_shell",Py_BuildValue("d",30.000000000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"equat_shell",Py_BuildValue("d",250.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"equat_core",Py_BuildValue("d",200.000000000000));
+        PyDict_SetItemString(self->params,"polar_core",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"sld_shell",Py_BuildValue("d",0.000001000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->equat_core.dispersion->accept_as_source(visitor, self->model->equat_core.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "equat_core", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->polar_core.dispersion->accept_as_source(visitor, self->model->polar_core.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "polar_core", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->equat_shell.dispersion->accept_as_source(visitor, self->model->equat_shell.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "equat_shell", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->polar_shell.dispersion->accept_as_source(visitor, self->model->polar_shell.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "polar_shell", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCoreShellEllipsoidModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCoreShellEllipsoidModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCoreShellEllipsoidModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCoreShellEllipsoidModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreShellEllipsoidModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(CoreShellEllipsoidModel* 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;
+	}
+#pragma omp parallel for
+	 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( CoreShellEllipsoidModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCoreShellEllipsoidModelError, 
+                   "CCoreShellEllipsoidModel.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(CCoreShellEllipsoidModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model->polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model->sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_core");
+    self->model->equat_core.dispersion->accept_as_destination(visitor, self->model->equat_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_core");
+    self->model->polar_core.dispersion->accept_as_destination(visitor, self->model->polar_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_shell");
+    self->model->equat_shell.dispersion->accept_as_destination(visitor, self->model->equat_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_shell");
+    self->model->polar_shell.dispersion->accept_as_destination(visitor, self->model->polar_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.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(CCoreShellEllipsoidModelError, 
+	    	"CCoreShellEllipsoidModel.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(CCoreShellEllipsoidModelError, 
+                   "CCoreShellEllipsoidModel.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(CCoreShellEllipsoidModelError, 
+	    		"CCoreShellEllipsoidModel.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(CCoreShellEllipsoidModelError, 
+                   "CCoreShellEllipsoidModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCoreShellEllipsoidModelError, 
+                   "CCoreShellEllipsoidModel.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(CCoreShellEllipsoidModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model->polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model->sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_core");
+    self->model->equat_core.dispersion->accept_as_destination(visitor, self->model->equat_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_core");
+    self->model->polar_core.dispersion->accept_as_destination(visitor, self->model->polar_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_shell");
+    self->model->equat_shell.dispersion->accept_as_destination(visitor, self->model->equat_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_shell");
+    self->model->polar_shell.dispersion->accept_as_destination(visitor, self->model->polar_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.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(CCoreShellEllipsoidModelError, 
+	    	"CCoreShellEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    		"CCoreShellEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CCoreShellEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCoreShellEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model->polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model->sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_core");
+    self->model->equat_core.dispersion->accept_as_destination(visitor, self->model->equat_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_core");
+    self->model->polar_core.dispersion->accept_as_destination(visitor, self->model->polar_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_shell");
+    self->model->equat_shell.dispersion->accept_as_destination(visitor, self->model->equat_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_shell");
+    self->model->polar_shell.dispersion->accept_as_destination(visitor, self->model->polar_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCoreShellEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model->polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model->sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_core");
+    self->model->equat_core.dispersion->accept_as_destination(visitor, self->model->equat_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_core");
+    self->model->polar_core.dispersion->accept_as_destination(visitor, self->model->polar_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_shell");
+    self->model->equat_shell.dispersion->accept_as_destination(visitor, self->model->equat_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_shell");
+    self->model->polar_shell.dispersion->accept_as_destination(visitor, self->model->polar_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreShellEllipsoidModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->polar_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_shell") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->equat_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_shell") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->equat_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "equat_core") );
+    self->model->polar_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "polar_core") );
+    self->model->sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_shell") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_core");
+    self->model->equat_core.dispersion->accept_as_destination(visitor, self->model->equat_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_core");
+    self->model->polar_core.dispersion->accept_as_destination(visitor, self->model->polar_core.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "equat_shell");
+    self->model->equat_shell.dispersion->accept_as_destination(visitor, self->model->equat_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "polar_shell");
+    self->model->polar_shell.dispersion->accept_as_destination(visitor, self->model->polar_shell.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.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(CCoreShellEllipsoidModelError, 
+	    	"CCoreShellEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CCoreShellEllipsoidModelError, 
+	    		"CCoreShellEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreShellEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CCoreShellEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreShellEllipsoidModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCoreShellEllipsoidModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCoreShellEllipsoidModelError,
+	    	"CCoreShellEllipsoidModel.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, "equat_core")) {
+        self->model->equat_core.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "polar_core")) {
+        self->model->polar_core.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "equat_shell")) {
+        self->model->equat_shell.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "polar_shell")) {
+        self->model->polar_shell.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCoreShellEllipsoidModelError,
+	    	"CCoreShellEllipsoidModel.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 CCoreShellEllipsoidModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCoreShellEllipsoidModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreShellEllipsoidModel",             /*tp_name*/
+    sizeof(CCoreShellEllipsoidModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreShellEllipsoidModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CCoreShellEllipsoidModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreShellEllipsoidModel_methods,             /* tp_methods */
+    CCoreShellEllipsoidModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreShellEllipsoidModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreShellEllipsoidModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCCoreShellEllipsoidModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreShellEllipsoidModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreShellEllipsoidModelType);
+    PyModule_AddObject(module, "CCoreShellEllipsoidModel", (PyObject *)&CCoreShellEllipsoidModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCoreShellEllipsoidModel.error";
+    CCoreShellEllipsoidModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCoreShellEllipsoidModelError", CCoreShellEllipsoidModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCoreShellModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCoreShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCoreShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,681 @@
+/**
+	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
+ */
+
+/** CCoreShellModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\core_shell.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 "core_shell.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCoreShellModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CoreShellModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCoreShellModel;
+
+
+static void
+CCoreShellModel_dealloc(CCoreShellModel* 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 *
+CCoreShellModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCoreShellModel *self;
+    
+    self = (CCoreShellModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCoreShellModel_init(CCoreShellModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CoreShellModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"Up_frac_i",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"M_phi_shell",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Up_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"M_theta_core",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_shell",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_core",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Up_frac_f",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"M_theta_shell",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_core",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000002000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thickness.dispersion->accept_as_source(visitor, self->model->thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thickness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCoreShellModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCoreShellModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCoreShellModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCoreShellModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCoreShellModel_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(CoreShellModel* 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;
+	}
+#pragma omp parallel for
+	 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( CoreShellModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCoreShellModelError, 
+                   "CCoreShellModel.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(CCoreShellModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->M_phi_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->M_theta_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core") );
+    self->model->M0_sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_theta_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell") );
+    self->model->M_phi_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CCoreShellModelError, 
+	    	"CCoreShellModel.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(CCoreShellModelError, 
+                   "CCoreShellModel.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(CCoreShellModelError, 
+	    		"CCoreShellModel.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(CCoreShellModelError, 
+                   "CCoreShellModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCoreShellModelError, 
+                   "CCoreShellModel.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(CCoreShellModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->M_phi_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->M_theta_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core") );
+    self->model->M0_sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_theta_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell") );
+    self->model->M_phi_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CCoreShellModelError, 
+	    	"CCoreShellModel.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(CCoreShellModelError, 
+	    		"CCoreShellModel.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 = CCoreShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCoreShellModel_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 = CCoreShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCoreShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->M_phi_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->M_theta_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core") );
+    self->model->M0_sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_theta_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell") );
+    self->model->M_phi_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCoreShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->M_phi_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->M_theta_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core") );
+    self->model->M0_sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_theta_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell") );
+    self->model->M_phi_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCoreShellModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->M_phi_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_shell") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->M_theta_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_core") );
+    self->model->M0_sld_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_shell") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->M0_sld_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_core") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_theta_shell = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_shell") );
+    self->model->M_phi_core = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_core") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CCoreShellModelError, 
+	    	"CCoreShellModel.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(CCoreShellModelError, 
+	    		"CCoreShellModel.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 = CCoreShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCoreShellModel_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 = CCoreShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCoreShellModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCoreShellModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCoreShellModelError,
+	    	"CCoreShellModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thickness")) {
+        self->model->thickness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCoreShellModelError,
+	    	"CCoreShellModel.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 CCoreShellModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCoreShellModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCoreShellModel",             /*tp_name*/
+    sizeof(CCoreShellModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCoreShellModel_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*/
+    "CCoreShellModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCoreShellModel_methods,             /* tp_methods */
+    CCoreShellModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCoreShellModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCoreShellModel_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 addCCoreShellModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCoreShellModelType) < 0)
+        return;
+
+    Py_INCREF(&CCoreShellModelType);
+    PyModule_AddObject(module, "CCoreShellModel", (PyObject *)&CCoreShellModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCoreShellModel.error";
+    CCoreShellModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCoreShellModelError", CCoreShellModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,699 @@
+/**
+	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
+ */
+
+/** CCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\cylinder.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 "cylinder.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    CylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CCylinderModel;
+
+
+static void
+CCylinderModel_dealloc(CCylinderModel* 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 *
+CCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CCylinderModel *self;
+    
+    self = (CCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CCylinderModel_init(CCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new CylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"Up_frac_i",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"Up_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_cyl",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldCyl",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"M0_sld_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_cyl",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"cyl_theta",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_cyl",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Up_frac_f",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"cyl_phi",Py_BuildValue("d",60.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->cyl_theta.dispersion->accept_as_source(visitor, self->model->cyl_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "cyl_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->cyl_phi.dispersion->accept_as_source(visitor, self->model->cyl_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "cyl_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CCylinderModel_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(CylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( CylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CCylinderModelError, 
+                   "CCylinderModel.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(CCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M0_sld_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_cyl") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_cyl") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M_phi_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_cyl") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.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(CCylinderModelError, 
+	    	"CCylinderModel.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(CCylinderModelError, 
+                   "CCylinderModel.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(CCylinderModelError, 
+	    		"CCylinderModel.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(CCylinderModelError, 
+                   "CCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CCylinderModelError, 
+                   "CCylinderModel.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(CCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M0_sld_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_cyl") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_cyl") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M_phi_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_cyl") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.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(CCylinderModelError, 
+	    	"CCylinderModel.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(CCylinderModelError, 
+	    		"CCylinderModel.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 = CCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CCylinderModel_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 = CCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M0_sld_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_cyl") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_cyl") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M_phi_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_cyl") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M0_sld_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_cyl") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_cyl") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M_phi_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_cyl") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M0_sld_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_cyl") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->M_theta_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_cyl") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M_phi_cyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_cyl") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.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(CCylinderModelError, 
+	    	"CCylinderModel.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(CCylinderModelError, 
+	    		"CCylinderModel.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 = CCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CCylinderModel_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 = CCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CCylinderModelError,
+	    	"CCylinderModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "cyl_theta")) {
+        self->model->cyl_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "cyl_phi")) {
+        self->model->cyl_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CCylinderModelError,
+	    	"CCylinderModel.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 CCylinderModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CCylinderModel",             /*tp_name*/
+    sizeof(CCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CCylinderModel_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*/
+    "CCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CCylinderModel_methods,             /* tp_methods */
+    CCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CCylinderModel_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 addCCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CCylinderModelType);
+    PyModule_AddObject(module, "CCylinderModel", (PyObject *)&CCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CCylinderModel.error";
+    CCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CCylinderModelError", CCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CDABModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CDABModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CDABModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,600 @@
+/**
+	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
+ */
+
+/** CDABModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\dabmodel.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 "dabmodel.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CDABModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    DABModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CDABModel;
+
+
+static void
+CDABModel_dealloc(CDABModel* 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 *
+CDABModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CDABModel *self;
+    
+    self = (CDABModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CDABModel_init(CDABModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new DABModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->scale.dispersion->accept_as_source(visitor, self->model->scale.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "scale", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->background.dispersion->accept_as_source(visitor, self->model->background.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "background", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CDABModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CDABModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CDABModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CDABModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CDABModel_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(DABModel* 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;
+	}
+#pragma omp parallel for
+	 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( DABModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CDABModelError, 
+                   "CDABModel.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(CDABModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CDABModelError, 
+	    	"CDABModel.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(CDABModelError, 
+                   "CDABModel.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(CDABModelError, 
+	    		"CDABModel.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(CDABModelError, 
+                   "CDABModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CDABModelError, 
+                   "CDABModel.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(CDABModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CDABModelError, 
+	    	"CDABModel.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(CDABModelError, 
+	    		"CDABModel.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 = CDABModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CDABModel_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 = CDABModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CDABModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CDABModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CDABModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CDABModelError, 
+	    	"CDABModel.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(CDABModelError, 
+	    		"CDABModel.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 = CDABModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CDABModel_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 = CDABModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CDABModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CDABModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CDABModelError,
+	    	"CDABModel.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, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "scale")) {
+        self->model->scale.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "background")) {
+        self->model->background.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CDABModelError,
+	    	"CDABModel.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 CDABModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CDABModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CDABModel",             /*tp_name*/
+    sizeof(CDABModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CDABModel_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*/
+    "CDABModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CDABModel_methods,             /* tp_methods */
+    CDABModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CDABModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CDABModel_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 addCDABModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CDABModelType) < 0)
+        return;
+
+    Py_INCREF(&CDABModelType);
+    PyModule_AddObject(module, "CDABModel", (PyObject *)&CDABModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CDABModel.error";
+    CDABModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CDABModelError", CDABModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CDiamCylFunc.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CDiamCylFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CDiamCylFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,579 @@
+/**
+	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
+ */
+
+/** CDiamCylFunc
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\DiamCyl.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 "DiamCyl.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CDiamCylFuncError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    DiamCylFunc * model;
+    /// Log for unit testing
+    PyObject * log;
+} CDiamCylFunc;
+
+
+static void
+CDiamCylFunc_dealloc(CDiamCylFunc* 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 *
+CDiamCylFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CDiamCylFunc *self;
+    
+    self = (CDiamCylFunc *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CDiamCylFunc_init(CDiamCylFunc *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new DiamCylFunc();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CDiamCylFunc_members[] = {
+    {name_params, T_OBJECT, offsetof(CDiamCylFunc, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CDiamCylFunc, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CDiamCylFunc, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CDiamCylFunc_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(DiamCylFunc* 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;
+	}
+#pragma omp parallel for
+	 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( DiamCylFunc* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CDiamCylFuncError, 
+                   "CDiamCylFunc.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(CDiamCylFunc *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.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(CDiamCylFuncError, 
+	    	"CDiamCylFunc.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(CDiamCylFuncError, 
+                   "CDiamCylFunc.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(CDiamCylFuncError, 
+	    		"CDiamCylFunc.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(CDiamCylFuncError, 
+                   "CDiamCylFunc.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CDiamCylFuncError, 
+                   "CDiamCylFunc.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(CDiamCylFunc *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.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(CDiamCylFuncError, 
+	    	"CDiamCylFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamCylFuncError, 
+	    		"CDiamCylFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CDiamCylFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CDiamCylFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CDiamCylFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CDiamCylFunc *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.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(CDiamCylFuncError, 
+	    	"CDiamCylFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamCylFuncError, 
+	    		"CDiamCylFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CDiamCylFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CDiamCylFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CDiamCylFunc *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CDiamCylFunc *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CDiamCylFuncError,
+	    	"CDiamCylFunc.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CDiamCylFuncError,
+	    	"CDiamCylFunc.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 CDiamCylFunc_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CDiamCylFuncType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CDiamCylFunc",             /*tp_name*/
+    sizeof(CDiamCylFunc),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CDiamCylFunc_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CDiamCylFunc objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CDiamCylFunc_methods,             /* tp_methods */
+    CDiamCylFunc_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CDiamCylFunc_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CDiamCylFunc_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCDiamCylFunc(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CDiamCylFuncType) < 0)
+        return;
+
+    Py_INCREF(&CDiamCylFuncType);
+    PyModule_AddObject(module, "CDiamCylFunc", (PyObject *)&CDiamCylFuncType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CDiamCylFunc.error";
+    CDiamCylFuncError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CDiamCylFuncError", CDiamCylFuncError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CDiamEllipFunc.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CDiamEllipFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CDiamEllipFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,579 @@
+/**
+	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
+ */
+
+/** CDiamEllipFunc
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\DiamEllip.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 "DiamEllip.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CDiamEllipFuncError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    DiamEllipFunc * model;
+    /// Log for unit testing
+    PyObject * log;
+} CDiamEllipFunc;
+
+
+static void
+CDiamEllipFunc_dealloc(CDiamEllipFunc* 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 *
+CDiamEllipFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CDiamEllipFunc *self;
+    
+    self = (CDiamEllipFunc *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CDiamEllipFunc_init(CDiamEllipFunc *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new DiamEllipFunc();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"radius_b",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"radius_a",Py_BuildValue("d",20.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius_a.dispersion->accept_as_source(visitor, self->model->radius_a.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_a", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius_b.dispersion->accept_as_source(visitor, self->model->radius_b.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_b", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CDiamEllipFunc_members[] = {
+    {name_params, T_OBJECT, offsetof(CDiamEllipFunc, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CDiamEllipFunc, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CDiamEllipFunc, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CDiamEllipFunc_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(DiamEllipFunc* 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;
+	}
+#pragma omp parallel for
+	 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( DiamEllipFunc* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CDiamEllipFuncError, 
+                   "CDiamEllipFunc.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(CDiamEllipFunc *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.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(CDiamEllipFuncError, 
+	    	"CDiamEllipFunc.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(CDiamEllipFuncError, 
+                   "CDiamEllipFunc.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(CDiamEllipFuncError, 
+	    		"CDiamEllipFunc.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(CDiamEllipFuncError, 
+                   "CDiamEllipFunc.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CDiamEllipFuncError, 
+                   "CDiamEllipFunc.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(CDiamEllipFunc *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.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(CDiamEllipFuncError, 
+	    	"CDiamEllipFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamEllipFuncError, 
+	    		"CDiamEllipFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CDiamEllipFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CDiamEllipFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CDiamEllipFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CDiamEllipFunc *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.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(CDiamEllipFuncError, 
+	    	"CDiamEllipFunc.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CDiamEllipFuncError, 
+	    		"CDiamEllipFunc.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CDiamEllipFunc_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CDiamEllipFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CDiamEllipFunc *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CDiamEllipFunc *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CDiamEllipFuncError,
+	    	"CDiamEllipFunc.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, "radius_a")) {
+        self->model->radius_a.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius_b")) {
+        self->model->radius_b.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CDiamEllipFuncError,
+	    	"CDiamEllipFunc.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 CDiamEllipFunc_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CDiamEllipFuncType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CDiamEllipFunc",             /*tp_name*/
+    sizeof(CDiamEllipFunc),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CDiamEllipFunc_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CDiamEllipFunc objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CDiamEllipFunc_methods,             /* tp_methods */
+    CDiamEllipFunc_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CDiamEllipFunc_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CDiamEllipFunc_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCDiamEllipFunc(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CDiamEllipFuncType) < 0)
+        return;
+
+    Py_INCREF(&CDiamEllipFuncType);
+    PyModule_AddObject(module, "CDiamEllipFunc", (PyObject *)&CDiamEllipFuncType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CDiamEllipFunc.error";
+    CDiamEllipFuncError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CDiamEllipFuncError", CDiamEllipFuncError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CEllipsoidModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,645 @@
+/**
+	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
+ */
+
+/** CEllipsoidModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\ellipsoid.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 "ellipsoid.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CEllipsoidModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    EllipsoidModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CEllipsoidModel;
+
+
+static void
+CEllipsoidModel_dealloc(CEllipsoidModel* 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 *
+CEllipsoidModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CEllipsoidModel *self;
+    
+    self = (CEllipsoidModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CEllipsoidModel_init(CEllipsoidModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new EllipsoidModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",90.000000000000));
+        PyDict_SetItemString(self->params,"radius_b",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"radius_a",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldEll",Py_BuildValue("d",0.000004000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius_a.dispersion->accept_as_source(visitor, self->model->radius_a.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_a", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius_b.dispersion->accept_as_source(visitor, self->model->radius_b.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_b", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CEllipsoidModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CEllipsoidModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CEllipsoidModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CEllipsoidModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CEllipsoidModel_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(EllipsoidModel* 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;
+	}
+#pragma omp parallel for
+	 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( EllipsoidModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CEllipsoidModelError, 
+                   "CEllipsoidModel.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(CEllipsoidModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CEllipsoidModelError, 
+	    	"CEllipsoidModel.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(CEllipsoidModelError, 
+                   "CEllipsoidModel.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(CEllipsoidModelError, 
+	    		"CEllipsoidModel.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(CEllipsoidModelError, 
+                   "CEllipsoidModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CEllipsoidModelError, 
+                   "CEllipsoidModel.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(CEllipsoidModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CEllipsoidModelError, 
+	    	"CEllipsoidModel.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(CEllipsoidModelError, 
+	    		"CEllipsoidModel.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 = CEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CEllipsoidModel_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 = CEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CEllipsoidModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->radius_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_b") );
+    self->model->radius_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_a") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_a");
+    self->model->radius_a.dispersion->accept_as_destination(visitor, self->model->radius_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_b");
+    self->model->radius_b.dispersion->accept_as_destination(visitor, self->model->radius_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CEllipsoidModelError, 
+	    	"CEllipsoidModel.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(CEllipsoidModelError, 
+	    		"CEllipsoidModel.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 = CEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CEllipsoidModel_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 = CEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CEllipsoidModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CEllipsoidModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CEllipsoidModelError,
+	    	"CEllipsoidModel.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, "radius_a")) {
+        self->model->radius_a.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius_b")) {
+        self->model->radius_b.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CEllipsoidModelError,
+	    	"CEllipsoidModel.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 CEllipsoidModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CEllipsoidModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CEllipsoidModel",             /*tp_name*/
+    sizeof(CEllipsoidModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CEllipsoidModel_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*/
+    "CEllipsoidModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CEllipsoidModel_methods,             /* tp_methods */
+    CEllipsoidModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CEllipsoidModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CEllipsoidModel_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 addCEllipsoidModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CEllipsoidModelType) < 0)
+        return;
+
+    Py_INCREF(&CEllipsoidModelType);
+    PyModule_AddObject(module, "CEllipsoidModel", (PyObject *)&CEllipsoidModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CEllipsoidModel.error";
+    CEllipsoidModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CEllipsoidModelError", CEllipsoidModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CEllipticalCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CEllipticalCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CEllipticalCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,687 @@
+/**
+	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
+ */
+
+/** CEllipticalCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\elliptical_cylinder.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 "elliptical_cylinder.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CEllipticalCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    EllipticalCylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CEllipticalCylinderModel;
+
+
+static void
+CEllipticalCylinderModel_dealloc(CEllipticalCylinderModel* 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 *
+CEllipticalCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CEllipticalCylinderModel *self;
+    
+    self = (CEllipticalCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CEllipticalCylinderModel_init(CEllipticalCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new EllipticalCylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sldCyl",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"cyl_psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"r_minor",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"cyl_theta",Py_BuildValue("d",90.000000000000));
+        PyDict_SetItemString(self->params,"r_ratio",Py_BuildValue("d",1.500000000000));
+        PyDict_SetItemString(self->params,"cyl_phi",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->r_minor.dispersion->accept_as_source(visitor, self->model->r_minor.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "r_minor", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->r_ratio.dispersion->accept_as_source(visitor, self->model->r_ratio.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "r_ratio", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->cyl_theta.dispersion->accept_as_source(visitor, self->model->cyl_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "cyl_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->cyl_phi.dispersion->accept_as_source(visitor, self->model->cyl_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "cyl_phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->cyl_psi.dispersion->accept_as_source(visitor, self->model->cyl_psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "cyl_psi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CEllipticalCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CEllipticalCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CEllipticalCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CEllipticalCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CEllipticalCylinderModel_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(EllipticalCylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( EllipticalCylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CEllipticalCylinderModelError, 
+                   "CEllipticalCylinderModel.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(CEllipticalCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->cyl_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_psi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->r_minor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_minor") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->r_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_ratio") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_minor");
+    self->model->r_minor.dispersion->accept_as_destination(visitor, self->model->r_minor.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_ratio");
+    self->model->r_ratio.dispersion->accept_as_destination(visitor, self->model->r_ratio.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_psi");
+    self->model->cyl_psi.dispersion->accept_as_destination(visitor, self->model->cyl_psi.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(CEllipticalCylinderModelError, 
+	    	"CEllipticalCylinderModel.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(CEllipticalCylinderModelError, 
+                   "CEllipticalCylinderModel.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(CEllipticalCylinderModelError, 
+	    		"CEllipticalCylinderModel.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(CEllipticalCylinderModelError, 
+                   "CEllipticalCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CEllipticalCylinderModelError, 
+                   "CEllipticalCylinderModel.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(CEllipticalCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->cyl_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_psi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->r_minor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_minor") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->r_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_ratio") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_minor");
+    self->model->r_minor.dispersion->accept_as_destination(visitor, self->model->r_minor.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_ratio");
+    self->model->r_ratio.dispersion->accept_as_destination(visitor, self->model->r_ratio.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_psi");
+    self->model->cyl_psi.dispersion->accept_as_destination(visitor, self->model->cyl_psi.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(CEllipticalCylinderModelError, 
+	    	"CEllipticalCylinderModel.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(CEllipticalCylinderModelError, 
+	    		"CEllipticalCylinderModel.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 = CEllipticalCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CEllipticalCylinderModel_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 = CEllipticalCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CEllipticalCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->cyl_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_psi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->r_minor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_minor") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->r_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_ratio") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_minor");
+    self->model->r_minor.dispersion->accept_as_destination(visitor, self->model->r_minor.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_ratio");
+    self->model->r_ratio.dispersion->accept_as_destination(visitor, self->model->r_ratio.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_psi");
+    self->model->cyl_psi.dispersion->accept_as_destination(visitor, self->model->cyl_psi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CEllipticalCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->cyl_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_psi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->r_minor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_minor") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->r_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_ratio") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_minor");
+    self->model->r_minor.dispersion->accept_as_destination(visitor, self->model->r_minor.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_ratio");
+    self->model->r_ratio.dispersion->accept_as_destination(visitor, self->model->r_ratio.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_psi");
+    self->model->cyl_psi.dispersion->accept_as_destination(visitor, self->model->cyl_psi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CEllipticalCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->cyl_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_psi") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->r_minor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_minor") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->cyl_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_theta") );
+    self->model->r_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "r_ratio") );
+    self->model->cyl_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cyl_phi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_minor");
+    self->model->r_minor.dispersion->accept_as_destination(visitor, self->model->r_minor.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "r_ratio");
+    self->model->r_ratio.dispersion->accept_as_destination(visitor, self->model->r_ratio.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_theta");
+    self->model->cyl_theta.dispersion->accept_as_destination(visitor, self->model->cyl_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_phi");
+    self->model->cyl_phi.dispersion->accept_as_destination(visitor, self->model->cyl_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "cyl_psi");
+    self->model->cyl_psi.dispersion->accept_as_destination(visitor, self->model->cyl_psi.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(CEllipticalCylinderModelError, 
+	    	"CEllipticalCylinderModel.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(CEllipticalCylinderModelError, 
+	    		"CEllipticalCylinderModel.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 = CEllipticalCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CEllipticalCylinderModel_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 = CEllipticalCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CEllipticalCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CEllipticalCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CEllipticalCylinderModelError,
+	    	"CEllipticalCylinderModel.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, "r_minor")) {
+        self->model->r_minor.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "r_ratio")) {
+        self->model->r_ratio.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "cyl_theta")) {
+        self->model->cyl_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "cyl_phi")) {
+        self->model->cyl_phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "cyl_psi")) {
+        self->model->cyl_psi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CEllipticalCylinderModelError,
+	    	"CEllipticalCylinderModel.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 CEllipticalCylinderModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CEllipticalCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CEllipticalCylinderModel",             /*tp_name*/
+    sizeof(CEllipticalCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CEllipticalCylinderModel_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*/
+    "CEllipticalCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CEllipticalCylinderModel_methods,             /* tp_methods */
+    CEllipticalCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CEllipticalCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CEllipticalCylinderModel_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 addCEllipticalCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CEllipticalCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CEllipticalCylinderModelType);
+    PyModule_AddObject(module, "CEllipticalCylinderModel", (PyObject *)&CEllipticalCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CEllipticalCylinderModel.error";
+    CEllipticalCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CEllipticalCylinderModelError", CEllipticalCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFCCrystalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,657 @@
+/**
+	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
+ */
+
+/** CFCCrystalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\fcc.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 "fcc.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFCCrystalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FCCrystalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFCCrystalModel;
+
+
+static void
+CFCCrystalModel_dealloc(CFCCrystalModel* 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 *
+CFCCrystalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFCCrystalModel *self;
+    
+    self = (CFCCrystalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFCCrystalModel_init(CFCCrystalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FCCrystalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"dnn",Py_BuildValue("d",220.000000000000));
+        PyDict_SetItemString(self->params,"sldSph",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"d_factor",Py_BuildValue("d",0.060000000000));
+        PyDict_SetItemString(self->params,"psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->phi.dispersion->accept_as_source(visitor, self->model->phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->psi.dispersion->accept_as_source(visitor, self->model->psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "psi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->theta.dispersion->accept_as_source(visitor, self->model->theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFCCrystalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CFCCrystalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFCCrystalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFCCrystalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFCCrystalModel_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(FCCrystalModel* 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;
+	}
+#pragma omp parallel for
+	 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( FCCrystalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFCCrystalModelError, 
+                   "CFCCrystalModel.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(CFCCrystalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CFCCrystalModelError, 
+	    	"CFCCrystalModel.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(CFCCrystalModelError, 
+                   "CFCCrystalModel.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(CFCCrystalModelError, 
+	    		"CFCCrystalModel.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(CFCCrystalModelError, 
+                   "CFCCrystalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFCCrystalModelError, 
+                   "CFCCrystalModel.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(CFCCrystalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CFCCrystalModelError, 
+	    	"CFCCrystalModel.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(CFCCrystalModelError, 
+	    		"CFCCrystalModel.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 = CFCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFCCrystalModel_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 = CFCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFCCrystalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CFCCrystalModelError, 
+	    	"CFCCrystalModel.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(CFCCrystalModelError, 
+	    		"CFCCrystalModel.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 = CFCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFCCrystalModel_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 = CFCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFCCrystalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFCCrystalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFCCrystalModelError,
+	    	"CFCCrystalModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "phi")) {
+        self->model->phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "psi")) {
+        self->model->psi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "theta")) {
+        self->model->theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CFCCrystalModelError,
+	    	"CFCCrystalModel.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 CFCCrystalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFCCrystalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFCCrystalModel",             /*tp_name*/
+    sizeof(CFCCrystalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFCCrystalModel_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*/
+    "CFCCrystalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFCCrystalModel_methods,             /* tp_methods */
+    CFCCrystalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFCCrystalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFCCrystalModel_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 addCFCCrystalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFCCrystalModelType) < 0)
+        return;
+
+    Py_INCREF(&CFCCrystalModelType);
+    PyModule_AddObject(module, "CFCCrystalModel", (PyObject *)&CFCCrystalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFCCrystalModel.error";
+    CFCCrystalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFCCrystalModelError", CFCCrystalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFlexCylEllipXModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFlexCylEllipXModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFlexCylEllipXModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,645 @@
+/**
+	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
+ */
+
+/** CFlexCylEllipXModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\flexcyl_ellipX.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 "flexcyl_ellipX.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFlexCylEllipXModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FlexCylEllipXModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFlexCylEllipXModel;
+
+
+static void
+CFlexCylEllipXModel_dealloc(CFlexCylEllipXModel* 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 *
+CFlexCylEllipXModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFlexCylEllipXModel *self;
+    
+    self = (CFlexCylEllipXModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFlexCylEllipXModel_init(CFlexCylEllipXModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FlexCylEllipXModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sldCyl",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"axis_ratio",Py_BuildValue("d",1.500000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000100000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"kuhn_length",Py_BuildValue("d",100.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->kuhn_length.dispersion->accept_as_source(visitor, self->model->kuhn_length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "kuhn_length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_ratio.dispersion->accept_as_source(visitor, self->model->axis_ratio.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_ratio", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFlexCylEllipXModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CFlexCylEllipXModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFlexCylEllipXModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFlexCylEllipXModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFlexCylEllipXModel_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(FlexCylEllipXModel* 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;
+	}
+#pragma omp parallel for
+	 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( FlexCylEllipXModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFlexCylEllipXModelError, 
+                   "CFlexCylEllipXModel.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(CFlexCylEllipXModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->axis_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_ratio") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_ratio");
+    self->model->axis_ratio.dispersion->accept_as_destination(visitor, self->model->axis_ratio.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(CFlexCylEllipXModelError, 
+	    	"CFlexCylEllipXModel.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(CFlexCylEllipXModelError, 
+                   "CFlexCylEllipXModel.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(CFlexCylEllipXModelError, 
+	    		"CFlexCylEllipXModel.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(CFlexCylEllipXModelError, 
+                   "CFlexCylEllipXModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFlexCylEllipXModelError, 
+                   "CFlexCylEllipXModel.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(CFlexCylEllipXModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->axis_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_ratio") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_ratio");
+    self->model->axis_ratio.dispersion->accept_as_destination(visitor, self->model->axis_ratio.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(CFlexCylEllipXModelError, 
+	    	"CFlexCylEllipXModel.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(CFlexCylEllipXModelError, 
+	    		"CFlexCylEllipXModel.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 = CFlexCylEllipXModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFlexCylEllipXModel_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 = CFlexCylEllipXModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFlexCylEllipXModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->axis_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_ratio") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_ratio");
+    self->model->axis_ratio.dispersion->accept_as_destination(visitor, self->model->axis_ratio.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFlexCylEllipXModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->axis_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_ratio") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_ratio");
+    self->model->axis_ratio.dispersion->accept_as_destination(visitor, self->model->axis_ratio.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFlexCylEllipXModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->axis_ratio = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_ratio") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_ratio");
+    self->model->axis_ratio.dispersion->accept_as_destination(visitor, self->model->axis_ratio.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(CFlexCylEllipXModelError, 
+	    	"CFlexCylEllipXModel.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(CFlexCylEllipXModelError, 
+	    		"CFlexCylEllipXModel.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 = CFlexCylEllipXModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFlexCylEllipXModel_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 = CFlexCylEllipXModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFlexCylEllipXModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFlexCylEllipXModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFlexCylEllipXModelError,
+	    	"CFlexCylEllipXModel.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, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "kuhn_length")) {
+        self->model->kuhn_length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_ratio")) {
+        self->model->axis_ratio.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CFlexCylEllipXModelError,
+	    	"CFlexCylEllipXModel.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 CFlexCylEllipXModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFlexCylEllipXModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFlexCylEllipXModel",             /*tp_name*/
+    sizeof(CFlexCylEllipXModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFlexCylEllipXModel_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*/
+    "CFlexCylEllipXModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFlexCylEllipXModel_methods,             /* tp_methods */
+    CFlexCylEllipXModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFlexCylEllipXModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFlexCylEllipXModel_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 addCFlexCylEllipXModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFlexCylEllipXModelType) < 0)
+        return;
+
+    Py_INCREF(&CFlexCylEllipXModelType);
+    PyModule_AddObject(module, "CFlexCylEllipXModel", (PyObject *)&CFlexCylEllipXModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFlexCylEllipXModel.error";
+    CFlexCylEllipXModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFlexCylEllipXModelError", CFlexCylEllipXModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFlexibleCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFlexibleCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFlexibleCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,624 @@
+/**
+	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
+ */
+
+/** CFlexibleCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\flexible_cylinder.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 "flexible_cylinder.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFlexibleCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FlexibleCylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFlexibleCylinderModel;
+
+
+static void
+CFlexibleCylinderModel_dealloc(CFlexibleCylinderModel* 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 *
+CFlexibleCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFlexibleCylinderModel *self;
+    
+    self = (CFlexibleCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFlexibleCylinderModel_init(CFlexibleCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FlexibleCylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sldCyl",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000100000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"kuhn_length",Py_BuildValue("d",100.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->kuhn_length.dispersion->accept_as_source(visitor, self->model->kuhn_length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "kuhn_length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFlexibleCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CFlexibleCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFlexibleCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFlexibleCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFlexibleCylinderModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(FlexibleCylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( FlexibleCylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFlexibleCylinderModelError, 
+                   "CFlexibleCylinderModel.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(CFlexibleCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFlexibleCylinderModelError, 
+	    	"CFlexibleCylinderModel.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(CFlexibleCylinderModelError, 
+                   "CFlexibleCylinderModel.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(CFlexibleCylinderModelError, 
+	    		"CFlexibleCylinderModel.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(CFlexibleCylinderModelError, 
+                   "CFlexibleCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFlexibleCylinderModelError, 
+                   "CFlexibleCylinderModel.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(CFlexibleCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFlexibleCylinderModelError, 
+	    	"CFlexibleCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CFlexibleCylinderModelError, 
+	    		"CFlexibleCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CFlexibleCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFlexibleCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFlexibleCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFlexibleCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->kuhn_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "kuhn_length") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "kuhn_length");
+    self->model->kuhn_length.dispersion->accept_as_destination(visitor, self->model->kuhn_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFlexibleCylinderModelError, 
+	    	"CFlexibleCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CFlexibleCylinderModelError, 
+	    		"CFlexibleCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFlexibleCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CFlexibleCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFlexibleCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFlexibleCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFlexibleCylinderModelError,
+	    	"CFlexibleCylinderModel.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, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "kuhn_length")) {
+        self->model->kuhn_length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CFlexibleCylinderModelError,
+	    	"CFlexibleCylinderModel.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 CFlexibleCylinderModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFlexibleCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFlexibleCylinderModel",             /*tp_name*/
+    sizeof(CFlexibleCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFlexibleCylinderModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CFlexibleCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFlexibleCylinderModel_methods,             /* tp_methods */
+    CFlexibleCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFlexibleCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFlexibleCylinderModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCFlexibleCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFlexibleCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CFlexibleCylinderModelType);
+    PyModule_AddObject(module, "CFlexibleCylinderModel", (PyObject *)&CFlexibleCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFlexibleCylinderModel.error";
+    CFlexibleCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFlexibleCylinderModelError", CFlexibleCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFractalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,594 @@
+/**
+	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
+ */
+
+/** CFractalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\fractal.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 "fractal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFractalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FractalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFractalModel;
+
+
+static void
+CFractalModel_dealloc(CFractalModel* 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 *
+CFractalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFractalModel *self;
+    
+    self = (CFractalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFractalModel_init(CFractalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FractalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",0.050000000000));
+        PyDict_SetItemString(self->params,"fractal_dim",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006350000));
+        PyDict_SetItemString(self->params,"cor_length",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",5.000000000000));
+        PyDict_SetItemString(self->params,"sldBlock",Py_BuildValue("d",0.000002000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFractalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CFractalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFractalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFractalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFractalModel_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(FractalModel* 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;
+	}
+#pragma omp parallel for
+	 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( FractalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFractalModelError, 
+                   "CFractalModel.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(CFractalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->fractal_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fractal_dim") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->cor_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cor_length") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sldBlock = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldBlock") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFractalModelError, 
+	    	"CFractalModel.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(CFractalModelError, 
+                   "CFractalModel.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(CFractalModelError, 
+	    		"CFractalModel.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(CFractalModelError, 
+                   "CFractalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFractalModelError, 
+                   "CFractalModel.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(CFractalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->fractal_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fractal_dim") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->cor_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cor_length") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sldBlock = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldBlock") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFractalModelError, 
+	    	"CFractalModel.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(CFractalModelError, 
+	    		"CFractalModel.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 = CFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFractalModel_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 = CFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->fractal_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fractal_dim") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->cor_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cor_length") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sldBlock = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldBlock") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->fractal_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fractal_dim") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->cor_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cor_length") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sldBlock = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldBlock") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFractalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->fractal_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fractal_dim") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->cor_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cor_length") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sldBlock = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldBlock") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CFractalModelError, 
+	    	"CFractalModel.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(CFractalModelError, 
+	    		"CFractalModel.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 = CFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFractalModel_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 = CFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFractalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFractalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFractalModelError,
+	    	"CFractalModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CFractalModelError,
+	    	"CFractalModel.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 CFractalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFractalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFractalModel",             /*tp_name*/
+    sizeof(CFractalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFractalModel_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*/
+    "CFractalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFractalModel_methods,             /* tp_methods */
+    CFractalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFractalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFractalModel_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 addCFractalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFractalModelType) < 0)
+        return;
+
+    Py_INCREF(&CFractalModelType);
+    PyModule_AddObject(module, "CFractalModel", (PyObject *)&CFractalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFractalModel.error";
+    CFractalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFractalModelError", CFractalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFractalO_Z.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFractalO_Z.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFractalO_Z.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,555 @@
+/**
+	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
+ */
+
+/** CFractalO_Z
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\FractalQtoN.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 "FractalQtoN.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFractalO_ZError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FractalO_Z * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFractalO_Z;
+
+
+static void
+CFractalO_Z_dealloc(CFractalO_Z* 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 *
+CFractalO_Z_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFractalO_Z *self;
+    
+    self = (CFractalO_Z *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFractalO_Z_init(CFractalO_Z *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FractalO_Z();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"s_fractal",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"cluster_rg",Py_BuildValue("d",3520.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",10000.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.010000000000));
+        PyDict_SetItemString(self->params,"m_fractal",Py_BuildValue("d",1.800000000000));
+        PyDict_SetItemString(self->params,"primary_rg",Py_BuildValue("d",82.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFractalO_Z_members[] = {
+    {name_params, T_OBJECT, offsetof(CFractalO_Z, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFractalO_Z, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFractalO_Z, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFractalO_Z_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(FractalO_Z* 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;
+	}
+#pragma omp parallel for
+	 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( FractalO_Z* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFractalO_ZError, 
+                   "CFractalO_Z.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(CFractalO_Z *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->s_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_fractal") );
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->m_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "m_fractal") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CFractalO_ZError, 
+	    	"CFractalO_Z.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(CFractalO_ZError, 
+                   "CFractalO_Z.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(CFractalO_ZError, 
+	    		"CFractalO_Z.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(CFractalO_ZError, 
+                   "CFractalO_Z.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFractalO_ZError, 
+                   "CFractalO_Z.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(CFractalO_Z *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->s_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_fractal") );
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->m_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "m_fractal") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CFractalO_ZError, 
+	    	"CFractalO_Z.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(CFractalO_ZError, 
+	    		"CFractalO_Z.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 = CFractalO_Z_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFractalO_Z_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 = CFractalO_Z_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFractalO_Z *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->s_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_fractal") );
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->m_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "m_fractal") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFractalO_Z *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->s_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_fractal") );
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->m_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "m_fractal") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFractalO_Z *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->s_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_fractal") );
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->m_fractal = PyFloat_AsDouble( PyDict_GetItemString(self->params, "m_fractal") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CFractalO_ZError, 
+	    	"CFractalO_Z.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(CFractalO_ZError, 
+	    		"CFractalO_Z.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 = CFractalO_Z_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFractalO_Z_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 = CFractalO_Z_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFractalO_Z *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFractalO_Z *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFractalO_ZError,
+	    	"CFractalO_Z.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CFractalO_ZError,
+	    	"CFractalO_Z.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 CFractalO_Z_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFractalO_ZType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFractalO_Z",             /*tp_name*/
+    sizeof(CFractalO_Z),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFractalO_Z_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*/
+    "CFractalO_Z objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFractalO_Z_methods,             /* tp_methods */
+    CFractalO_Z_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFractalO_Z_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFractalO_Z_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 addCFractalO_Z(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFractalO_ZType) < 0)
+        return;
+
+    Py_INCREF(&CFractalO_ZType);
+    PyModule_AddObject(module, "CFractalO_Z", (PyObject *)&CFractalO_ZType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFractalO_Z.error";
+    CFractalO_ZError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFractalO_ZError", CFractalO_ZError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CFuzzySphereModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CFuzzySphereModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CFuzzySphereModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,603 @@
+/**
+	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
+ */
+
+/** CFuzzySphereModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\fuzzysphere.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 "fuzzysphere.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CFuzzySphereModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    FuzzySphereModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CFuzzySphereModel;
+
+
+static void
+CFuzzySphereModel_dealloc(CFuzzySphereModel* 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 *
+CFuzzySphereModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CFuzzySphereModel *self;
+    
+    self = (CFuzzySphereModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CFuzzySphereModel_init(CFuzzySphereModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new FuzzySphereModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",0.010000000000));
+        PyDict_SetItemString(self->params,"sldSph",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"fuzziness",Py_BuildValue("d",10.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->fuzziness.dispersion->accept_as_source(visitor, self->model->fuzziness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "fuzziness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CFuzzySphereModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CFuzzySphereModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CFuzzySphereModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CFuzzySphereModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CFuzzySphereModel_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(FuzzySphereModel* 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;
+	}
+#pragma omp parallel for
+	 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( FuzzySphereModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CFuzzySphereModelError, 
+                   "CFuzzySphereModel.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(CFuzzySphereModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->fuzziness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fuzziness") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "fuzziness");
+    self->model->fuzziness.dispersion->accept_as_destination(visitor, self->model->fuzziness.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(CFuzzySphereModelError, 
+	    	"CFuzzySphereModel.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(CFuzzySphereModelError, 
+                   "CFuzzySphereModel.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(CFuzzySphereModelError, 
+	    		"CFuzzySphereModel.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(CFuzzySphereModelError, 
+                   "CFuzzySphereModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CFuzzySphereModelError, 
+                   "CFuzzySphereModel.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(CFuzzySphereModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->fuzziness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fuzziness") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "fuzziness");
+    self->model->fuzziness.dispersion->accept_as_destination(visitor, self->model->fuzziness.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(CFuzzySphereModelError, 
+	    	"CFuzzySphereModel.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(CFuzzySphereModelError, 
+	    		"CFuzzySphereModel.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 = CFuzzySphereModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CFuzzySphereModel_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 = CFuzzySphereModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CFuzzySphereModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->fuzziness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fuzziness") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "fuzziness");
+    self->model->fuzziness.dispersion->accept_as_destination(visitor, self->model->fuzziness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CFuzzySphereModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->fuzziness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fuzziness") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "fuzziness");
+    self->model->fuzziness.dispersion->accept_as_destination(visitor, self->model->fuzziness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CFuzzySphereModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->fuzziness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fuzziness") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "fuzziness");
+    self->model->fuzziness.dispersion->accept_as_destination(visitor, self->model->fuzziness.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(CFuzzySphereModelError, 
+	    	"CFuzzySphereModel.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(CFuzzySphereModelError, 
+	    		"CFuzzySphereModel.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 = CFuzzySphereModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CFuzzySphereModel_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 = CFuzzySphereModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CFuzzySphereModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CFuzzySphereModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CFuzzySphereModelError,
+	    	"CFuzzySphereModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "fuzziness")) {
+        self->model->fuzziness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CFuzzySphereModelError,
+	    	"CFuzzySphereModel.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 CFuzzySphereModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CFuzzySphereModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CFuzzySphereModel",             /*tp_name*/
+    sizeof(CFuzzySphereModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CFuzzySphereModel_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*/
+    "CFuzzySphereModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CFuzzySphereModel_methods,             /* tp_methods */
+    CFuzzySphereModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CFuzzySphereModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CFuzzySphereModel_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 addCFuzzySphereModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CFuzzySphereModelType) < 0)
+        return;
+
+    Py_INCREF(&CFuzzySphereModelType);
+    PyModule_AddObject(module, "CFuzzySphereModel", (PyObject *)&CFuzzySphereModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CFuzzySphereModel.error";
+    CFuzzySphereModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CFuzzySphereModelError", CFuzzySphereModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CGaussian.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CGaussian.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CGaussian.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,537 @@
+/**
+	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
+ */
+
+/** CGaussian
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\gaussian.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 "gaussian.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CGaussianError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Gaussian * model;
+    /// Log for unit testing
+    PyObject * log;
+} CGaussian;
+
+
+static void
+CGaussian_dealloc(CGaussian* 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 *
+CGaussian_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CGaussian *self;
+    
+    self = (CGaussian *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CGaussian_init(CGaussian *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new Gaussian();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sigma",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"center",Py_BuildValue("d",0.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CGaussian_members[] = {
+    {name_params, T_OBJECT, offsetof(CGaussian, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CGaussian, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CGaussian, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CGaussian_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(Gaussian* 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;
+	}
+#pragma omp parallel for
+	 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( Gaussian* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CGaussianError, 
+                   "CGaussian.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(CGaussian *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGaussianError, 
+	    	"CGaussian.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(CGaussianError, 
+                   "CGaussian.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(CGaussianError, 
+	    		"CGaussian.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(CGaussianError, 
+                   "CGaussian.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CGaussianError, 
+                   "CGaussian.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(CGaussian *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGaussianError, 
+	    	"CGaussian.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(CGaussianError, 
+	    		"CGaussian.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 = CGaussian_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CGaussian_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 = CGaussian_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CGaussian *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CGaussian *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CGaussian *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGaussianError, 
+	    	"CGaussian.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(CGaussianError, 
+	    		"CGaussian.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 = CGaussian_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CGaussian_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 = CGaussian_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CGaussian *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CGaussian *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CGaussianError,
+	    	"CGaussian.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CGaussianError,
+	    	"CGaussian.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 CGaussian_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CGaussianType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CGaussian",             /*tp_name*/
+    sizeof(CGaussian),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CGaussian_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*/
+    "CGaussian objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CGaussian_methods,             /* tp_methods */
+    CGaussian_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CGaussian_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CGaussian_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 addCGaussian(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CGaussianType) < 0)
+        return;
+
+    Py_INCREF(&CGaussianType);
+    PyModule_AddObject(module, "CGaussian", (PyObject *)&CGaussianType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CGaussian.error";
+    CGaussianError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CGaussianError", CGaussianError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CGelFitModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CGelFitModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CGelFitModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,555 @@
+/**
+	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
+ */
+
+/** CGelFitModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\GelFit.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 "GelFit.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CGelFitModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    GelFitModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CGelFitModel;
+
+
+static void
+CGelFitModel_dealloc(CGelFitModel* 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 *
+CGelFitModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CGelFitModel *self;
+    
+    self = (CGelFitModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CGelFitModel_init(CGelFitModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new GelFitModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"gScale",Py_BuildValue("d",1.700000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",104.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.010000000000));
+        PyDict_SetItemString(self->params,"zeta",Py_BuildValue("d",16.000000000000));
+        PyDict_SetItemString(self->params,"lScale",Py_BuildValue("d",3.500000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CGelFitModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CGelFitModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CGelFitModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CGelFitModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CGelFitModel_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(GelFitModel* 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;
+	}
+#pragma omp parallel for
+	 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( GelFitModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CGelFitModelError, 
+                   "CGelFitModel.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(CGelFitModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->gScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gScale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->zeta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "zeta") );
+    self->model->lScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lScale") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGelFitModelError, 
+	    	"CGelFitModel.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(CGelFitModelError, 
+                   "CGelFitModel.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(CGelFitModelError, 
+	    		"CGelFitModel.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(CGelFitModelError, 
+                   "CGelFitModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CGelFitModelError, 
+                   "CGelFitModel.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(CGelFitModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->gScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gScale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->zeta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "zeta") );
+    self->model->lScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lScale") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGelFitModelError, 
+	    	"CGelFitModel.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(CGelFitModelError, 
+	    		"CGelFitModel.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 = CGelFitModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CGelFitModel_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 = CGelFitModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CGelFitModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->gScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gScale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->zeta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "zeta") );
+    self->model->lScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lScale") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CGelFitModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->gScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gScale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->zeta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "zeta") );
+    self->model->lScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lScale") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CGelFitModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->gScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gScale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->zeta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "zeta") );
+    self->model->lScale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lScale") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CGelFitModelError, 
+	    	"CGelFitModel.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(CGelFitModelError, 
+	    		"CGelFitModel.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 = CGelFitModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CGelFitModel_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 = CGelFitModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CGelFitModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CGelFitModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CGelFitModelError,
+	    	"CGelFitModel.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CGelFitModelError,
+	    	"CGelFitModel.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 CGelFitModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CGelFitModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CGelFitModel",             /*tp_name*/
+    sizeof(CGelFitModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CGelFitModel_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*/
+    "CGelFitModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CGelFitModel_methods,             /* tp_methods */
+    CGelFitModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CGelFitModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CGelFitModel_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 addCGelFitModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CGelFitModelType) < 0)
+        return;
+
+    Py_INCREF(&CGelFitModelType);
+    PyModule_AddObject(module, "CGelFitModel", (PyObject *)&CGelFitModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CGelFitModel.error";
+    CGelFitModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CGelFitModelError", CGelFitModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CHardsphereStructure.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CHardsphereStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CHardsphereStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,564 @@
+/**
+	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
+ */
+
+/** CHardsphereStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\Hardsphere.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 "Hardsphere.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CHardsphereStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    HardsphereStructure * model;
+    /// Log for unit testing
+    PyObject * log;
+} CHardsphereStructure;
+
+
+static void
+CHardsphereStructure_dealloc(CHardsphereStructure* 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 *
+CHardsphereStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHardsphereStructure *self;
+    
+    self = (CHardsphereStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHardsphereStructure_init(CHardsphereStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new HardsphereStructure();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"effect_radius",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.200000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->effect_radius.dispersion->accept_as_source(visitor, self->model->effect_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "effect_radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CHardsphereStructure_members[] = {
+    {name_params, T_OBJECT, offsetof(CHardsphereStructure, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CHardsphereStructure, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CHardsphereStructure, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHardsphereStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(HardsphereStructure* 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;
+	}
+#pragma omp parallel for
+	 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( HardsphereStructure* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CHardsphereStructureError, 
+                   "CHardsphereStructure.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(CHardsphereStructure *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHardsphereStructureError, 
+	    	"CHardsphereStructure.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(CHardsphereStructureError, 
+                   "CHardsphereStructure.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(CHardsphereStructureError, 
+	    		"CHardsphereStructure.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(CHardsphereStructureError, 
+                   "CHardsphereStructure.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CHardsphereStructureError, 
+                   "CHardsphereStructure.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(CHardsphereStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHardsphereStructureError, 
+	    	"CHardsphereStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHardsphereStructureError, 
+	    		"CHardsphereStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHardsphereStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CHardsphereStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CHardsphereStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHardsphereStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHardsphereStructureError, 
+	    	"CHardsphereStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHardsphereStructureError, 
+	    		"CHardsphereStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHardsphereStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHardsphereStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CHardsphereStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CHardsphereStructure *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CHardsphereStructureError,
+	    	"CHardsphereStructure.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, "effect_radius")) {
+        self->model->effect_radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CHardsphereStructureError,
+	    	"CHardsphereStructure.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 CHardsphereStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CHardsphereStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHardsphereStructure",             /*tp_name*/
+    sizeof(CHardsphereStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHardsphereStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHardsphereStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHardsphereStructure_methods,             /* tp_methods */
+    CHardsphereStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHardsphereStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHardsphereStructure_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHardsphereStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHardsphereStructureType) < 0)
+        return;
+
+    Py_INCREF(&CHardsphereStructureType);
+    PyModule_AddObject(module, "CHardsphereStructure", (PyObject *)&CHardsphereStructureType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CHardsphereStructure.error";
+    CHardsphereStructureError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CHardsphereStructureError", CHardsphereStructureError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CHayterMSAStructure.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CHayterMSAStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CHayterMSAStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,588 @@
+/**
+	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
+ */
+
+/** CHayterMSAStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\HayterMSA.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 "HayterMSA.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CHayterMSAStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    HayterMSAStructure * model;
+    /// Log for unit testing
+    PyObject * log;
+} CHayterMSAStructure;
+
+
+static void
+CHayterMSAStructure_dealloc(CHayterMSAStructure* 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 *
+CHayterMSAStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHayterMSAStructure *self;
+    
+    self = (CHayterMSAStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHayterMSAStructure_init(CHayterMSAStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new HayterMSAStructure();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"temperature",Py_BuildValue("d",318.160000000000));
+        PyDict_SetItemString(self->params,"saltconc",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"dielectconst",Py_BuildValue("d",71.080000000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.019200000000));
+        PyDict_SetItemString(self->params,"charge",Py_BuildValue("d",19.000000000000));
+        PyDict_SetItemString(self->params,"effect_radius",Py_BuildValue("d",20.750000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->effect_radius.dispersion->accept_as_source(visitor, self->model->effect_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "effect_radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CHayterMSAStructure_members[] = {
+    {name_params, T_OBJECT, offsetof(CHayterMSAStructure, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CHayterMSAStructure, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CHayterMSAStructure, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHayterMSAStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(HayterMSAStructure* 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;
+	}
+#pragma omp parallel for
+	 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( HayterMSAStructure* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CHayterMSAStructureError, 
+                   "CHayterMSAStructure.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(CHayterMSAStructure *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model->saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model->dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHayterMSAStructureError, 
+	    	"CHayterMSAStructure.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(CHayterMSAStructureError, 
+                   "CHayterMSAStructure.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(CHayterMSAStructureError, 
+	    		"CHayterMSAStructure.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(CHayterMSAStructureError, 
+                   "CHayterMSAStructure.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CHayterMSAStructureError, 
+                   "CHayterMSAStructure.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(CHayterMSAStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model->saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model->dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHayterMSAStructureError, 
+	    	"CHayterMSAStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHayterMSAStructureError, 
+	    		"CHayterMSAStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHayterMSAStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CHayterMSAStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model->saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model->dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CHayterMSAStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model->saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model->dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHayterMSAStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->temperature = PyFloat_AsDouble( PyDict_GetItemString(self->params, "temperature") );
+    self->model->saltconc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "saltconc") );
+    self->model->dielectconst = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dielectconst") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->charge = PyFloat_AsDouble( PyDict_GetItemString(self->params, "charge") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CHayterMSAStructureError, 
+	    	"CHayterMSAStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHayterMSAStructureError, 
+	    		"CHayterMSAStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHayterMSAStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHayterMSAStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CHayterMSAStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CHayterMSAStructure *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CHayterMSAStructureError,
+	    	"CHayterMSAStructure.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, "effect_radius")) {
+        self->model->effect_radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CHayterMSAStructureError,
+	    	"CHayterMSAStructure.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 CHayterMSAStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CHayterMSAStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHayterMSAStructure",             /*tp_name*/
+    sizeof(CHayterMSAStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHayterMSAStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHayterMSAStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHayterMSAStructure_methods,             /* tp_methods */
+    CHayterMSAStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHayterMSAStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHayterMSAStructure_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHayterMSAStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHayterMSAStructureType) < 0)
+        return;
+
+    Py_INCREF(&CHayterMSAStructureType);
+    PyModule_AddObject(module, "CHayterMSAStructure", (PyObject *)&CHayterMSAStructureType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CHayterMSAStructure.error";
+    CHayterMSAStructureError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CHayterMSAStructureError", CHayterMSAStructureError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CHollowCylinderModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CHollowCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CHollowCylinderModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,666 @@
+/**
+	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
+ */
+
+/** CHollowCylinderModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\hollow_cylinder.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 "hollow_cylinder.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CHollowCylinderModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    HollowCylinderModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CHollowCylinderModel;
+
+
+static void
+CHollowCylinderModel_dealloc(CHollowCylinderModel* 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 *
+CHollowCylinderModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CHollowCylinderModel *self;
+    
+    self = (CHollowCylinderModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CHollowCylinderModel_init(CHollowCylinderModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new HollowCylinderModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sldCyl",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"core_radius",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",90.000000000000));
+        PyDict_SetItemString(self->params,"length",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.010000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",30.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->core_radius.dispersion->accept_as_source(visitor, self->model->core_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "core_radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->length.dispersion->accept_as_source(visitor, self->model->length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CHollowCylinderModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CHollowCylinderModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CHollowCylinderModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CHollowCylinderModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CHollowCylinderModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(HollowCylinderModel* 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;
+	}
+#pragma omp parallel for
+	 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( HollowCylinderModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CHollowCylinderModelError, 
+                   "CHollowCylinderModel.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(CHollowCylinderModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CHollowCylinderModelError, 
+	    	"CHollowCylinderModel.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(CHollowCylinderModelError, 
+                   "CHollowCylinderModel.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(CHollowCylinderModelError, 
+	    		"CHollowCylinderModel.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(CHollowCylinderModelError, 
+                   "CHollowCylinderModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CHollowCylinderModelError, 
+                   "CHollowCylinderModel.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(CHollowCylinderModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CHollowCylinderModelError, 
+	    	"CHollowCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHollowCylinderModelError, 
+	    		"CHollowCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CHollowCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CHollowCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CHollowCylinderModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CHollowCylinderModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldCyl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldCyl") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "length") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "length");
+    self->model->length.dispersion->accept_as_destination(visitor, self->model->length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CHollowCylinderModelError, 
+	    	"CHollowCylinderModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CHollowCylinderModelError, 
+	    		"CHollowCylinderModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CHollowCylinderModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CHollowCylinderModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CHollowCylinderModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CHollowCylinderModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CHollowCylinderModelError,
+	    	"CHollowCylinderModel.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, "core_radius")) {
+        self->model->core_radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "length")) {
+        self->model->length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CHollowCylinderModelError,
+	    	"CHollowCylinderModel.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 CHollowCylinderModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CHollowCylinderModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CHollowCylinderModel",             /*tp_name*/
+    sizeof(CHollowCylinderModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CHollowCylinderModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CHollowCylinderModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CHollowCylinderModel_methods,             /* tp_methods */
+    CHollowCylinderModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CHollowCylinderModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CHollowCylinderModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCHollowCylinderModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CHollowCylinderModelType) < 0)
+        return;
+
+    Py_INCREF(&CHollowCylinderModelType);
+    PyModule_AddObject(module, "CHollowCylinderModel", (PyObject *)&CHollowCylinderModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CHollowCylinderModel.error";
+    CHollowCylinderModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CHollowCylinderModelError", CHollowCylinderModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLamellarFFHGModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLamellarFFHGModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLamellarFFHGModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,609 @@
+/**
+	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
+ */
+
+/** CLamellarFFHGModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lamellarFF_HG.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 "lamellarFF_HG.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarFFHGModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LamellarFFHGModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLamellarFFHGModel;
+
+
+static void
+CLamellarFFHGModel_dealloc(CLamellarFFHGModel* 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 *
+CLamellarFFHGModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarFFHGModel *self;
+    
+    self = (CLamellarFFHGModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarFFHGModel_init(CLamellarFFHGModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LamellarFFHGModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"h_thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"sld_tail",Py_BuildValue("d",0.000000400000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006000000));
+        PyDict_SetItemString(self->params,"t_length",Py_BuildValue("d",15.000000000000));
+        PyDict_SetItemString(self->params,"sld_head",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->t_length.dispersion->accept_as_source(visitor, self->model->t_length.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "t_length", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->h_thickness.dispersion->accept_as_source(visitor, self->model->h_thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "h_thickness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLamellarFFHGModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLamellarFFHGModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLamellarFFHGModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLamellarFFHGModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarFFHGModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(LamellarFFHGModel* 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;
+	}
+#pragma omp parallel for
+	 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( LamellarFFHGModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLamellarFFHGModelError, 
+                   "CLamellarFFHGModel.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(CLamellarFFHGModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "t_length");
+    self->model->t_length.dispersion->accept_as_destination(visitor, self->model->t_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "h_thickness");
+    self->model->h_thickness.dispersion->accept_as_destination(visitor, self->model->h_thickness.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(CLamellarFFHGModelError, 
+	    	"CLamellarFFHGModel.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(CLamellarFFHGModelError, 
+                   "CLamellarFFHGModel.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(CLamellarFFHGModelError, 
+	    		"CLamellarFFHGModel.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(CLamellarFFHGModelError, 
+                   "CLamellarFFHGModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLamellarFFHGModelError, 
+                   "CLamellarFFHGModel.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(CLamellarFFHGModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "t_length");
+    self->model->t_length.dispersion->accept_as_destination(visitor, self->model->t_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "h_thickness");
+    self->model->h_thickness.dispersion->accept_as_destination(visitor, self->model->h_thickness.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(CLamellarFFHGModelError, 
+	    	"CLamellarFFHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarFFHGModelError, 
+	    		"CLamellarFFHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarFFHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLamellarFFHGModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "t_length");
+    self->model->t_length.dispersion->accept_as_destination(visitor, self->model->t_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "h_thickness");
+    self->model->h_thickness.dispersion->accept_as_destination(visitor, self->model->h_thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLamellarFFHGModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "t_length");
+    self->model->t_length.dispersion->accept_as_destination(visitor, self->model->t_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "h_thickness");
+    self->model->h_thickness.dispersion->accept_as_destination(visitor, self->model->h_thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarFFHGModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->h_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "h_thickness") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->t_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "t_length") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "t_length");
+    self->model->t_length.dispersion->accept_as_destination(visitor, self->model->t_length.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "h_thickness");
+    self->model->h_thickness.dispersion->accept_as_destination(visitor, self->model->h_thickness.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(CLamellarFFHGModelError, 
+	    	"CLamellarFFHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarFFHGModelError, 
+	    		"CLamellarFFHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarFFHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarFFHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarFFHGModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLamellarFFHGModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLamellarFFHGModelError,
+	    	"CLamellarFFHGModel.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, "t_length")) {
+        self->model->t_length.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "h_thickness")) {
+        self->model->h_thickness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLamellarFFHGModelError,
+	    	"CLamellarFFHGModel.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 CLamellarFFHGModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLamellarFFHGModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarFFHGModel",             /*tp_name*/
+    sizeof(CLamellarFFHGModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarFFHGModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarFFHGModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarFFHGModel_methods,             /* tp_methods */
+    CLamellarFFHGModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarFFHGModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarFFHGModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarFFHGModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarFFHGModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarFFHGModelType);
+    PyModule_AddObject(module, "CLamellarFFHGModel", (PyObject *)&CLamellarFFHGModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLamellarFFHGModel.error";
+    CLamellarFFHGModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarFFHGModelError", CLamellarFFHGModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLamellarModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLamellarModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLamellarModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,582 @@
+/**
+	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
+ */
+
+/** CLamellarModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lamellar.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 "lamellar.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LamellarModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLamellarModel;
+
+
+static void
+CLamellarModel_dealloc(CLamellarModel* 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 *
+CLamellarModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarModel *self;
+    
+    self = (CLamellarModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarModel_init(CLamellarModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LamellarModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"sld_sol",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"bi_thick",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_bi",Py_BuildValue("d",0.000001000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->bi_thick.dispersion->accept_as_source(visitor, self->model->bi_thick.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "bi_thick", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLamellarModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLamellarModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLamellarModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLamellarModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(LamellarModel* 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;
+	}
+#pragma omp parallel for
+	 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( LamellarModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLamellarModelError, 
+                   "CLamellarModel.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(CLamellarModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "bi_thick");
+    self->model->bi_thick.dispersion->accept_as_destination(visitor, self->model->bi_thick.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(CLamellarModelError, 
+	    	"CLamellarModel.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(CLamellarModelError, 
+                   "CLamellarModel.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(CLamellarModelError, 
+	    		"CLamellarModel.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(CLamellarModelError, 
+                   "CLamellarModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLamellarModelError, 
+                   "CLamellarModel.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(CLamellarModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "bi_thick");
+    self->model->bi_thick.dispersion->accept_as_destination(visitor, self->model->bi_thick.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(CLamellarModelError, 
+	    	"CLamellarModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarModelError, 
+	    		"CLamellarModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLamellarModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "bi_thick");
+    self->model->bi_thick.dispersion->accept_as_destination(visitor, self->model->bi_thick.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLamellarModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "bi_thick");
+    self->model->bi_thick.dispersion->accept_as_destination(visitor, self->model->bi_thick.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bi_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bi_thick") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "bi_thick");
+    self->model->bi_thick.dispersion->accept_as_destination(visitor, self->model->bi_thick.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(CLamellarModelError, 
+	    	"CLamellarModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarModelError, 
+	    		"CLamellarModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLamellarModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLamellarModelError,
+	    	"CLamellarModel.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, "bi_thick")) {
+        self->model->bi_thick.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLamellarModelError,
+	    	"CLamellarModel.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 CLamellarModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLamellarModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarModel",             /*tp_name*/
+    sizeof(CLamellarModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarModel_methods,             /* tp_methods */
+    CLamellarModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarModelType);
+    PyModule_AddObject(module, "CLamellarModel", (PyObject *)&CLamellarModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLamellarModel.error";
+    CLamellarModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarModelError", CLamellarModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLamellarPCrystalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLamellarPCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLamellarPCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,600 @@
+/**
+	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
+ */
+
+/** CLamellarPCrystalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lamellarPC.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 "lamellarPC.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarPCrystalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LamellarPCrystalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLamellarPCrystalModel;
+
+
+static void
+CLamellarPCrystalModel_dealloc(CLamellarPCrystalModel* 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 *
+CLamellarPCrystalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarPCrystalModel *self;
+    
+    self = (CLamellarPCrystalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarPCrystalModel_init(CLamellarPCrystalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LamellarPCrystalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"Nlayers",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"spacing",Py_BuildValue("d",250.000000000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006340000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",33.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"pd_spacing",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_layer",Py_BuildValue("d",0.000001000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->thickness.dispersion->accept_as_source(visitor, self->model->thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thickness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLamellarPCrystalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLamellarPCrystalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLamellarPCrystalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLamellarPCrystalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarPCrystalModel_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(LamellarPCrystalModel* 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;
+	}
+#pragma omp parallel for
+	 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( LamellarPCrystalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLamellarPCrystalModelError, 
+                   "CLamellarPCrystalModel.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(CLamellarPCrystalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Nlayers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nlayers") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->pd_spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "pd_spacing") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_layer = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_layer") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CLamellarPCrystalModelError, 
+	    	"CLamellarPCrystalModel.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(CLamellarPCrystalModelError, 
+                   "CLamellarPCrystalModel.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(CLamellarPCrystalModelError, 
+	    		"CLamellarPCrystalModel.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(CLamellarPCrystalModelError, 
+                   "CLamellarPCrystalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLamellarPCrystalModelError, 
+                   "CLamellarPCrystalModel.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(CLamellarPCrystalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Nlayers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nlayers") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->pd_spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "pd_spacing") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_layer = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_layer") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CLamellarPCrystalModelError, 
+	    	"CLamellarPCrystalModel.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(CLamellarPCrystalModelError, 
+	    		"CLamellarPCrystalModel.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 = CLamellarPCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarPCrystalModel_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 = CLamellarPCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLamellarPCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Nlayers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nlayers") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->pd_spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "pd_spacing") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_layer = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_layer") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLamellarPCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Nlayers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nlayers") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->pd_spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "pd_spacing") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_layer = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_layer") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarPCrystalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Nlayers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nlayers") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->pd_spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "pd_spacing") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_layer = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_layer") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CLamellarPCrystalModelError, 
+	    	"CLamellarPCrystalModel.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(CLamellarPCrystalModelError, 
+	    		"CLamellarPCrystalModel.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 = CLamellarPCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarPCrystalModel_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 = CLamellarPCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarPCrystalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLamellarPCrystalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLamellarPCrystalModelError,
+	    	"CLamellarPCrystalModel.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, "thickness")) {
+        self->model->thickness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLamellarPCrystalModelError,
+	    	"CLamellarPCrystalModel.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 CLamellarPCrystalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLamellarPCrystalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarPCrystalModel",             /*tp_name*/
+    sizeof(CLamellarPCrystalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarPCrystalModel_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*/
+    "CLamellarPCrystalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarPCrystalModel_methods,             /* tp_methods */
+    CLamellarPCrystalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarPCrystalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarPCrystalModel_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 addCLamellarPCrystalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarPCrystalModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarPCrystalModelType);
+    PyModule_AddObject(module, "CLamellarPCrystalModel", (PyObject *)&CLamellarPCrystalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLamellarPCrystalModel.error";
+    CLamellarPCrystalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarPCrystalModelError", CLamellarPCrystalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLamellarPSHGModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLamellarPSHGModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLamellarPSHGModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,642 @@
+/**
+	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
+ */
+
+/** CLamellarPSHGModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lamellarPS_HG.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 "lamellarPS_HG.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarPSHGModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LamellarPSHGModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLamellarPSHGModel;
+
+
+static void
+CLamellarPSHGModel_dealloc(CLamellarPSHGModel* 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 *
+CLamellarPSHGModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarPSHGModel *self;
+    
+    self = (CLamellarPSHGModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarPSHGModel_init(CLamellarPSHGModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LamellarPSHGModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"n_plates",Py_BuildValue("d",30.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"deltaT",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"spacing",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"sld_tail",Py_BuildValue("d",0.000000400000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006000000));
+        PyDict_SetItemString(self->params,"caille",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"sld_head",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"deltaH",Py_BuildValue("d",2.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->deltaT.dispersion->accept_as_source(visitor, self->model->deltaT.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "deltaT", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->deltaH.dispersion->accept_as_source(visitor, self->model->deltaH.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "deltaH", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->spacing.dispersion->accept_as_source(visitor, self->model->spacing.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "spacing", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLamellarPSHGModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLamellarPSHGModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLamellarPSHGModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLamellarPSHGModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarPSHGModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(LamellarPSHGModel* 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;
+	}
+#pragma omp parallel for
+	 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( LamellarPSHGModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLamellarPSHGModelError, 
+                   "CLamellarPSHGModel.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(CLamellarPSHGModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaT");
+    self->model->deltaT.dispersion->accept_as_destination(visitor, self->model->deltaT.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaH");
+    self->model->deltaH.dispersion->accept_as_destination(visitor, self->model->deltaH.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSHGModelError, 
+	    	"CLamellarPSHGModel.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(CLamellarPSHGModelError, 
+                   "CLamellarPSHGModel.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(CLamellarPSHGModelError, 
+	    		"CLamellarPSHGModel.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(CLamellarPSHGModelError, 
+                   "CLamellarPSHGModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLamellarPSHGModelError, 
+                   "CLamellarPSHGModel.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(CLamellarPSHGModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaT");
+    self->model->deltaT.dispersion->accept_as_destination(visitor, self->model->deltaT.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaH");
+    self->model->deltaH.dispersion->accept_as_destination(visitor, self->model->deltaH.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSHGModelError, 
+	    	"CLamellarPSHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSHGModelError, 
+	    		"CLamellarPSHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarPSHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLamellarPSHGModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaT");
+    self->model->deltaT.dispersion->accept_as_destination(visitor, self->model->deltaT.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaH");
+    self->model->deltaH.dispersion->accept_as_destination(visitor, self->model->deltaH.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLamellarPSHGModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaT");
+    self->model->deltaT.dispersion->accept_as_destination(visitor, self->model->deltaT.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaH");
+    self->model->deltaH.dispersion->accept_as_destination(visitor, self->model->deltaH.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarPSHGModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->deltaT = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaT") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->sld_tail = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_tail") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->sld_head = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_head") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->deltaH = PyFloat_AsDouble( PyDict_GetItemString(self->params, "deltaH") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaT");
+    self->model->deltaT.dispersion->accept_as_destination(visitor, self->model->deltaT.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "deltaH");
+    self->model->deltaH.dispersion->accept_as_destination(visitor, self->model->deltaH.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSHGModelError, 
+	    	"CLamellarPSHGModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSHGModelError, 
+	    		"CLamellarPSHGModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarPSHGModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarPSHGModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarPSHGModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLamellarPSHGModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLamellarPSHGModelError,
+	    	"CLamellarPSHGModel.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, "deltaT")) {
+        self->model->deltaT.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "deltaH")) {
+        self->model->deltaH.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "spacing")) {
+        self->model->spacing.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLamellarPSHGModelError,
+	    	"CLamellarPSHGModel.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 CLamellarPSHGModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLamellarPSHGModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarPSHGModel",             /*tp_name*/
+    sizeof(CLamellarPSHGModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarPSHGModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarPSHGModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarPSHGModel_methods,             /* tp_methods */
+    CLamellarPSHGModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarPSHGModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarPSHGModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarPSHGModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarPSHGModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarPSHGModelType);
+    PyModule_AddObject(module, "CLamellarPSHGModel", (PyObject *)&CLamellarPSHGModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLamellarPSHGModel.error";
+    CLamellarPSHGModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarPSHGModelError", CLamellarPSHGModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLamellarPSModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLamellarPSModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLamellarPSModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,615 @@
+/**
+	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
+ */
+
+/** CLamellarPSModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lamellarPS.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 "lamellarPS.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLamellarPSModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LamellarPSModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLamellarPSModel;
+
+
+static void
+CLamellarPSModel_dealloc(CLamellarPSModel* 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 *
+CLamellarPSModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLamellarPSModel *self;
+    
+    self = (CLamellarPSModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLamellarPSModel_init(CLamellarPSModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LamellarPSModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"n_plates",Py_BuildValue("d",20.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_sol",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"delta",Py_BuildValue("d",30.000000000000));
+        PyDict_SetItemString(self->params,"spacing",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"caille",Py_BuildValue("d",0.100000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_bi",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->delta.dispersion->accept_as_source(visitor, self->model->delta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "delta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->spacing.dispersion->accept_as_source(visitor, self->model->spacing.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "spacing", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLamellarPSModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLamellarPSModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLamellarPSModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLamellarPSModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLamellarPSModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(LamellarPSModel* 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;
+	}
+#pragma omp parallel for
+	 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( LamellarPSModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLamellarPSModelError, 
+                   "CLamellarPSModel.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(CLamellarPSModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "delta");
+    self->model->delta.dispersion->accept_as_destination(visitor, self->model->delta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSModelError, 
+	    	"CLamellarPSModel.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(CLamellarPSModelError, 
+                   "CLamellarPSModel.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(CLamellarPSModelError, 
+	    		"CLamellarPSModel.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(CLamellarPSModelError, 
+                   "CLamellarPSModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLamellarPSModelError, 
+                   "CLamellarPSModel.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(CLamellarPSModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "delta");
+    self->model->delta.dispersion->accept_as_destination(visitor, self->model->delta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSModelError, 
+	    	"CLamellarPSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSModelError, 
+	    		"CLamellarPSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CLamellarPSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLamellarPSModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "delta");
+    self->model->delta.dispersion->accept_as_destination(visitor, self->model->delta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLamellarPSModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "delta");
+    self->model->delta.dispersion->accept_as_destination(visitor, self->model->delta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLamellarPSModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->n_plates = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_plates") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sld_sol = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_sol") );
+    self->model->delta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta") );
+    self->model->spacing = PyFloat_AsDouble( PyDict_GetItemString(self->params, "spacing") );
+    self->model->caille = PyFloat_AsDouble( PyDict_GetItemString(self->params, "caille") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_bi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bi") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "delta");
+    self->model->delta.dispersion->accept_as_destination(visitor, self->model->delta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "spacing");
+    self->model->spacing.dispersion->accept_as_destination(visitor, self->model->spacing.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(CLamellarPSModelError, 
+	    	"CLamellarPSModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CLamellarPSModelError, 
+	    		"CLamellarPSModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLamellarPSModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CLamellarPSModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLamellarPSModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLamellarPSModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLamellarPSModelError,
+	    	"CLamellarPSModel.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, "delta")) {
+        self->model->delta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "spacing")) {
+        self->model->spacing.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLamellarPSModelError,
+	    	"CLamellarPSModel.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 CLamellarPSModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLamellarPSModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLamellarPSModel",             /*tp_name*/
+    sizeof(CLamellarPSModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLamellarPSModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CLamellarPSModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLamellarPSModel_methods,             /* tp_methods */
+    CLamellarPSModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLamellarPSModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLamellarPSModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCLamellarPSModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLamellarPSModelType) < 0)
+        return;
+
+    Py_INCREF(&CLamellarPSModelType);
+    PyModule_AddObject(module, "CLamellarPSModel", (PyObject *)&CLamellarPSModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLamellarPSModel.error";
+    CLamellarPSModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLamellarPSModelError", CLamellarPSModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLinearPearlsModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLinearPearlsModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLinearPearlsModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,609 @@
+/**
+	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
+ */
+
+/** CLinearPearlsModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\linearpearls.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 "linearpearls.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLinearPearlsModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LinearPearlsModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLinearPearlsModel;
+
+
+static void
+CLinearPearlsModel_dealloc(CLinearPearlsModel* 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 *
+CLinearPearlsModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLinearPearlsModel *self;
+    
+    self = (CLinearPearlsModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLinearPearlsModel_init(CLinearPearlsModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LinearPearlsModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"num_pearls",Py_BuildValue("d",3.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"edge_separation",Py_BuildValue("d",350.000000000000));
+        PyDict_SetItemString(self->params,"sld_pearl",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",80.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->edge_separation.dispersion->accept_as_source(visitor, self->model->edge_separation.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "edge_separation", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLinearPearlsModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CLinearPearlsModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLinearPearlsModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLinearPearlsModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLinearPearlsModel_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(LinearPearlsModel* 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;
+	}
+#pragma omp parallel for
+	 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( LinearPearlsModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLinearPearlsModelError, 
+                   "CLinearPearlsModel.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(CLinearPearlsModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CLinearPearlsModelError, 
+	    	"CLinearPearlsModel.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(CLinearPearlsModelError, 
+                   "CLinearPearlsModel.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(CLinearPearlsModelError, 
+	    		"CLinearPearlsModel.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(CLinearPearlsModelError, 
+                   "CLinearPearlsModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLinearPearlsModelError, 
+                   "CLinearPearlsModel.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(CLinearPearlsModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CLinearPearlsModelError, 
+	    	"CLinearPearlsModel.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(CLinearPearlsModelError, 
+	    		"CLinearPearlsModel.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 = CLinearPearlsModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLinearPearlsModel_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 = CLinearPearlsModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLinearPearlsModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLinearPearlsModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLinearPearlsModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CLinearPearlsModelError, 
+	    	"CLinearPearlsModel.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(CLinearPearlsModelError, 
+	    		"CLinearPearlsModel.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 = CLinearPearlsModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLinearPearlsModel_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 = CLinearPearlsModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLinearPearlsModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLinearPearlsModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLinearPearlsModelError,
+	    	"CLinearPearlsModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "edge_separation")) {
+        self->model->edge_separation.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CLinearPearlsModelError,
+	    	"CLinearPearlsModel.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 CLinearPearlsModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLinearPearlsModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLinearPearlsModel",             /*tp_name*/
+    sizeof(CLinearPearlsModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLinearPearlsModel_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*/
+    "CLinearPearlsModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLinearPearlsModel_methods,             /* tp_methods */
+    CLinearPearlsModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLinearPearlsModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLinearPearlsModel_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 addCLinearPearlsModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLinearPearlsModelType) < 0)
+        return;
+
+    Py_INCREF(&CLinearPearlsModelType);
+    PyModule_AddObject(module, "CLinearPearlsModel", (PyObject *)&CLinearPearlsModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLinearPearlsModel.error";
+    CLinearPearlsModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLinearPearlsModelError", CLinearPearlsModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLogNormal.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLogNormal.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLogNormal.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,537 @@
+/**
+	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
+ */
+
+/** CLogNormal
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\logNormal.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 "logNormal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLogNormalError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    LogNormal * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLogNormal;
+
+
+static void
+CLogNormal_dealloc(CLogNormal* 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 *
+CLogNormal_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLogNormal *self;
+    
+    self = (CLogNormal *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLogNormal_init(CLogNormal *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new LogNormal();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sigma",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"center",Py_BuildValue("d",0.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLogNormal_members[] = {
+    {name_params, T_OBJECT, offsetof(CLogNormal, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLogNormal, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLogNormal, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLogNormal_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(LogNormal* 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;
+	}
+#pragma omp parallel for
+	 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( LogNormal* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLogNormalError, 
+                   "CLogNormal.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(CLogNormal *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLogNormalError, 
+	    	"CLogNormal.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(CLogNormalError, 
+                   "CLogNormal.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(CLogNormalError, 
+	    		"CLogNormal.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(CLogNormalError, 
+                   "CLogNormal.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLogNormalError, 
+                   "CLogNormal.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(CLogNormal *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLogNormalError, 
+	    	"CLogNormal.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(CLogNormalError, 
+	    		"CLogNormal.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 = CLogNormal_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLogNormal_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 = CLogNormal_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLogNormal *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLogNormal *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLogNormal *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLogNormalError, 
+	    	"CLogNormal.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(CLogNormalError, 
+	    		"CLogNormal.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 = CLogNormal_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLogNormal_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 = CLogNormal_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLogNormal *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLogNormal *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLogNormalError,
+	    	"CLogNormal.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CLogNormalError,
+	    	"CLogNormal.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 CLogNormal_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLogNormalType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLogNormal",             /*tp_name*/
+    sizeof(CLogNormal),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLogNormal_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*/
+    "CLogNormal objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLogNormal_methods,             /* tp_methods */
+    CLogNormal_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLogNormal_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLogNormal_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 addCLogNormal(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLogNormalType) < 0)
+        return;
+
+    Py_INCREF(&CLogNormalType);
+    PyModule_AddObject(module, "CLogNormal", (PyObject *)&CLogNormalType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLogNormal.error";
+    CLogNormalError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLogNormalError", CLogNormalError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CLorentzian.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CLorentzian.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CLorentzian.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,537 @@
+/**
+	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
+ */
+
+/** CLorentzian
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\lorentzian.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 "lorentzian.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CLorentzianError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Lorentzian * model;
+    /// Log for unit testing
+    PyObject * log;
+} CLorentzian;
+
+
+static void
+CLorentzian_dealloc(CLorentzian* 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 *
+CLorentzian_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CLorentzian *self;
+    
+    self = (CLorentzian *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CLorentzian_init(CLorentzian *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new Lorentzian();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"center",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"gamma",Py_BuildValue("d",1.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CLorentzian_members[] = {
+    {name_params, T_OBJECT, offsetof(CLorentzian, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CLorentzian, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CLorentzian, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CLorentzian_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(Lorentzian* 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;
+	}
+#pragma omp parallel for
+	 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( Lorentzian* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CLorentzianError, 
+                   "CLorentzian.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(CLorentzian *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    self->model->gamma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gamma") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLorentzianError, 
+	    	"CLorentzian.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(CLorentzianError, 
+                   "CLorentzian.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(CLorentzianError, 
+	    		"CLorentzian.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(CLorentzianError, 
+                   "CLorentzian.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CLorentzianError, 
+                   "CLorentzian.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(CLorentzian *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    self->model->gamma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gamma") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLorentzianError, 
+	    	"CLorentzian.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(CLorentzianError, 
+	    		"CLorentzian.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 = CLorentzian_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CLorentzian_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 = CLorentzian_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CLorentzian *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    self->model->gamma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gamma") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CLorentzian *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    self->model->gamma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gamma") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CLorentzian *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+    self->model->gamma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "gamma") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CLorentzianError, 
+	    	"CLorentzian.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(CLorentzianError, 
+	    		"CLorentzian.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 = CLorentzian_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CLorentzian_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 = CLorentzian_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CLorentzian *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CLorentzian *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CLorentzianError,
+	    	"CLorentzian.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CLorentzianError,
+	    	"CLorentzian.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 CLorentzian_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CLorentzianType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CLorentzian",             /*tp_name*/
+    sizeof(CLorentzian),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CLorentzian_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*/
+    "CLorentzian objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CLorentzian_methods,             /* tp_methods */
+    CLorentzian_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CLorentzian_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CLorentzian_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 addCLorentzian(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CLorentzianType) < 0)
+        return;
+
+    Py_INCREF(&CLorentzianType);
+    PyModule_AddObject(module, "CLorentzian", (PyObject *)&CLorentzianType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CLorentzian.error";
+    CLorentzianError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CLorentzianError", CLorentzianError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CMassFractalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CMassFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CMassFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,549 @@
+/**
+	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
+ */
+
+/** CMassFractalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\massfractal.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 "massfractal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CMassFractalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    MassFractalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CMassFractalModel;
+
+
+static void
+CMassFractalModel_dealloc(CMassFractalModel* 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 *
+CMassFractalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CMassFractalModel *self;
+    
+    self = (CMassFractalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CMassFractalModel_init(CMassFractalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new MassFractalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"co_length",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"mass_dim",Py_BuildValue("d",1.900000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CMassFractalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CMassFractalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CMassFractalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CMassFractalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CMassFractalModel_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(MassFractalModel* 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;
+	}
+#pragma omp parallel for
+	 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( MassFractalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CMassFractalModelError, 
+                   "CMassFractalModel.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(CMassFractalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassFractalModelError, 
+	    	"CMassFractalModel.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(CMassFractalModelError, 
+                   "CMassFractalModel.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(CMassFractalModelError, 
+	    		"CMassFractalModel.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(CMassFractalModelError, 
+                   "CMassFractalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CMassFractalModelError, 
+                   "CMassFractalModel.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(CMassFractalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassFractalModelError, 
+	    	"CMassFractalModel.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(CMassFractalModelError, 
+	    		"CMassFractalModel.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 = CMassFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CMassFractalModel_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 = CMassFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CMassFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CMassFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CMassFractalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassFractalModelError, 
+	    	"CMassFractalModel.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(CMassFractalModelError, 
+	    		"CMassFractalModel.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 = CMassFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CMassFractalModel_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 = CMassFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CMassFractalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CMassFractalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CMassFractalModelError,
+	    	"CMassFractalModel.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CMassFractalModelError,
+	    	"CMassFractalModel.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 CMassFractalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CMassFractalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CMassFractalModel",             /*tp_name*/
+    sizeof(CMassFractalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CMassFractalModel_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*/
+    "CMassFractalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CMassFractalModel_methods,             /* tp_methods */
+    CMassFractalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CMassFractalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CMassFractalModel_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 addCMassFractalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CMassFractalModelType) < 0)
+        return;
+
+    Py_INCREF(&CMassFractalModelType);
+    PyModule_AddObject(module, "CMassFractalModel", (PyObject *)&CMassFractalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CMassFractalModel.error";
+    CMassFractalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CMassFractalModelError", CMassFractalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CMassSurfaceFractal.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CMassSurfaceFractal.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CMassSurfaceFractal.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,555 @@
+/**
+	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
+ */
+
+/** CMassSurfaceFractal
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\masssurfacefractal.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 "masssurfacefractal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CMassSurfaceFractalError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    MassSurfaceFractal * model;
+    /// Log for unit testing
+    PyObject * log;
+} CMassSurfaceFractal;
+
+
+static void
+CMassSurfaceFractal_dealloc(CMassSurfaceFractal* 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 *
+CMassSurfaceFractal_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CMassSurfaceFractal *self;
+    
+    self = (CMassSurfaceFractal *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CMassSurfaceFractal_init(CMassSurfaceFractal *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new MassSurfaceFractal();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"cluster_rg",Py_BuildValue("d",86.700000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"mass_dim",Py_BuildValue("d",1.800000000000));
+        PyDict_SetItemString(self->params,"surface_dim",Py_BuildValue("d",2.300000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"primary_rg",Py_BuildValue("d",4000.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CMassSurfaceFractal_members[] = {
+    {name_params, T_OBJECT, offsetof(CMassSurfaceFractal, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CMassSurfaceFractal, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CMassSurfaceFractal, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CMassSurfaceFractal_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(MassSurfaceFractal* 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;
+	}
+#pragma omp parallel for
+	 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( MassSurfaceFractal* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CMassSurfaceFractalError, 
+                   "CMassSurfaceFractal.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(CMassSurfaceFractal *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassSurfaceFractalError, 
+	    	"CMassSurfaceFractal.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(CMassSurfaceFractalError, 
+                   "CMassSurfaceFractal.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(CMassSurfaceFractalError, 
+	    		"CMassSurfaceFractal.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(CMassSurfaceFractalError, 
+                   "CMassSurfaceFractal.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CMassSurfaceFractalError, 
+                   "CMassSurfaceFractal.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(CMassSurfaceFractal *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassSurfaceFractalError, 
+	    	"CMassSurfaceFractal.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(CMassSurfaceFractalError, 
+	    		"CMassSurfaceFractal.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 = CMassSurfaceFractal_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CMassSurfaceFractal_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 = CMassSurfaceFractal_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CMassSurfaceFractal *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CMassSurfaceFractal *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CMassSurfaceFractal *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->cluster_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "cluster_rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->mass_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "mass_dim") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->primary_rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "primary_rg") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CMassSurfaceFractalError, 
+	    	"CMassSurfaceFractal.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(CMassSurfaceFractalError, 
+	    		"CMassSurfaceFractal.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 = CMassSurfaceFractal_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CMassSurfaceFractal_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 = CMassSurfaceFractal_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CMassSurfaceFractal *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CMassSurfaceFractal *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CMassSurfaceFractalError,
+	    	"CMassSurfaceFractal.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CMassSurfaceFractalError,
+	    	"CMassSurfaceFractal.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 CMassSurfaceFractal_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CMassSurfaceFractalType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CMassSurfaceFractal",             /*tp_name*/
+    sizeof(CMassSurfaceFractal),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CMassSurfaceFractal_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*/
+    "CMassSurfaceFractal objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CMassSurfaceFractal_methods,             /* tp_methods */
+    CMassSurfaceFractal_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CMassSurfaceFractal_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CMassSurfaceFractal_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 addCMassSurfaceFractal(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CMassSurfaceFractalType) < 0)
+        return;
+
+    Py_INCREF(&CMassSurfaceFractalType);
+    PyModule_AddObject(module, "CMassSurfaceFractal", (PyObject *)&CMassSurfaceFractalType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CMassSurfaceFractal.error";
+    CMassSurfaceFractalError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CMassSurfaceFractalError", CMassSurfaceFractalError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CMultiShellModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CMultiShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CMultiShellModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,630 @@
+/**
+	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
+ */
+
+/** CMultiShellModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\multishell.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 "multishell.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CMultiShellModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    MultiShellModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CMultiShellModel;
+
+
+static void
+CMultiShellModel_dealloc(CMultiShellModel* 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 *
+CMultiShellModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CMultiShellModel *self;
+    
+    self = (CMultiShellModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CMultiShellModel_init(CMultiShellModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new MultiShellModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000006400000));
+        PyDict_SetItemString(self->params,"core_radius",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"n_pairs",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"w_thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"s_thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000000400000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->core_radius.dispersion->accept_as_source(visitor, self->model->core_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "core_radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->s_thickness.dispersion->accept_as_source(visitor, self->model->s_thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "s_thickness", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->w_thickness.dispersion->accept_as_source(visitor, self->model->w_thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "w_thickness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CMultiShellModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CMultiShellModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CMultiShellModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CMultiShellModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CMultiShellModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(MultiShellModel* 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;
+	}
+#pragma omp parallel for
+	 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( MultiShellModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CMultiShellModelError, 
+                   "CMultiShellModel.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(CMultiShellModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model->w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model->s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_thickness");
+    self->model->s_thickness.dispersion->accept_as_destination(visitor, self->model->s_thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "w_thickness");
+    self->model->w_thickness.dispersion->accept_as_destination(visitor, self->model->w_thickness.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(CMultiShellModelError, 
+	    	"CMultiShellModel.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(CMultiShellModelError, 
+                   "CMultiShellModel.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(CMultiShellModelError, 
+	    		"CMultiShellModel.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(CMultiShellModelError, 
+                   "CMultiShellModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CMultiShellModelError, 
+                   "CMultiShellModel.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(CMultiShellModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model->w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model->s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_thickness");
+    self->model->s_thickness.dispersion->accept_as_destination(visitor, self->model->s_thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "w_thickness");
+    self->model->w_thickness.dispersion->accept_as_destination(visitor, self->model->w_thickness.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(CMultiShellModelError, 
+	    	"CMultiShellModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CMultiShellModelError, 
+	    		"CMultiShellModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CMultiShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CMultiShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model->w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model->s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_thickness");
+    self->model->s_thickness.dispersion->accept_as_destination(visitor, self->model->s_thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "w_thickness");
+    self->model->w_thickness.dispersion->accept_as_destination(visitor, self->model->w_thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CMultiShellModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model->w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model->s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_thickness");
+    self->model->s_thickness.dispersion->accept_as_destination(visitor, self->model->s_thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "w_thickness");
+    self->model->w_thickness.dispersion->accept_as_destination(visitor, self->model->w_thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CMultiShellModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_radius") );
+    self->model->n_pairs = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_pairs") );
+    self->model->w_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "w_thickness") );
+    self->model->s_thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "s_thickness") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_radius");
+    self->model->core_radius.dispersion->accept_as_destination(visitor, self->model->core_radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "s_thickness");
+    self->model->s_thickness.dispersion->accept_as_destination(visitor, self->model->s_thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "w_thickness");
+    self->model->w_thickness.dispersion->accept_as_destination(visitor, self->model->w_thickness.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(CMultiShellModelError, 
+	    	"CMultiShellModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CMultiShellModelError, 
+	    		"CMultiShellModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CMultiShellModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CMultiShellModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CMultiShellModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CMultiShellModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CMultiShellModelError,
+	    	"CMultiShellModel.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, "core_radius")) {
+        self->model->core_radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "s_thickness")) {
+        self->model->s_thickness.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "w_thickness")) {
+        self->model->w_thickness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CMultiShellModelError,
+	    	"CMultiShellModel.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 CMultiShellModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CMultiShellModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CMultiShellModel",             /*tp_name*/
+    sizeof(CMultiShellModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CMultiShellModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CMultiShellModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CMultiShellModel_methods,             /* tp_methods */
+    CMultiShellModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CMultiShellModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CMultiShellModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCMultiShellModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CMultiShellModelType) < 0)
+        return;
+
+    Py_INCREF(&CMultiShellModelType);
+    PyModule_AddObject(module, "CMultiShellModel", (PyObject *)&CMultiShellModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CMultiShellModel.error";
+    CMultiShellModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CMultiShellModelError", CMultiShellModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/COnionModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/COnionModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/COnionModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,1038 @@
+/**
+	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 src\sans\models\include\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 "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.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell5",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell9",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell7",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_core0",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"rad_core0",Py_BuildValue("d",200.000000000000));
+        PyDict_SetItemString(self->params,"A_shell10",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell1",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"func_shell4",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"func_shell5",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"func_shell6",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"func_shell1",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell10",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"func_shell3",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"func_shell8",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"func_shell9",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"sld_in_shell5",Py_BuildValue("d",0.000003700000));
+        PyDict_SetItemString(self->params,"func_shell10",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"sld_in_shell4",Py_BuildValue("d",0.000003200000));
+        PyDict_SetItemString(self->params,"sld_in_shell7",Py_BuildValue("d",0.000004700000));
+        PyDict_SetItemString(self->params,"sld_out_shell9",Py_BuildValue("d",0.000006000000));
+        PyDict_SetItemString(self->params,"sld_out_shell8",Py_BuildValue("d",0.000005500000));
+        PyDict_SetItemString(self->params,"thick_shell6",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_out_shell2",Py_BuildValue("d",0.000002500000));
+        PyDict_SetItemString(self->params,"sld_in_shell9",Py_BuildValue("d",0.000005700000));
+        PyDict_SetItemString(self->params,"sld_in_shell8",Py_BuildValue("d",0.000005200000));
+        PyDict_SetItemString(self->params,"thick_shell2",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell3",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_out_shell1",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"sld_out_shell5",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_out_shell3",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"sld_in_shell6",Py_BuildValue("d",0.000004200000));
+        PyDict_SetItemString(self->params,"sld_in_shell1",Py_BuildValue("d",0.000001700000));
+        PyDict_SetItemString(self->params,"sld_out_shell4",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_in_shell3",Py_BuildValue("d",0.000002700000));
+        PyDict_SetItemString(self->params,"sld_out_shell6",Py_BuildValue("d",0.000004500000));
+        PyDict_SetItemString(self->params,"func_shell7",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"sld_out_shell7",Py_BuildValue("d",0.000005000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"n_shells",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_in_shell2",Py_BuildValue("d",0.000002200000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006400000));
+        PyDict_SetItemString(self->params,"func_shell2",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"thick_shell8",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_out_shell10",Py_BuildValue("d",0.000006200000));
+        PyDict_SetItemString(self->params,"sld_in_shell10",Py_BuildValue("d",0.000006000000));
+        PyDict_SetItemString(self->params,"A_shell8",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell9",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell6",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell7",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell4",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell5",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell2",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell3",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"A_shell1",Py_BuildValue("d",1.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_core0.dispersion->accept_as_source(visitor, self->model->rad_core0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_core0", 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 char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef COnionModel_members[] = {
+    {name_params, T_OBJECT, offsetof(COnionModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(COnionModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(COnionModel, log), 0, def_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;
+	}
+#pragma omp parallel for
+	 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 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. */
+#pragma omp parallel for
+        for (int 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->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    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->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->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    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_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    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_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    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->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->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    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_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    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_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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) {
+
+	// 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->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    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->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->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    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_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    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_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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 cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(COnionModel *self) {
+
+	// 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->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    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->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->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    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_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    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_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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_VR());
+
+}
+/**
+ * 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->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    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->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->thick_shell3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_shell3") );
+    self->model->sld_out_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell1") );
+    self->model->sld_out_shell5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_out_shell5") );
+    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_in_shell1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_in_shell1") );
+    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_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.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_core0")) {
+        self->model->rad_core0.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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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);
+    static char error_name[] = "COnionModel.error";
+    COnionModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "COnionModelError", COnionModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CParallelepipedModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CParallelepipedModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CParallelepipedModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,741 @@
+/**
+	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
+ */
+
+/** CParallelepipedModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\parallelepiped.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 "parallelepiped.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CParallelepipedModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    ParallelepipedModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CParallelepipedModel;
+
+
+static void
+CParallelepipedModel_dealloc(CParallelepipedModel* 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 *
+CParallelepipedModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CParallelepipedModel *self;
+    
+    self = (CParallelepipedModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CParallelepipedModel_init(CParallelepipedModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new ParallelepipedModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"Up_frac_i",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"short_a",Py_BuildValue("d",35.000000000000));
+        PyDict_SetItemString(self->params,"short_b",Py_BuildValue("d",75.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"long_c",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"sldPipe",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"Up_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_pipe",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"parallel_psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"parallel_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"parallel_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Up_frac_f",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"M_phi_pipe",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_pipe",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->short_a.dispersion->accept_as_source(visitor, self->model->short_a.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "short_a", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->short_b.dispersion->accept_as_source(visitor, self->model->short_b.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "short_b", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->long_c.dispersion->accept_as_source(visitor, self->model->long_c.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "long_c", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_phi.dispersion->accept_as_source(visitor, self->model->parallel_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_psi.dispersion->accept_as_source(visitor, self->model->parallel_psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_psi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->parallel_theta.dispersion->accept_as_source(visitor, self->model->parallel_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "parallel_theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CParallelepipedModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CParallelepipedModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CParallelepipedModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CParallelepipedModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CParallelepipedModel_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(ParallelepipedModel* 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;
+	}
+#pragma omp parallel for
+	 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( ParallelepipedModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CParallelepipedModelError, 
+                   "CParallelepipedModel.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(CParallelepipedModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->short_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_a") );
+    self->model->short_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_b") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->long_c = PyFloat_AsDouble( PyDict_GetItemString(self->params, "long_c") );
+    self->model->sldPipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldPipe") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->M_theta_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_pipe") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_phi_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_pipe") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M0_sld_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_pipe") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_a");
+    self->model->short_a.dispersion->accept_as_destination(visitor, self->model->short_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_b");
+    self->model->short_b.dispersion->accept_as_destination(visitor, self->model->short_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "long_c");
+    self->model->long_c.dispersion->accept_as_destination(visitor, self->model->long_c.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CParallelepipedModelError, 
+	    	"CParallelepipedModel.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(CParallelepipedModelError, 
+                   "CParallelepipedModel.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(CParallelepipedModelError, 
+	    		"CParallelepipedModel.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(CParallelepipedModelError, 
+                   "CParallelepipedModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CParallelepipedModelError, 
+                   "CParallelepipedModel.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(CParallelepipedModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->short_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_a") );
+    self->model->short_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_b") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->long_c = PyFloat_AsDouble( PyDict_GetItemString(self->params, "long_c") );
+    self->model->sldPipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldPipe") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->M_theta_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_pipe") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_phi_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_pipe") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M0_sld_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_pipe") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_a");
+    self->model->short_a.dispersion->accept_as_destination(visitor, self->model->short_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_b");
+    self->model->short_b.dispersion->accept_as_destination(visitor, self->model->short_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "long_c");
+    self->model->long_c.dispersion->accept_as_destination(visitor, self->model->long_c.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CParallelepipedModelError, 
+	    	"CParallelepipedModel.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(CParallelepipedModelError, 
+	    		"CParallelepipedModel.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 = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CParallelepipedModel_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 = CParallelepipedModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CParallelepipedModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->short_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_a") );
+    self->model->short_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_b") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->long_c = PyFloat_AsDouble( PyDict_GetItemString(self->params, "long_c") );
+    self->model->sldPipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldPipe") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->M_theta_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_pipe") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_phi_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_pipe") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M0_sld_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_pipe") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_a");
+    self->model->short_a.dispersion->accept_as_destination(visitor, self->model->short_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_b");
+    self->model->short_b.dispersion->accept_as_destination(visitor, self->model->short_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "long_c");
+    self->model->long_c.dispersion->accept_as_destination(visitor, self->model->long_c.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CParallelepipedModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->short_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_a") );
+    self->model->short_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_b") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->long_c = PyFloat_AsDouble( PyDict_GetItemString(self->params, "long_c") );
+    self->model->sldPipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldPipe") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->M_theta_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_pipe") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_phi_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_pipe") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M0_sld_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_pipe") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_a");
+    self->model->short_a.dispersion->accept_as_destination(visitor, self->model->short_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_b");
+    self->model->short_b.dispersion->accept_as_destination(visitor, self->model->short_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "long_c");
+    self->model->long_c.dispersion->accept_as_destination(visitor, self->model->long_c.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CParallelepipedModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->short_a = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_a") );
+    self->model->short_b = PyFloat_AsDouble( PyDict_GetItemString(self->params, "short_b") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->long_c = PyFloat_AsDouble( PyDict_GetItemString(self->params, "long_c") );
+    self->model->sldPipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldPipe") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->M_theta_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_pipe") );
+    self->model->parallel_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_psi") );
+    self->model->parallel_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_phi") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->parallel_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "parallel_theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->M_phi_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_pipe") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M0_sld_pipe = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_pipe") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_a");
+    self->model->short_a.dispersion->accept_as_destination(visitor, self->model->short_a.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "short_b");
+    self->model->short_b.dispersion->accept_as_destination(visitor, self->model->short_b.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "long_c");
+    self->model->long_c.dispersion->accept_as_destination(visitor, self->model->long_c.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_phi");
+    self->model->parallel_phi.dispersion->accept_as_destination(visitor, self->model->parallel_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_psi");
+    self->model->parallel_psi.dispersion->accept_as_destination(visitor, self->model->parallel_psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "parallel_theta");
+    self->model->parallel_theta.dispersion->accept_as_destination(visitor, self->model->parallel_theta.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(CParallelepipedModelError, 
+	    	"CParallelepipedModel.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(CParallelepipedModelError, 
+	    		"CParallelepipedModel.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 = CParallelepipedModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CParallelepipedModel_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 = CParallelepipedModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CParallelepipedModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CParallelepipedModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CParallelepipedModelError,
+	    	"CParallelepipedModel.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, "short_a")) {
+        self->model->short_a.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "short_b")) {
+        self->model->short_b.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "long_c")) {
+        self->model->long_c.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_phi")) {
+        self->model->parallel_phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_psi")) {
+        self->model->parallel_psi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "parallel_theta")) {
+        self->model->parallel_theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CParallelepipedModelError,
+	    	"CParallelepipedModel.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 CParallelepipedModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CParallelepipedModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CParallelepipedModel",             /*tp_name*/
+    sizeof(CParallelepipedModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CParallelepipedModel_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*/
+    "CParallelepipedModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CParallelepipedModel_methods,             /* tp_methods */
+    CParallelepipedModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CParallelepipedModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CParallelepipedModel_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 addCParallelepipedModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CParallelepipedModelType) < 0)
+        return;
+
+    Py_INCREF(&CParallelepipedModelType);
+    PyModule_AddObject(module, "CParallelepipedModel", (PyObject *)&CParallelepipedModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CParallelepipedModel.error";
+    CParallelepipedModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CParallelepipedModelError", CParallelepipedModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CPearlNecklaceModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CPearlNecklaceModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CPearlNecklaceModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,621 @@
+/**
+	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
+ */
+
+/** CPearlNecklaceModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\pearlnecklace.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 "pearlnecklace.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CPearlNecklaceModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    PearlNecklaceModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CPearlNecklaceModel;
+
+
+static void
+CPearlNecklaceModel_dealloc(CPearlNecklaceModel* 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 *
+CPearlNecklaceModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CPearlNecklaceModel *self;
+    
+    self = (CPearlNecklaceModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CPearlNecklaceModel_init(CPearlNecklaceModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new PearlNecklaceModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"num_pearls",Py_BuildValue("d",3.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_string",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"sld_string",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"edge_separation",Py_BuildValue("d",350.000000000000));
+        PyDict_SetItemString(self->params,"sld_pearl",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",80.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->edge_separation.dispersion->accept_as_source(visitor, self->model->edge_separation.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "edge_separation", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CPearlNecklaceModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CPearlNecklaceModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CPearlNecklaceModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CPearlNecklaceModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CPearlNecklaceModel_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(PearlNecklaceModel* 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;
+	}
+#pragma omp parallel for
+	 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( PearlNecklaceModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CPearlNecklaceModelError, 
+                   "CPearlNecklaceModel.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(CPearlNecklaceModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_string") );
+    self->model->sld_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_string") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CPearlNecklaceModelError, 
+	    	"CPearlNecklaceModel.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(CPearlNecklaceModelError, 
+                   "CPearlNecklaceModel.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(CPearlNecklaceModelError, 
+	    		"CPearlNecklaceModel.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(CPearlNecklaceModelError, 
+                   "CPearlNecklaceModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CPearlNecklaceModelError, 
+                   "CPearlNecklaceModel.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(CPearlNecklaceModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_string") );
+    self->model->sld_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_string") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CPearlNecklaceModelError, 
+	    	"CPearlNecklaceModel.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(CPearlNecklaceModelError, 
+	    		"CPearlNecklaceModel.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 = CPearlNecklaceModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CPearlNecklaceModel_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 = CPearlNecklaceModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CPearlNecklaceModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_string") );
+    self->model->sld_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_string") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CPearlNecklaceModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_string") );
+    self->model->sld_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_string") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CPearlNecklaceModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->num_pearls = PyFloat_AsDouble( PyDict_GetItemString(self->params, "num_pearls") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_string") );
+    self->model->sld_string = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_string") );
+    self->model->edge_separation = PyFloat_AsDouble( PyDict_GetItemString(self->params, "edge_separation") );
+    self->model->sld_pearl = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pearl") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "edge_separation");
+    self->model->edge_separation.dispersion->accept_as_destination(visitor, self->model->edge_separation.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(CPearlNecklaceModelError, 
+	    	"CPearlNecklaceModel.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(CPearlNecklaceModelError, 
+	    		"CPearlNecklaceModel.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 = CPearlNecklaceModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CPearlNecklaceModel_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 = CPearlNecklaceModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CPearlNecklaceModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CPearlNecklaceModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CPearlNecklaceModelError,
+	    	"CPearlNecklaceModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "edge_separation")) {
+        self->model->edge_separation.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CPearlNecklaceModelError,
+	    	"CPearlNecklaceModel.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 CPearlNecklaceModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CPearlNecklaceModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CPearlNecklaceModel",             /*tp_name*/
+    sizeof(CPearlNecklaceModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CPearlNecklaceModel_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*/
+    "CPearlNecklaceModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CPearlNecklaceModel_methods,             /* tp_methods */
+    CPearlNecklaceModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CPearlNecklaceModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CPearlNecklaceModel_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 addCPearlNecklaceModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CPearlNecklaceModelType) < 0)
+        return;
+
+    Py_INCREF(&CPearlNecklaceModelType);
+    PyModule_AddObject(module, "CPearlNecklaceModel", (PyObject *)&CPearlNecklaceModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CPearlNecklaceModel.error";
+    CPearlNecklaceModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CPearlNecklaceModelError", CPearlNecklaceModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CPoly_GaussCoil.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CPoly_GaussCoil.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CPoly_GaussCoil.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,576 @@
+/**
+	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
+ */
+
+/** CPoly_GaussCoil
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\polygausscoil.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 "polygausscoil.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CPoly_GaussCoilError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Poly_GaussCoil * model;
+    /// Log for unit testing
+    PyObject * log;
+} CPoly_GaussCoil;
+
+
+static void
+CPoly_GaussCoil_dealloc(CPoly_GaussCoil* 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 *
+CPoly_GaussCoil_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CPoly_GaussCoil *self;
+    
+    self = (CPoly_GaussCoil *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CPoly_GaussCoil_init(CPoly_GaussCoil *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new Poly_GaussCoil();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"poly_m",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"rg",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rg.dispersion->accept_as_source(visitor, self->model->rg.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rg", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CPoly_GaussCoil_members[] = {
+    {name_params, T_OBJECT, offsetof(CPoly_GaussCoil, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CPoly_GaussCoil, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CPoly_GaussCoil, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CPoly_GaussCoil_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(Poly_GaussCoil* 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;
+	}
+#pragma omp parallel for
+	 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( Poly_GaussCoil* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CPoly_GaussCoilError, 
+                   "CPoly_GaussCoil.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(CPoly_GaussCoil *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->poly_m = PyFloat_AsDouble( PyDict_GetItemString(self->params, "poly_m") );
+    self->model->rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rg");
+    self->model->rg.dispersion->accept_as_destination(visitor, self->model->rg.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(CPoly_GaussCoilError, 
+	    	"CPoly_GaussCoil.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(CPoly_GaussCoilError, 
+                   "CPoly_GaussCoil.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(CPoly_GaussCoilError, 
+	    		"CPoly_GaussCoil.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(CPoly_GaussCoilError, 
+                   "CPoly_GaussCoil.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CPoly_GaussCoilError, 
+                   "CPoly_GaussCoil.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(CPoly_GaussCoil *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->poly_m = PyFloat_AsDouble( PyDict_GetItemString(self->params, "poly_m") );
+    self->model->rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rg");
+    self->model->rg.dispersion->accept_as_destination(visitor, self->model->rg.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(CPoly_GaussCoilError, 
+	    	"CPoly_GaussCoil.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(CPoly_GaussCoilError, 
+	    		"CPoly_GaussCoil.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 = CPoly_GaussCoil_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CPoly_GaussCoil_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 = CPoly_GaussCoil_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CPoly_GaussCoil *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->poly_m = PyFloat_AsDouble( PyDict_GetItemString(self->params, "poly_m") );
+    self->model->rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rg");
+    self->model->rg.dispersion->accept_as_destination(visitor, self->model->rg.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CPoly_GaussCoil *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->poly_m = PyFloat_AsDouble( PyDict_GetItemString(self->params, "poly_m") );
+    self->model->rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rg");
+    self->model->rg.dispersion->accept_as_destination(visitor, self->model->rg.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CPoly_GaussCoil *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->poly_m = PyFloat_AsDouble( PyDict_GetItemString(self->params, "poly_m") );
+    self->model->rg = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rg") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rg");
+    self->model->rg.dispersion->accept_as_destination(visitor, self->model->rg.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(CPoly_GaussCoilError, 
+	    	"CPoly_GaussCoil.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(CPoly_GaussCoilError, 
+	    		"CPoly_GaussCoil.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 = CPoly_GaussCoil_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CPoly_GaussCoil_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 = CPoly_GaussCoil_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CPoly_GaussCoil *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CPoly_GaussCoil *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CPoly_GaussCoilError,
+	    	"CPoly_GaussCoil.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, "rg")) {
+        self->model->rg.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CPoly_GaussCoilError,
+	    	"CPoly_GaussCoil.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 CPoly_GaussCoil_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CPoly_GaussCoilType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CPoly_GaussCoil",             /*tp_name*/
+    sizeof(CPoly_GaussCoil),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CPoly_GaussCoil_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*/
+    "CPoly_GaussCoil objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CPoly_GaussCoil_methods,             /* tp_methods */
+    CPoly_GaussCoil_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CPoly_GaussCoil_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CPoly_GaussCoil_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 addCPoly_GaussCoil(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CPoly_GaussCoilType) < 0)
+        return;
+
+    Py_INCREF(&CPoly_GaussCoilType);
+    PyModule_AddObject(module, "CPoly_GaussCoil", (PyObject *)&CPoly_GaussCoilType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CPoly_GaussCoil.error";
+    CPoly_GaussCoilError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CPoly_GaussCoilError", CPoly_GaussCoilError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CPringlesModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CPringlesModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CPringlesModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,645 @@
+/**
+	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
+ */
+
+/** CPringlesModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\pringles.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 "pringles.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CPringlesModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    PringlesModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CPringlesModel;
+
+
+static void
+CPringlesModel_dealloc(CPringlesModel* 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 *
+CPringlesModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CPringlesModel *self;
+    
+    self = (CPringlesModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CPringlesModel_init(CPringlesModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new PringlesModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_solvent",Py_BuildValue("d",0.000006350000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"beta",Py_BuildValue("d",0.020000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"sld_pringle",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"alpha",Py_BuildValue("d",0.001000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thickness.dispersion->accept_as_source(visitor, self->model->thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thickness", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->alpha.dispersion->accept_as_source(visitor, self->model->alpha.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "alpha", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->beta.dispersion->accept_as_source(visitor, self->model->beta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "beta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CPringlesModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CPringlesModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CPringlesModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CPringlesModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CPringlesModel_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(PringlesModel* 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;
+	}
+#pragma omp parallel for
+	 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( PringlesModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CPringlesModelError, 
+                   "CPringlesModel.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(CPringlesModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->beta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "beta") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sld_pringle = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pringle") );
+    self->model->alpha = PyFloat_AsDouble( PyDict_GetItemString(self->params, "alpha") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "alpha");
+    self->model->alpha.dispersion->accept_as_destination(visitor, self->model->alpha.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "beta");
+    self->model->beta.dispersion->accept_as_destination(visitor, self->model->beta.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(CPringlesModelError, 
+	    	"CPringlesModel.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(CPringlesModelError, 
+                   "CPringlesModel.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(CPringlesModelError, 
+	    		"CPringlesModel.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(CPringlesModelError, 
+                   "CPringlesModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CPringlesModelError, 
+                   "CPringlesModel.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(CPringlesModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->beta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "beta") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sld_pringle = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pringle") );
+    self->model->alpha = PyFloat_AsDouble( PyDict_GetItemString(self->params, "alpha") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "alpha");
+    self->model->alpha.dispersion->accept_as_destination(visitor, self->model->alpha.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "beta");
+    self->model->beta.dispersion->accept_as_destination(visitor, self->model->beta.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(CPringlesModelError, 
+	    	"CPringlesModel.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(CPringlesModelError, 
+	    		"CPringlesModel.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 = CPringlesModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CPringlesModel_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 = CPringlesModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CPringlesModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->beta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "beta") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sld_pringle = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pringle") );
+    self->model->alpha = PyFloat_AsDouble( PyDict_GetItemString(self->params, "alpha") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "alpha");
+    self->model->alpha.dispersion->accept_as_destination(visitor, self->model->alpha.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "beta");
+    self->model->beta.dispersion->accept_as_destination(visitor, self->model->beta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CPringlesModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->beta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "beta") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sld_pringle = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pringle") );
+    self->model->alpha = PyFloat_AsDouble( PyDict_GetItemString(self->params, "alpha") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "alpha");
+    self->model->alpha.dispersion->accept_as_destination(visitor, self->model->alpha.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "beta");
+    self->model->beta.dispersion->accept_as_destination(visitor, self->model->beta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CPringlesModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sld_solvent = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solvent") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->beta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "beta") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->sld_pringle = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_pringle") );
+    self->model->alpha = PyFloat_AsDouble( PyDict_GetItemString(self->params, "alpha") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "alpha");
+    self->model->alpha.dispersion->accept_as_destination(visitor, self->model->alpha.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "beta");
+    self->model->beta.dispersion->accept_as_destination(visitor, self->model->beta.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(CPringlesModelError, 
+	    	"CPringlesModel.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(CPringlesModelError, 
+	    		"CPringlesModel.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 = CPringlesModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CPringlesModel_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 = CPringlesModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CPringlesModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CPringlesModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CPringlesModelError,
+	    	"CPringlesModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thickness")) {
+        self->model->thickness.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "alpha")) {
+        self->model->alpha.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "beta")) {
+        self->model->beta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CPringlesModelError,
+	    	"CPringlesModel.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 CPringlesModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CPringlesModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CPringlesModel",             /*tp_name*/
+    sizeof(CPringlesModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CPringlesModel_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*/
+    "CPringlesModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CPringlesModel_methods,             /* tp_methods */
+    CPringlesModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CPringlesModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CPringlesModel_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 addCPringlesModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CPringlesModelType) < 0)
+        return;
+
+    Py_INCREF(&CPringlesModelType);
+    PyModule_AddObject(module, "CPringlesModel", (PyObject *)&CPringlesModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CPringlesModel.error";
+    CPringlesModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CPringlesModelError", CPringlesModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CRPAModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CRPAModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CRPAModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,726 @@
+/**
+	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
+ */
+
+/** CRPAModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\rpa.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 "rpa.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CRPAModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    RPAModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CRPAModel;
+
+
+static void
+CRPAModel_dealloc(CRPAModel* 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 *
+CRPAModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CRPAModel *self;
+    
+    self = (CRPAModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CRPAModel_init(CRPAModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new RPAModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"va",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"vb",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"vc",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"Lb",Py_BuildValue("d",0.000000000001));
+        PyDict_SetItemString(self->params,"Lc",Py_BuildValue("d",0.000000000001));
+        PyDict_SetItemString(self->params,"La",Py_BuildValue("d",0.000000000001));
+        PyDict_SetItemString(self->params,"Na",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"Nb",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"Nc",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"Nd",Py_BuildValue("d",1000.000000000000));
+        PyDict_SetItemString(self->params,"Ld",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Kcd",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"vd",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"Phib",Py_BuildValue("d",0.250000000000));
+        PyDict_SetItemString(self->params,"Kac",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"Kab",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"bb",Py_BuildValue("d",5.000000000000));
+        PyDict_SetItemString(self->params,"Kad",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"bd",Py_BuildValue("d",5.000000000000));
+        PyDict_SetItemString(self->params,"Phid",Py_BuildValue("d",0.250000000000));
+        PyDict_SetItemString(self->params,"Phic",Py_BuildValue("d",0.250000000000));
+        PyDict_SetItemString(self->params,"ba",Py_BuildValue("d",5.000000000000));
+        PyDict_SetItemString(self->params,"Phia",Py_BuildValue("d",0.250000000000));
+        PyDict_SetItemString(self->params,"bc",Py_BuildValue("d",5.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Kbc",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"Kbd",Py_BuildValue("d",-0.000400000000));
+        PyDict_SetItemString(self->params,"lcase_n",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->background.dispersion->accept_as_source(visitor, self->model->background.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "background", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CRPAModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CRPAModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CRPAModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CRPAModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CRPAModel_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(RPAModel* 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;
+	}
+#pragma omp parallel for
+	 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( RPAModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CRPAModelError, 
+                   "CRPAModel.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(CRPAModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->va = PyFloat_AsDouble( PyDict_GetItemString(self->params, "va") );
+    self->model->vb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vb") );
+    self->model->vc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vc") );
+    self->model->Lb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lb") );
+    self->model->Lc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lc") );
+    self->model->La = PyFloat_AsDouble( PyDict_GetItemString(self->params, "La") );
+    self->model->Na = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Na") );
+    self->model->Nb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nb") );
+    self->model->Nc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nc") );
+    self->model->Nd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nd") );
+    self->model->Ld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Ld") );
+    self->model->Kcd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kcd") );
+    self->model->vd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vd") );
+    self->model->Phib = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phib") );
+    self->model->Kac = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kac") );
+    self->model->Kab = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kab") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bb") );
+    self->model->Kad = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kad") );
+    self->model->bd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bd") );
+    self->model->Phid = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phid") );
+    self->model->Phic = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phic") );
+    self->model->ba = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ba") );
+    self->model->Phia = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phia") );
+    self->model->bc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bc") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->Kbc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbc") );
+    self->model->Kbd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbd") );
+    self->model->lcase_n = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lcase_n") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CRPAModelError, 
+	    	"CRPAModel.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(CRPAModelError, 
+                   "CRPAModel.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(CRPAModelError, 
+	    		"CRPAModel.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(CRPAModelError, 
+                   "CRPAModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CRPAModelError, 
+                   "CRPAModel.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(CRPAModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->va = PyFloat_AsDouble( PyDict_GetItemString(self->params, "va") );
+    self->model->vb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vb") );
+    self->model->vc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vc") );
+    self->model->Lb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lb") );
+    self->model->Lc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lc") );
+    self->model->La = PyFloat_AsDouble( PyDict_GetItemString(self->params, "La") );
+    self->model->Na = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Na") );
+    self->model->Nb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nb") );
+    self->model->Nc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nc") );
+    self->model->Nd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nd") );
+    self->model->Ld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Ld") );
+    self->model->Kcd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kcd") );
+    self->model->vd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vd") );
+    self->model->Phib = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phib") );
+    self->model->Kac = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kac") );
+    self->model->Kab = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kab") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bb") );
+    self->model->Kad = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kad") );
+    self->model->bd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bd") );
+    self->model->Phid = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phid") );
+    self->model->Phic = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phic") );
+    self->model->ba = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ba") );
+    self->model->Phia = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phia") );
+    self->model->bc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bc") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->Kbc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbc") );
+    self->model->Kbd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbd") );
+    self->model->lcase_n = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lcase_n") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CRPAModelError, 
+	    	"CRPAModel.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(CRPAModelError, 
+	    		"CRPAModel.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 = CRPAModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CRPAModel_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 = CRPAModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CRPAModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->va = PyFloat_AsDouble( PyDict_GetItemString(self->params, "va") );
+    self->model->vb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vb") );
+    self->model->vc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vc") );
+    self->model->Lb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lb") );
+    self->model->Lc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lc") );
+    self->model->La = PyFloat_AsDouble( PyDict_GetItemString(self->params, "La") );
+    self->model->Na = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Na") );
+    self->model->Nb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nb") );
+    self->model->Nc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nc") );
+    self->model->Nd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nd") );
+    self->model->Ld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Ld") );
+    self->model->Kcd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kcd") );
+    self->model->vd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vd") );
+    self->model->Phib = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phib") );
+    self->model->Kac = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kac") );
+    self->model->Kab = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kab") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bb") );
+    self->model->Kad = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kad") );
+    self->model->bd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bd") );
+    self->model->Phid = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phid") );
+    self->model->Phic = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phic") );
+    self->model->ba = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ba") );
+    self->model->Phia = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phia") );
+    self->model->bc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bc") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->Kbc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbc") );
+    self->model->Kbd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbd") );
+    self->model->lcase_n = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lcase_n") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CRPAModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->va = PyFloat_AsDouble( PyDict_GetItemString(self->params, "va") );
+    self->model->vb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vb") );
+    self->model->vc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vc") );
+    self->model->Lb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lb") );
+    self->model->Lc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lc") );
+    self->model->La = PyFloat_AsDouble( PyDict_GetItemString(self->params, "La") );
+    self->model->Na = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Na") );
+    self->model->Nb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nb") );
+    self->model->Nc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nc") );
+    self->model->Nd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nd") );
+    self->model->Ld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Ld") );
+    self->model->Kcd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kcd") );
+    self->model->vd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vd") );
+    self->model->Phib = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phib") );
+    self->model->Kac = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kac") );
+    self->model->Kab = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kab") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bb") );
+    self->model->Kad = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kad") );
+    self->model->bd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bd") );
+    self->model->Phid = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phid") );
+    self->model->Phic = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phic") );
+    self->model->ba = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ba") );
+    self->model->Phia = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phia") );
+    self->model->bc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bc") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->Kbc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbc") );
+    self->model->Kbd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbd") );
+    self->model->lcase_n = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lcase_n") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CRPAModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->va = PyFloat_AsDouble( PyDict_GetItemString(self->params, "va") );
+    self->model->vb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vb") );
+    self->model->vc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vc") );
+    self->model->Lb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lb") );
+    self->model->Lc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Lc") );
+    self->model->La = PyFloat_AsDouble( PyDict_GetItemString(self->params, "La") );
+    self->model->Na = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Na") );
+    self->model->Nb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nb") );
+    self->model->Nc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nc") );
+    self->model->Nd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Nd") );
+    self->model->Ld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Ld") );
+    self->model->Kcd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kcd") );
+    self->model->vd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "vd") );
+    self->model->Phib = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phib") );
+    self->model->Kac = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kac") );
+    self->model->Kab = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kab") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->bb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bb") );
+    self->model->Kad = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kad") );
+    self->model->bd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bd") );
+    self->model->Phid = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phid") );
+    self->model->Phic = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phic") );
+    self->model->ba = PyFloat_AsDouble( PyDict_GetItemString(self->params, "ba") );
+    self->model->Phia = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Phia") );
+    self->model->bc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "bc") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->Kbc = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbc") );
+    self->model->Kbd = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Kbd") );
+    self->model->lcase_n = PyFloat_AsDouble( PyDict_GetItemString(self->params, "lcase_n") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CRPAModelError, 
+	    	"CRPAModel.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(CRPAModelError, 
+	    		"CRPAModel.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 = CRPAModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CRPAModel_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 = CRPAModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CRPAModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CRPAModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CRPAModelError,
+	    	"CRPAModel.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, "background")) {
+        self->model->background.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CRPAModelError,
+	    	"CRPAModel.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 CRPAModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CRPAModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CRPAModel",             /*tp_name*/
+    sizeof(CRPAModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CRPAModel_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*/
+    "CRPAModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CRPAModel_methods,             /* tp_methods */
+    CRPAModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CRPAModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CRPAModel_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 addCRPAModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CRPAModelType) < 0)
+        return;
+
+    Py_INCREF(&CRPAModelType);
+    PyModule_AddObject(module, "CRPAModel", (PyObject *)&CRPAModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CRPAModel.error";
+    CRPAModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CRPAModelError", CRPAModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CRaspBerryModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CRaspBerryModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CRaspBerryModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,612 @@
+/**
+	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
+ */
+
+/** CRaspBerryModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\raspberry.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 "raspberry.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CRaspBerryModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    RaspBerryModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CRaspBerryModel;
+
+
+static void
+CRaspBerryModel_dealloc(CRaspBerryModel* 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 *
+CRaspBerryModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CRaspBerryModel *self;
+    
+    self = (CRaspBerryModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CRaspBerryModel_init(CRaspBerryModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new RaspBerryModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"volf_Ssph",Py_BuildValue("d",0.005000000000));
+        PyDict_SetItemString(self->params,"sld_Ssph",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"radius_Ssph",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"delta_Ssph",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"radius_Lsph",Py_BuildValue("d",5000.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"surfrac_Ssph",Py_BuildValue("d",0.400000000000));
+        PyDict_SetItemString(self->params,"sld_Lsph",Py_BuildValue("d",-0.000000400000));
+        PyDict_SetItemString(self->params,"volf_Lsph",Py_BuildValue("d",0.050000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius_Lsph.dispersion->accept_as_source(visitor, self->model->radius_Lsph.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius_Lsph", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CRaspBerryModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CRaspBerryModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CRaspBerryModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CRaspBerryModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CRaspBerryModel_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(RaspBerryModel* 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;
+	}
+#pragma omp parallel for
+	 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( RaspBerryModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CRaspBerryModelError, 
+                   "CRaspBerryModel.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(CRaspBerryModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->volf_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Ssph") );
+    self->model->sld_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Ssph") );
+    self->model->radius_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Ssph") );
+    self->model->delta_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta_Ssph") );
+    self->model->radius_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Lsph") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->surfrac_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surfrac_Ssph") );
+    self->model->sld_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Lsph") );
+    self->model->volf_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Lsph") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_Lsph");
+    self->model->radius_Lsph.dispersion->accept_as_destination(visitor, self->model->radius_Lsph.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(CRaspBerryModelError, 
+	    	"CRaspBerryModel.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(CRaspBerryModelError, 
+                   "CRaspBerryModel.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(CRaspBerryModelError, 
+	    		"CRaspBerryModel.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(CRaspBerryModelError, 
+                   "CRaspBerryModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CRaspBerryModelError, 
+                   "CRaspBerryModel.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(CRaspBerryModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->volf_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Ssph") );
+    self->model->sld_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Ssph") );
+    self->model->radius_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Ssph") );
+    self->model->delta_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta_Ssph") );
+    self->model->radius_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Lsph") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->surfrac_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surfrac_Ssph") );
+    self->model->sld_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Lsph") );
+    self->model->volf_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Lsph") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_Lsph");
+    self->model->radius_Lsph.dispersion->accept_as_destination(visitor, self->model->radius_Lsph.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(CRaspBerryModelError, 
+	    	"CRaspBerryModel.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(CRaspBerryModelError, 
+	    		"CRaspBerryModel.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 = CRaspBerryModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CRaspBerryModel_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 = CRaspBerryModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CRaspBerryModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->volf_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Ssph") );
+    self->model->sld_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Ssph") );
+    self->model->radius_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Ssph") );
+    self->model->delta_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta_Ssph") );
+    self->model->radius_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Lsph") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->surfrac_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surfrac_Ssph") );
+    self->model->sld_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Lsph") );
+    self->model->volf_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Lsph") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_Lsph");
+    self->model->radius_Lsph.dispersion->accept_as_destination(visitor, self->model->radius_Lsph.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CRaspBerryModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->volf_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Ssph") );
+    self->model->sld_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Ssph") );
+    self->model->radius_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Ssph") );
+    self->model->delta_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta_Ssph") );
+    self->model->radius_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Lsph") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->surfrac_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surfrac_Ssph") );
+    self->model->sld_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Lsph") );
+    self->model->volf_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Lsph") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_Lsph");
+    self->model->radius_Lsph.dispersion->accept_as_destination(visitor, self->model->radius_Lsph.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CRaspBerryModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->volf_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Ssph") );
+    self->model->sld_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Ssph") );
+    self->model->radius_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Ssph") );
+    self->model->delta_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "delta_Ssph") );
+    self->model->radius_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius_Lsph") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->surfrac_Ssph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surfrac_Ssph") );
+    self->model->sld_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_Lsph") );
+    self->model->volf_Lsph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volf_Lsph") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius_Lsph");
+    self->model->radius_Lsph.dispersion->accept_as_destination(visitor, self->model->radius_Lsph.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(CRaspBerryModelError, 
+	    	"CRaspBerryModel.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(CRaspBerryModelError, 
+	    		"CRaspBerryModel.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 = CRaspBerryModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CRaspBerryModel_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 = CRaspBerryModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CRaspBerryModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CRaspBerryModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CRaspBerryModelError,
+	    	"CRaspBerryModel.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, "radius_Lsph")) {
+        self->model->radius_Lsph.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CRaspBerryModelError,
+	    	"CRaspBerryModel.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 CRaspBerryModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CRaspBerryModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CRaspBerryModel",             /*tp_name*/
+    sizeof(CRaspBerryModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CRaspBerryModel_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*/
+    "CRaspBerryModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CRaspBerryModel_methods,             /* tp_methods */
+    CRaspBerryModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CRaspBerryModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CRaspBerryModel_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 addCRaspBerryModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CRaspBerryModelType) < 0)
+        return;
+
+    Py_INCREF(&CRaspBerryModelType);
+    PyModule_AddObject(module, "CRaspBerryModel", (PyObject *)&CRaspBerryModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CRaspBerryModel.error";
+    CRaspBerryModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CRaspBerryModelError", CRaspBerryModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CReflAdvModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CReflAdvModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CReflAdvModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,978 @@
+/**
+	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
+ */
+
+/** CReflAdvModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\refl_adv.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 "refl_adv.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CReflAdvModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    ReflAdvModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CReflAdvModel;
+
+
+static void
+CReflAdvModel_dealloc(CReflAdvModel* 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 *
+CReflAdvModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CReflAdvModel *self;
+    
+    self = (CReflAdvModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CReflAdvModel_init(CReflAdvModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new ReflAdvModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"sldIM_flat4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat8",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat9",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat7",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat10",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat5",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat1",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat3",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"n_layers",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat6",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat7",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat4",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat5",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter0",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter1",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_bottom0",Py_BuildValue("d",0.000002070000));
+        PyDict_SetItemString(self->params,"thick_inter3",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter4",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter5",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter6",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter7",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter8",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter9",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"npts_inter",Py_BuildValue("d",21.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter9",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter10",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_flat3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter8",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat2",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"func_inter0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_medium",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"func_inter2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat10",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"func_inter5",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter6",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter7",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat4",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat5",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat6",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat7",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat1",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat2",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat3",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sldIM_flat8",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat8",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat9",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sldIM_flat9",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"nu_inter10",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_sub0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldIM_medium",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat10",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sldIM_flat6",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter2",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"nu_inter8",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter5",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter4",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter7",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter6",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter1",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter0",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter3",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter2",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter9",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"func_inter10",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->thick_inter0.dispersion->accept_as_source(visitor, self->model->thick_inter0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_inter0", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CReflAdvModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CReflAdvModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CReflAdvModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CReflAdvModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CReflAdvModel_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(ReflAdvModel* 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;
+	}
+#pragma omp parallel for
+	 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( ReflAdvModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CReflAdvModelError, 
+                   "CReflAdvModel.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(CReflAdvModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sldIM_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat4") );
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->sldIM_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat7") );
+    self->model->sldIM_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat10") );
+    self->model->sldIM_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat5") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->sldIM_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldIM_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat2") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->sldIM_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat3") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sldIM_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat8") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->sldIM_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sldIM_sub0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_sub0") );
+    self->model->sldIM_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_medium") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->sldIM_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat6") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflAdvModelError, 
+	    	"CReflAdvModel.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(CReflAdvModelError, 
+                   "CReflAdvModel.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(CReflAdvModelError, 
+	    		"CReflAdvModel.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(CReflAdvModelError, 
+                   "CReflAdvModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CReflAdvModelError, 
+                   "CReflAdvModel.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(CReflAdvModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sldIM_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat4") );
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->sldIM_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat7") );
+    self->model->sldIM_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat10") );
+    self->model->sldIM_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat5") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->sldIM_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldIM_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat2") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->sldIM_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat3") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sldIM_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat8") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->sldIM_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sldIM_sub0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_sub0") );
+    self->model->sldIM_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_medium") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->sldIM_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat6") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflAdvModelError, 
+	    	"CReflAdvModel.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(CReflAdvModelError, 
+	    		"CReflAdvModel.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 = CReflAdvModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CReflAdvModel_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 = CReflAdvModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CReflAdvModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sldIM_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat4") );
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->sldIM_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat7") );
+    self->model->sldIM_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat10") );
+    self->model->sldIM_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat5") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->sldIM_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldIM_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat2") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->sldIM_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat3") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sldIM_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat8") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->sldIM_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sldIM_sub0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_sub0") );
+    self->model->sldIM_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_medium") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->sldIM_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat6") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CReflAdvModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sldIM_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat4") );
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->sldIM_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat7") );
+    self->model->sldIM_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat10") );
+    self->model->sldIM_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat5") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->sldIM_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldIM_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat2") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->sldIM_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat3") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sldIM_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat8") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->sldIM_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sldIM_sub0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_sub0") );
+    self->model->sldIM_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_medium") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->sldIM_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat6") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CReflAdvModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->sldIM_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat4") );
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->sldIM_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat7") );
+    self->model->sldIM_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat10") );
+    self->model->sldIM_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat5") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->sldIM_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sldIM_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat2") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->sldIM_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat3") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sldIM_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat8") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->sldIM_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sldIM_sub0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_sub0") );
+    self->model->sldIM_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_medium") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->sldIM_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldIM_flat6") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflAdvModelError, 
+	    	"CReflAdvModel.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(CReflAdvModelError, 
+	    		"CReflAdvModel.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 = CReflAdvModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CReflAdvModel_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 = CReflAdvModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CReflAdvModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CReflAdvModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CReflAdvModelError,
+	    	"CReflAdvModel.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, "thick_inter0")) {
+        self->model->thick_inter0.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CReflAdvModelError,
+	    	"CReflAdvModel.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 CReflAdvModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CReflAdvModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CReflAdvModel",             /*tp_name*/
+    sizeof(CReflAdvModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CReflAdvModel_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*/
+    "CReflAdvModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CReflAdvModel_methods,             /* tp_methods */
+    CReflAdvModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CReflAdvModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CReflAdvModel_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 addCReflAdvModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CReflAdvModelType) < 0)
+        return;
+
+    Py_INCREF(&CReflAdvModelType);
+    PyModule_AddObject(module, "CReflAdvModel", (PyObject *)&CReflAdvModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CReflAdvModel.error";
+    CReflAdvModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CReflAdvModelError", CReflAdvModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CReflModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CReflModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CReflModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,834 @@
+/**
+	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
+ */
+
+/** CReflModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\refl.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 "refl.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CReflModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    ReflModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CReflModel;
+
+
+static void
+CReflModel_dealloc(CReflModel* 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 *
+CReflModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CReflModel *self;
+    
+    self = (CReflModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CReflModel_init(CReflModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new ReflModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"thick_flat8",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat9",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat1",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat3",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"n_layers",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat6",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat7",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat4",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat5",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter0",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter1",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_bottom0",Py_BuildValue("d",0.000002070000));
+        PyDict_SetItemString(self->params,"thick_inter3",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter4",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter5",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter6",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter7",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter8",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter9",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"func_inter9",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter10",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"func_inter8",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat2",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"func_inter0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_medium",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"func_inter2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat10",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"func_inter5",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter6",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter7",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat4",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat5",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat6",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat7",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat1",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat2",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat3",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat8",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat9",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat10",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"func_inter4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter2",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"func_inter10",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->thick_inter0.dispersion->accept_as_source(visitor, self->model->thick_inter0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_inter0", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CReflModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CReflModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CReflModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CReflModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CReflModel_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(ReflModel* 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;
+	}
+#pragma omp parallel for
+	 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( ReflModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CReflModelError, 
+                   "CReflModel.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(CReflModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflModelError, 
+	    	"CReflModel.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(CReflModelError, 
+                   "CReflModel.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(CReflModelError, 
+	    		"CReflModel.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(CReflModelError, 
+                   "CReflModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CReflModelError, 
+                   "CReflModel.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(CReflModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflModelError, 
+	    	"CReflModel.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(CReflModelError, 
+	    		"CReflModel.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 = CReflModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CReflModel_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 = CReflModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CReflModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CReflModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CReflModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->n_layers = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_layers") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->sld_bottom0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_bottom0") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->sld_medium = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_medium") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->sld_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CReflModelError, 
+	    	"CReflModel.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(CReflModelError, 
+	    		"CReflModel.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 = CReflModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CReflModel_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 = CReflModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CReflModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CReflModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CReflModelError,
+	    	"CReflModel.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, "thick_inter0")) {
+        self->model->thick_inter0.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CReflModelError,
+	    	"CReflModel.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 CReflModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CReflModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CReflModel",             /*tp_name*/
+    sizeof(CReflModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CReflModel_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*/
+    "CReflModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CReflModel_methods,             /* tp_methods */
+    CReflModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CReflModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CReflModel_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 addCReflModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CReflModelType) < 0)
+        return;
+
+    Py_INCREF(&CReflModelType);
+    PyModule_AddObject(module, "CReflModel", (PyObject *)&CReflModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CReflModel.error";
+    CReflModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CReflModelError", CReflModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSCCrystalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSCCrystalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,657 @@
+/**
+	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
+ */
+
+/** CSCCrystalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\sc.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 "sc.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSCCrystalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SCCrystalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSCCrystalModel;
+
+
+static void
+CSCCrystalModel_dealloc(CSCCrystalModel* 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 *
+CSCCrystalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSCCrystalModel *self;
+    
+    self = (CSCCrystalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSCCrystalModel_init(CSCCrystalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SCCrystalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"dnn",Py_BuildValue("d",220.000000000000));
+        PyDict_SetItemString(self->params,"sldSph",Py_BuildValue("d",0.000003000000));
+        PyDict_SetItemString(self->params,"d_factor",Py_BuildValue("d",0.060000000000));
+        PyDict_SetItemString(self->params,"psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",40.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->phi.dispersion->accept_as_source(visitor, self->model->phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->psi.dispersion->accept_as_source(visitor, self->model->psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "psi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->theta.dispersion->accept_as_source(visitor, self->model->theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "theta", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSCCrystalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CSCCrystalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSCCrystalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSCCrystalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSCCrystalModel_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(SCCrystalModel* 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;
+	}
+#pragma omp parallel for
+	 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( SCCrystalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSCCrystalModelError, 
+                   "CSCCrystalModel.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(CSCCrystalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CSCCrystalModelError, 
+	    	"CSCCrystalModel.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(CSCCrystalModelError, 
+                   "CSCCrystalModel.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(CSCCrystalModelError, 
+	    		"CSCCrystalModel.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(CSCCrystalModelError, 
+                   "CSCCrystalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSCCrystalModelError, 
+                   "CSCCrystalModel.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(CSCCrystalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CSCCrystalModelError, 
+	    	"CSCCrystalModel.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(CSCCrystalModelError, 
+	    		"CSCCrystalModel.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 = CSCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSCCrystalModel_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 = CSCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSCCrystalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSCCrystalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "phi") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->dnn = PyFloat_AsDouble( PyDict_GetItemString(self->params, "dnn") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->d_factor = PyFloat_AsDouble( PyDict_GetItemString(self->params, "d_factor") );
+    self->model->psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "psi") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "theta") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "phi");
+    self->model->phi.dispersion->accept_as_destination(visitor, self->model->phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "psi");
+    self->model->psi.dispersion->accept_as_destination(visitor, self->model->psi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "theta");
+    self->model->theta.dispersion->accept_as_destination(visitor, self->model->theta.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(CSCCrystalModelError, 
+	    	"CSCCrystalModel.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(CSCCrystalModelError, 
+	    		"CSCCrystalModel.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 = CSCCrystalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSCCrystalModel_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 = CSCCrystalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSCCrystalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSCCrystalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSCCrystalModelError,
+	    	"CSCCrystalModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "phi")) {
+        self->model->phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "psi")) {
+        self->model->psi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "theta")) {
+        self->model->theta.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CSCCrystalModelError,
+	    	"CSCCrystalModel.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 CSCCrystalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSCCrystalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSCCrystalModel",             /*tp_name*/
+    sizeof(CSCCrystalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSCCrystalModel_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*/
+    "CSCCrystalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSCCrystalModel_methods,             /* tp_methods */
+    CSCCrystalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSCCrystalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSCCrystalModel_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 addCSCCrystalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSCCrystalModelType) < 0)
+        return;
+
+    Py_INCREF(&CSCCrystalModelType);
+    PyModule_AddObject(module, "CSCCrystalModel", (PyObject *)&CSCCrystalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSCCrystalModel.error";
+    CSCCrystalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSCCrystalModelError", CSCCrystalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSLDCalFunc.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSLDCalFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSLDCalFunc.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,588 @@
+/**
+	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
+ */
+
+/** CSLDCalFunc
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\sld_cal.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 "sld_cal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSLDCalFuncError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SLDCalFunc * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSLDCalFunc;
+
+
+static void
+CSLDCalFunc_dealloc(CSLDCalFunc* 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 *
+CSLDCalFunc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSLDCalFunc *self;
+    
+    self = (CSLDCalFunc *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSLDCalFunc_init(CSLDCalFunc *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SLDCalFunc();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"fun_type",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"nu_inter",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"shell_num",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_right",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_left",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"npts_inter",Py_BuildValue("d",21.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->npts_inter.dispersion->accept_as_source(visitor, self->model->npts_inter.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "npts_inter", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSLDCalFunc_members[] = {
+    {name_params, T_OBJECT, offsetof(CSLDCalFunc, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSLDCalFunc, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSLDCalFunc, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSLDCalFunc_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(SLDCalFunc* 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;
+	}
+#pragma omp parallel for
+	 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( SLDCalFunc* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSLDCalFuncError, 
+                   "CSLDCalFunc.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(CSLDCalFunc *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->fun_type = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fun_type") );
+    self->model->nu_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter") );
+    self->model->shell_num = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_num") );
+    self->model->sld_right = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_right") );
+    self->model->sld_left = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_left") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "npts_inter");
+    self->model->npts_inter.dispersion->accept_as_destination(visitor, self->model->npts_inter.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(CSLDCalFuncError, 
+	    	"CSLDCalFunc.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(CSLDCalFuncError, 
+                   "CSLDCalFunc.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(CSLDCalFuncError, 
+	    		"CSLDCalFunc.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(CSLDCalFuncError, 
+                   "CSLDCalFunc.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSLDCalFuncError, 
+                   "CSLDCalFunc.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(CSLDCalFunc *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->fun_type = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fun_type") );
+    self->model->nu_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter") );
+    self->model->shell_num = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_num") );
+    self->model->sld_right = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_right") );
+    self->model->sld_left = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_left") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "npts_inter");
+    self->model->npts_inter.dispersion->accept_as_destination(visitor, self->model->npts_inter.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(CSLDCalFuncError, 
+	    	"CSLDCalFunc.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(CSLDCalFuncError, 
+	    		"CSLDCalFunc.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 = CSLDCalFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSLDCalFunc_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 = CSLDCalFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSLDCalFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->fun_type = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fun_type") );
+    self->model->nu_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter") );
+    self->model->shell_num = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_num") );
+    self->model->sld_right = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_right") );
+    self->model->sld_left = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_left") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "npts_inter");
+    self->model->npts_inter.dispersion->accept_as_destination(visitor, self->model->npts_inter.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSLDCalFunc *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->fun_type = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fun_type") );
+    self->model->nu_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter") );
+    self->model->shell_num = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_num") );
+    self->model->sld_right = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_right") );
+    self->model->sld_left = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_left") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "npts_inter");
+    self->model->npts_inter.dispersion->accept_as_destination(visitor, self->model->npts_inter.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSLDCalFunc *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->fun_type = PyFloat_AsDouble( PyDict_GetItemString(self->params, "fun_type") );
+    self->model->nu_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter") );
+    self->model->shell_num = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_num") );
+    self->model->sld_right = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_right") );
+    self->model->sld_left = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_left") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "npts_inter");
+    self->model->npts_inter.dispersion->accept_as_destination(visitor, self->model->npts_inter.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(CSLDCalFuncError, 
+	    	"CSLDCalFunc.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(CSLDCalFuncError, 
+	    		"CSLDCalFunc.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 = CSLDCalFunc_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSLDCalFunc_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 = CSLDCalFunc_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSLDCalFunc *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSLDCalFunc *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSLDCalFuncError,
+	    	"CSLDCalFunc.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, "npts_inter")) {
+        self->model->npts_inter.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CSLDCalFuncError,
+	    	"CSLDCalFunc.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 CSLDCalFunc_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSLDCalFuncType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSLDCalFunc",             /*tp_name*/
+    sizeof(CSLDCalFunc),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSLDCalFunc_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*/
+    "CSLDCalFunc objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSLDCalFunc_methods,             /* tp_methods */
+    CSLDCalFunc_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSLDCalFunc_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSLDCalFunc_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 addCSLDCalFunc(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSLDCalFuncType) < 0)
+        return;
+
+    Py_INCREF(&CSLDCalFuncType);
+    PyModule_AddObject(module, "CSLDCalFunc", (PyObject *)&CSLDCalFuncType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSLDCalFunc.error";
+    CSLDCalFuncError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSLDCalFuncError", CSLDCalFuncError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSchulz.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSchulz.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSchulz.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,537 @@
+/**
+	This software was developed by the University of Tennessee as part of the
+	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+	project funded by the US National Science Foundation.
+
+	If you use DANSE applications to do scientific research that leads to
+	publication, we ask that you acknowledge the use of the software with the
+	following sentence:
+
+	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+
+	copyright 2008, University of Tennessee
+ */
+
+/** CSchulz
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\schulz.h
+ *          AND RE-RUN THE GENERATOR SCRIPT
+ *
+ */
+#define NO_IMPORT_ARRAY
+#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_sans
+ 
+extern "C" {
+#include <Python.h>
+#include <arrayobject.h>
+#include "structmember.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+}
+
+#include "schulz.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSchulzError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    Schulz * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSchulz;
+
+
+static void
+CSchulz_dealloc(CSchulz* self)
+{
+    Py_DECREF(self->params);
+    Py_DECREF(self->dispersion);
+    Py_DECREF(self->log);
+    delete self->model;
+    self->ob_type->tp_free((PyObject*)self);
+    
+
+}
+
+static PyObject *
+CSchulz_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSchulz *self;
+    
+    self = (CSchulz *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSchulz_init(CSchulz *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new Schulz();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sigma",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"center",Py_BuildValue("d",0.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSchulz_members[] = {
+    {name_params, T_OBJECT, offsetof(CSchulz, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSchulz, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSchulz, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSchulz_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(Schulz* model, PyArrayObject *q){
+    PyArrayObject *result;
+   
+    // Check validity of array q , q must be of dimension 1, an array of double
+    if (q->nd != 1 || q->descr->type_num != PyArray_DOUBLE)
+    {
+        //const char * message= "Invalid array: q->nd=%d,type_num=%d\n",q->nd,q->descr->type_num;
+        //PyErr_SetString(PyExc_ValueError , message);
+        return NULL;
+    }
+    result = (PyArrayObject *)PyArray_FromDims(q->nd, (int *)(q->dimensions), PyArray_DOUBLE);
+	if (result == NULL) {
+        const char * message= "Could not create result ";
+        PyErr_SetString(PyExc_RuntimeError , message);
+		return NULL;
+	}
+#pragma omp parallel for
+	 for (int i = 0; i < q->dimensions[0]; i++){
+      double q_value  = *(double *)(q->data + i*q->strides[0]);
+      double *result_value = (double *)(result->data + i*result->strides[0]);
+      *result_value =(*model)(q_value);
+	}
+    return PyArray_Return(result); 
+ }
+
+ /**
+ * Function to call to evaluate model
+ * @param args: input numpy array  [x[],y[]]
+ * @return: numpy array object 
+ */
+ static PyObject * evaluateTwoDimXY( Schulz* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSchulzError, 
+                   "CSchulz.evaluateTwoDimXY couldn't run.");
+	        return NULL;
+		}      	
+}
+/**
+ *  evalDistribution function evaluate a model function with input vector
+ *  @param args: input q as vector or [qx, qy] where qx, qy are vectors
+ *
+ */ 
+static PyObject * evalDistribution(CSchulz *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.evalDistribution expects a q value.");
+		return NULL;
+	}
+    // Check params
+	
+    if(PyArray_Check(pars)==1) {
+		
+	    // Length of list should 1 or 2
+	    npars = pars->nd; 
+	    if(npars==1) {
+	        // input is a numpy array
+	        if (PyArray_Check(pars)) {
+		        return evaluateOneDim(self->model, (PyArrayObject*)pars); 
+		    }
+		}else{
+		    PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution expect numpy array of one dimension.");
+	        return NULL;
+		}
+    }else if( PyList_Check(pars)==1) {
+    	// Length of list should be 2 for I(qx,qy)
+	    mpars = PyList_GET_SIZE(pars); 
+	    if(mpars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.evalDistribution expects a list of dimension 2.");
+	    	return NULL;
+	    }
+	     qx = PyList_GET_ITEM(pars,0);
+	     qy = PyList_GET_ITEM(pars,1);
+	     if (PyArray_Check(qx) && PyArray_Check(qy)) {
+	         return evaluateTwoDimXY(self->model, (PyArrayObject*)qx,
+		           (PyArrayObject*)qy);
+		 }else{
+		    PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSchulzError, 
+                   "CSchulz.evalDistribution couln't be run.");
+	return NULL;
+	
+}
+
+/**
+ * Function to call to evaluate model
+ * @param args: input q or [q,phi]
+ * @return: function value
+ */
+static PyObject * run(CSchulz *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CSchulz_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSchulz_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSchulz *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSchulz *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSchulz *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->sigma = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma") );
+    self->model->center = PyFloat_AsDouble( PyDict_GetItemString(self->params, "center") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSchulzError, 
+	    	"CSchulz.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSchulzError, 
+	    		"CSchulz.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CSchulz_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSchulz_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CSchulz_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSchulz *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSchulz *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSchulzError,
+	    	"CSchulz.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CSchulzError,
+	    	"CSchulz.set_dispersion expects a valid parameter name.");
+		return NULL;
+	}
+
+	DispersionVisitor* visitor = new DispersionVisitor();
+	PyObject * disp_dict = PyDict_New();
+	dispersion->accept_as_source(visitor, dispersion, disp_dict);
+	PyDict_SetItemString(self->dispersion, par_name, disp_dict);
+    return Py_BuildValue("i",1);
+}
+
+
+static PyMethodDef CSchulz_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"evalDistribution",  (PyCFunction)evalDistribution , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy vector "},
+    {"reset",    (PyCFunction)reset   , METH_VARARGS,
+      "Reset pair correlation"},
+    {"set_dispersion",      (PyCFunction)set_dispersion     , METH_VARARGS,
+      "Set the dispersion model for a given parameter"},
+   {NULL}
+};
+
+static PyTypeObject CSchulzType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSchulz",             /*tp_name*/
+    sizeof(CSchulz),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSchulz_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CSchulz objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSchulz_methods,             /* tp_methods */
+    CSchulz_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSchulz_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSchulz_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCSchulz(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSchulzType) < 0)
+        return;
+
+    Py_INCREF(&CSchulzType);
+    PyModule_AddObject(module, "CSchulz", (PyObject *)&CSchulzType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSchulz.error";
+    CSchulzError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSchulzError", CSchulzError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSphereModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSphereModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSphereModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,636 @@
+/**
+	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
+ */
+
+/** CSphereModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\sphere.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 "sphere.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSphereModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SphereModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSphereModel;
+
+
+static void
+CSphereModel_dealloc(CSphereModel* 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 *
+CSphereModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSphereModel *self;
+    
+    self = (CSphereModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSphereModel_init(CSphereModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SphereModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"Up_frac_i",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"Up_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_sph",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSph",Py_BuildValue("d",0.000002000000));
+        PyDict_SetItemString(self->params,"M_theta_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M_phi_solv",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"M0_sld_sph",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"Up_frac_f",Py_BuildValue("d",0.500000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",60.000000000000));
+        PyDict_SetItemString(self->params,"M_theta_sph",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSphereModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CSphereModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSphereModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSphereModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSphereModel_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(SphereModel* 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;
+	}
+#pragma omp parallel for
+	 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( SphereModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSphereModelError, 
+                   "CSphereModel.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(CSphereModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M_phi_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_sph") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_sph") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_sph") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CSphereModelError, 
+	    	"CSphereModel.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(CSphereModelError, 
+                   "CSphereModel.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(CSphereModelError, 
+	    		"CSphereModel.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(CSphereModelError, 
+                   "CSphereModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSphereModelError, 
+                   "CSphereModel.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(CSphereModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M_phi_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_sph") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_sph") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_sph") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CSphereModelError, 
+	    	"CSphereModel.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(CSphereModelError, 
+	    		"CSphereModel.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 = CSphereModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSphereModel_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 = CSphereModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSphereModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M_phi_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_sph") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_sph") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_sph") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSphereModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M_phi_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_sph") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_sph") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_sph") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSphereModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->Up_frac_i = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_i") );
+    self->model->Up_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_theta") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->M_phi_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_sph") );
+    self->model->M0_sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_solv") );
+    self->model->sldSph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSph") );
+    self->model->M_theta_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_solv") );
+    self->model->M_phi_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_phi_solv") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->M0_sld_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M0_sld_sph") );
+    self->model->Up_frac_f = PyFloat_AsDouble( PyDict_GetItemString(self->params, "Up_frac_f") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->M_theta_sph = PyFloat_AsDouble( PyDict_GetItemString(self->params, "M_theta_sph") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.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(CSphereModelError, 
+	    	"CSphereModel.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(CSphereModelError, 
+	    		"CSphereModel.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 = CSphereModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSphereModel_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 = CSphereModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSphereModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSphereModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSphereModelError,
+	    	"CSphereModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CSphereModelError,
+	    	"CSphereModel.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 CSphereModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSphereModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSphereModel",             /*tp_name*/
+    sizeof(CSphereModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSphereModel_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*/
+    "CSphereModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSphereModel_methods,             /* tp_methods */
+    CSphereModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSphereModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSphereModel_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 addCSphereModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSphereModelType) < 0)
+        return;
+
+    Py_INCREF(&CSphereModelType);
+    PyModule_AddObject(module, "CSphereModel", (PyObject *)&CSphereModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSphereModel.error";
+    CSphereModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSphereModelError", CSphereModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSphereSLDModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSphereSLDModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSphereSLDModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,927 @@
+/**
+	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
+ */
+
+/** CSphereSLDModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\spheresld.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 "spheresld.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSphereSLDModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SphereSLDModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSphereSLDModel;
+
+
+static void
+CSphereSLDModel_dealloc(CSphereSLDModel* 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 *
+CSphereSLDModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSphereSLDModel *self;
+    
+    self = (CSphereSLDModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSphereSLDModel_init(CSphereSLDModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SphereSLDModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"thick_flat8",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat9",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat2",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat3",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat1",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat6",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat7",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat4",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat5",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter0",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter1",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter2",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter3",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"sld_core0",Py_BuildValue("d",0.000002070000));
+        PyDict_SetItemString(self->params,"thick_inter5",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter6",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter7",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter8",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter9",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"rad_core0",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"npts_inter",Py_BuildValue("d",35.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thick_inter10",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"func_inter8",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter9",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_solv",Py_BuildValue("d",0.000001000000));
+        PyDict_SetItemString(self->params,"func_inter0",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter1",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter2",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter3",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"thick_flat10",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"func_inter5",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter6",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"func_inter7",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat4",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat5",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat6",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat7",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat1",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat2",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat3",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"sld_flat8",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"sld_flat9",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"nu_inter10",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"n_shells",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"sld_flat10",Py_BuildValue("d",0.000003500000));
+        PyDict_SetItemString(self->params,"func_inter4",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"nu_inter8",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter5",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter4",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter7",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter6",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter1",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter0",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter3",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"nu_inter2",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"thick_inter4",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"nu_inter9",Py_BuildValue("d",2.500000000000));
+        PyDict_SetItemString(self->params,"func_inter10",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->rad_core0.dispersion->accept_as_source(visitor, self->model->rad_core0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "rad_core0", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thick_inter0.dispersion->accept_as_source(visitor, self->model->thick_inter0.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thick_inter0", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSphereSLDModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CSphereSLDModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSphereSLDModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSphereSLDModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSphereSLDModel_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(SphereSLDModel* 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;
+	}
+#pragma omp parallel for
+	 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( SphereSLDModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSphereSLDModelError, 
+                   "CSphereSLDModel.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(CSphereSLDModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    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_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CSphereSLDModelError, 
+	    	"CSphereSLDModel.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(CSphereSLDModelError, 
+                   "CSphereSLDModel.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(CSphereSLDModelError, 
+	    		"CSphereSLDModel.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(CSphereSLDModelError, 
+                   "CSphereSLDModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSphereSLDModelError, 
+                   "CSphereSLDModel.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(CSphereSLDModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    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_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CSphereSLDModelError, 
+	    	"CSphereSLDModel.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(CSphereSLDModelError, 
+	    		"CSphereSLDModel.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 = CSphereSLDModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSphereSLDModel_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 = CSphereSLDModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSphereSLDModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    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_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSphereSLDModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    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_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSphereSLDModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->thick_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat8") );
+    self->model->thick_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat9") );
+    self->model->thick_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat2") );
+    self->model->thick_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat3") );
+    self->model->thick_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat1") );
+    self->model->thick_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat6") );
+    self->model->thick_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat7") );
+    self->model->thick_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat4") );
+    self->model->thick_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat5") );
+    self->model->thick_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter0") );
+    self->model->thick_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter1") );
+    self->model->thick_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter2") );
+    self->model->thick_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter3") );
+    self->model->sld_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_core0") );
+    self->model->thick_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter5") );
+    self->model->thick_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter6") );
+    self->model->thick_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter7") );
+    self->model->thick_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter8") );
+    self->model->thick_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter9") );
+    self->model->rad_core0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "rad_core0") );
+    self->model->npts_inter = PyFloat_AsDouble( PyDict_GetItemString(self->params, "npts_inter") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thick_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter10") );
+    self->model->func_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter8") );
+    self->model->func_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter9") );
+    self->model->sld_solv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_solv") );
+    self->model->func_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter0") );
+    self->model->func_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter1") );
+    self->model->func_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter2") );
+    self->model->func_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter3") );
+    self->model->thick_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_flat10") );
+    self->model->func_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter5") );
+    self->model->func_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter6") );
+    self->model->func_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter7") );
+    self->model->sld_flat4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat4") );
+    self->model->sld_flat5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat5") );
+    self->model->sld_flat6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat6") );
+    self->model->sld_flat7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat7") );
+    self->model->sld_flat1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat1") );
+    self->model->sld_flat2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat2") );
+    self->model->sld_flat3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat3") );
+    self->model->sld_flat8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat8") );
+    self->model->sld_flat9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat9") );
+    self->model->nu_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter10") );
+    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_flat10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sld_flat10") );
+    self->model->func_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter4") );
+    self->model->nu_inter8 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter8") );
+    self->model->nu_inter5 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter5") );
+    self->model->nu_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter4") );
+    self->model->nu_inter7 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter7") );
+    self->model->nu_inter6 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter6") );
+    self->model->nu_inter1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter1") );
+    self->model->nu_inter0 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter0") );
+    self->model->nu_inter3 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter3") );
+    self->model->nu_inter2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter2") );
+    self->model->thick_inter4 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thick_inter4") );
+    self->model->nu_inter9 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "nu_inter9") );
+    self->model->func_inter10 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "func_inter10") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "rad_core0");
+    self->model->rad_core0.dispersion->accept_as_destination(visitor, self->model->rad_core0.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thick_inter0");
+    self->model->thick_inter0.dispersion->accept_as_destination(visitor, self->model->thick_inter0.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(CSphereSLDModelError, 
+	    	"CSphereSLDModel.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(CSphereSLDModelError, 
+	    		"CSphereSLDModel.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 = CSphereSLDModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSphereSLDModel_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 = CSphereSLDModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSphereSLDModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSphereSLDModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSphereSLDModelError,
+	    	"CSphereSLDModel.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_core0")) {
+        self->model->rad_core0.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thick_inter0")) {
+        self->model->thick_inter0.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CSphereSLDModelError,
+	    	"CSphereSLDModel.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 CSphereSLDModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSphereSLDModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSphereSLDModel",             /*tp_name*/
+    sizeof(CSphereSLDModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSphereSLDModel_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*/
+    "CSphereSLDModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSphereSLDModel_methods,             /* tp_methods */
+    CSphereSLDModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSphereSLDModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSphereSLDModel_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 addCSphereSLDModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSphereSLDModelType) < 0)
+        return;
+
+    Py_INCREF(&CSphereSLDModelType);
+    PyModule_AddObject(module, "CSphereSLDModel", (PyObject *)&CSphereSLDModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSphereSLDModel.error";
+    CSphereSLDModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSphereSLDModelError", CSphereSLDModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSquareWellStructure.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSquareWellStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSquareWellStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,576 @@
+/**
+	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
+ */
+
+/** CSquareWellStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\SquareWell.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 "SquareWell.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSquareWellStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SquareWellStructure * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSquareWellStructure;
+
+
+static void
+CSquareWellStructure_dealloc(CSquareWellStructure* 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 *
+CSquareWellStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSquareWellStructure *self;
+    
+    self = (CSquareWellStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSquareWellStructure_init(CSquareWellStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SquareWellStructure();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"welldepth",Py_BuildValue("d",1.500000000000));
+        PyDict_SetItemString(self->params,"effect_radius",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.040000000000));
+        PyDict_SetItemString(self->params,"wellwidth",Py_BuildValue("d",1.200000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->effect_radius.dispersion->accept_as_source(visitor, self->model->effect_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "effect_radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSquareWellStructure_members[] = {
+    {name_params, T_OBJECT, offsetof(CSquareWellStructure, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSquareWellStructure, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSquareWellStructure, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSquareWellStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(SquareWellStructure* 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;
+	}
+#pragma omp parallel for
+	 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( SquareWellStructure* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSquareWellStructureError, 
+                   "CSquareWellStructure.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(CSquareWellStructure *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CSquareWellStructureError, 
+	    	"CSquareWellStructure.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(CSquareWellStructureError, 
+                   "CSquareWellStructure.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(CSquareWellStructureError, 
+	    		"CSquareWellStructure.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(CSquareWellStructureError, 
+                   "CSquareWellStructure.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSquareWellStructureError, 
+                   "CSquareWellStructure.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(CSquareWellStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CSquareWellStructureError, 
+	    	"CSquareWellStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSquareWellStructureError, 
+	    		"CSquareWellStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CSquareWellStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSquareWellStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSquareWellStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSquareWellStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->welldepth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "welldepth") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->wellwidth = PyFloat_AsDouble( PyDict_GetItemString(self->params, "wellwidth") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CSquareWellStructureError, 
+	    	"CSquareWellStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CSquareWellStructureError, 
+	    		"CSquareWellStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSquareWellStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CSquareWellStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSquareWellStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSquareWellStructure *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSquareWellStructureError,
+	    	"CSquareWellStructure.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, "effect_radius")) {
+        self->model->effect_radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CSquareWellStructureError,
+	    	"CSquareWellStructure.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 CSquareWellStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSquareWellStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSquareWellStructure",             /*tp_name*/
+    sizeof(CSquareWellStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSquareWellStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CSquareWellStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSquareWellStructure_methods,             /* tp_methods */
+    CSquareWellStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSquareWellStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSquareWellStructure_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCSquareWellStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSquareWellStructureType) < 0)
+        return;
+
+    Py_INCREF(&CSquareWellStructureType);
+    PyModule_AddObject(module, "CSquareWellStructure", (PyObject *)&CSquareWellStructureType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSquareWellStructure.error";
+    CSquareWellStructureError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSquareWellStructureError", CSquareWellStructureError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CStackedDisksModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CStackedDisksModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CStackedDisksModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,684 @@
+/**
+	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
+ */
+
+/** CStackedDisksModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\stacked_disks.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 "stacked_disks.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CStackedDisksModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    StackedDisksModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CStackedDisksModel;
+
+
+static void
+CStackedDisksModel_dealloc(CStackedDisksModel* 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 *
+CStackedDisksModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CStackedDisksModel *self;
+    
+    self = (CStackedDisksModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CStackedDisksModel_init(CStackedDisksModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new StackedDisksModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"core_sld",Py_BuildValue("d",0.000004000000));
+        PyDict_SetItemString(self->params,"core_thick",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"layer_thick",Py_BuildValue("d",15.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"layer_sld",Py_BuildValue("d",-0.000000400000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"solvent_sld",Py_BuildValue("d",0.000005000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",0.010000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",3000.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.001000000000));
+        PyDict_SetItemString(self->params,"sigma_d",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"n_stacking",Py_BuildValue("d",1.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->core_thick.dispersion->accept_as_source(visitor, self->model->core_thick.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "core_thick", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->layer_thick.dispersion->accept_as_source(visitor, self->model->layer_thick.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "layer_thick", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CStackedDisksModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CStackedDisksModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CStackedDisksModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CStackedDisksModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CStackedDisksModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(StackedDisksModel* 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;
+	}
+#pragma omp parallel for
+	 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( StackedDisksModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CStackedDisksModelError, 
+                   "CStackedDisksModel.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(CStackedDisksModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model->layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model->n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_thick");
+    self->model->core_thick.dispersion->accept_as_destination(visitor, self->model->core_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "layer_thick");
+    self->model->layer_thick.dispersion->accept_as_destination(visitor, self->model->layer_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CStackedDisksModelError, 
+	    	"CStackedDisksModel.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(CStackedDisksModelError, 
+                   "CStackedDisksModel.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(CStackedDisksModelError, 
+	    		"CStackedDisksModel.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(CStackedDisksModelError, 
+                   "CStackedDisksModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CStackedDisksModelError, 
+                   "CStackedDisksModel.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(CStackedDisksModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model->layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model->n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_thick");
+    self->model->core_thick.dispersion->accept_as_destination(visitor, self->model->core_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "layer_thick");
+    self->model->layer_thick.dispersion->accept_as_destination(visitor, self->model->layer_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CStackedDisksModelError, 
+	    	"CStackedDisksModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStackedDisksModelError, 
+	    		"CStackedDisksModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CStackedDisksModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CStackedDisksModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model->layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model->n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_thick");
+    self->model->core_thick.dispersion->accept_as_destination(visitor, self->model->core_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "layer_thick");
+    self->model->layer_thick.dispersion->accept_as_destination(visitor, self->model->layer_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CStackedDisksModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model->layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model->n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_thick");
+    self->model->core_thick.dispersion->accept_as_destination(visitor, self->model->core_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "layer_thick");
+    self->model->layer_thick.dispersion->accept_as_destination(visitor, self->model->layer_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CStackedDisksModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->core_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_sld") );
+    self->model->core_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "core_thick") );
+    self->model->layer_thick = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_thick") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->layer_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "layer_sld") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->solvent_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solvent_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sigma_d = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sigma_d") );
+    self->model->n_stacking = PyFloat_AsDouble( PyDict_GetItemString(self->params, "n_stacking") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "core_thick");
+    self->model->core_thick.dispersion->accept_as_destination(visitor, self->model->core_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "layer_thick");
+    self->model->layer_thick.dispersion->accept_as_destination(visitor, self->model->layer_thick.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.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(CStackedDisksModelError, 
+	    	"CStackedDisksModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStackedDisksModelError, 
+	    		"CStackedDisksModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CStackedDisksModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CStackedDisksModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CStackedDisksModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CStackedDisksModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CStackedDisksModelError,
+	    	"CStackedDisksModel.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, "core_thick")) {
+        self->model->core_thick.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "layer_thick")) {
+        self->model->layer_thick.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CStackedDisksModelError,
+	    	"CStackedDisksModel.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 CStackedDisksModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CStackedDisksModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CStackedDisksModel",             /*tp_name*/
+    sizeof(CStackedDisksModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CStackedDisksModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CStackedDisksModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CStackedDisksModel_methods,             /* tp_methods */
+    CStackedDisksModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CStackedDisksModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CStackedDisksModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCStackedDisksModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CStackedDisksModelType) < 0)
+        return;
+
+    Py_INCREF(&CStackedDisksModelType);
+    PyModule_AddObject(module, "CStackedDisksModel", (PyObject *)&CStackedDisksModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CStackedDisksModel.error";
+    CStackedDisksModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CStackedDisksModelError", CStackedDisksModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CStarPolymer.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CStarPolymer.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CStarPolymer.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,621 @@
+/**
+	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
+ */
+
+/** CStarPolymer
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\starpolymer.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 "starpolymer.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CStarPolymerError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    StarPolymer * model;
+    /// Log for unit testing
+    PyObject * log;
+} CStarPolymer;
+
+
+static void
+CStarPolymer_dealloc(CStarPolymer* 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 *
+CStarPolymer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CStarPolymer *self;
+    
+    self = (CStarPolymer *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CStarPolymer_init(CStarPolymer *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new StarPolymer();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"arms",Py_BuildValue("d",3.000000000000));
+        PyDict_SetItemString(self->params,"R2",Py_BuildValue("d",100.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->arms.dispersion->accept_as_source(visitor, self->model->arms.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "arms", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->R2.dispersion->accept_as_source(visitor, self->model->R2.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "R2", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->scale.dispersion->accept_as_source(visitor, self->model->scale.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "scale", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->background.dispersion->accept_as_source(visitor, self->model->background.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "background", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CStarPolymer_members[] = {
+    {name_params, T_OBJECT, offsetof(CStarPolymer, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CStarPolymer, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CStarPolymer, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CStarPolymer_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(StarPolymer* 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;
+	}
+#pragma omp parallel for
+	 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( StarPolymer* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CStarPolymerError, 
+                   "CStarPolymer.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(CStarPolymer *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->arms = PyFloat_AsDouble( PyDict_GetItemString(self->params, "arms") );
+    self->model->R2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "R2") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "arms");
+    self->model->arms.dispersion->accept_as_destination(visitor, self->model->arms.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "R2");
+    self->model->R2.dispersion->accept_as_destination(visitor, self->model->R2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CStarPolymerError, 
+	    	"CStarPolymer.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(CStarPolymerError, 
+                   "CStarPolymer.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(CStarPolymerError, 
+	    		"CStarPolymer.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(CStarPolymerError, 
+                   "CStarPolymer.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CStarPolymerError, 
+                   "CStarPolymer.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(CStarPolymer *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->arms = PyFloat_AsDouble( PyDict_GetItemString(self->params, "arms") );
+    self->model->R2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "R2") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "arms");
+    self->model->arms.dispersion->accept_as_destination(visitor, self->model->arms.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "R2");
+    self->model->R2.dispersion->accept_as_destination(visitor, self->model->R2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CStarPolymerError, 
+	    	"CStarPolymer.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(CStarPolymerError, 
+	    		"CStarPolymer.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 = CStarPolymer_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CStarPolymer_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 = CStarPolymer_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CStarPolymer *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->arms = PyFloat_AsDouble( PyDict_GetItemString(self->params, "arms") );
+    self->model->R2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "R2") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "arms");
+    self->model->arms.dispersion->accept_as_destination(visitor, self->model->arms.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "R2");
+    self->model->R2.dispersion->accept_as_destination(visitor, self->model->R2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CStarPolymer *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->arms = PyFloat_AsDouble( PyDict_GetItemString(self->params, "arms") );
+    self->model->R2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "R2") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "arms");
+    self->model->arms.dispersion->accept_as_destination(visitor, self->model->arms.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "R2");
+    self->model->R2.dispersion->accept_as_destination(visitor, self->model->R2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CStarPolymer *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->arms = PyFloat_AsDouble( PyDict_GetItemString(self->params, "arms") );
+    self->model->R2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "R2") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "arms");
+    self->model->arms.dispersion->accept_as_destination(visitor, self->model->arms.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "R2");
+    self->model->R2.dispersion->accept_as_destination(visitor, self->model->R2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CStarPolymerError, 
+	    	"CStarPolymer.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(CStarPolymerError, 
+	    		"CStarPolymer.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 = CStarPolymer_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CStarPolymer_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 = CStarPolymer_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CStarPolymer *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CStarPolymer *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CStarPolymerError,
+	    	"CStarPolymer.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, "arms")) {
+        self->model->arms.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "R2")) {
+        self->model->R2.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "scale")) {
+        self->model->scale.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "background")) {
+        self->model->background.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CStarPolymerError,
+	    	"CStarPolymer.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 CStarPolymer_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CStarPolymerType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CStarPolymer",             /*tp_name*/
+    sizeof(CStarPolymer),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CStarPolymer_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*/
+    "CStarPolymer objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CStarPolymer_methods,             /* tp_methods */
+    CStarPolymer_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CStarPolymer_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CStarPolymer_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 addCStarPolymer(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CStarPolymerType) < 0)
+        return;
+
+    Py_INCREF(&CStarPolymerType);
+    PyModule_AddObject(module, "CStarPolymer", (PyObject *)&CStarPolymerType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CStarPolymer.error";
+    CStarPolymerError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CStarPolymerError", CStarPolymerError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CStickyHSStructure.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CStickyHSStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CStickyHSStructure.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,576 @@
+/**
+	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
+ */
+
+/** CStickyHSStructure
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\StickyHS.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 "StickyHS.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CStickyHSStructureError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    StickyHSStructure * model;
+    /// Log for unit testing
+    PyObject * log;
+} CStickyHSStructure;
+
+
+static void
+CStickyHSStructure_dealloc(CStickyHSStructure* 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 *
+CStickyHSStructure_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CStickyHSStructure *self;
+    
+    self = (CStickyHSStructure *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CStickyHSStructure_init(CStickyHSStructure *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new StickyHSStructure();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"stickiness",Py_BuildValue("d",0.200000000000));
+        PyDict_SetItemString(self->params,"effect_radius",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.100000000000));
+        PyDict_SetItemString(self->params,"perturb",Py_BuildValue("d",0.050000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->effect_radius.dispersion->accept_as_source(visitor, self->model->effect_radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "effect_radius", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CStickyHSStructure_members[] = {
+    {name_params, T_OBJECT, offsetof(CStickyHSStructure, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CStickyHSStructure, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CStickyHSStructure, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CStickyHSStructure_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(StickyHSStructure* 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;
+	}
+#pragma omp parallel for
+	 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( StickyHSStructure* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CStickyHSStructureError, 
+                   "CStickyHSStructure.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(CStickyHSStructure *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CStickyHSStructureError, 
+	    	"CStickyHSStructure.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(CStickyHSStructureError, 
+                   "CStickyHSStructure.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(CStickyHSStructureError, 
+	    		"CStickyHSStructure.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(CStickyHSStructureError, 
+                   "CStickyHSStructure.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CStickyHSStructureError, 
+                   "CStickyHSStructure.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(CStickyHSStructure *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CStickyHSStructureError, 
+	    	"CStickyHSStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStickyHSStructureError, 
+	    		"CStickyHSStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CStickyHSStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CStickyHSStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CStickyHSStructure *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CStickyHSStructure *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->stickiness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "stickiness") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->perturb = PyFloat_AsDouble( PyDict_GetItemString(self->params, "perturb") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "effect_radius");
+    self->model->effect_radius.dispersion->accept_as_destination(visitor, self->model->effect_radius.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(CStickyHSStructureError, 
+	    	"CStickyHSStructure.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CStickyHSStructureError, 
+	    		"CStickyHSStructure.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CStickyHSStructure_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CStickyHSStructure_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CStickyHSStructure *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CStickyHSStructure *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CStickyHSStructureError,
+	    	"CStickyHSStructure.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, "effect_radius")) {
+        self->model->effect_radius.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CStickyHSStructureError,
+	    	"CStickyHSStructure.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 CStickyHSStructure_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CStickyHSStructureType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CStickyHSStructure",             /*tp_name*/
+    sizeof(CStickyHSStructure),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CStickyHSStructure_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CStickyHSStructure objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CStickyHSStructure_methods,             /* tp_methods */
+    CStickyHSStructure_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CStickyHSStructure_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CStickyHSStructure_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCStickyHSStructure(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CStickyHSStructureType) < 0)
+        return;
+
+    Py_INCREF(&CStickyHSStructureType);
+    PyModule_AddObject(module, "CStickyHSStructure", (PyObject *)&CStickyHSStructureType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CStickyHSStructure.error";
+    CStickyHSStructureError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CStickyHSStructureError", CStickyHSStructureError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CSurfaceFractalModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CSurfaceFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CSurfaceFractalModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,549 @@
+/**
+	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
+ */
+
+/** CSurfaceFractalModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\surfacefractal.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 "surfacefractal.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CSurfaceFractalModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    SurfaceFractalModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CSurfaceFractalModel;
+
+
+static void
+CSurfaceFractalModel_dealloc(CSurfaceFractalModel* 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 *
+CSurfaceFractalModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CSurfaceFractalModel *self;
+    
+    self = (CSurfaceFractalModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CSurfaceFractalModel_init(CSurfaceFractalModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new SurfaceFractalModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"co_length",Py_BuildValue("d",500.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"surface_dim",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CSurfaceFractalModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CSurfaceFractalModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CSurfaceFractalModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CSurfaceFractalModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CSurfaceFractalModel_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(SurfaceFractalModel* 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;
+	}
+#pragma omp parallel for
+	 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( SurfaceFractalModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CSurfaceFractalModelError, 
+                   "CSurfaceFractalModel.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(CSurfaceFractalModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSurfaceFractalModelError, 
+	    	"CSurfaceFractalModel.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(CSurfaceFractalModelError, 
+                   "CSurfaceFractalModel.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(CSurfaceFractalModelError, 
+	    		"CSurfaceFractalModel.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(CSurfaceFractalModelError, 
+                   "CSurfaceFractalModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CSurfaceFractalModelError, 
+                   "CSurfaceFractalModel.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(CSurfaceFractalModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSurfaceFractalModelError, 
+	    	"CSurfaceFractalModel.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(CSurfaceFractalModelError, 
+	    		"CSurfaceFractalModel.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 = CSurfaceFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CSurfaceFractalModel_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 = CSurfaceFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CSurfaceFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CSurfaceFractalModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CSurfaceFractalModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->co_length = PyFloat_AsDouble( PyDict_GetItemString(self->params, "co_length") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->surface_dim = PyFloat_AsDouble( PyDict_GetItemString(self->params, "surface_dim") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CSurfaceFractalModelError, 
+	    	"CSurfaceFractalModel.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(CSurfaceFractalModelError, 
+	    		"CSurfaceFractalModel.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 = CSurfaceFractalModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CSurfaceFractalModel_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 = CSurfaceFractalModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CSurfaceFractalModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CSurfaceFractalModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CSurfaceFractalModelError,
+	    	"CSurfaceFractalModel.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CSurfaceFractalModelError,
+	    	"CSurfaceFractalModel.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 CSurfaceFractalModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CSurfaceFractalModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CSurfaceFractalModel",             /*tp_name*/
+    sizeof(CSurfaceFractalModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CSurfaceFractalModel_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*/
+    "CSurfaceFractalModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CSurfaceFractalModel_methods,             /* tp_methods */
+    CSurfaceFractalModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CSurfaceFractalModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CSurfaceFractalModel_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 addCSurfaceFractalModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CSurfaceFractalModelType) < 0)
+        return;
+
+    Py_INCREF(&CSurfaceFractalModelType);
+    PyModule_AddObject(module, "CSurfaceFractalModel", (PyObject *)&CSurfaceFractalModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CSurfaceFractalModel.error";
+    CSurfaceFractalModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CSurfaceFractalModelError", CSurfaceFractalModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CTeubnerStreyModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CTeubnerStreyModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CTeubnerStreyModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,621 @@
+/**
+	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
+ */
+
+/** CTeubnerStreyModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\teubner_strey.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 "teubner_strey.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CTeubnerStreyModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    TeubnerStreyModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CTeubnerStreyModel;
+
+
+static void
+CTeubnerStreyModel_dealloc(CTeubnerStreyModel* 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 *
+CTeubnerStreyModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CTeubnerStreyModel *self;
+    
+    self = (CTeubnerStreyModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CTeubnerStreyModel_init(CTeubnerStreyModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new TeubnerStreyModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"c2",Py_BuildValue("d",5000.000000000000));
+        PyDict_SetItemString(self->params,"c1",Py_BuildValue("d",-30.000000000000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",0.100000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->scale.dispersion->accept_as_source(visitor, self->model->scale.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "scale", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->c1.dispersion->accept_as_source(visitor, self->model->c1.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "c1", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->c2.dispersion->accept_as_source(visitor, self->model->c2.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "c2", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->background.dispersion->accept_as_source(visitor, self->model->background.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "background", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CTeubnerStreyModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CTeubnerStreyModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CTeubnerStreyModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CTeubnerStreyModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CTeubnerStreyModel_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(TeubnerStreyModel* 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;
+	}
+#pragma omp parallel for
+	 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( TeubnerStreyModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CTeubnerStreyModelError, 
+                   "CTeubnerStreyModel.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(CTeubnerStreyModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->c2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c2") );
+    self->model->c1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c1");
+    self->model->c1.dispersion->accept_as_destination(visitor, self->model->c1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c2");
+    self->model->c2.dispersion->accept_as_destination(visitor, self->model->c2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CTeubnerStreyModelError, 
+	    	"CTeubnerStreyModel.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(CTeubnerStreyModelError, 
+                   "CTeubnerStreyModel.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(CTeubnerStreyModelError, 
+	    		"CTeubnerStreyModel.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(CTeubnerStreyModelError, 
+                   "CTeubnerStreyModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CTeubnerStreyModelError, 
+                   "CTeubnerStreyModel.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(CTeubnerStreyModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->c2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c2") );
+    self->model->c1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c1");
+    self->model->c1.dispersion->accept_as_destination(visitor, self->model->c1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c2");
+    self->model->c2.dispersion->accept_as_destination(visitor, self->model->c2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CTeubnerStreyModelError, 
+	    	"CTeubnerStreyModel.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(CTeubnerStreyModelError, 
+	    		"CTeubnerStreyModel.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 = CTeubnerStreyModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CTeubnerStreyModel_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 = CTeubnerStreyModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CTeubnerStreyModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->c2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c2") );
+    self->model->c1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c1");
+    self->model->c1.dispersion->accept_as_destination(visitor, self->model->c1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c2");
+    self->model->c2.dispersion->accept_as_destination(visitor, self->model->c2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CTeubnerStreyModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->c2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c2") );
+    self->model->c1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c1");
+    self->model->c1.dispersion->accept_as_destination(visitor, self->model->c1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c2");
+    self->model->c2.dispersion->accept_as_destination(visitor, self->model->c2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CTeubnerStreyModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->c2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c2") );
+    self->model->c1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "c1") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "scale");
+    self->model->scale.dispersion->accept_as_destination(visitor, self->model->scale.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c1");
+    self->model->c1.dispersion->accept_as_destination(visitor, self->model->c1.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "c2");
+    self->model->c2.dispersion->accept_as_destination(visitor, self->model->c2.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "background");
+    self->model->background.dispersion->accept_as_destination(visitor, self->model->background.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(CTeubnerStreyModelError, 
+	    	"CTeubnerStreyModel.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(CTeubnerStreyModelError, 
+	    		"CTeubnerStreyModel.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 = CTeubnerStreyModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CTeubnerStreyModel_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 = CTeubnerStreyModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CTeubnerStreyModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CTeubnerStreyModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CTeubnerStreyModelError,
+	    	"CTeubnerStreyModel.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, "scale")) {
+        self->model->scale.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "c1")) {
+        self->model->c1.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "c2")) {
+        self->model->c2.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "background")) {
+        self->model->background.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CTeubnerStreyModelError,
+	    	"CTeubnerStreyModel.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 CTeubnerStreyModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CTeubnerStreyModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CTeubnerStreyModel",             /*tp_name*/
+    sizeof(CTeubnerStreyModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CTeubnerStreyModel_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*/
+    "CTeubnerStreyModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CTeubnerStreyModel_methods,             /* tp_methods */
+    CTeubnerStreyModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CTeubnerStreyModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CTeubnerStreyModel_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 addCTeubnerStreyModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CTeubnerStreyModelType) < 0)
+        return;
+
+    Py_INCREF(&CTeubnerStreyModelType);
+    PyModule_AddObject(module, "CTeubnerStreyModel", (PyObject *)&CTeubnerStreyModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CTeubnerStreyModel.error";
+    CTeubnerStreyModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CTeubnerStreyModelError", CTeubnerStreyModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CTriaxialEllipsoidModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CTriaxialEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CTriaxialEllipsoidModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,687 @@
+/**
+	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
+ */
+
+/** CTriaxialEllipsoidModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\triaxial_ellipsoid.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 "triaxial_ellipsoid.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CTriaxialEllipsoidModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    TriaxialEllipsoidModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CTriaxialEllipsoidModel;
+
+
+static void
+CTriaxialEllipsoidModel_dealloc(CTriaxialEllipsoidModel* 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 *
+CTriaxialEllipsoidModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CTriaxialEllipsoidModel *self;
+    
+    self = (CTriaxialEllipsoidModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CTriaxialEllipsoidModel_init(CTriaxialEllipsoidModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new TriaxialEllipsoidModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"axis_psi",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"axis_theta",Py_BuildValue("d",57.325000000000));
+        PyDict_SetItemString(self->params,"semi_axisA",Py_BuildValue("d",35.000000000000));
+        PyDict_SetItemString(self->params,"semi_axisB",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"semi_axisC",Py_BuildValue("d",400.000000000000));
+        PyDict_SetItemString(self->params,"axis_phi",Py_BuildValue("d",57.325000000000));
+        PyDict_SetItemString(self->params,"sldSolv",Py_BuildValue("d",0.000006300000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"sldEll",Py_BuildValue("d",0.000001000000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->semi_axisA.dispersion->accept_as_source(visitor, self->model->semi_axisA.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "semi_axisA", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->semi_axisB.dispersion->accept_as_source(visitor, self->model->semi_axisB.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "semi_axisB", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->semi_axisC.dispersion->accept_as_source(visitor, self->model->semi_axisC.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "semi_axisC", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_theta.dispersion->accept_as_source(visitor, self->model->axis_theta.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_theta", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_phi.dispersion->accept_as_source(visitor, self->model->axis_phi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_phi", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->axis_psi.dispersion->accept_as_source(visitor, self->model->axis_psi.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "axis_psi", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CTriaxialEllipsoidModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CTriaxialEllipsoidModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CTriaxialEllipsoidModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CTriaxialEllipsoidModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CTriaxialEllipsoidModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(TriaxialEllipsoidModel* 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;
+	}
+#pragma omp parallel for
+	 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( TriaxialEllipsoidModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CTriaxialEllipsoidModelError, 
+                   "CTriaxialEllipsoidModel.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(CTriaxialEllipsoidModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisA");
+    self->model->semi_axisA.dispersion->accept_as_destination(visitor, self->model->semi_axisA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisB");
+    self->model->semi_axisB.dispersion->accept_as_destination(visitor, self->model->semi_axisB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisC");
+    self->model->semi_axisC.dispersion->accept_as_destination(visitor, self->model->semi_axisC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_psi");
+    self->model->axis_psi.dispersion->accept_as_destination(visitor, self->model->axis_psi.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(CTriaxialEllipsoidModelError, 
+	    	"CTriaxialEllipsoidModel.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(CTriaxialEllipsoidModelError, 
+                   "CTriaxialEllipsoidModel.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(CTriaxialEllipsoidModelError, 
+	    		"CTriaxialEllipsoidModel.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(CTriaxialEllipsoidModelError, 
+                   "CTriaxialEllipsoidModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CTriaxialEllipsoidModelError, 
+                   "CTriaxialEllipsoidModel.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(CTriaxialEllipsoidModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisA");
+    self->model->semi_axisA.dispersion->accept_as_destination(visitor, self->model->semi_axisA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisB");
+    self->model->semi_axisB.dispersion->accept_as_destination(visitor, self->model->semi_axisB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisC");
+    self->model->semi_axisC.dispersion->accept_as_destination(visitor, self->model->semi_axisC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_psi");
+    self->model->axis_psi.dispersion->accept_as_destination(visitor, self->model->axis_psi.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(CTriaxialEllipsoidModelError, 
+	    	"CTriaxialEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    		"CTriaxialEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CTriaxialEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CTriaxialEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisA");
+    self->model->semi_axisA.dispersion->accept_as_destination(visitor, self->model->semi_axisA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisB");
+    self->model->semi_axisB.dispersion->accept_as_destination(visitor, self->model->semi_axisB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisC");
+    self->model->semi_axisC.dispersion->accept_as_destination(visitor, self->model->semi_axisC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_psi");
+    self->model->axis_psi.dispersion->accept_as_destination(visitor, self->model->axis_psi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CTriaxialEllipsoidModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisA");
+    self->model->semi_axisA.dispersion->accept_as_destination(visitor, self->model->semi_axisA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisB");
+    self->model->semi_axisB.dispersion->accept_as_destination(visitor, self->model->semi_axisB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisC");
+    self->model->semi_axisC.dispersion->accept_as_destination(visitor, self->model->semi_axisC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_psi");
+    self->model->axis_psi.dispersion->accept_as_destination(visitor, self->model->axis_psi.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CTriaxialEllipsoidModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->axis_psi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_psi") );
+    self->model->axis_theta = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_theta") );
+    self->model->semi_axisA = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisA") );
+    self->model->semi_axisB = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisB") );
+    self->model->semi_axisC = PyFloat_AsDouble( PyDict_GetItemString(self->params, "semi_axisC") );
+    self->model->axis_phi = PyFloat_AsDouble( PyDict_GetItemString(self->params, "axis_phi") );
+    self->model->sldSolv = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldSolv") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->sldEll = PyFloat_AsDouble( PyDict_GetItemString(self->params, "sldEll") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisA");
+    self->model->semi_axisA.dispersion->accept_as_destination(visitor, self->model->semi_axisA.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisB");
+    self->model->semi_axisB.dispersion->accept_as_destination(visitor, self->model->semi_axisB.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "semi_axisC");
+    self->model->semi_axisC.dispersion->accept_as_destination(visitor, self->model->semi_axisC.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_theta");
+    self->model->axis_theta.dispersion->accept_as_destination(visitor, self->model->axis_theta.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_phi");
+    self->model->axis_phi.dispersion->accept_as_destination(visitor, self->model->axis_phi.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "axis_psi");
+    self->model->axis_psi.dispersion->accept_as_destination(visitor, self->model->axis_psi.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(CTriaxialEllipsoidModelError, 
+	    	"CTriaxialEllipsoidModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CTriaxialEllipsoidModelError, 
+	    		"CTriaxialEllipsoidModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CTriaxialEllipsoidModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CTriaxialEllipsoidModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CTriaxialEllipsoidModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CTriaxialEllipsoidModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CTriaxialEllipsoidModelError,
+	    	"CTriaxialEllipsoidModel.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, "semi_axisA")) {
+        self->model->semi_axisA.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "semi_axisB")) {
+        self->model->semi_axisB.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "semi_axisC")) {
+        self->model->semi_axisC.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_theta")) {
+        self->model->axis_theta.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_phi")) {
+        self->model->axis_phi.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "axis_psi")) {
+        self->model->axis_psi.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CTriaxialEllipsoidModelError,
+	    	"CTriaxialEllipsoidModel.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 CTriaxialEllipsoidModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CTriaxialEllipsoidModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CTriaxialEllipsoidModel",             /*tp_name*/
+    sizeof(CTriaxialEllipsoidModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CTriaxialEllipsoidModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CTriaxialEllipsoidModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CTriaxialEllipsoidModel_methods,             /* tp_methods */
+    CTriaxialEllipsoidModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CTriaxialEllipsoidModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CTriaxialEllipsoidModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCTriaxialEllipsoidModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CTriaxialEllipsoidModelType) < 0)
+        return;
+
+    Py_INCREF(&CTriaxialEllipsoidModelType);
+    PyModule_AddObject(module, "CTriaxialEllipsoidModel", (PyObject *)&CTriaxialEllipsoidModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CTriaxialEllipsoidModel.error";
+    CTriaxialEllipsoidModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CTriaxialEllipsoidModelError", CTriaxialEllipsoidModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CTwoYukawaModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CTwoYukawaModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CTwoYukawaModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,555 @@
+/**
+	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
+ */
+
+/** CTwoYukawaModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\TwoYukawa.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 "TwoYukawa.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CTwoYukawaModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    TwoYukawaModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CTwoYukawaModel;
+
+
+static void
+CTwoYukawaModel_dealloc(CTwoYukawaModel* 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 *
+CTwoYukawaModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CTwoYukawaModel *self;
+    
+    self = (CTwoYukawaModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CTwoYukawaModel_init(CTwoYukawaModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new TwoYukawaModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"decayConst_Z1",Py_BuildValue("d",10.000000000000));
+        PyDict_SetItemString(self->params,"decayConst_Z2",Py_BuildValue("d",2.000000000000));
+        PyDict_SetItemString(self->params,"volfraction",Py_BuildValue("d",0.200000000000));
+        PyDict_SetItemString(self->params,"effect_radius",Py_BuildValue("d",50.000000000000));
+        PyDict_SetItemString(self->params,"scale_K1",Py_BuildValue("d",6.000000000000));
+        PyDict_SetItemString(self->params,"scale_K2",Py_BuildValue("d",-1.000000000000));
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CTwoYukawaModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CTwoYukawaModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CTwoYukawaModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CTwoYukawaModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CTwoYukawaModel_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(TwoYukawaModel* 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;
+	}
+#pragma omp parallel for
+	 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( TwoYukawaModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CTwoYukawaModelError, 
+                   "CTwoYukawaModel.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(CTwoYukawaModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->decayConst_Z1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z1") );
+    self->model->decayConst_Z2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z2") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->scale_K1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K1") );
+    self->model->scale_K2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K2") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CTwoYukawaModelError, 
+	    	"CTwoYukawaModel.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(CTwoYukawaModelError, 
+                   "CTwoYukawaModel.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(CTwoYukawaModelError, 
+	    		"CTwoYukawaModel.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(CTwoYukawaModelError, 
+                   "CTwoYukawaModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CTwoYukawaModelError, 
+                   "CTwoYukawaModel.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(CTwoYukawaModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->decayConst_Z1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z1") );
+    self->model->decayConst_Z2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z2") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->scale_K1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K1") );
+    self->model->scale_K2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K2") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CTwoYukawaModelError, 
+	    	"CTwoYukawaModel.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(CTwoYukawaModelError, 
+	    		"CTwoYukawaModel.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 = CTwoYukawaModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CTwoYukawaModel_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 = CTwoYukawaModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CTwoYukawaModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->decayConst_Z1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z1") );
+    self->model->decayConst_Z2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z2") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->scale_K1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K1") );
+    self->model->scale_K2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K2") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CTwoYukawaModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->decayConst_Z1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z1") );
+    self->model->decayConst_Z2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z2") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->scale_K1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K1") );
+    self->model->scale_K2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K2") );
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CTwoYukawaModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->decayConst_Z1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z1") );
+    self->model->decayConst_Z2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "decayConst_Z2") );
+    self->model->volfraction = PyFloat_AsDouble( PyDict_GetItemString(self->params, "volfraction") );
+    self->model->effect_radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "effect_radius") );
+    self->model->scale_K1 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K1") );
+    self->model->scale_K2 = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale_K2") );
+
+	
+	// Get input and determine whether we have to supply a 1D or 2D return value.
+	if ( !PyArg_ParseTuple(args,"O",&pars) ) {
+	    PyErr_SetString(CTwoYukawaModelError, 
+	    	"CTwoYukawaModel.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(CTwoYukawaModelError, 
+	    		"CTwoYukawaModel.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 = CTwoYukawaModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CTwoYukawaModel_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 = CTwoYukawaModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CTwoYukawaModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CTwoYukawaModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CTwoYukawaModelError,
+	    	"CTwoYukawaModel.set_dispersion expects a DispersionModel object.");
+		return NULL;
+	}
+	void *temp = PyCObject_AsVoidPtr(disp);
+	DispersionModel * dispersion = static_cast<DispersionModel *>(temp);
+
+
+	// Ugliness necessary to go from python to C
+	    // TODO: refactor this
+ {
+	    PyErr_SetString(CTwoYukawaModelError,
+	    	"CTwoYukawaModel.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 CTwoYukawaModel_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"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CTwoYukawaModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CTwoYukawaModel",             /*tp_name*/
+    sizeof(CTwoYukawaModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CTwoYukawaModel_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*/
+    "CTwoYukawaModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CTwoYukawaModel_methods,             /* tp_methods */
+    CTwoYukawaModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CTwoYukawaModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CTwoYukawaModel_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 addCTwoYukawaModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CTwoYukawaModelType) < 0)
+        return;
+
+    Py_INCREF(&CTwoYukawaModelType);
+    PyModule_AddObject(module, "CTwoYukawaModel", (PyObject *)&CTwoYukawaModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CTwoYukawaModel.error";
+    CTwoYukawaModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CTwoYukawaModelError", CTwoYukawaModelError);
+}
+
Index: src/sans/models/c_extension/python_wrapper/generated/CVesicleModel.cpp
===================================================================
--- src/sans/models/c_extension/python_wrapper/generated/CVesicleModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
+++ src/sans/models/c_extension/python_wrapper/generated/CVesicleModel.cpp	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -0,0 +1,603 @@
+/**
+	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
+ */
+
+/** CVesicleModel
+ *
+ * C extension 
+ *
+ * WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+ *          DO NOT MODIFY THIS FILE, MODIFY src\sans\models\include\vesicle.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 "vesicle.h"
+#include "dispersion_visitor.hh"
+
+/// Error object for raised exceptions
+static PyObject * CVesicleModelError = NULL;
+
+
+// Class definition
+typedef struct {
+    PyObject_HEAD
+    /// Parameters
+    PyObject * params;
+    /// Dispersion parameters
+    PyObject * dispersion;
+    /// Underlying model object
+    VesicleModel * model;
+    /// Log for unit testing
+    PyObject * log;
+} CVesicleModel;
+
+
+static void
+CVesicleModel_dealloc(CVesicleModel* 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 *
+CVesicleModel_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    CVesicleModel *self;
+    
+    self = (CVesicleModel *)type->tp_alloc(type, 0);
+   
+    return (PyObject *)self;
+}
+
+static int
+CVesicleModel_init(CVesicleModel *self, PyObject *args, PyObject *kwds)
+{
+    if (self != NULL) {
+    	
+    	// Create parameters
+        self->params = PyDict_New();
+        self->dispersion = PyDict_New();
+
+	self->model = new VesicleModel();
+
+        // Initialize parameter dictionary
+        PyDict_SetItemString(self->params,"solv_sld",Py_BuildValue("d",0.000006360000));
+        PyDict_SetItemString(self->params,"scale",Py_BuildValue("d",1.000000000000));
+        PyDict_SetItemString(self->params,"thickness",Py_BuildValue("d",30.000000000000));
+        PyDict_SetItemString(self->params,"radius",Py_BuildValue("d",100.000000000000));
+        PyDict_SetItemString(self->params,"background",Py_BuildValue("d",0.000000000000));
+        PyDict_SetItemString(self->params,"shell_sld",Py_BuildValue("d",0.000000500000));
+        // Initialize dispersion / averaging parameter dict
+        DispersionVisitor* visitor = new DispersionVisitor();
+        PyObject * disp_dict;
+        disp_dict = PyDict_New();
+        self->model->radius.dispersion->accept_as_source(visitor, self->model->radius.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "radius", disp_dict);
+        disp_dict = PyDict_New();
+        self->model->thickness.dispersion->accept_as_source(visitor, self->model->thickness.dispersion, disp_dict);
+        PyDict_SetItemString(self->dispersion, "thickness", disp_dict);
+
+
+         
+        // Create empty log
+        self->log = PyDict_New();
+        
+        
+
+    }
+    return 0;
+}
+
+static char name_params[] = "params";
+static char def_params[] = "Parameters";
+static char name_dispersion[] = "dispersion";
+static char def_dispersion[] = "Dispersion parameters";
+static char name_log[] = "log";
+static char def_log[] = "Log";
+
+static PyMemberDef CVesicleModel_members[] = {
+    {name_params, T_OBJECT, offsetof(CVesicleModel, params), 0, def_params},
+	{name_dispersion, T_OBJECT, offsetof(CVesicleModel, dispersion), 0, def_dispersion},     
+    {name_log, T_OBJECT, offsetof(CVesicleModel, log), 0, def_log},
+    {NULL}  /* Sentinel */
+};
+
+/** Read double from PyObject
+    @param p PyObject
+    @return double
+*/
+double CVesicleModel_readDouble(PyObject *p) {
+    if (PyFloat_Check(p)==1) {
+        return (double)(((PyFloatObject *)(p))->ob_fval);
+    } else if (PyInt_Check(p)==1) {
+        return (double)(((PyIntObject *)(p))->ob_ival);
+    } else if (PyLong_Check(p)==1) {
+        return (double)PyLong_AsLong(p);
+    } else {
+        return 0.0;
+    }
+}
+/**
+ * Function to call to evaluate model
+ * @param args: input numpy array q[] 
+ * @return: numpy array object 
+ */
+ 
+static PyObject *evaluateOneDim(VesicleModel* 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;
+	}
+#pragma omp parallel for
+	 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( VesicleModel* model, 
+                              PyArrayObject *x, PyArrayObject *y)
+ {
+    PyArrayObject *result;
+    int 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. */
+#pragma omp parallel for
+        for (int 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(CVesicleModelError, 
+                   "CVesicleModel.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(CVesicleModel *self, PyObject *args){
+	PyObject *qx, *qy;
+	PyArrayObject * pars;
+	int npars ,mpars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->solv_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solv_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CVesicleModelError, 
+	    	"CVesicleModel.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(CVesicleModelError, 
+                   "CVesicleModel.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(CVesicleModelError, 
+	    		"CVesicleModel.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(CVesicleModelError, 
+                   "CVesicleModel.evalDistribution expect 2 numpy arrays in list.");
+	        return NULL;
+	     }
+	}
+	PyErr_SetString(CVesicleModelError, 
+                   "CVesicleModel.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(CVesicleModel *self, PyObject *args) {
+	double q_value, phi_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->solv_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solv_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CVesicleModelError, 
+	    	"CVesicleModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(q,phi)
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CVesicleModelError, 
+	    		"CVesicleModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the q and phi values at which
+	    // to evaluate I(q,phi)
+	    q_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    phi_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,1));
+	    // Skip zero
+	    if (q_value==0) {
+	    	return Py_BuildValue("d",0.0);
+	    }
+		return Py_BuildValue("d",(*(self->model)).evaluate_rphi(q_value,phi_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		q_value = CVesicleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(q_value));
+	}	
+}
+/**
+ * Function to call to calculate_ER
+ * @return: effective radius value 
+ */
+static PyObject * calculate_ER(CVesicleModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->solv_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solv_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_ER());
+
+}
+/**
+ * Function to call to cal the ratio shell volume/ total volume
+ * @return: the ratio shell volume/ total volume 
+ */
+static PyObject * calculate_VR(CVesicleModel *self) {
+
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->solv_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solv_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.dispersion, disp_dict);
+
+		
+	return Py_BuildValue("d",(*(self->model)).calculate_VR());
+
+}
+/**
+ * Function to call to evaluate model in cartesian coordinates
+ * @param args: input q or [qx, qy]]
+ * @return: function value
+ */
+static PyObject * runXY(CVesicleModel *self, PyObject *args) {
+	double qx_value, qy_value;
+	PyObject* pars;
+	int npars;
+	
+	// Get parameters
+	
+	    // Reader parameter dictionary
+    self->model->solv_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "solv_sld") );
+    self->model->scale = PyFloat_AsDouble( PyDict_GetItemString(self->params, "scale") );
+    self->model->thickness = PyFloat_AsDouble( PyDict_GetItemString(self->params, "thickness") );
+    self->model->radius = PyFloat_AsDouble( PyDict_GetItemString(self->params, "radius") );
+    self->model->background = PyFloat_AsDouble( PyDict_GetItemString(self->params, "background") );
+    self->model->shell_sld = PyFloat_AsDouble( PyDict_GetItemString(self->params, "shell_sld") );
+    // Read in dispersion parameters
+    PyObject* disp_dict;
+    DispersionVisitor* visitor = new DispersionVisitor();
+    disp_dict = PyDict_GetItemString(self->dispersion, "radius");
+    self->model->radius.dispersion->accept_as_destination(visitor, self->model->radius.dispersion, disp_dict);
+    disp_dict = PyDict_GetItemString(self->dispersion, "thickness");
+    self->model->thickness.dispersion->accept_as_destination(visitor, self->model->thickness.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(CVesicleModelError, 
+	    	"CVesicleModel.run expects a q value.");
+		return NULL;
+	}
+	  
+	// Check params
+	if( PyList_Check(pars)==1) {
+		
+		// Length of list should be 2 for I(qx, qy))
+	    npars = PyList_GET_SIZE(pars); 
+	    if(npars!=2) {
+	    	PyErr_SetString(CVesicleModelError, 
+	    		"CVesicleModel.run expects a double or a list of dimension 2.");
+	    	return NULL;
+	    }
+	    // We have a vector q, get the qx and qy values at which
+	    // to evaluate I(qx,qy)
+	    qx_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,0));
+	    qy_value = CVesicleModel_readDouble(PyList_GET_ITEM(pars,1));
+	    return Py_BuildValue("d",(*(self->model))(qx_value,qy_value));
+
+	} else {
+
+		// We have a scalar q, we will evaluate I(q)
+		qx_value = CVesicleModel_readDouble(pars);		
+		
+		return Py_BuildValue("d",(*(self->model))(qx_value));
+	}	
+}
+
+static PyObject * reset(CVesicleModel *self, PyObject *args) {
+    
+
+    return Py_BuildValue("d",0.0);
+}
+
+static PyObject * set_dispersion(CVesicleModel *self, PyObject *args) {
+	PyObject * disp;
+	const char * par_name;
+
+	if ( !PyArg_ParseTuple(args,"sO", &par_name, &disp) ) {
+	    PyErr_SetString(CVesicleModelError,
+	    	"CVesicleModel.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, "radius")) {
+        self->model->radius.dispersion = dispersion;
+    } else    if (!strcmp(par_name, "thickness")) {
+        self->model->thickness.dispersion = dispersion;
+    } else {
+	    PyErr_SetString(CVesicleModelError,
+	    	"CVesicleModel.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 CVesicleModel_methods[] = {
+    {"run",      (PyCFunction)run     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"runXY",      (PyCFunction)runXY     , METH_VARARGS,
+      "Evaluate the model at a given Q or Qx, Qy"},
+    {"calculate_ER",      (PyCFunction)calculate_ER     , METH_VARARGS,
+      "Evaluate the model at a given Q or Q, phi"},
+    {"calculate_VR",      (PyCFunction)calculate_VR     , METH_VARARGS,
+      "Evaluate VR"},    
+    {"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 CVesicleModelType = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "CVesicleModel",             /*tp_name*/
+    sizeof(CVesicleModel),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor)CVesicleModel_dealloc, /*tp_dealloc*/
+    0,                         /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "CVesicleModel objects",           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    CVesicleModel_methods,             /* tp_methods */
+    CVesicleModel_members,             /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    (initproc)CVesicleModel_init,      /* tp_init */
+    0,                         /* tp_alloc */
+    CVesicleModel_new,                 /* tp_new */
+};
+
+
+//static PyMethodDef module_methods[] = {
+//    {NULL} 
+//};
+
+/**
+ * Function used to add the model class to a module
+ * @param module: module to add the class to
+ */ 
+void addCVesicleModel(PyObject *module) {
+	PyObject *d;
+	
+    if (PyType_Ready(&CVesicleModelType) < 0)
+        return;
+
+    Py_INCREF(&CVesicleModelType);
+    PyModule_AddObject(module, "CVesicleModel", (PyObject *)&CVesicleModelType);
+    
+    d = PyModule_GetDict(module);
+    static char error_name[] = "CVesicleModel.error";
+    CVesicleModelError = PyErr_NewException(error_name, NULL, NULL);
+    PyDict_SetItemString(d, "CVesicleModelError", CVesicleModelError);
+}
+
Index: test/pr_inversion/test/test_output.txt
===================================================================
--- test/pr_inversion/test/test_output.txt	(revision 5777106e8a4a0a62fe2ee0fbaf7c0aa19c0bb92b)
+++ test/pr_inversion/test/test_output.txt	(revision 81b524f07169c5a9b32c97df6fd594592331f005)
@@ -3,5 +3,5 @@
 #alpha=0.0007
 #chi2=836.797
-#elapsed=0.000825167
+#elapsed=0.000999928
 #qmin=None
 #qmax=None
