Index: src/sas/sascalc/fit/MultiplicationModel.py
===================================================================
--- src/sas/sascalc/fit/MultiplicationModel.py	(revision cb4ef58d8aabd8393aae14823d3fa98d1ba0c1a2)
+++ src/sas/sascalc/fit/MultiplicationModel.py	(revision 68669da9154d53fe949cb741efa850cd516ce157)
@@ -8,7 +8,7 @@
     r"""
         Use for P(Q)\*S(Q); function call must be in the order of P(Q) and then S(Q):
-        The model parameters are combined from both models, P(Q) and S(Q), except 1) 'effect_radius' of S(Q)
-        which will be calculated from P(Q) via calculate_ER(), 
-        and 2) 'scale' in P model which is synchronized w/ volfraction in S 
+        The model parameters are combined from both models, P(Q) and S(Q), except 1) 'radius_effective' of S(Q)
+        which will be calculated from P(Q) via calculate_ER(),
+        and 2) 'scale' in P model which is synchronized w/ volfraction in S
         then P*S is multiplied by a new parameter, 'scale_factor'.
         The polydispersion is applicable only to P(Q), not to S(Q).
@@ -34,8 +34,11 @@
         ## Parameter details [units, min, max]
         self.details = {}
-        
-        ##models 
+
+        ## Define parameters to exclude from multiplication model
+        self.excluded_params={'radius_effective','scale','background'}
+
+        ##models
         self.p_model = p_model
-        self.s_model = s_model        
+        self.s_model = s_model
         self.magnetic_params = []
         ## dispersion
@@ -45,16 +48,18 @@
         ## New parameter:Scaling factor
         self.params['scale_factor'] = 1
-        
+        self.params['background']  = 0
+
         ## Parameter details [units, min, max]
         self._set_details()
         self.details['scale_factor'] = ['', 0.0, numpy.inf]
-        
+        self.details['background'] = ['',-numpy.inf,numpy.inf]
+
         #list of parameter that can be fitted
-        self._set_fixed_params()  
+        self._set_fixed_params()
         ## parameters with orientation
         for item in self.p_model.orientation_params:
             self.orientation_params.append(item)
-        for item in self.p_model.magnetic_params:  
-            self.magnetic_params.append(item) 
+        for item in self.p_model.magnetic_params:
+            self.magnetic_params.append(item)
         for item in self.s_model.orientation_params:
             if not item in self.orientation_params:
@@ -66,13 +71,13 @@
             multiplicity = 1
         ## functional multiplicity of the model
-        self.multiplicity = multiplicity    
-          
+        self.multiplicity = multiplicity
+
         # non-fittable parameters
-        self.non_fittable = p_model.non_fittable  
-        self.multiplicity_info = [] 
+        self.non_fittable = p_model.non_fittable
+        self.multiplicity_info = []
         self.fun_list = {}
         if self.non_fittable > 1:
             try:
-                self.multiplicity_info = p_model.multiplicity_info 
+                self.multiplicity_info = p_model.multiplicity_info
                 self.fun_list = p_model.fun_list
                 self.is_multiplicity_model = True
@@ -82,5 +87,5 @@
             self.is_multiplicity_model = False
             self.multiplicity_info = [0]
-            
+
     def _clone(self, obj):
         """
@@ -96,6 +101,6 @@
         #obj = copy.deepcopy(self)
         return obj
-    
-    
+
+
     def _set_dispersion(self):
         """
@@ -103,12 +108,12 @@
         applied to s_model
         """
-        ##set dispersion only from p_model 
+        ##set dispersion only from p_model
         for name , value in self.p_model.dispersion.iteritems():
-            self.dispersion[name] = value 
-                                      
+            self.dispersion[name] = value
+
     def getProfile(self):
         """
         Get SLD profile of p_model if exists
-        
+
         :return: (r, beta) where r is a list of radius of the transition points\
                 beta is a list of the corresponding SLD values
@@ -121,40 +126,51 @@
             x = None
             y = None
-            
+
         return x, y
-    
+
     def _set_params(self):
         """
         Concatenate the parameters of the two models to create
-        these model parameters 
+        these model parameters
         """
 
         for name , value in self.p_model.params.iteritems():
-            if not name in self.params.keys() and name != 'scale':
+            if not name in self.params.keys() and name not in self.excluded_params:
                 self.params[name] = value
-            
+
         for name , value in self.s_model.params.iteritems():
-            #Remove the effect_radius from the (P*S) model parameters.
-            if not name in self.params.keys() and name != 'effect_radius':
+            #Remove the radius_effective from the (P*S) model parameters.
+            if not name in self.params.keys() and name not in self.excluded_params:
                 self.params[name] = value
-                
+
         # Set "scale and effec_radius to P and S model as initializing
         # since run P*S comes from P and S separately.
+        self._set_backgrounds()
         self._set_scale_factor()
-        self._set_effect_radius()       
-            
+        self._set_radius_effective()
+
     def _set_details(self):
         """
         Concatenate details of the two models to create
-        this model's details 
+        this model's details
         """
         for name, detail in self.p_model.details.iteritems():
-            if name != 'scale':
+            if name not in self.excluded_params:
                 self.details[name] = detail
-            
+
         for name , detail in self.s_model.details.iteritems():
-            if not name in self.details.keys() or name != 'effect_radius':
+            if not name in self.details.keys() or name not in self.exluded_params:
                 self.details[name] = detail
-    
+
+    def _set_backgrounds(self):
+        """
+        Set component backgrounds to zero
+        """
+        if 'background' in self.p_model.params:
+            self.p_model.setParam('background',0)
+        if 'background' in self.s_model.params:
+            self.s_model.setParam('background',0)
+
+
     def _set_scale_factor(self):
         """
@@ -162,5 +178,5 @@
         """
         value = self.params['volfraction']
-        if value != None: 
+        if value != None:
             factor = self.p_model.calculate_VR()
             if factor == None or factor == NotImplemented or factor == 0.0:
@@ -170,20 +186,20 @@
             self.p_model.setParam('scale', value)
             self.s_model.setParam('volfraction', val)
-            
-    def _set_effect_radius(self):
+
+    def _set_radius_effective(self):
         """
         Set effective radius to S(Q) model
         """
-        if not 'effect_radius' in self.s_model.params.keys():
+        if not 'radius_effective' in self.s_model.params.keys():
             return
         effective_radius = self.p_model.calculate_ER()
         #Reset the effective_radius of s_model just before the run
         if effective_radius != None and effective_radius != NotImplemented:
-            self.s_model.setParam('effect_radius', effective_radius)
-                
+            self.s_model.setParam('radius_effective', effective_radius)
+
     def setParam(self, name, value):
-        """ 
+        """
         Set the value of a model parameter
-        
+
         :param name: name of the parameter
         :param value: value of the parameter
@@ -191,22 +207,22 @@
         # set param to P*S model
         self._setParamHelper( name, value)
-        
-        ## setParam to p model 
-        # set 'scale' in P(Q) equal to volfraction 
+
+        ## setParam to p model
+        # set 'scale' in P(Q) equal to volfraction
         if name == 'volfraction':
             self._set_scale_factor()
-        elif name in self.p_model.getParamList():
+        elif name in self.p_model.getParamList() and name not in self.excluded_params:
             self.p_model.setParam( name, value)
-        
-        ## setParam to s model 
-        # This is a little bit abundant: Todo: find better way         
-        self._set_effect_radius()
-        if name in self.s_model.getParamList():
+
+        ## setParam to s model
+        # This is a little bit abundant: Todo: find better way
+        self._set_radius_effective()
+        if name in self.s_model.getParamList() and name not in self.excluded_params:
             if name != 'volfraction':
                 self.s_model.setParam( name, value)
-            
+
 
         #self._setParamHelper( name, value)
-        
+
     def _setParamHelper(self, name, value):
         """
@@ -228,8 +244,8 @@
                     self.params[item] = value
                     return
-            
+
         raise ValueError, "Model does not contain parameter %s" % name
-             
-   
+
+
     def _set_fixed_params(self):
         """
@@ -240,47 +256,47 @@
 
         self.fixed.sort()
-                
-                
+
+
     def run(self, x = 0.0):
-        """ 
+        """
         Evaluate the model
-        
+
         :param x: input q-value (float or [float, float] as [r, theta])
         :return: (scattering function value)
         """
         # set effective radius and scaling factor before run
-        self._set_effect_radius()
+        self._set_radius_effective()
         self._set_scale_factor()
         return self.params['scale_factor'] * self.p_model.run(x) * \
-                            self.s_model.run(x)
+                            self.s_model.run(x) + self.params['background']
 
     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
-        """  
+        """
         # set effective radius and scaling factor before run
-        self._set_effect_radius()
+        self._set_radius_effective()
         self._set_scale_factor()
         out = self.params['scale_factor'] * self.p_model.runXY(x) * \
-                        self.s_model.runXY(x)
+                        self.s_model.runXY(x) + self.params['background']
         return out
-    
-    ## Now (May27,10) directly uses the model eval function 
+
+    ## 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
-        self._set_effect_radius()
+        self._set_radius_effective()
         self._set_scale_factor()
         out = self.params['scale_factor'] * self.p_model.evalDistribution(x) * \
-                        self.s_model.evalDistribution(x)
+                        self.s_model.evalDistribution(x) + self.params['background']
         return out
 
@@ -288,5 +304,5 @@
         """
         Set the dispersion object for a model parameter
-        
+
         :param parameter: name of the parameter [string]
         :dispersion: dispersion object of type DispersionModel
@@ -299,5 +315,5 @@
             return value
         except:
-            raise 
+            raise
 
     def fill_description(self, p_model, s_model):
@@ -306,5 +322,5 @@
         """
         description = ""
-        description += "Note:1) The effect_radius (effective radius) of %s \n"%\
+        description += "Note:1) The radius_effective (effective radius) of %s \n"%\
                                                                 (s_model.name)
         description += "             is automatically calculated "
@@ -318,3 +334,2 @@
         description += "        for details of individual models."
         self.description += description
-    
