Index: sansmodels/src/sans/models/OnionExpShellModel.py
===================================================================
--- sansmodels/src/sans/models/OnionExpShellModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
+++ sansmodels/src/sans/models/OnionExpShellModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -0,0 +1,298 @@
+   
+from sans.models.BaseComponent import BaseComponent
+from sans.models.OnionModel import OnionModel
+import copy
+max_nshells = 10
+class OnionExpShellModel(BaseComponent):
+    """
+    This multi-model is based on CoreMultiShellModel with exponential 
+    func shells and provides the capability
+    of changing the number of shells between 1 and 10.
+    """
+    def __init__(self, n_shells=1):
+        BaseComponent.__init__(self)
+        """
+        :param n_shells: number of shells in the model, 
+        assumes 1<= n_shells <=10.
+        """
+
+        ## Setting  model name model description
+        self.description=""
+        model = OnionModel()
+        self.model = model
+        self.name = "OnionExpShellModel"
+        self.description=model.description
+        self.n_shells = n_shells
+        ## Define parameters
+        self.params = {}
+
+        ## Parameter details [units, min, max]
+        self.details = {}
+        
+        ## dispersion
+        self._set_dispersion()
+        ## Define parameters
+        self._set_params()
+        
+        ## Parameter details [units, min, max]
+        self._set_details()
+        
+        #list of parameter that can be fitted
+        self._set_fixed_params()  
+        self.model.params['n_shells'] = self.n_shells
+        ## functional multiplicity info of the model
+        # [int(maximum no. of functionality),"str(Titl),
+        # [str(name of function0),...], [str(x-asix name of sld),...]]
+        self.multiplicity_info = [max_nshells,"No. of Shells:",[],['Radius']]
+
+        ## parameters with orientation: can be removed since there is 
+        # no orientational params
+        for item in self.model.orientation_params:
+            self.orientation_params.append(item)
+        self.getProfile()        
+    def _clone(self, obj):
+        """
+        Internal utility function to copy the internal
+        data members to a fresh copy.
+        """
+        obj.params     = copy.deepcopy(self.params)
+        obj.description     = copy.deepcopy(self.description)
+        obj.details    = copy.deepcopy(self.details)
+        obj.dispersion = copy.deepcopy(self.dispersion)
+        obj.model  = self.model.clone()
+
+        return obj
+    
+    
+    def _set_dispersion(self):
+        """
+        model dispersions
+        """ 
+        ##set dispersion from model 
+        for name , value in self.model.dispersion.iteritems():   
+              
+            nshell = 0
+            if name.split('_')[0] == 'thick':
+                while nshell<self.n_shells:
+                    nshell += 1
+                    if name.split('_')[1] == 'shell%s' % str(nshell):
+                        self.dispersion[name]= value
+                    else: 
+                        continue
+            else:
+                self.dispersion[name]= value
+                    
+
+    def _set_params(self):
+        """
+        Concatenate the parameters of the model to create
+        this model parameters 
+        """
+        # rearrange the parameters for the given # of shells
+        for name , value in self.model.params.iteritems():
+            nshell = 0
+            pos = len(name.split('_'))-1
+            if name.split('_')[0] == 'func':
+                continue
+            elif name.split('_')[pos][0:5] == 'shell':
+                    while nshell<self.n_shells:
+                        nshell += 1
+                        if name.split('_')[pos] == 'shell%s' % str(nshell):
+                            self.params[name]= value
+                            continue
+            else:
+                self.params[name]= value
+               
+        self.model.params['n_shells'] = self.n_shells    
+
+        # set constrained values for the original model params
+        self._set_xtra_model_param()       
+  
+    def _set_details(self):
+        """
+        Concatenate details of the original model to create
+        this model details 
+        """
+        for name ,detail in self.model.details.iteritems():
+            if name in self.params.iterkeys():
+                self.details[name]= detail
+            
+    
+    def _set_xtra_model_param(self):
+        """
+        Set params of original model that are hidden from this model
+        """
+        # look for the model parameters that are not in param list
+        for key in self.model.params.iterkeys():
+            if key not in self.params.keys():
+                if  key.split('_')[0] == 'thick':
+                    self.model.setParam(key, 0)
+                    continue
+                if  key.split('_')[0] == 'A':
+                    self.model.setParam(key, 0)
+                    continue
+                if  key.split('_')[0] == 'func':
+                    self.model.setParam(key, 2)
+                    continue
+                for nshell in range(self.n_shells,max_nshells):
+                    if key.split('_')[1] == 'sld_in_shell%s' % str(nshell+1):
+                        try:
+                            value = self.model.params['sld_solv']
+                            self.model.setParam(key, value)
+                        except: pass
+    def getProfile(self):
+        """
+        Get SLD profile 
+        
+        : return: (r, beta) where r is a list of radius of the transition 
+                points and  beta is a list of the corresponding SLD values 
+        """
+        # max_pts for each shells
+        max_pts = 10
+        r = []
+        beta = []
+        # for core at r=0
+        r.append(0)
+        beta.append(self.params['sld_core0'])
+        # for core at r=rad_core
+        r.append(self.params['rad_core0'])
+        beta.append(self.params['sld_core0'])
+        
+        # for shells
+        for n in range(1,self.n_shells+1):
+            # Left side of each shells
+            r0 = r[len(r)-1]            
+            r.append(r0)
+            beta.append(self.params['sld_in_shell%s'% str(n)])
+            
+            A = self.params['A_shell%s'% str(n)]
+            from math import fabs
+            if fabs(A) <1.0e-16:
+                # Right side of each shells
+                r0 += self.params['thick_shell%s'% str(n)]
+                r.append(r0)
+                beta.append(self.params['sld_in_shell%s'% str(n)])
+            else:
+                from math import exp
+                rn = r0
+                for n_sub in range(0,max_pts):
+                    # Right side of each sub_shells
+                    rn += self.params['thick_shell%s'% str(n)]/10.0
+                    r.append(rn)
+                    slope = (self.params['sld_out_shell%s'% str(n)] \
+                                    -self.params['sld_in_shell%s'% str(n)]) \
+                                     /(exp(self.params['A_shell%s'% str(n)])-1)
+                    const = (self.params['sld_in_shell%s'% str(n)]-slope)
+                    beta_n = slope*exp((self.params['A_shell%s'% str(n)]* \
+                        (rn-r0)/self.params['thick_shell%s'% str(n)])) + const
+                    beta.append(beta_n)
+            
+        # for solvent
+        r0 = r[len(r)-1]            
+        r.append(r0)
+        beta.append(self.params['sld_solv'])
+        r_solv = 5*r0/4
+        r.append(r_solv)
+        beta.append(self.params['sld_solv'])
+        
+        return r, beta
+    
+    def setParam(self, name, value):
+        """ 
+        Set the value of a model parameter
+    
+        : param name: name of the parameter
+        : param value: value of the parameter
+        """
+        # set param to new model
+        self._setParamHelper( name, value)
+        
+        ## setParam to model 
+        if name=='sld_solv':
+            # the sld_*** model.params not in params must set to value 
+            # of sld_solv
+            for key in self.model.params.iterkeys():
+                if key not in self.params.keys()and key.split('_')[0] == 'sld':
+                        self.model.setParam(key, value)
+        self.model.setParam( name, value)
+       
+    def _setParamHelper(self, name, value):
+        """
+        Helper function to setParam
+        """
+        #look for dispersion parameters
+        toks = name.split('.')
+        if len(toks)==2:
+            for item in self.dispersion.keys():
+                if item.lower()==toks[0].lower():
+                    for par in self.dispersion[item]:
+                        if par.lower() == toks[1].lower():
+                            self.dispersion[item][par] = value
+                            return
+        # Look for standard parameter
+        for item in self.params.keys():
+            if item.lower()==name.lower():
+                self.params[item] = value
+                return
+        
+        raise ValueError, "Model does not contain parameter %s" % name
+             
+   
+    def _set_fixed_params(self):
+        """
+        Fill the self.fixed list with the model fixed list
+        """
+        for item in self.model.fixed:
+            if item.split('.')[0] in self.params.keys(): 
+                self.fixed.append(item)
+
+        self.fixed.sort()
+        pass         
+                
+    def run(self, x = 0.0):
+        """ 
+        Evaluate the model
+        
+        : param x: input q-value (float or [float, float] as [r, theta])
+        : return: (I value)
+        """
+
+        return self.model.run(x)
+
+    def runXY(self, x = 0.0):
+        """ 
+        Evaluate the model
+        
+        : param x: input q-value (float or [float, float] as [qx, qy])
+        : return: I value
+        """  
+
+        return self.model.runXY(x)
+    
+    ## Now (May27,10) directly uses the model eval function 
+    ## instead of the for-loop in Base Component.
+    def evalDistribution(self, x = []):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        : param x: input q[], or [qx[], qy[]]
+        : return: scattering function P(q[])
+        """
+        # set effective radius and scaling factor before run
+        return self.model.evalDistribution(x)
+
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        : param parameter: name of the parameter [string]
+        :dispersion: dispersion object of type DispersionModel
+        """
+        value= None
+        try:
+            if parameter in self.model.dispersion.keys():
+                value= self.model.set_dispersion(parameter, dispersion)
+            self._set_dispersion()
+            return value
+        except:
+            raise 
Index: sansmodels/src/sans/models/ReflModel.py
===================================================================
--- sansmodels/src/sans/models/ReflModel.py	(revision 339ce675656e3ab89eff7b84d8292a2e0ffe6109)
+++ sansmodels/src/sans/models/ReflModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -40,5 +40,5 @@
          thick_inter0    = 1.0 [A]
          func_inter0     = 0.0 
-         sld_sub0        = 2.07e-006 [1/A^(2)]
+         sld_bottom0     = 2.07e-006 [1/A^(2)]
          sld_medium      = 1e-006 [1/A^(2)]
          background      = 0.0 
@@ -83,16 +83,4 @@
          func_inter9     = 0.0 
          func_inter10    = 0.0 
-         sldIM_flat1     = 0.0 
-         sldIM_flat2     = 0.0 
-         sldIM_flat3     = 0.0 
-         sldIM_flat4     = 0.0 
-         sldIM_flat5     = 0.0 
-         sldIM_flat6     = 0.0 
-         sldIM_flat7     = 0.0 
-         sldIM_flat8     = 0.0 
-         sldIM_flat9     = 0.0 
-         sldIM_flat10    = 0.0 
-         sldIM_sub0      = 0.0 
-         sldIM_medium    = 0.0 
 
     """
@@ -108,27 +96,21 @@
         self.name = "ReflModel"
         ## 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_core: radius of sphere(core)
-		thick_shell#:the thickness of the shell#
-		sld_core: 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"""
+        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]
@@ -138,5 +120,5 @@
         self.details['thick_inter0'] = ['[A]', None, None]
         self.details['func_inter0'] = ['', None, None]
-        self.details['sld_sub0'] = ['[1/A^(2)]', 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]
@@ -181,16 +163,4 @@
         self.details['func_inter9'] = ['', None, None]
         self.details['func_inter10'] = ['', None, None]
-        self.details['sldIM_flat1'] = ['', None, None]
-        self.details['sldIM_flat2'] = ['', None, None]
-        self.details['sldIM_flat3'] = ['', None, None]
-        self.details['sldIM_flat4'] = ['', None, None]
-        self.details['sldIM_flat5'] = ['', None, None]
-        self.details['sldIM_flat6'] = ['', None, None]
-        self.details['sldIM_flat7'] = ['', None, None]
-        self.details['sldIM_flat8'] = ['', None, None]
-        self.details['sldIM_flat9'] = ['', None, None]
-        self.details['sldIM_flat10'] = ['', None, None]
-        self.details['sldIM_sub0'] = ['', None, None]
-        self.details['sldIM_medium'] = ['', None, None]
 
         ## fittable parameters
Index: sansmodels/src/sans/models/ReflectivityModel.py
===================================================================
--- sansmodels/src/sans/models/ReflectivityModel.py	(revision 8f20419d5be1d467bd17c7dfade28c96f90656ca)
+++ sansmodels/src/sans/models/ReflectivityModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -5,6 +5,5 @@
 from math import floor
 from scipy.special import erf
-func_list = {'Erf':0, 'Linear':1, 'RParabolic':2, \
-                     'LParabola':3, 'RCubic':4, 'LCubic':5}
+func_list = {'Erf':0, 'Linear':1}
 max_nshells = 10
 class ReflectivityModel(BaseComponent):
@@ -16,5 +15,6 @@
         BaseComponent.__init__(self)
         """
-        :param multfactor: number of layers in the model, assumes 0<= n_shells <=10.
+        :param multfactor: number of layers in the model, 
+        assumes 0<= n_shells <=10.
         """
 
@@ -173,5 +173,5 @@
         sub_range = floor(n_sub/2.0)
         z.append(0)
-        beta.append(self.params['sld_sub0']) 
+        beta.append(self.params['sld_bottom0']) 
        
         z0 = 0
@@ -205,5 +205,5 @@
 
                         if i == 1:
-                            sld_l = self.params['sld_sub0']
+                            sld_l = self.params['sld_bottom0']
                         else:
                             sld_l = self.params['sld_flat%s'% str(i-1)]
@@ -235,5 +235,5 @@
         beta.append(self.params['sld_medium']) 
         z.insert(0,-z_ext)
-        beta.insert(0,self.params['sld_sub0']) 
+        beta.insert(0,self.params['sld_bottom0']) 
         z = [z0 - x for x in z]
         z.reverse()
@@ -294,5 +294,6 @@
         ## setParam to model 
         if name=='sld_medium':
-            # the sld_*** model.params not in params must set to value of sld_solv
+            # the sld_*** model.params not in params must set 
+            # to value of sld_solv
             for key in self.model.params.iterkeys():
                 if key not in self.params.keys()and key.split('_')[0] == 'sld':
Index: sansmodels/src/sans/models/SLDCalFunc.py
===================================================================
--- sansmodels/src/sans/models/SLDCalFunc.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
+++ sansmodels/src/sans/models/SLDCalFunc.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+
+##############################################################################
+#	This software was developed by the University of Tennessee as part of the
+#	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+#	project funded by the US National Science Foundation.
+#
+#	If you use DANSE applications to do scientific research that leads to
+#	publication, we ask that you acknowledge the use of the software with the
+#	following sentence:
+#
+#	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+#
+#	copyright 2008, University of Tennessee
+##############################################################################
+
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY ..\c_extensions\sld_cal.h
+         AND RE-RUN THE GENERATOR SCRIPT
+
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans_extension.c_models import CSLDCalFunc
+import copy    
+    
+class SLDCalFunc(CSLDCalFunc, BaseComponent):
+    """ 
+    Class that evaluates a SLDCalFunc model. 
+    This file was auto-generated from ..\c_extensions\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):
+        """ Initialization """
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        CSLDCalFunc.__init__(self)
+        
+        ## 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 =[]
+   
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SLDCalFunc())   
+        
+    def __getstate__(self):
+        """
+        return object state for pickling and copying
+        """
+        model_state = {'params': self.params, 'dispersion': self.dispersion, 'log': self.log}
+        
+        return self.__dict__, model_state
+        
+    def __setstate__(self, state):
+        """
+        create object from pickled state
+        
+        :param state: the state of the current model
+        
+        """
+        
+        self.__dict__, model_state = state
+        self.params = model_state['params']
+        self.dispersion = model_state['dispersion']
+        self.log = model_state['log']
+       	
+   
+    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 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: sansmodels/src/sans/models/SphereSLDModel.py
===================================================================
--- sansmodels/src/sans/models/SphereSLDModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
+++ sansmodels/src/sans/models/SphereSLDModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -0,0 +1,283 @@
+#!/usr/bin/env python
+
+##############################################################################
+#	This software was developed by the University of Tennessee as part of the
+#	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+#	project funded by the US National Science Foundation.
+#
+#	If you use DANSE applications to do scientific research that leads to
+#	publication, we ask that you acknowledge the use of the software with the
+#	following sentence:
+#
+#	"This work benefited from DANSE software developed under NSF award DMR-0520547."
+#
+#	copyright 2008, University of Tennessee
+##############################################################################
+
+
+""" 
+Provide functionality for a C extension model
+
+:WARNING: THIS FILE WAS GENERATED BY WRAPPERGENERATOR.PY
+         DO NOT MODIFY THIS FILE, MODIFY ..\c_extensions\spheresld.h
+         AND RE-RUN THE GENERATOR SCRIPT
+
+"""
+
+from sans.models.BaseComponent import BaseComponent
+from sans_extension.c_models import CSphereSLDModel
+import copy    
+    
+class SphereSLDModel(CSphereSLDModel, BaseComponent):
+    """ 
+    Class that evaluates a SphereSLDModel model. 
+    This file was auto-generated from ..\c_extensions\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-006 [1/A^(2)]
+         sld_solv        = 1e-006 [1/A^(2)]
+         background      = 0.0 
+         sld_flat1       = 4e-006 [1/A^(2)]
+         sld_flat2       = 3.5e-006 [1/A^(2)]
+         sld_flat3       = 4e-006 [1/A^(2)]
+         sld_flat4       = 3.5e-006 [1/A^(2)]
+         sld_flat5       = 4e-006 [1/A^(2)]
+         sld_flat6       = 3.5e-006 [1/A^(2)]
+         sld_flat7       = 4e-006 [1/A^(2)]
+         sld_flat8       = 3.5e-006 [1/A^(2)]
+         sld_flat9       = 4e-006 [1/A^(2)]
+         sld_flat10      = 3.5e-006 [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):
+        """ Initialization """
+        
+        # Initialize BaseComponent first, then sphere
+        BaseComponent.__init__(self)
+        CSphereSLDModel.__init__(self)
+        
+        ## 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=[]
+        
+        ## 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 =[]
+   
+    def clone(self):
+        """ Return a identical copy of self """
+        return self._clone(SphereSLDModel())   
+        
+    def __getstate__(self):
+        """
+        return object state for pickling and copying
+        """
+        model_state = {'params': self.params, 'dispersion': self.dispersion, 'log': self.log}
+        
+        return self.__dict__, model_state
+        
+    def __setstate__(self, state):
+        """
+        create object from pickled state
+        
+        :param state: the state of the current model
+        
+        """
+        
+        self.__dict__, model_state = state
+        self.params = model_state['params']
+        self.dispersion = model_state['dispersion']
+        self.log = model_state['log']
+       	
+   
+    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 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: sansmodels/src/sans/models/SphericalSLDModel.py
===================================================================
--- sansmodels/src/sans/models/SphericalSLDModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
+++ sansmodels/src/sans/models/SphericalSLDModel.py	(revision 4b3d25baa17f0bb0a51e61b205a2b0b0c2548415)
@@ -0,0 +1,341 @@
+   
+from sans.models.BaseComponent import BaseComponent
+from sans.models.SphereSLDModel import SphereSLDModel
+from copy import deepcopy
+from math import floor
+#from scipy.special import erf
+func_list = {'Erf(|nu|*z)':0, 'RPower(z^|nu|)':1, 'LPower(z^|nu|)':2, \
+                     'RExp(-|nu|*z)':3, 'LExp(-|nu|*z)':4}
+max_nshells = 10
+class SphericalSLDModel(BaseComponent):
+    """
+    This multi-model is based on Parratt formalism and provides the capability
+    of changing the number of layers between 0 and 10.
+    """
+    def __init__(self, multfactor=1):
+        BaseComponent.__init__(self)
+        """
+        :param multfactor: number of layers in the model, 
+        assumes 0<= n_shells <=10.
+        """
+
+        ## Setting  model name model description
+        self.description=""
+        model = SphereSLDModel()
+        self.model = model
+        self.name = "SphericalSLDModel"
+        self.description=model.description
+        self.n_shells = multfactor
+        ## Define parameters
+        self.params = {}
+        
+        ## Parameter details [units, min, max]
+        self.details = {}
+        
+        # non-fittable parameters
+        self.non_fittable = model.non_fittable
+        
+        # list of function in order of the function number 
+        self.fun_list = self._get_func_list()
+        ## dispersion
+        self._set_dispersion()
+        ## Define parameters
+        self._set_params()
+        
+        ## Parameter details [units, min, max]
+        self._set_details()
+        
+        #list of parameter that can be fitted
+        self._set_fixed_params()  
+        self.model.params['n_shells'] = self.n_shells
+        
+        ## functional multiplicity info of the model
+        # [int(maximum no. of functionality),"str(Titl),
+        # [str(name of function0),...], [str(x-asix name of sld),...]]
+        self.multiplicity_info = [max_nshells,"No. of Shells:",[],['Radius']]
+        
+    
+    def _clone(self, obj):
+        """
+        Internal utility function to copy the internal
+        data members to a fresh copy.
+        """
+        obj.params     = deepcopy(self.params)
+        obj.non_fittable     = deepcopy(self.non_fittable)
+        obj.description     = deepcopy(self.description)
+        obj.details    = deepcopy(self.details)
+        obj.dispersion = deepcopy(self.dispersion)
+        obj.model  = self.model.clone()
+
+        return obj
+    
+    
+    def _set_dispersion(self):
+        """
+        model dispersions
+        """ 
+        ##set dispersion from model 
+        self.dispersion = {}
+                    
+
+    def _set_params(self):
+        """
+        Concatenate the parameters of the model to create
+        this model parameters 
+        """
+        # rearrange the parameters for the given # of shells
+        for name , value in self.model.params.iteritems():
+            n = 0
+            pos = len(name.split('_'))-1
+            first_name = name.split('_')[0]
+            last_name = name.split('_')[pos]
+            if first_name == 'npts':
+                self.params[name]=value
+                continue
+            elif first_name == 'func':
+                n= -1
+                while n<self.n_shells:
+                    n += 1
+                    if last_name == 'inter%s' % str(n): 
+                        self.params[name]=value
+                        continue
+            elif last_name[0:5] == 'inter':
+                n= -1
+                while n<self.n_shells:
+                    n += 1
+                    if last_name == 'inter%s' % str(n):
+                        self.params[name]= value
+                        continue
+            elif last_name[0:4] == 'flat':
+                while n<self.n_shells:
+                    n += 1
+                    if last_name == 'flat%s' % str(n):
+                        self.params[name]= value
+                        continue
+            elif name == 'n_shells':
+                continue
+            else:
+                self.params[name]= value
+  
+        self.model.params['n_shells'] = self.n_shells    
+  
+        # set constrained values for the original model params
+        self._set_xtra_model_param()       
+
+    def _set_details(self):
+        """
+        Concatenate details of the original model to create
+        this model details 
+        """
+        for name ,detail in self.model.details.iteritems():
+            if name in self.params.iterkeys():
+                self.details[name]= detail
+            
+    
+    def _set_xtra_model_param(self):
+        """
+        Set params of original model that are hidden from this model
+        """
+        # look for the model parameters that are not in param list
+        for key in self.model.params.iterkeys():
+            if key not in self.params.keys():
+                if  key.split('_')[0] == 'thick':
+                    self.model.setParam(key, 0)
+                    continue
+                if  key.split('_')[0] == 'func': 
+                        self.model.setParam(key, 0)
+                        continue
+
+                for nshell in range(self.n_shells,max_nshells):
+                    if key.split('_')[1] == 'flat%s' % str(nshell+1):
+                        try:
+                            if key.split('_')[0] == 'sld':
+                                value = self.model.params['sld_solv']
+                            self.model.setParam(key, value)
+                        except: pass
+    
+    def _get_func_list(self):
+        """
+        Get the list of functions in each layer (shell) 
+        """
+        #func_list = {}
+        return func_list
+        
+    def getProfile(self):
+        """
+        Get SLD profile 
+        
+        : return: (z, beta) where z is a list of depth of the transition points
+                beta is a list of the corresponding SLD values 
+        """
+        # max_pts for each layers
+        n_sub = self.params['npts_inter']
+        z = []
+        beta = []
+        z0 = 0
+        sub_range = floor(n_sub/2.0)
+        # two sld points for core
+        z.append(0)
+        beta.append(self.params['sld_core0']) 
+        z.append(self.params['rad_core0']) 
+        beta.append(self.params['sld_core0']) 
+        z0 += self.params['rad_core0']
+        # for layers from the core
+        for n in range(1,self.n_shells+2):
+            i = n
+            # j=0 for interface, j=1 for flat layer 
+            for j in range(0,2):
+                # interation for sub-layers
+                for n_s in range(0,n_sub+1):
+                    if j==1:
+                        if i==self.n_shells+1:
+                            break
+                        # shift half sub thickness for the first point
+                        z0 -= dz#/2.0
+                        z.append(z0)
+                        #z0 -= dz/2.0
+                        z0 += self.params['thick_flat%s'% str(i)]
+                        
+                        sld_i = self.params['sld_flat%s'% str(i)]
+                        beta.append(self.params['sld_flat%s'% str(i)])
+                        dz = 0
+                    else:
+                        dz = self.params['thick_inter%s'% str(i-1)]/n_sub
+                        nu = self.params['nu_inter%s'% str(i-1)]
+                        # decide which sld is which, sld_r or sld_l
+                        if i == 1:
+                            sld_l = self.params['sld_core0']
+                        else:
+                            sld_l = self.params['sld_flat%s'% str(i-1)]
+                        if i == self.n_shells+1:
+                            sld_r = self.params['sld_solv']
+                        else:
+                            sld_r = self.params['sld_flat%s'% str(i)]
+                        # get function type
+                        func_idx = self.params['func_inter%s'% str(i-1)]
+                        # calculate the sld
+                        sld_i = self._get_sld(func_idx, n_sub, n_s, nu,
+                                              sld_l, sld_r)
+                    # append to the list
+                    z.append(z0)
+                    beta.append(sld_i)
+                    z0 += dz
+                    if j==1: break
+        # put sld of solvent
+        z.append(z0)
+        beta.append(self.params['sld_solv'])  
+        z_ext = z0/5.0
+        z.append(z0+z_ext)
+        beta.append(self.params['sld_solv']) 
+        # return sld profile (r, beta)
+        return z, beta
+    
+    def _get_sld(self, func_idx, n_sub, n_s, nu, sld_l, sld_r):
+        """
+        Get the function asked to build sld profile
+        : param func_idx: func type number
+        : param n_sub: total number of sub_layer
+        : param n_s: index of sub_layer
+        : param nu: coefficient of the function
+        : param sld_l: sld on the left side
+        : param sld_r: sld on the right side
+        : return: sld value, float
+        """
+        from sans.models.SLDCalFunc import SLDCalFunc
+        # sld_cal init
+        sld_cal = SLDCalFunc()
+        # set params
+        sld_cal.setParam('fun_type',func_idx)
+        sld_cal.setParam('npts_inter',n_sub)
+        sld_cal.setParam('shell_num',n_s)
+        sld_cal.setParam('nu_inter',nu)
+        sld_cal.setParam('sld_left',sld_l)
+        sld_cal.setParam('sld_right',sld_r)
+        # return sld value
+        return sld_cal.run()
+    
+    def setParam(self, name, value):
+        """ 
+        Set the value of a model parameter
+    
+        : param name: name of the parameter
+        : param value: value of the parameter
+        """
+        # set param to new model
+        self._setParamHelper( name, value)
+        
+        ## setParam to model 
+        if name=='sld_solv':
+            # the sld_*** model.params not in params must set to 
+            # value of sld_solv
+            for key in self.model.params.iterkeys():
+                if key not in self.params.keys()and key.split('_')[0] == 'sld':
+                        self.model.setParam(key, value)
+            
+        self.model.setParam( name, value)
+
+    def _setParamHelper(self, name, value):
+        """
+        Helper function to setParam
+        """
+
+        # Look for standard parameter
+        for item in self.params.keys():
+            if item.lower()==name.lower():
+                self.params[item] = value
+                return
+        
+        raise ValueError, "Model does not contain parameter %s" % name
+             
+   
+    def _set_fixed_params(self):
+        """
+        Fill the self.fixed list with the model fixed list
+        """
+        pass         
+
+    def run(self, x = 0.0):
+        """ 
+        Evaluate the model
+        
+        :param x: input q, or [q,phi]
+        
+        :return: scattering function P(q)
+        
+        """
+
+        return self.model.run(x)
+
+    def runXY(self, x = 0.0):
+        """ 
+        Evaluate the model
+        
+        : param x: input q-value (float or [float, float] as [qx, qy])
+        : return: scattering function value
+        """  
+
+        return self.model.runXY(x)
+    
+    ## Now (May27,10) directly uses the model eval function 
+    ## instead of the for-loop in Base Component.
+    def evalDistribution(self, x = []):
+        """ 
+        Evaluate the model in cartesian coordinates
+        
+        : param x: input q[], or [qx[], qy[]]
+        : return: scattering function P(q[])
+        """
+        # set effective radius and scaling factor before run
+        return self.model.evalDistribution(x)
+    def calculate_ER(self):
+        """
+        """
+        return self.model.calculate_ER()
+    def set_dispersion(self, parameter, dispersion):
+        """
+        Set the dispersion object for a model parameter
+        
+        : param parameter: name of the parameter [string]
+        :dispersion: dispersion object of type DispersionModel
+        """
+        pass
