Index: sansview/perspectives/fitting/basepage.py
===================================================================
--- sansview/perspectives/fitting/basepage.py	(revision 65b77529f8195f0b582b7190c6372fcd39406c45)
+++ sansview/perspectives/fitting/basepage.py	(revision f72333f17352e43cc9070c075edce981b721111e)
@@ -14,4 +14,5 @@
 (PreviousStateEvent, EVT_PREVIOUS_STATE)   = wx.lib.newevent.NewEvent()
 (NextStateEvent, EVT_NEXT_STATE)   = wx.lib.newevent.NewEvent()
+
 _BOX_WIDTH = 76
 _QMIN_DEFAULT = 0.001
@@ -55,4 +56,5 @@
         self.data = None
         self.mask = None
+        self.theory = None
         self.state = PageState(parent=parent)
         ## dictionary containing list of models
@@ -136,5 +138,5 @@
         #self.onSave(event=None)
         self.Bind(wx.EVT_CONTEXT_MENU, self.onContextMenu)
-        
+
         ## create the basic structure of the panel with empty sizer
         self.define_page_structure()
@@ -1097,5 +1099,5 @@
                         flag = self.update_pinhole_smear()
                     else:
-                        self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
+                        self.manager.set_smearer_nodraw(smearer=temp_smearer, qmin= float(self.qmin_x),
                                                  qmax= float(self.qmax_x))
                 elif not is_2Ddata:
@@ -1362,11 +1364,11 @@
                     temp_smear= self.current_smearer
             
-            self.manager.draw_model(self.model, data=self.data,
+            self.manager.draw_model(self.model, 
+                                    data=self.data,
                                     smearer= temp_smear,
                                     qmin=float(self.qmin_x), 
                                     qmax=float(self.qmax_x),
                                     qstep= float(self.num_points),
-                                    enable2D=self.enable2D) 
-       
+                                    enable2D=self.enable2D)
         
     def _set_model_sizer(self,sizer, box_sizer, title="", object=None):
@@ -1507,4 +1509,5 @@
             item must model class
         """
+        st = time.time()
         for models in list:
             model= models()
@@ -1514,5 +1517,5 @@
                     name = model.name
                 combobox.Append(name,models)
-     
+
         return 0
 
@@ -1629,6 +1632,6 @@
             self.structurebox.Enable()
             self.text2.Enable()
-        if self.data.__class__.__name__ =="Data2D":
-            self.smear_description_2d.Show(True)
+        #if self.data.__class__.__name__ =="Data2D":
+            #self.smear_description_2d.Show(True)
             
         s_id = self.structurebox.GetCurrentSelection()
@@ -2152,5 +2155,6 @@
         if ON_MAC == True:
             time.sleep(1)
-             
+            
+
     def on_reset_clicked(self,event):
         """
@@ -2167,4 +2171,12 @@
             self.qmin_x = data_min
             self.qmax_x = math.sqrt(x*x + y*y)
+            # check smearing
+            if not self.disable_smearer.GetValue():
+                temp_smearer= self.current_smearer
+                ## set smearing value whether or not the data contain the smearing info
+                if self.pinhole_smearer.GetValue():
+                    flag = self.update_pinhole_smear()
+                else:
+                    flag = True
         elif self.data.__class__.__name__ != "Data2D":
             self.qmin_x = min(self.data.x)
@@ -2205,5 +2217,5 @@
         #reset the q range values
         self._reset_plotting_range(self.state)
-        self.compute_chisqr(smearer=self.current_smearer)
+        #self.compute_chisqr(smearer=self.current_smearer)
         #Re draw plot
         self._draw_model()
Index: sansview/perspectives/fitting/fitpage.py
===================================================================
--- sansview/perspectives/fitting/fitpage.py	(revision 2d409fa1dad7b0478c524a8dac970ef1fe4a4a58)
+++ sansview/perspectives/fitting/fitpage.py	(revision f72333f17352e43cc9070c075edce981b721111e)
@@ -20,4 +20,5 @@
 (FitterTypeEvent, EVT_FITTER_TYPE)   = wx.lib.newevent.NewEvent()
 (FitStopEvent, EVT_FIT_STOP)   = wx.lib.newevent.NewEvent()
+(Chi2UpdateEvent, EVT_CHI2_UPDATE)   = wx.lib.newevent.NewEvent()
 _BOX_WIDTH = 76
 _DATA_BOX_WIDTH = 300
@@ -54,9 +55,16 @@
         self.smearer = None
         self.current_smearer = None
+        ## 2D smear accuracy default
+        self.smear2d_accuracy = 'Low'
+        ## slit smear: 
         self.dxl = None
         self.dxw = None
+        ## pinhole smear 
         self.dx_min = None
         self.dx_max = None
         
+        ## model data (theory) calculated on drawing.
+        self.theory_data = None
+      
         ## draw sizer
         self._fill_datainfo_sizer()
@@ -78,7 +86,7 @@
             if self.smearer ==None:
                 self.enable_smearer.Disable()
-            if self.data.__class__.__name__ =="Data2D":
-                if self.model != None:
-                    self.smear_description_2d.Show(True)
+            #if self.data.__class__.__name__ =="Data2D":
+                #if self.model != None:
+                    #self.smear_description_2d.Show(True)
                     
         self.disp_cb_dict = {}
@@ -86,5 +94,5 @@
         self.Bind(EVT_FITTER_TYPE,self._on_engine_change)
         self.Bind(EVT_FIT_STOP,self._on_fit_complete)
-        
+        self.Bind(EVT_CHI2_UPDATE, self.on_complete_chisqr)
 
     def _on_fit_complete(self, event):
@@ -97,5 +105,14 @@
         pass
         
-        
+    def _is_2D(self):
+        """
+            Check if data_name is Data2D
+            @return: True or False
+        """
+        
+        if self.data.__class__.__name__ =="Data2D":
+            return True
+        return False
+            
     def _on_engine_change(self, event):
         """
@@ -182,9 +199,11 @@
         smear_message_none  =  "No smearing is selected..."
         smear_message_dqdata  =  "The dQ data is being used for smearing..."
-        smear_message_2d  =  "No smearing is supported for 2D model fitting..."
+        smear_message_2d  =  "Higher accuracy is very time-expensive. Use it with care..."
         smear_message_new_ssmear  =  "Please enter only the value of interest to customize smearing..."
         smear_message_new_psmear  =  "Please enter both; the dQ will be generated by interpolation..."
-        smear_message_pinhole_min_title = "dQ_min[1/A]:"
-        smear_message_pinhole_max_title = "dQ_max[1/A]:"
+        smear_message_2d_x_title = "<dQx>[1/A]:"
+        smear_message_2d_y_title = "<dQy>[1/A]:"
+        smear_message_pinhole_min_title = "dQ_low[1/A]:"
+        smear_message_pinhole_max_title = "dQ_high[1/A]:"
         smear_message_slit_height_title = "Slit height[1/A]:"
         smear_message_slit_width_title = "Slit width[1/A]:"
@@ -205,4 +224,15 @@
         sizer_fit = wx.GridSizer(2, 4,2,6)
         
+        # combobox for smear2d accuracy selection
+        self.smear_accuracy = wx.ComboBox(self, -1,size=(50,-1),style=wx.CB_READONLY)
+        self._set_accuracy_list()
+        self.smear_accuracy.SetValue(self.smear2d_accuracy)
+        self.smear_accuracy.SetSelection(0)
+        self.smear_accuracy.SetToolTipString("'Higher' uses more Gaussian points for smearing computation.")
+                   
+        
+             
+        wx.EVT_COMBOBOX(self.smear_accuracy,-1, self._on_select_accuracy)
+
         #Fit button
         self.btFit = wx.Button(self,wx.NewId(),'Fit', size=(88,25))
@@ -210,19 +240,21 @@
         self.btFit.SetToolTipString("Start fitting.")
         
-        #textcntrl for new resolution
-        self.smear_pinhole_max = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+        #textcntrl for custom resolution
+        self.smear_pinhole_max = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER,
                                             text_enter_callback = self.onPinholeSmear)
-        self.smear_pinhole_min = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+        self.smear_pinhole_min = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER,
                                             text_enter_callback = self.onPinholeSmear)
-        self.smear_slit_height= self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+        self.smear_slit_height= self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER,
                                             text_enter_callback = self.onSlitSmear)
-        self.smear_slit_width = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-20,20),style=wx.TE_PROCESS_ENTER,
+        self.smear_slit_width = self.ModelTextCtrl(self, -1,size=(_BOX_WIDTH-25,20),style=wx.TE_PROCESS_ENTER,
                                             text_enter_callback = self.onSlitSmear)
-        self.smear_data_left= BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
+
+        ## smear
+        self.smear_data_left= BGTextCtrl(self, -1, size=(_BOX_WIDTH-25,20), style=0)
         self.smear_data_left.SetValue(str(self.dq_l))
-        self.smear_data_right = BGTextCtrl(self, -1, size=(_BOX_WIDTH-20,20), style=0)
+        self.smear_data_right = BGTextCtrl(self, -1, size=(_BOX_WIDTH-25,20), style=0)
         self.smear_data_right.SetValue(str(self.dq_r))
 
-        #set default values
+        #set default values for smear
         self.smear_pinhole_max.SetValue(str(self.dx_max))
         self.smear_pinhole_min.SetValue(str(self.dx_min))
@@ -281,5 +313,6 @@
         self.smear_description_dqdata    =  wx.StaticText(self, -1, smear_message_dqdata , style=wx.ALIGN_LEFT)
         self.smear_description_type    =  wx.StaticText(self, -1, "Type:" , style=wx.ALIGN_LEFT)
-        self.smear_description_smear_type    =  BGTextCtrl(self, -1, size=(45,20), style=0)
+        self.smear_description_accuracy_type    =  wx.StaticText(self, -1, "Accuracy:" , style=wx.ALIGN_LEFT)
+        self.smear_description_smear_type    =  BGTextCtrl(self, -1, size=(57,20), style=0)
         self.smear_description_smear_type.SetValue(str(self.dq_l))
         self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
@@ -287,4 +320,6 @@
         self.smear_message_new_s = wx.StaticText(self, -1, smear_message_new_ssmear  , style=wx.ALIGN_LEFT)
         self.smear_message_new_p = wx.StaticText(self, -1, smear_message_new_psmear  , style=wx.ALIGN_LEFT)
+        self.smear_description_2d_x     =  wx.StaticText(self, -1, smear_message_2d_x_title  , style=wx.ALIGN_LEFT)
+        self.smear_description_2d_y     =  wx.StaticText(self, -1, smear_message_2d_y_title  , style=wx.ALIGN_LEFT)
         self.smear_description_pin_min     =  wx.StaticText(self, -1, smear_message_pinhole_min_title  , style=wx.ALIGN_LEFT)
         self.smear_description_pin_max     =  wx.StaticText(self, -1, smear_message_pinhole_max_title  , style=wx.ALIGN_LEFT)
@@ -300,14 +335,20 @@
         self.sizer_set_smearer.Add( self.smear_description_2d,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_description_type,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_description_accuracy_type,0, wx.CENTER, 10 )
+        self.sizer_new_smear.Add( self.smear_accuracy )
         self.sizer_new_smear.Add( self.smear_description_smear_type,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add((15,-1))
+        self.sizer_new_smear.Add( self.smear_description_2d_x,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_description_pin_min,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_description_slit_height,0, wx.CENTER, 10 )
+
         self.sizer_new_smear.Add( self.smear_pinhole_min,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_slit_height,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_data_left,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add((20,-1))
+        self.sizer_new_smear.Add( self.smear_description_2d_y,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_description_pin_max,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_description_slit_width,0, wx.CENTER, 10 )
+
         self.sizer_new_smear.Add( self.smear_pinhole_max,0, wx.CENTER, 10 )
         self.sizer_new_smear.Add( self.smear_slit_width,0, wx.CENTER, 10 )
@@ -336,8 +377,9 @@
                 self.enable_smearer.Disable()  
             else:
-                self.smear_description_2d.Show(True) 
-                self.pinhole_smearer.Disable() 
+                self.smear_description_none.Show(True)
+                #self.smear_description_2d.Show(True) 
+                #self.pinhole_smearer.Disable() 
                 self.slit_smearer.Disable()   
-                self.enable_smearer.Disable() 
+                #self.enable_smearer.Disable() 
         else: self._show_smear_sizer()
         boxsizer_range.Add(self.sizer_set_masking)
@@ -811,5 +853,5 @@
                 if self.enable_smearer.GetValue():
                     temp_smear= self.smearer
-                self.compute_chisqr(temp_smear)
+                #self.compute_chisqr(temp_smear)
             except:
                 ## error occured on chisqr computation
@@ -864,5 +906,5 @@
                                                              qmax= float(self.qmax_x)) 
                 if flag:   
-                    self.compute_chisqr(smearer= temp_smearer)
+                    #self.compute_chisqr(smearer= temp_smearer)
         
                     ## new state posted
@@ -975,5 +1017,7 @@
            wx.PostEvent(self.parent.parent, StatusEvent(status = msg ))
         
-        self.compute_chisqr()   
+        self._draw_model()
+        ##update chi2
+        #self.compute_chisqr(smearer= temp_smearer)
         #self._undo.Enable(True)
         self.save_current_state()
@@ -981,5 +1025,5 @@
         wx.PostEvent(self.parent, event)
         self.state_change= False
-        self._draw_model()
+
         return
     def _clear_Err_on_Fit(self):
@@ -1046,16 +1090,25 @@
         self.dq_l = None
         self.dq_r = None
-        
-        if self.data is None or\
-                self.data.__class__.__name__ == 'Data2D':           
+        data = self.data
+        if self.data is None:
             return
-
-        data = self.data
+        elif self.data.__class__.__name__ == 'Data2D':  
+            if data.dqx_data == None or  data.dqy_data ==None: 
+                return
+            elif self.smearer != None and all(data.dqx_data !=0)and all(data.dqy_data !=0): 
+                self.smear_type = "Pinhole2d"
+                self.dq_l = format_number(numpy.average(data.dqx_data)) 
+                self.dq_r = format_number(numpy.average(data.dqy_data))  
+                return 
+            else: 
+                return
+
+       
 
         # check if it is pinhole smear and get min max if it is.
         if data.dx != None and all(data.dx !=0): 
             self.smear_type = "Pinhole" 
-            self.dq_l = numpy.min(data.dx)
-            self.dq_r = numpy.max(data.dx)
+            self.dq_l = data.dx[0]
+            self.dq_r = data.dx[-1]
             
         # check if it is slit smear and get min max if it is.
@@ -1073,25 +1126,44 @@
             Show only the sizers depending on smear selection
         """
+        # smear disabled
         if self.disable_smearer.GetValue():
             self.smear_description_none.Show(True)
+        # 2Dsmear
+        elif self._is_2D():
+            self.smear_description_accuracy_type.Show(True)
+            self.smear_accuracy.Show(True)
+            self.smear_description_accuracy_type.Show(True)
+            self.smear_description_2d.Show(True)
+            self.smear_description_2d_x.Show(True)
+            self.smear_description_2d_y.Show(True)
+            if self.pinhole_smearer.GetValue():
+                self.smear_pinhole_min.Show(True)
+                self.smear_pinhole_max.Show(True)
+        # smear from data
         elif self.enable_smearer.GetValue():
+
             self.smear_description_dqdata.Show(True)
             if self.smear_type != None:
-                self.smear_description_type.Show(True)
                 self.smear_description_smear_type.Show(True)
                 if self.smear_type == 'Slit':
                     self.smear_description_slit_height.Show(True)
-                    self.smear_description_slit_width.Show(True)
+                    self.smear_description_slit_width.Show(True)                
                 elif self.smear_type == 'Pinhole':
                     self.smear_description_pin_min.Show(True)
                     self.smear_description_pin_max.Show(True)
+                self.smear_description_smear_type.Show(True)
+                self.smear_description_type.Show(True)
                 self.smear_data_left.Show(True)
                 self.smear_data_right.Show(True)
+        # custom pinhole smear
         elif self.pinhole_smearer.GetValue():
-            self.smear_message_new_p.Show(True)
-            self.smear_description_pin_min.Show(True)
+            if self.smear_type == 'Pinhole':
+                self.smear_message_new_p.Show(True)
+                self.smear_description_pin_min.Show(True)
+                self.smear_description_pin_max.Show(True)
+
             self.smear_pinhole_min.Show(True)
-            self.smear_description_pin_max.Show(True)
             self.smear_pinhole_max.Show(True)
+        # custom slit smear
         elif self.slit_smearer.GetValue():
             self.smear_message_new_s.Show(True)
@@ -1109,5 +1181,10 @@
         self.smear_description_type.Hide()
         self.smear_description_smear_type.Hide()
+        self.smear_description_accuracy_type.Hide()
+        self.smear_description_2d_x.Hide()
+        self.smear_description_2d_y.Hide()
         self.smear_description_2d.Hide()
+        
+        self.smear_accuracy.Hide()
         self.smear_data_left.Hide()
         self.smear_data_right.Hide()
@@ -1123,4 +1200,28 @@
         self.smear_message_new_s.Hide()
     
+    def _set_accuracy_list(self):
+        """
+            Set the list of an accuracy in 2D custum smear: Xhigh, High, Med, or Low
+        """
+        # list of accuracy choices
+        list = ['Low','Med','High','Xhigh']
+        for idx in range(len(list)):
+            self.smear_accuracy.Append(list[idx],idx)
+            
+    def _on_select_accuracy(self,event):
+        """
+            Select an accuracy in 2D custom smear: Xhigh, High, Med, or Low
+        """
+        #event.Skip()
+        accuracy = event.GetEventObject()
+        
+        self.smear2d_accuracy = accuracy.GetValue()
+        if self.pinhole_smearer.GetValue():
+            self.onPinholeSmear(event=None)
+        
+        else:    self.onSmear(event=None)
+        if self.current_smearer !=None:
+                self.current_smearer.set_accuracy(accuracy = self.smear2d_accuracy)
+        event.Skip()
     def _onMask(self, event):     
         """
@@ -1136,4 +1237,7 @@
         
     def _draw_masked_model(self,event):
+        """
+        Draw model image w/mask
+        """
         event.Skip()
 
@@ -1177,8 +1281,4 @@
             # more disables for 2D
             if self.data.__class__.__name__ =="Data2D":
-                if self.model != None:
-                    self.smear_description_2d.Show(True)
-                self.smear_description_none.Hide()
-                self.pinhole_smearer.Disable()
                 self.slit_smearer.Disable()
                 self.default_mask = copy.deepcopy(self.data.mask)
@@ -1437,6 +1537,8 @@
                             "Smear: %s"%msg))
             return
+        
         # Need update param values
-        self._update_paramv_on_fit()
+        self._update_paramv_on_fit()     
+
         # msg default
         msg = None
@@ -1457,9 +1559,12 @@
         # hide all silt sizer    
         self._hide_all_smear_info()
-           
+        
         ##Calculate chi2
-        self.compute_chisqr(smearer= self.current_smearer) 
+        temp_smearer = self.current_smearer
+        #self.compute_chisqr(smearer= temp_smearer)
+            
         # show relevant slit sizers 
         self._show_smear_sizer()
+
         self.sizer_set_smearer.Layout()
         self.Layout()   
@@ -1505,38 +1610,58 @@
         # copy data
         data = copy.deepcopy(self.data)
-        data_len = len(data.x)
-        data.dx = None
-        data.dxl = None
-        data.dxw = None
+        if self._is_2D():
+            self.smear_type = 'Pinhole2d'
+            len_data = len(data.data)
+            data.dqx_data = numpy.zeros(len_data)
+            data.dqy_data = numpy.zeros(len_data)
+        else:
+            self.smear_type = 'Pinhole'
+            len_data = len(data.x)
+            data.dx = numpy.zeros(len_data)
+            data.dxl = None
+            data.dxw = None
         msg = None
    
-        # make sure once more if it is smearer
-        data = copy.deepcopy(self.data)
-        len_data = len(data.x)
-        data.dx = numpy.zeros(len_data)
         get_pin_min = self.smear_pinhole_min
         get_pin_max = self.smear_pinhole_max        
 
-        if self._validate_qrange(get_pin_min, get_pin_max ):
+        if not check_float(get_pin_min):
+            get_pin_min.SetBackgroundColour("pink")
+            msg= "Model Error:wrong value entered!!!"
+        elif not check_float(get_pin_max ):
+            get_pin_max.SetBackgroundColour("pink")
+            msg= "Model Error:wrong value entered!!!"
+        else:
             if len_data < 2: len_data = 2     
             self.dx_min = float(get_pin_min.GetValue())
             self.dx_max = float(get_pin_max.GetValue())
-            if self.dx_min != None and self.dx_max != None:             
-                if self.dx_min == self.dx_max:
+            if self.dx_min < 0:
+                get_pin_min.SetBackgroundColour("pink")
+                msg= "Model Error:This value can not be negative!!!"
+            elif self.dx_max <0:
+                get_pin_max.SetBackgroundColour("pink")
+                msg= "Model Error:This value can not be negative!!!"
+            elif self.dx_min != None and self.dx_max != None:   
+                if self._is_2D():
+                    data.dqx_data[data.dqx_data==0] = self.dx_min
+                    data.dqy_data[data.dqy_data==0] = self.dx_max          
+                elif self.dx_min == self.dx_max:
                     data.dx[data.dx==0] = self.dx_min
                 else:
-                    step = math.fabs(self.dx_max - self.dx_min)/(len_data-1)    
+                    step = (self.dx_max - self.dx_min)/(len_data-1)    
                     data.dx = numpy.arange(self.dx_min,self.dx_max+step/1.1,step)            
             elif self.dx_min != None: 
-                data.dx[data.dx==0] = self.dx_min 
+                if self._is_2D(): data.dqx_data[data.dqx_data==0] = self.dx_min
+                else: data.dx[data.dx==0] = self.dx_min 
             elif self.dx_max != None:
-                data.dx[data.dx==0] = self.dx_max          
+                if self._is_2D(): data.dqy_data[data.dqy_data==0] = self.dx_max
+                else: data.dx[data.dx==0] = self.dx_max          
             self.current_smearer = smear_selection(data)
 
+        if msg != None:
+            wx.PostEvent(self.manager.parent, StatusEvent(status = msg ))
         else:
-            get_pin_min.SetBackgroundColour("pink")
-            get_pin_max.SetBackgroundColour("pink")
-            msg= "Model Error:wrong value entered!!!"
-            wx.PostEvent(self.manager.parent, StatusEvent(status = msg ))
+            get_pin_min.SetBackgroundColour("white")
+            get_pin_max.SetBackgroundColour("white")
         ## set smearing value whether or not the data contain the smearing info
         self.manager.set_smearer(smearer=self.current_smearer, qmin= float(self.qmin_x),qmax= float(self.qmax_x))
@@ -1579,4 +1704,5 @@
         # Need update param values
         self._update_paramv_on_fit()
+
         # msg default
         msg = None
@@ -1600,5 +1726,5 @@
         self._hide_all_smear_info()        
         ##Calculate chi2
-        self.compute_chisqr(smearer= self.current_smearer)  
+        #self.compute_chisqr(smearer= self.current_smearer)  
         # show relevant slit sizers       
         self._show_smear_sizer()
@@ -1725,4 +1851,6 @@
             are compute when fitting
         """
+        if event != None: 
+            event.Skip()    
         if self.check_invalid_panel():
             return
@@ -1732,7 +1860,8 @@
                             "Smear: %s"%msg))
             return
+        
         # Need update param values
         self._update_paramv_on_fit()
-        
+              
         temp_smearer = None
         self._get_smear_info()
@@ -1743,5 +1872,5 @@
             self.smear_data_left.SetValue(str(self.dq_l))   
             self.smear_data_right.SetValue(str(self.dq_r))       
-        
+
         self._hide_all_smear_info()
         
@@ -1749,7 +1878,6 @@
         # make sure once more if it is smearer
         self.current_smearer = smear_selection(data)
-
+        
         if self.enable_smearer.GetValue():
-            temp_smearer= self.current_smearer
             if hasattr(self.data,"dxl"):
                 
@@ -1762,12 +1890,15 @@
             else:
                 wx.PostEvent(self.manager.parent, StatusEvent(status=\
-                            "Data contains smearing information %s"%msg))
-            self.smear_description_dqdata.Show(True)
+                            "Data contains smearing information"))
+
+            #self.smear_description_dqdata.Show(True)
             self.smear_data_left.Show(True)
             self.smear_data_right.Show(True)
+            temp_smearer= self.current_smearer
         elif self.disable_smearer.GetValue():
             self.smear_description_none.Show(True)
             
         self._show_smear_sizer()
+        
         self.sizer_set_smearer.Layout()
         self.Layout()
@@ -1775,6 +1906,7 @@
         self.manager.set_smearer(smearer=temp_smearer, qmin= float(self.qmin_x),
                                      qmax= float(self.qmax_x)) 
+
         ##Calculate chi2
-        self.compute_chisqr(smearer= temp_smearer)  
+        #self.compute_chisqr(smearer= temp_smearer)
         
         self.state.enable_smearer=  self.enable_smearer.GetValue()
@@ -1782,4 +1914,20 @@
         self.state.pinhole_smearer = self.pinhole_smearer.GetValue()
         self.state.slit_smearer = self.slit_smearer.GetValue()
+      
+    def on_complete_chisqr(self, event):  
+        """
+            print result chisqr 
+            @event: activated by fitting/ complete after draw
+        """
+        try:
+            if event ==None:
+                output= "-"
+            else:
+                output = event.output
+            self.tcChi.SetValue(str(format_number(output)))
+
+            self.state.tcChi =self.tcChi
+        except:
+            pass  
         
     def complete_chisqr(self, output, elapsed=None):  
@@ -1794,5 +1942,5 @@
 
             self.state.tcChi =self.tcChi
-          
+
         except:
             pass
@@ -1829,5 +1977,5 @@
         
         
-    def compute_chisqr2D(self):
+    def compute_chisqr2D(self,smearer=None):
         """ 
             compute chi square given a model and data 2D and set the value
@@ -1843,7 +1991,9 @@
             if self.calc_Chisqr!= None and self.calc_Chisqr.isrunning():
                 self.calc_Chisqr.stop()
-           
+            if smearer !=None:
+                smearer.set_accuracy(accuracy = self.smear2d_accuracy)
             self.calc_Chisqr= CalcChisqr2D( data2d= self.data,
                                             model= self.model,
+                                            smearer=smearer,
                                             qmin= self.qmin_x,
                                             qmax = self.qmax_x,
@@ -1857,5 +2007,5 @@
 
         
-    def compute_chisqr(self , smearer=None):
+    def compute_chisqr(self ,output=None, smearer=None):
         """ 
             compute chi square given a model and data 1D and set the value
@@ -1866,5 +2016,5 @@
             try:
                 if hasattr(self.data,"data"):
-                    self.compute_chisqr2D()
+                    self.compute_chisqr2D(smearer=smearer)
                     return
                 else:
Index: sansview/perspectives/fitting/fitting.py
===================================================================
--- sansview/perspectives/fitting/fitting.py	(revision 784e2fae9c3bd35d2a6901a3c368d2a2692799f5)
+++ sansview/perspectives/fitting/fitting.py	(revision f72333f17352e43cc9070c075edce981b721111e)
@@ -44,5 +44,5 @@
 (PageInfoEvent, EVT_PAGE_INFO)   = wx.lib.newevent.NewEvent()
 
-
+from fitpage import Chi2UpdateEvent
 class PlotInfo:
     """
@@ -104,5 +104,5 @@
         #dictionary containing data name and error on dy of that data 
         self.err_dy = {}
-        
+        self.theory_data = None      
    
         
@@ -146,5 +146,5 @@
         self.fit_panel.set_model_list(self.menu_mng.get_model_list())
         owner.Bind(fitpage.EVT_MODEL_BOX,self._on_model_panel)
-      
+
         #create  menubar items
         return [(id, self.menu1, "Fitting")]
@@ -370,4 +370,19 @@
             wx.PostEvent(self.parent, StatusEvent(status="Fitting  \
                 is cancelled" , type="stop"))
+           
+    def set_smearer_nodraw(self,smearer, qmin=None, qmax=None):
+        """
+            Get a smear object and store it to a fit problem
+            @param smearer: smear object to allow smearing data
+        """  
+        self.current_pg=self.fit_panel.get_current_page()
+        self.page_finder[self.current_pg].set_smearer(smearer)
+        ## draw model 1D with smeared data
+        data =  self.page_finder[self.current_pg].get_fit_data()
+        model = self.page_finder[self.current_pg].get_model()
+        ## if user has already selected a model to plot
+        ## redraw the model with data smeared
+        
+        smear =self.page_finder[self.current_pg].get_smearer()   
             
     def set_smearer(self,smearer, qmin=None, qmax=None):
@@ -383,5 +398,5 @@
         ## if user has already selected a model to plot
         ## redraw the model with data smeared
-        
+
         smear =self.page_finder[self.current_pg].get_smearer()
         if model!= None:
@@ -405,14 +420,20 @@
              
         """
-        ## draw model 1D with no loaded data
-        self._draw_model1D( model= model, data= data,enable1D=enable1D, smearer= smearer,
-                           qmin= qmin, qmax= qmax, qstep= qstep )
-        ## draw model 2D with no initial data
-        self._draw_model2D(model=model,
-                           data = data,
-                           enable2D= enable2D,
-                           qmin=qmin,
-                           qmax=qmax,
-                           qstep=qstep)
+
+        if data.__class__.__name__ !="Data2D":    
+            ## draw model 1D with no loaded data
+            self._draw_model1D( model= model, data= data,
+                                                    enable1D=enable1D, 
+                                                    smearer= smearer,
+                                                    qmin= qmin, qmax= qmax, qstep= qstep )
+        else:     
+            ## draw model 2D with no initial data
+             self._draw_model2D(model=model,
+                                      data = data,
+                                      enable2D= enable2D,
+                                      smearer= smearer,
+                                      qmin=qmin,
+                                      qmax=qmax,
+                                      qstep=qstep)
             
     def onFit(self):
@@ -600,5 +621,6 @@
             wx.PostEvent(self.parent, StatusEvent(status=msg, info="error"))
             return
-    
+
+        
     def _onEVT_SLICER_PANEL(self, event):
         """
@@ -1087,5 +1109,5 @@
                 
                 
-    def _complete1D(self, x,y, elapsed,model,data=None):
+    def _complete1D(self, x,y, elapsed,index,model,data=None):
         """
             Complete plotting 1D data
@@ -1106,4 +1128,6 @@
            
             title= new_plot.name
+            # x, y are only in range of index 
+            self.theory_data = new_plot
             #new_plot.perspective = self.get_perspective()
             # Pass the reset flag to let the plotting event handler
@@ -1116,4 +1140,7 @@
             else:
                 wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot,title= str(title)))
+            # Chisqr in fitpage
+            current_pg=self.fit_panel.get_current_page()
+            wx.PostEvent(current_pg,Chi2UpdateEvent(output=self._cal_chisqr(data=data,index=index)))
             msg = "Plot 1D  complete !"
             wx.PostEvent( self.parent, StatusEvent(status=msg , type="stop" ))
@@ -1134,5 +1161,5 @@
         
         
-    def _complete2D(self, image,data, model,  elapsed,qmin, qmax,qstep=DEFAULT_NPTS):
+    def _complete2D(self, image,data, model,  elapsed,index,qmin, qmax,qstep=DEFAULT_NPTS):
         """
             Complete get the result of modelthread and create model 2D
@@ -1165,12 +1192,15 @@
             theory.xmin= data.xmin
             theory.xmax= data.xmax
-      
-       
+            
+        self.theory_data = theory
         ## plot
         wx.PostEvent(self.parent, NewPlotEvent(plot=theory,
                          title="Analytical model 2D ", reset=True ))
+        # Chisqr in fitpage
+        current_pg=self.fit_panel.get_current_page()
+        wx.PostEvent(current_pg,Chi2UpdateEvent(output=self._cal_chisqr(data=data,index=index)))
         msg = "Plot 2D complete !"
         wx.PostEvent( self.parent, StatusEvent( status= msg , type="stop" ))
-         
+     
     def _on_data_error(self, event):
         """
@@ -1179,7 +1209,6 @@
         """
         self.err_dy = event.err_dy
-        #print "receiving error dy",self.err_dy
          
-    def _draw_model2D(self,model,data=None,description=None, enable2D=False,
+    def _draw_model2D(self,model,data=None, smearer= None,description=None, enable2D=False,
                       qmin=DEFAULT_QMIN, qmax=DEFAULT_QMAX, qstep=DEFAULT_NPTS):
         """
@@ -1208,7 +1237,7 @@
                 x= data.x_bins
                 y= data.y_bins
-                
+               
         if not enable2D:
-            return
+            return None,None
         try:
             from model_thread import Calc2D
@@ -1216,8 +1245,10 @@
             if self.calc_2D != None and self.calc_2D.isrunning():
                 self.calc_2D.stop()
+
             self.calc_2D = Calc2D(  x= x,
                                     y= y,
                                     model= model, 
                                     data = data,
+                                    smearer = smearer,
                                     qmin= qmin,
                                     qmax= qmax,
@@ -1226,10 +1257,10 @@
                                     updatefn= self._update2D )
             self.calc_2D.queue()
-            
+
         except:
             msg= " Error occurred when drawing %s Model 2D: "%model.name
             msg+= " %s"%sys.exc_value
             wx.PostEvent( self.parent, StatusEvent(status= msg ))
-            return  
+
    
     def _draw_model1D(self, model, data=None, smearer= None,
@@ -1257,5 +1288,5 @@
         
         if not enable1D:
-            return
+            return 
     
         try:
@@ -1273,12 +1304,42 @@
                                   updatefn = self._update1D  )
             self.calc_1D.queue()
-            
+
         except:
             msg= " Error occurred when drawing %s Model 1D: "%model.name
             msg+= " %s"%sys.exc_value
             wx.PostEvent( self.parent, StatusEvent(status= msg ))
-            return  
-            
-
+
+    def _cal_chisqr(self, data=None, index=None): 
+        """
+            Get handy Chisqr using the output from draw1D and 2D, 
+            instead of calling expansive CalcChisqr in guithread
+        """
+        # default chisqr
+        chisqr = None
+        # return None if data == None
+        if data == None: return chisqr
+
+        # Get data: data I, theory I, and data dI in order
+        if data.__class__.__name__ =="Data2D":
+            if index == None: index = numpy.ones(len(data.data),ntype=bool)
+            fn = data.data[index] 
+            gn = self.theory_data.data[index]
+            en = data.err_data[index]
+        else:
+            # 1 d theory from model_thread is only in the range of index
+            if index == None: index = numpy.ones(len(data.y),ntype=bool)
+            
+            fn = data.y[index] 
+            gn = self.theory_data.y
+            en = data.dy[index]
+
+        # residual
+        res = (fn - gn)/en
+        # get chisqr only w/finite
+        chisqr = numpy.average(res[numpy.isfinite(res)]*res[numpy.isfinite(res)])
+
+        return chisqr
+    
+    
 def profile(fn, *args, **kw):
     import cProfile, pstats, os
Index: sansview/perspectives/fitting/gui_thread.py
===================================================================
--- sansview/perspectives/fitting/gui_thread.py	(revision 425ef040ae7e7a92bdc677c65792907937349a5a)
+++ sansview/perspectives/fitting/gui_thread.py	(revision f72333f17352e43cc9070c075edce981b721111e)
@@ -10,5 +10,5 @@
 from data_util.calcthread import CalcThread
 from sans.fit.AbstractFitEngine import FitData2D, FitData1D, SansAssembly
-
+from DataLoader.smearing_2d import Smearer2D
 
 class CalcChisqr1D(CalcThread):
@@ -87,4 +87,5 @@
     
     def __init__(self,data2d, model,
+                 smearer,
                  qmin,
                  qmax,
@@ -105,10 +106,10 @@
             msg= str(data2d.__class__.__name__)
             raise ValueError, "need Data2D to compute chisqr. Current class %s"%msg
-       
+        self.smearer = smearer
         self.fitdata = FitData2D(sans_data2d=data2d ,data=data2d.data, err_data=data2d.err_data)
         self.fitdata.setFitRange(qmin=qmin,qmax=qmax)
      
         self.model = model
-      
+
         self.starttime = 0  
         
@@ -128,9 +129,19 @@
         """
         self.starttime = time.time()
-       
+        
         output= None
         res=[]
         try:
-            res = self.fitdata.residuals(self.model.evalDistribution)
+            if self.smearer == None:
+                fn = self.model.evalDistribution
+            else:
+                # Set model in smearer
+                self.smearer.set_model(self.model)
+                # set fn
+                fn = self.smearer
+                # set self.smearer != None in fitdata
+                self.fitdata.set_smearer(fn)
+
+            res = self.fitdata.residuals(fn)
             sum=0
             for item in res:
Index: sansview/perspectives/fitting/model_thread.py
===================================================================
--- sansview/perspectives/fitting/model_thread.py	(revision 51a71a3f6482bdb1392cffcfb429fa350bdb9b17)
+++ sansview/perspectives/fitting/model_thread.py	(revision f72333f17352e43cc9070c075edce981b721111e)
@@ -3,5 +3,6 @@
 import sys
 import numpy,math
-
+from DataLoader.smearing_2d import Smearer2D
+import fitpage
 class Calc2D(CalcThread):
     """
@@ -12,5 +13,5 @@
     """
     
-    def __init__(self, x, y, data,model,qmin, qmax,qstep,
+    def __init__(self, x, y, data,model,smearer,qmin, qmax,qstep,
                  completefn = None,
                  updatefn   = None,
@@ -31,4 +32,5 @@
         # the model on to calculate
         self.model = model
+        self.smearer = smearer#(data=self.data,model=self.model)
         self.starttime = 0  
         
@@ -51,4 +53,6 @@
             self.qx_data = self.data.qx_data
             self.qy_data = self.data.qy_data
+            self.dqx_data = self.data.dqx_data
+            self.dqy_data = self.data.dqy_data
             self.mask    = self.data.mask
         else:          
@@ -86,14 +90,27 @@
             # Only qmin value will be consider for the detector
             index_model = index_data  
-             
-        value = self.model.evalDistribution([self.qx_data[index_model],self.qy_data[index_model]] )
+
+        if self.smearer != None:
+            # Set smearer w/ data, model and index.
+            fn = self.smearer
+            fn.set_model(self.model)
+            fn.set_index(index_model)
+            # Get necessary data from self.data and set the data for smearing
+            fn.get_data()
+            # Calculate smeared Intensity (by Gaussian averaging): DataLoader/smearing2d/Smearer2D()
+            value = fn.get_value()
+
+        else:    
+            # calculation w/o smearing
+            value =  self.model.evalDistribution([self.qx_data[index_model],self.qy_data[index_model]])
 
         output = numpy.zeros(len(self.qx_data))
         
         # output default is None
-        # This method is to distinguish between masked point and data point = 0.
+        # This method is to distinguish between masked point(nan) and data point = 0.
         output = output/output
         # set value for self.mask==True, else still None to Plottools
         output[index_model] = value 
+
         elapsed = time.time()-self.starttime
         self.complete( image = output,
@@ -101,10 +118,9 @@
                        model = self.model,
                        elapsed = elapsed,
+                       index = index_model,
                        qmin = self.qmin,
                        qmax = self.qmax,
                        qstep = self.qstep )
         
-   
-    
 
 class Calc1D(CalcThread):
@@ -153,7 +169,12 @@
        
         self.complete(x= self.x[index], y= output[index], 
-                      elapsed=elapsed, model= self.model, data=self.data)
-        
- 
+                      elapsed=elapsed,index=index, model= self.model, data=self.data)
+
+        
+    def results(self):
+        """
+            Send resuts of the computation
+        """
+        return [self.out, self.index]
                 
 class CalcCommandline:
