Index: c/sas/sascalc/data_util/qsmearing.py
===================================================================
--- src/sas/sascalc/data_util/qsmearing.py	(revision 235f514ba93b57fa63e44309f182acef0b98bb55)
+++ 	(revision )
@@ -1,253 +1,0 @@
-"""
-    Handle Q smearing
-"""
-#####################################################################
-#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. 
-#See the license text in license.txt
-#copyright 2008, University of Tennessee
-######################################################################
-import math
-import logging
-import sys
-
-import numpy as np  # type: ignore
-from numpy import pi, exp # type:ignore
-
-from sasmodels.resolution import Slit1D, Pinhole1D
-from sasmodels.sesans import SesansTransform
-from sasmodels.resolution2d import Pinhole2D
-from .nxsunit import Converter
-
-def smear_selection(data, model = None):
-    """
-    Creates the right type of smearer according
-    to the data.
-    The canSAS format has a rule that either
-    slit smearing data OR resolution smearing data
-    is available.
-
-    For the present purpose, we choose the one that
-    has none-zero data. If both slit and resolution
-    smearing arrays are filled with good data
-    (which should not happen), then we choose the
-    resolution smearing data.
-
-    :param data: Data1D object
-    :param model: sas.model instance
-    """
-    # Sanity check. If we are not dealing with a SAS Data1D
-    # object, just return None
-    # This checks for 2D data (does not throw exception because fail is common)
-    if  data.__class__.__name__ not in ['Data1D', 'Theory1D']:
-        if data is None:
-            return None
-        elif data.dqx_data is None or data.dqy_data is None:
-            return None
-        return PySmear2D(data)
-    # This checks for 1D data with smearing info in the data itself (again, fail is likely; no exceptions)
-    if  not hasattr(data, "dx") and not hasattr(data, "dxl")\
-         and not hasattr(data, "dxw"):
-        return None
-
-    # Look for resolution smearing data
-    # This is the code that checks for SESANS data; it looks for the file loader
-    # TODO: change other sanity checks to check for file loader instead of data structure?
-    _found_sesans = False
-    #if data.dx is not None and data.meta_data['loader']=='SESANS':
-    if data.dx is not None and data.isSesans:
-        #if data.dx[0] > 0.0:
-        if np.size(data.dx[data.dx <= 0]) == 0:
-            _found_sesans = True
-        # if data.dx[0] <= 0.0:
-        if np.size(data.dx[data.dx <= 0]) > 0:
-            raise ValueError('one or more of your dx values are negative, please check the data file!')
-
-    if _found_sesans:
-        # Pre-compute the Hankel matrix (H)
-        SElength = Converter(data._xunit)(data.x, "A")
-
-        theta_max = Converter("radians")(data.sample.zacceptance)[0]
-        q_max = 2 * np.pi / np.max(data.source.wavelength) * np.sin(theta_max)
-        zaccept = Converter("1/A")(q_max, "1/" + data.source.wavelength_unit),
-
-        Rmax = 10000000
-        hankel = SesansTransform(data.x, SElength,
-                                 data.source.wavelength,
-                                 zaccept, Rmax)
-        # Then return the actual transform, as if it were a smearing function
-        return PySmear(hankel, model, offset=0)
-
-    _found_resolution = False
-    if data.dx is not None and len(data.dx) == len(data.x):
-
-        # Check that we have non-zero data
-        if data.dx[0] > 0.0:
-            _found_resolution = True
-            #print "_found_resolution",_found_resolution
-            #print "data1D.dx[0]",data1D.dx[0],data1D.dxl[0]
-    # If we found resolution smearing data, return a QSmearer
-    if _found_resolution == True:
-         return pinhole_smear(data, model)
-
-    # Look for slit smearing data
-    _found_slit = False
-    if data.dxl is not None and len(data.dxl) == len(data.x) \
-        and data.dxw is not None and len(data.dxw) == len(data.x):
-
-        # Check that we have non-zero data
-        if data.dxl[0] > 0.0 or data.dxw[0] > 0.0:
-            _found_slit = True
-
-        # Sanity check: all data should be the same as a function of Q
-        for item in data.dxl:
-            if data.dxl[0] != item:
-                _found_resolution = False
-                break
-
-        for item in data.dxw:
-            if data.dxw[0] != item:
-                _found_resolution = False
-                break
-    # If we found slit smearing data, return a slit smearer
-    if _found_slit == True:
-        return slit_smear(data, model)
-    return None
-
-
-class PySmear(object):
-    """
-    Wrapper for pure python sasmodels resolution functions.
-    """
-    def __init__(self, resolution, model, offset=None):
-        self.model = model
-        self.resolution = resolution
-        if offset is None:
-            offset = np.searchsorted(self.resolution.q_calc, self.resolution.q[0])
-        self.offset = offset
-
-    def apply(self, iq_in, first_bin=0, last_bin=None):
-        """
-        Apply the resolution function to the data.
-        Note that this is called with iq_in matching data.x, but with
-        iq_in[first_bin:last_bin] set to theory values for these bins,
-        and the remainder left undefined.  The first_bin, last_bin values
-        should be those returned from get_bin_range.
-        The returned value is of the same length as iq_in, with the range
-        first_bin:last_bin set to the resolution smeared values.
-        """
-        if last_bin is None: last_bin = len(iq_in)
-        start, end = first_bin + self.offset, last_bin + self.offset
-        q_calc = self.resolution.q_calc
-        iq_calc = np.empty_like(q_calc)
-        if start > 0:
-            iq_calc[:start] = self.model.evalDistribution(q_calc[:start])
-        if end+1 < len(q_calc):
-            iq_calc[end+1:] = self.model.evalDistribution(q_calc[end+1:])
-        iq_calc[start:end+1] = iq_in[first_bin:last_bin+1]
-        smeared = self.resolution.apply(iq_calc)
-        return smeared
-    __call__ = apply
-
-    def get_bin_range(self, q_min=None, q_max=None):
-        """
-        For a given q_min, q_max, find the corresponding indices in the data.
-        Returns first, last.
-        Note that these are indexes into q from the data, not the q_calc
-        needed by the resolution function.  Note also that these are the
-        indices, not the range limits.  That is, the complete range will be
-        q[first:last+1].
-        """
-        q = self.resolution.q
-        first = np.searchsorted(q, q_min)
-        last = np.searchsorted(q, q_max)
-        return first, min(last,len(q)-1)
-
-def slit_smear(data, model=None):
-    q = data.x
-    width = data.dxw if data.dxw is not None else 0
-    height = data.dxl if data.dxl is not None else 0
-    # TODO: width and height seem to be reversed
-    return PySmear(Slit1D(q, height, width), model)
-
-def pinhole_smear(data, model=None):
-    q = data.x
-    width = data.dx if data.dx is not None else 0
-    return PySmear(Pinhole1D(q, width), model)
-
-
-class PySmear2D(object):
-    """
-    Q smearing class for SAS 2d pinhole data
-    """
-
-    def __init__(self, data=None, model=None):
-        self.data = data
-        self.model = model
-        self.accuracy = 'Low'
-        self.limit = 3.0
-        self.index = None
-        self.coords = 'polar'
-        self.smearer = True
-
-    def set_accuracy(self, accuracy='Low'):
-        """
-        Set accuracy.
-
-        :param accuracy:  string
-        """
-        self.accuracy = accuracy
-
-    def set_smearer(self, smearer=True):
-        """
-        Set whether or not smearer will be used
-
-        :param smearer: smear object
-
-        """
-        self.smearer = smearer
-
-    def set_data(self, data=None):
-        """
-        Set data.
-
-        :param data: DataLoader.Data_info type
-        """
-        self.data = data
-
-    def set_model(self, model=None):
-        """
-        Set model.
-
-        :param model: sas.models instance
-        """
-        self.model = model
-
-    def set_index(self, index=None):
-        """
-        Set index.
-
-        :param index: 1d arrays
-        """
-        self.index = index
-
-    def get_value(self):
-        """
-        Over sampling of r_nbins times phi_nbins, calculate Gaussian weights,
-        then find smeared intensity
-        """
-        if self.smearer:
-            res = Pinhole2D(data=self.data, index=self.index,
-                            nsigma=3.0, accuracy=self.accuracy,
-                            coords=self.coords)
-            val = self.model.evalDistribution(res.q_calc)
-            return res.apply(val)
-        else:
-            index = self.index if self.index is not None else slice(None)
-            qx_data = self.data.qx_data[index]
-            qy_data = self.data.qy_data[index]
-            q_calc = [qx_data, qy_data]
-            val = self.model.evalDistribution(q_calc)
-            return val
-
Index: src/sas/sascalc/fit/AbstractFitEngine.py
===================================================================
--- src/sas/sascalc/fit/AbstractFitEngine.py	(revision a1b8fee73528559155793dd74cda07d0c32e9d72)
+++ src/sas/sascalc/fit/AbstractFitEngine.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -137,9 +137,9 @@
                that will smear the theory data (slit smearing or resolution
                smearing) when set.
-            
+
             The proper way to set the smearing object would be to
             do the following: ::
-            
-                from sas.sascalc.data_util.qsmearing import smear_selection
+
+                from sas.sascalc.fit.qsmearing import smear_selection
                 smearer = smear_selection(some_data)
                 fitdata1d = FitData1D( x= [1,3,..,],
@@ -147,9 +147,9 @@
                                         dx=None,
                                         dy=[1,2...], smearer= smearer)
-           
+
             :Note: that some_data _HAS_ to be of
                 class DataLoader.data_info.Data1D
                 Setting it back to None will turn smearing off.
-                
+
         """
         Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy, lam=lam, dlam=dlam)
@@ -176,5 +176,5 @@
         ## Max Q-value
         self.qmax = max(self.x)
-        
+
         # Range used for input to smearing
         self._qmin_unsmeared = self.qmin
@@ -184,5 +184,5 @@
         self.idx_unsmeared = (self.x >= self._qmin_unsmeared) \
                             & (self.x <= self._qmax_unsmeared)
-  
+
     def set_fit_range(self, qmin=None, qmax=None):
         """ to set the fit range"""
@@ -199,8 +199,8 @@
         self._qmin_unsmeared = self.qmin
         self._qmax_unsmeared = self.qmax
-        
+
         self._first_unsmeared_bin = 0
         self._last_unsmeared_bin = len(self.x) - 1
-        
+
         if self.smearer is not None:
             self._first_unsmeared_bin, self._last_unsmeared_bin = \
@@ -208,5 +208,5 @@
             self._qmin_unsmeared = self.x[self._first_unsmeared_bin]
             self._qmax_unsmeared = self.x[self._last_unsmeared_bin]
-            
+
         # Identify the bin range for the unsmeared and smeared spaces
         self.idx = (self.x >= self.qmin) & (self.x <= self.qmax)
@@ -231,10 +231,10 @@
         """
             Compute residuals.
-            
+
             If self.smearer has been set, use if to smear
             the data before computing chi squared.
-            
+
             :param fn: function that return model value
-            
+
             :return: residuals
         """
@@ -242,5 +242,5 @@
         fx = np.zeros(len(self.x))
         fx[self.idx_unsmeared] = fn(self.x[self.idx_unsmeared])
-       
+
         ## Smear theory data
         if self.smearer is not None:
@@ -253,10 +253,10 @@
             raise RuntimeError, msg
         return (self.y[self.idx] - fx[self.idx]) / self.dy[self.idx], fx[self.idx]
-            
+
     def residuals_deriv(self, model, pars=[]):
         """
             :return: residuals derivatives .
-            
-            :note: in this case just return empty array 
+
+            :note: in this case just return empty array
         """
         return []
@@ -293,5 +293,5 @@
         x_max = max(math.fabs(sas_data2d.xmin), math.fabs(sas_data2d.xmax))
         y_max = max(math.fabs(sas_data2d.ymin), math.fabs(sas_data2d.ymax))
-        
+
         ## fitting range
         if qmin is None:
@@ -305,7 +305,7 @@
             self.res_err_data = copy.deepcopy(self.err_data)
         #self.res_err_data[self.res_err_data==0]=1
-        
+
         self.radius = np.sqrt(self.qx_data**2 + self.qy_data**2)
-        
+
         # Note: mask = True: for MASK while mask = False for NOT to mask
         self.idx = ((self.qmin <= self.radius) &\
@@ -368,15 +368,15 @@
 
         return res, gn
-        
+
     def residuals_deriv(self, model, pars=[]):
         """
         :return: residuals derivatives .
-        
+
         :note: in this case just return empty array
-        
+
         """
         return []
-    
-    
+
+
 class FitAbort(Exception):
     """
@@ -396,23 +396,23 @@
         self.fit_arrange_dict = {}
         self.fitter_id = None
-        
+
     def set_model(self, model, id, pars=[], constraints=[], data=None):
         """
         set a model on a given  in the fit engine.
-        
-        :param model: sas.models type 
+
+        :param model: sas.models type
         :param id: is the key of the fitArrange dictionary where model is saved as a value
-        :param pars: the list of parameters to fit 
-        :param constraints: list of 
+        :param pars: the list of parameters to fit
+        :param constraints: list of
             tuple (name of parameter, value of parameters)
             the value of parameter must be a string to constraint 2 different
             parameters.
-            Example:  
+            Example:
             we want to fit 2 model M1 and M2 both have parameters A and B.
             constraints can be ``constraints = [(M1.A, M2.B+2), (M1.B= M2.A *5),...,]``
-            
-             
+
+
         :note: pars must contains only name of existing model's parameters
-        
+
         """
         if not pars:
@@ -445,5 +445,5 @@
         in a FitArrange object and adds that object in a dictionary
         with key id.
-        
+
         :param data: data added
         :param id: unique key corresponding to a fitArrange object with data
@@ -456,5 +456,5 @@
                                  dx=data.dx, dy=data.dy, smearer=smearer)
         fitdata.sas_data = data
-       
+
         fitdata.set_fit_range(qmin=qmin, qmax=qmax)
         #A fitArrange is already created but contains model only at id
@@ -466,9 +466,9 @@
             fitproblem.add_data(fitdata)
             self.fit_arrange_dict[id] = fitproblem
-   
+
     def get_model(self, id):
         """
         :param id: id is key in the dictionary containing the model to return
-        
+
         :return:  a model at this id or None if no FitArrange element was
             created with this id
@@ -478,15 +478,15 @@
         else:
             return None
-    
+
     def remove_fit_problem(self, id):
         """remove   fitarrange in id"""
         if id in self.fit_arrange_dict:
             del self.fit_arrange_dict[id]
-            
+
     def select_problem_for_fit(self, id, value):
         """
         select a couple of model and data at the id position in dictionary
         and set in self.selected value to value
-        
+
         :param value: the value to allow fitting.
                 can only have the value one or zero
@@ -494,15 +494,15 @@
         if id in self.fit_arrange_dict:
             self.fit_arrange_dict[id].set_to_fit(value)
-             
+
     def get_problem_to_fit(self, id):
         """
         return the self.selected value of the fit problem of id
-        
+
         :param id: the id of the problem
         """
         if id in self.fit_arrange_dict:
             self.fit_arrange_dict[id].get_to_fit()
-    
-    
+
+
 class FitArrange:
     def __init__(self):
@@ -511,8 +511,8 @@
         to perform the Fit.FitArrange must contain exactly one model
         and at least one data for the fit to be performed.
-        
+
         model: the model selected by the user
         Ldata: a list of data what the user wants to fit
-            
+
         """
         self.model = None
@@ -525,18 +525,18 @@
         """
         set_model save a copy of the model
-        
+
         :param model: the model being set
         """
         self.model = model
-        
+
     def add_data(self, data):
         """
         add_data fill a self.data_list with data to fit
-        
+
         :param data: Data to add in the list
         """
         if not data in self.data_list:
             self.data_list.append(data)
-            
+
     def get_model(self):
         """
@@ -544,5 +544,5 @@
         """
         return self.model
-     
+
     def get_data(self):
         """
@@ -550,22 +550,22 @@
         """
         return self.data_list[0]
-      
+
     def remove_data(self, data):
         """
         Remove one element from the list
-        
+
         :param data: Data to remove from data_list
         """
         if data in self.data_list:
             self.data_list.remove(data)
-            
+
     def set_to_fit(self, value=0):
         """
         set self.selected to 0 or 1  for other values raise an exception
-        
+
         :param value: integer between 0 or 1
         """
         self.selected = value
-        
+
     def get_to_fit(self):
         """
@@ -599,15 +599,15 @@
         if self.model is not None and self.data is not None:
             self.inputs = [(self.model, self.data)]
-     
+
     def set_model(self, model):
         """
         """
         self.model = model
-        
+
     def set_fitness(self, fitness):
         """
         """
         self.fitness = fitness
-        
+
     def __str__(self):
         """
@@ -624,5 +624,5 @@
         msg = [msg1, msg3] + msg2
         return "\n".join(msg)
-    
+
     def print_summary(self):
         """
Index: src/sas/sascalc/fit/qsmearing.py
===================================================================
--- src/sas/sascalc/fit/qsmearing.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
+++ src/sas/sascalc/fit/qsmearing.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -0,0 +1,254 @@
+"""
+    Handle Q smearing
+"""
+#####################################################################
+#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.
+#See the license text in license.txt
+#copyright 2008, University of Tennessee
+######################################################################
+import math
+import logging
+import sys
+
+import numpy as np  # type: ignore
+from numpy import pi, exp # type:ignore
+
+from sasmodels.resolution import Slit1D, Pinhole1D
+from sasmodels.sesans import SesansTransform
+from sasmodels.resolution2d import Pinhole2D
+
+from sas.sascalc.data_util.nxsunit import Converter
+
+def smear_selection(data, model = None):
+    """
+    Creates the right type of smearer according
+    to the data.
+    The canSAS format has a rule that either
+    slit smearing data OR resolution smearing data
+    is available.
+
+    For the present purpose, we choose the one that
+    has none-zero data. If both slit and resolution
+    smearing arrays are filled with good data
+    (which should not happen), then we choose the
+    resolution smearing data.
+
+    :param data: Data1D object
+    :param model: sas.model instance
+    """
+    # Sanity check. If we are not dealing with a SAS Data1D
+    # object, just return None
+    # This checks for 2D data (does not throw exception because fail is common)
+    if  data.__class__.__name__ not in ['Data1D', 'Theory1D']:
+        if data is None:
+            return None
+        elif data.dqx_data is None or data.dqy_data is None:
+            return None
+        return PySmear2D(data)
+    # This checks for 1D data with smearing info in the data itself (again, fail is likely; no exceptions)
+    if  not hasattr(data, "dx") and not hasattr(data, "dxl")\
+         and not hasattr(data, "dxw"):
+        return None
+
+    # Look for resolution smearing data
+    # This is the code that checks for SESANS data; it looks for the file loader
+    # TODO: change other sanity checks to check for file loader instead of data structure?
+    _found_sesans = False
+    #if data.dx is not None and data.meta_data['loader']=='SESANS':
+    if data.dx is not None and data.isSesans:
+        #if data.dx[0] > 0.0:
+        if np.size(data.dx[data.dx <= 0]) == 0:
+            _found_sesans = True
+        # if data.dx[0] <= 0.0:
+        if np.size(data.dx[data.dx <= 0]) > 0:
+            raise ValueError('one or more of your dx values are negative, please check the data file!')
+
+    if _found_sesans:
+        # Pre-compute the Hankel matrix (H)
+        SElength = Converter(data._xunit)(data.x, "A")
+
+        theta_max = Converter("radians")(data.sample.zacceptance)[0]
+        q_max = 2 * np.pi / np.max(data.source.wavelength) * np.sin(theta_max)
+        zaccept = Converter("1/A")(q_max, "1/" + data.source.wavelength_unit),
+
+        Rmax = 10000000
+        hankel = SesansTransform(data.x, SElength,
+                                 data.source.wavelength,
+                                 zaccept, Rmax)
+        # Then return the actual transform, as if it were a smearing function
+        return PySmear(hankel, model, offset=0)
+
+    _found_resolution = False
+    if data.dx is not None and len(data.dx) == len(data.x):
+
+        # Check that we have non-zero data
+        if data.dx[0] > 0.0:
+            _found_resolution = True
+            #print "_found_resolution",_found_resolution
+            #print "data1D.dx[0]",data1D.dx[0],data1D.dxl[0]
+    # If we found resolution smearing data, return a QSmearer
+    if _found_resolution == True:
+         return pinhole_smear(data, model)
+
+    # Look for slit smearing data
+    _found_slit = False
+    if data.dxl is not None and len(data.dxl) == len(data.x) \
+        and data.dxw is not None and len(data.dxw) == len(data.x):
+
+        # Check that we have non-zero data
+        if data.dxl[0] > 0.0 or data.dxw[0] > 0.0:
+            _found_slit = True
+
+        # Sanity check: all data should be the same as a function of Q
+        for item in data.dxl:
+            if data.dxl[0] != item:
+                _found_resolution = False
+                break
+
+        for item in data.dxw:
+            if data.dxw[0] != item:
+                _found_resolution = False
+                break
+    # If we found slit smearing data, return a slit smearer
+    if _found_slit == True:
+        return slit_smear(data, model)
+    return None
+
+
+class PySmear(object):
+    """
+    Wrapper for pure python sasmodels resolution functions.
+    """
+    def __init__(self, resolution, model, offset=None):
+        self.model = model
+        self.resolution = resolution
+        if offset is None:
+            offset = np.searchsorted(self.resolution.q_calc, self.resolution.q[0])
+        self.offset = offset
+
+    def apply(self, iq_in, first_bin=0, last_bin=None):
+        """
+        Apply the resolution function to the data.
+        Note that this is called with iq_in matching data.x, but with
+        iq_in[first_bin:last_bin] set to theory values for these bins,
+        and the remainder left undefined.  The first_bin, last_bin values
+        should be those returned from get_bin_range.
+        The returned value is of the same length as iq_in, with the range
+        first_bin:last_bin set to the resolution smeared values.
+        """
+        if last_bin is None: last_bin = len(iq_in)
+        start, end = first_bin + self.offset, last_bin + self.offset
+        q_calc = self.resolution.q_calc
+        iq_calc = np.empty_like(q_calc)
+        if start > 0:
+            iq_calc[:start] = self.model.evalDistribution(q_calc[:start])
+        if end+1 < len(q_calc):
+            iq_calc[end+1:] = self.model.evalDistribution(q_calc[end+1:])
+        iq_calc[start:end+1] = iq_in[first_bin:last_bin+1]
+        smeared = self.resolution.apply(iq_calc)
+        return smeared
+    __call__ = apply
+
+    def get_bin_range(self, q_min=None, q_max=None):
+        """
+        For a given q_min, q_max, find the corresponding indices in the data.
+        Returns first, last.
+        Note that these are indexes into q from the data, not the q_calc
+        needed by the resolution function.  Note also that these are the
+        indices, not the range limits.  That is, the complete range will be
+        q[first:last+1].
+        """
+        q = self.resolution.q
+        first = np.searchsorted(q, q_min)
+        last = np.searchsorted(q, q_max)
+        return first, min(last,len(q)-1)
+
+def slit_smear(data, model=None):
+    q = data.x
+    width = data.dxw if data.dxw is not None else 0
+    height = data.dxl if data.dxl is not None else 0
+    # TODO: width and height seem to be reversed
+    return PySmear(Slit1D(q, height, width), model)
+
+def pinhole_smear(data, model=None):
+    q = data.x
+    width = data.dx if data.dx is not None else 0
+    return PySmear(Pinhole1D(q, width), model)
+
+
+class PySmear2D(object):
+    """
+    Q smearing class for SAS 2d pinhole data
+    """
+
+    def __init__(self, data=None, model=None):
+        self.data = data
+        self.model = model
+        self.accuracy = 'Low'
+        self.limit = 3.0
+        self.index = None
+        self.coords = 'polar'
+        self.smearer = True
+
+    def set_accuracy(self, accuracy='Low'):
+        """
+        Set accuracy.
+
+        :param accuracy:  string
+        """
+        self.accuracy = accuracy
+
+    def set_smearer(self, smearer=True):
+        """
+        Set whether or not smearer will be used
+
+        :param smearer: smear object
+
+        """
+        self.smearer = smearer
+
+    def set_data(self, data=None):
+        """
+        Set data.
+
+        :param data: DataLoader.Data_info type
+        """
+        self.data = data
+
+    def set_model(self, model=None):
+        """
+        Set model.
+
+        :param model: sas.models instance
+        """
+        self.model = model
+
+    def set_index(self, index=None):
+        """
+        Set index.
+
+        :param index: 1d arrays
+        """
+        self.index = index
+
+    def get_value(self):
+        """
+        Over sampling of r_nbins times phi_nbins, calculate Gaussian weights,
+        then find smeared intensity
+        """
+        if self.smearer:
+            res = Pinhole2D(data=self.data, index=self.index,
+                            nsigma=3.0, accuracy=self.accuracy,
+                            coords=self.coords)
+            val = self.model.evalDistribution(res.q_calc)
+            return res.apply(val)
+        else:
+            index = self.index if self.index is not None else slice(None)
+            qx_data = self.data.qx_data[index]
+            qy_data = self.data.qy_data[index]
+            q_calc = [qx_data, qy_data]
+            val = self.model.evalDistribution(q_calc)
+            return val
+
Index: src/sas/sascalc/pr/fit/AbstractFitEngine.py
===================================================================
--- src/sas/sascalc/pr/fit/AbstractFitEngine.py	(revision a1b8fee73528559155793dd74cda07d0c32e9d72)
+++ src/sas/sascalc/pr/fit/AbstractFitEngine.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -137,9 +137,9 @@
                that will smear the theory data (slit smearing or resolution
                smearing) when set.
-            
+
             The proper way to set the smearing object would be to
             do the following: ::
-            
-                from sas.sascalc.data_util.qsmearing import smear_selection
+
+                from sas.sascalc.fit.qsmearing import smear_selection
                 smearer = smear_selection(some_data)
                 fitdata1d = FitData1D( x= [1,3,..,],
@@ -147,9 +147,9 @@
                                         dx=None,
                                         dy=[1,2...], smearer= smearer)
-           
+
             :Note: that some_data _HAS_ to be of
                 class DataLoader.data_info.Data1D
                 Setting it back to None will turn smearing off.
-                
+
         """
         Data1D.__init__(self, x=x, y=y, dx=dx, dy=dy)
@@ -176,5 +176,5 @@
         ## Max Q-value
         self.qmax = max(self.x)
-        
+
         # Range used for input to smearing
         self._qmin_unsmeared = self.qmin
@@ -184,5 +184,5 @@
         self.idx_unsmeared = (self.x >= self._qmin_unsmeared) \
                             & (self.x <= self._qmax_unsmeared)
-  
+
     def set_fit_range(self, qmin=None, qmax=None):
         """ to set the fit range"""
@@ -199,8 +199,8 @@
         self._qmin_unsmeared = self.qmin
         self._qmax_unsmeared = self.qmax
-        
+
         self._first_unsmeared_bin = 0
         self._last_unsmeared_bin = len(self.x) - 1
-        
+
         if self.smearer is not None:
             self._first_unsmeared_bin, self._last_unsmeared_bin = \
@@ -208,5 +208,5 @@
             self._qmin_unsmeared = self.x[self._first_unsmeared_bin]
             self._qmax_unsmeared = self.x[self._last_unsmeared_bin]
-            
+
         # Identify the bin range for the unsmeared and smeared spaces
         self.idx = (self.x >= self.qmin) & (self.x <= self.qmax)
@@ -231,10 +231,10 @@
         """
             Compute residuals.
-            
+
             If self.smearer has been set, use if to smear
             the data before computing chi squared.
-            
+
             :param fn: function that return model value
-            
+
             :return: residuals
         """
@@ -242,5 +242,5 @@
         fx = np.zeros(len(self.x))
         fx[self.idx_unsmeared] = fn(self.x[self.idx_unsmeared])
-       
+
         ## Smear theory data
         if self.smearer is not None:
@@ -253,10 +253,10 @@
             raise RuntimeError, msg
         return (self.y[self.idx] - fx[self.idx]) / self.dy[self.idx], fx[self.idx]
-            
+
     def residuals_deriv(self, model, pars=[]):
         """
             :return: residuals derivatives .
-            
-            :note: in this case just return empty array 
+
+            :note: in this case just return empty array
         """
         return []
@@ -293,5 +293,5 @@
         x_max = max(math.fabs(sas_data2d.xmin), math.fabs(sas_data2d.xmax))
         y_max = max(math.fabs(sas_data2d.ymin), math.fabs(sas_data2d.ymax))
-        
+
         ## fitting range
         if qmin is None:
@@ -305,7 +305,7 @@
             self.res_err_data = copy.deepcopy(self.err_data)
         #self.res_err_data[self.res_err_data==0]=1
-        
+
         self.radius = np.sqrt(self.qx_data**2 + self.qy_data**2)
-        
+
         # Note: mask = True: for MASK while mask = False for NOT to mask
         self.idx = ((self.qmin <= self.radius) &\
@@ -371,15 +371,15 @@
 
         return res, gn
-        
+
     def residuals_deriv(self, model, pars=[]):
         """
         :return: residuals derivatives .
-        
+
         :note: in this case just return empty array
-        
+
         """
         return []
-    
-    
+
+
 class FitAbort(Exception):
     """
@@ -399,23 +399,23 @@
         self.fit_arrange_dict = {}
         self.fitter_id = None
-        
+
     def set_model(self, model, id, pars=[], constraints=[], data=None):
         """
         set a model on a given  in the fit engine.
-        
-        :param model: sas.models type 
+
+        :param model: sas.models type
         :param id: is the key of the fitArrange dictionary where model is saved as a value
-        :param pars: the list of parameters to fit 
-        :param constraints: list of 
+        :param pars: the list of parameters to fit
+        :param constraints: list of
             tuple (name of parameter, value of parameters)
             the value of parameter must be a string to constraint 2 different
             parameters.
-            Example:  
+            Example:
             we want to fit 2 model M1 and M2 both have parameters A and B.
             constraints can be ``constraints = [(M1.A, M2.B+2), (M1.B= M2.A *5),...,]``
-            
-             
+
+
         :note: pars must contains only name of existing model's parameters
-        
+
         """
         if not pars:
@@ -448,5 +448,5 @@
         in a FitArrange object and adds that object in a dictionary
         with key id.
-        
+
         :param data: data added
         :param id: unique key corresponding to a fitArrange object with data
@@ -459,5 +459,5 @@
                                  dx=data.dx, dy=data.dy, smearer=smearer)
         fitdata.sas_data = data
-       
+
         fitdata.set_fit_range(qmin=qmin, qmax=qmax)
         #A fitArrange is already created but contains model only at id
@@ -469,9 +469,9 @@
             fitproblem.add_data(fitdata)
             self.fit_arrange_dict[id] = fitproblem
-   
+
     def get_model(self, id):
         """
         :param id: id is key in the dictionary containing the model to return
-        
+
         :return:  a model at this id or None if no FitArrange element was
             created with this id
@@ -481,15 +481,15 @@
         else:
             return None
-    
+
     def remove_fit_problem(self, id):
         """remove   fitarrange in id"""
         if id in self.fit_arrange_dict:
             del self.fit_arrange_dict[id]
-            
+
     def select_problem_for_fit(self, id, value):
         """
         select a couple of model and data at the id position in dictionary
         and set in self.selected value to value
-        
+
         :param value: the value to allow fitting.
                 can only have the value one or zero
@@ -497,15 +497,15 @@
         if id in self.fit_arrange_dict:
             self.fit_arrange_dict[id].set_to_fit(value)
-             
+
     def get_problem_to_fit(self, id):
         """
         return the self.selected value of the fit problem of id
-        
+
         :param id: the id of the problem
         """
         if id in self.fit_arrange_dict:
             self.fit_arrange_dict[id].get_to_fit()
-    
-    
+
+
 class FitArrange:
     def __init__(self):
@@ -514,8 +514,8 @@
         to perform the Fit.FitArrange must contain exactly one model
         and at least one data for the fit to be performed.
-        
+
         model: the model selected by the user
         Ldata: a list of data what the user wants to fit
-            
+
         """
         self.model = None
@@ -528,18 +528,18 @@
         """
         set_model save a copy of the model
-        
+
         :param model: the model being set
         """
         self.model = model
-        
+
     def add_data(self, data):
         """
         add_data fill a self.data_list with data to fit
-        
+
         :param data: Data to add in the list
         """
         if not data in self.data_list:
             self.data_list.append(data)
-            
+
     def get_model(self):
         """
@@ -547,5 +547,5 @@
         """
         return self.model
-     
+
     def get_data(self):
         """
@@ -553,22 +553,22 @@
         """
         return self.data_list[0]
-      
+
     def remove_data(self, data):
         """
         Remove one element from the list
-        
+
         :param data: Data to remove from data_list
         """
         if data in self.data_list:
             self.data_list.remove(data)
-            
+
     def set_to_fit(self, value=0):
         """
         set self.selected to 0 or 1  for other values raise an exception
-        
+
         :param value: integer between 0 or 1
         """
         self.selected = value
-        
+
     def get_to_fit(self):
         """
@@ -602,15 +602,15 @@
         if self.model is not None and self.data is not None:
             self.inputs = [(self.model, self.data)]
-     
+
     def set_model(self, model):
         """
         """
         self.model = model
-        
+
     def set_fitness(self, fitness):
         """
         """
         self.fitness = fitness
-        
+
     def __str__(self):
         """
@@ -627,5 +627,5 @@
         msg = [msg1, msg3] + msg2
         return "\n".join(msg)
-    
+
     def print_summary(self):
         """
Index: src/sas/sasgui/perspectives/fitting/batchfitpage.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/batchfitpage.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/perspectives/fitting/batchfitpage.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -5,6 +5,12 @@
 import wx.lib.newevent
 import math
+
+from sas.sascalc.fit.qsmearing import smear_selection
+
 from sas.sasgui.guiframe.events import StatusEvent
 from sas.sasgui.guiframe.events import NewPlotEvent
+from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent
+from sas.sasgui.perspectives.fitting.fitpage import FitPage
+from sas.sasgui.perspectives.fitting.fitpage import check_data_validity
 
 (Chi2UpdateEvent, EVT_CHI2_UPDATE) = wx.lib.newevent.NewEvent()
@@ -13,9 +19,4 @@
 SMEAR_SIZE_L = 0.00
 SMEAR_SIZE_H = 0.00
-
-from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent
-from sas.sascalc.data_util.qsmearing import smear_selection
-from sas.sasgui.perspectives.fitting.fitpage import FitPage
-from sas.sasgui.perspectives.fitting.fitpage import check_data_validity
 
 class BatchFitPage(FitPage):
@@ -76,16 +77,16 @@
 #         """
 #         is_2Ddata = False
-#         
+#
 #         # Check if data is 2D
 #         if self.data.__class__.__name__ ==  "Data2D" or \
 #                         self.enable2D:
 #             is_2Ddata = True
-#             
-#         title = "Fitting"     
+#
+#         title = "Fitting"
 #         self._get_smear_info()
-#         
+#
 #         #Sizers
 #         box_description_range = wx.StaticBox(self, wx.ID_ANY, str(title))
-#         boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)      
+#         boxsizer_range = wx.StaticBoxSizer(box_description_range, wx.VERTICAL)
 #         self.sizer_set_smearer = wx.BoxSizer(wx.VERTICAL)
 #         #sizer_smearer = wx.BoxSizer(wx.HORIZONTAL)
@@ -93,5 +94,5 @@
 #         self.sizer_set_masking = wx.BoxSizer(wx.HORIZONTAL)
 #         sizer_chi2 = wx.BoxSizer(wx.VERTICAL)
-# 
+#
 #         sizer_fit = wx.GridSizer(2, 4, 2, 6)
 #         #Fit button
@@ -100,12 +101,12 @@
 #         self.btFit.Bind(wx.EVT_BUTTON, self._onFit, id= self.btFit.GetId())
 #         self.btFit.SetToolTipString("Start fitting.")
-# 
+#
 #         # Update and Draw button
 #         self.draw_button = wx.Button(self, self._ids.next(), 'Compute', size=(88, 24))
 #         self.draw_button.Bind(wx.EVT_BUTTON, \
 #                               self._onDraw,id=self.draw_button.GetId())
-#         self.draw_button.SetToolTipString("Compute and Draw.")  
+#         self.draw_button.SetToolTipString("Compute and Draw.")
 #         sizer_fit.Add(self.draw_button, 0, 0)
-#         sizer_fit.Add(self.btFit, 0, 0) 
+#         sizer_fit.Add(self.btFit, 0, 0)
 #         sizer_chi2.Add((-1, 5))
 #         # get smear_selection
@@ -114,77 +115,77 @@
 #          #2D data? default
 #         is_2Ddata = False
-#         
+#
 #         #check if it is 2D data
 #         if self.data.__class__.__name__ ==  "Data2D" or \
 #                         self.enable2D:
 #             is_2Ddata = True
-#             
+#
 #         self.sizer5.Clear(True)
-#      
+#
 #         self.qmin  = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20),
-#                                           style=wx.TE_PROCESS_ENTER, 
+#                                           style=wx.TE_PROCESS_ENTER,
 #                                     text_enter_callback = self._onQrangeEnter)
 #         self.qmin.SetValue(str(self.qmin_x))
 #         self.qmin.SetToolTipString("Minimun value of Q in linear scale.")
-#      
+#
 #         self.qmax  = ModelTextCtrl(self, wx.ID_ANY, size=(_BOX_WIDTH, 20),
-#                                           style=wx.TE_PROCESS_ENTER, 
+#                                           style=wx.TE_PROCESS_ENTER,
 #                                         text_enter_callback=self._onQrangeEnter)
 #         self.qmax.SetValue(str(self.qmax_x))
 #         self.qmax.SetToolTipString("Maximum value of Q in linear scale.")
-#         
+#
 #         id = self._ids.next()
 #         self.reset_qrange =wx.Button(self, id, 'Reset', size=(77, 20))
-#       
+#
 #         self.reset_qrange.Bind(wx.EVT_BUTTON, self.on_reset_clicked, id=id)
 #         self.reset_qrange.SetToolTipString(\
 #                                     "Reset Q range to the default values")
-#      
+#
 #         sizer_horizontal = wx.BoxSizer(wx.HORIZONTAL)
 #         sizer = wx.GridSizer(2, 4, 2, 6)
-# 
+#
 #         self.btEditMask = wx.Button(self, self._ids.next(),'Editor', size=(88, 23))
-#         self.btEditMask.Bind(wx.EVT_BUTTON, 
+#         self.btEditMask.Bind(wx.EVT_BUTTON,
 #                              self._onMask,id=self.btEditMask.GetId())
 #         self.btEditMask.SetToolTipString("Edit Mask.")
 #         self.EditMask_title = wx.StaticText(self, wx.ID_ANY, ' Masking(2D)')
-# 
+#
 #         sizer.Add(wx.StaticText(self, wx.ID_ANY, 'Q range'))
 #         sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Min[1/A]'))
 #         sizer.Add(wx.StaticText(self, wx.ID_ANY, ' Max[1/A]'))
 #         sizer.Add(self.EditMask_title)
-#  
-#         sizer.Add(self.reset_qrange)   
+#
+#         sizer.Add(self.reset_qrange)
 #         sizer.Add(self.qmin)
 #         sizer.Add(self.qmax)
-# 
+#
 #         sizer.Add(self.btEditMask)
-#         boxsizer_range.Add(sizer_chi2) 
+#         boxsizer_range.Add(sizer_chi2)
 #         boxsizer_range.Add((10, 10))
 #         boxsizer_range.Add(sizer)
-#         
+#
 #         boxsizer_range.Add((10, 15))
 #         boxsizer_range.Add(sizer_fit)
 #         if is_2Ddata:
-#             self.btEditMask.Enable()  
-#             self.EditMask_title.Enable() 
+#             self.btEditMask.Enable()
+#             self.EditMask_title.Enable()
 #         else:
-#             self.btEditMask.Disable()  
+#             self.btEditMask.Disable()
 #             self.EditMask_title.Disable()
-# 
+#
 #         ## save state
 #         #self.save_current_state()
-# 
+#
 #         self.sizer5.Add(boxsizer_range, 0, wx.EXPAND | wx.ALL, 10)
 #         self.sizer5.Layout()
-#        
-#     def _on_select_model(self, event=None): 
+#
+#     def _on_select_model(self, event=None):
 #         """
 #         call back for model selection
-#         """  
-#         
-#         self.Show(False)    
-#         self._on_select_model_helper() 
-#         self.set_model_param_sizer(self.model)                   
+#         """
+#
+#         self.Show(False)
+#         self._on_select_model_helper()
+#         self.set_model_param_sizer(self.model)
 #         if self.model is None:
 #             self._set_bookmark_flag(False)
@@ -199,5 +200,5 @@
 #         self.state.structurecombobox = self.structurebox.GetCurrentSelection()
 #         self.state.formfactorcombobox = self.formfactorbox.GetCurrentSelection()
-#       
+#
 #         if self.model is not None:
 #             self._set_copy_flag(True)
@@ -206,27 +207,27 @@
 #                 self._set_bookmark_flag(False)
 #                 self._keep.Enable(False)
-#                 
+#
 #             temp_smear = None
 #             ## event to post model to fit to fitting plugins
 #             (ModelEventbox, _) = wx.lib.newevent.NewEvent()
-#          
-#             ## set smearing value whether or not 
+#
+#             ## set smearing value whether or not
 #             #    the data contain the smearing info
-#             evt = ModelEventbox(model=self.model, 
-#                                         smearer=temp_smear, 
+#             evt = ModelEventbox(model=self.model,
+#                                         smearer=temp_smear,
 #                                         qmin=float(self.qmin_x),
 #                                         uid=self.uid,
-#                                      qmax=float(self.qmax_x)) 
-#    
+#                                      qmax=float(self.qmax_x))
+#
 #             self._manager._on_model_panel(evt=evt)
 #             self.mbox_description.SetLabel("Model [%s]" % str(self.model.name))
 #             self.state.model = self.model.clone()
 #             self.state.model.name = self.model.name
-# 
-#             
+#
+#
 #         if event is not None:
 #             ## post state to fit panel
 #             new_event = PageInfoEvent(page = self)
-#             wx.PostEvent(self.parent, new_event) 
+#             wx.PostEvent(self.parent, new_event)
 #             #update list of plugins if new plugin is available
 #             if self.plugin_rbutton.GetValue():
@@ -243,6 +244,6 @@
 #             self._draw_model()
 #         self.SetupScrolling()
-#         self.Show(True)   
-#         
+#         self.Show(True)
+#
 #     def _update_paramv_on_fit(self):
 #         """
@@ -253,5 +254,5 @@
 #         self.fitrange = True
 #         is_modified = False
-# 
+#
 #         if self.model is not None:
 #             ##Check the values
@@ -259,8 +260,8 @@
 #             self._check_value_enter( self.fixed_param)
 #             self._check_value_enter( self.parameters)
-# 
-#             # If qmin and qmax have been modified, update qmin and qmax and 
+#
+#             # If qmin and qmax have been modified, update qmin and qmax and
 #              # Here we should check whether the boundaries have been modified.
-#             # If qmin and qmax have been modified, update qmin and qmax and 
+#             # If qmin and qmax have been modified, update qmin and qmax and
 #             # set the is_modified flag to True
 #             self.fitrange = self._validate_qrange(self.qmin, self.qmax)
@@ -273,16 +274,16 @@
 #                     self.qmax_x = tempmax
 #                 if tempmax == tempmin:
-#                     flag = False    
+#                     flag = False
 #                 #temp_smearer = None
 #                 if self._is_2D():
-#                     # only 2D case set mask  
+#                     # only 2D case set mask
 #                     flag = self._validate_Npts()
 #                     if not flag:
 #                         return flag
 #             else: flag = False
-#         else: 
+#         else:
 #             flag = False
-# 
-#         #For invalid q range, disable the mask editor and fit button, vs.    
+#
+#         #For invalid q range, disable the mask editor and fit button, vs.
 #         if not self.fitrange:
 #             #self.btFit.Disable()
@@ -293,18 +294,18 @@
 #             if self._is_2D() and  self.data is not None:
 #                 self.btEditMask.Enable(True)
-# 
+#
 #         if not flag:
 #             msg = "Cannot Plot or Fit :Must select a "
 #             msg += " model or Fitting range is not valid!!!  "
 #             wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
-#         
+#
 #         self.save_current_state()
-#    
-#         return flag  
+#
+#         return flag
 #     def save_current_state(self):
 #         """
 #         Currently no save option implemented for batch page
 #         """
-#         pass 
+#         pass
 #     def save_current_state_fit(self):
 #         """
@@ -314,5 +315,5 @@
 #     def set_data(self, data):
 #         """
-#         reset the current data 
+#         reset the current data
 #         """
 #         #id = None
@@ -340,5 +341,5 @@
 #             self._set_save_flag(False)
 #             self._set_preview_flag(True)
-#   
+#
 #             self.formfactorbox.Enable()
 #             self.structurebox.Enable()
@@ -346,21 +347,21 @@
 #             #set maximum range for x in linear scale
 #             if not hasattr(self.data,"data"): #Display only for 1D data fit
-#                 # Minimum value of data   
+#                 # Minimum value of data
 #                 data_min = min(self.data.x)
-#                 # Maximum value of data  
+#                 # Maximum value of data
 #                 data_max = max(self.data.x)
-#                 self.btEditMask.Disable()  
+#                 self.btEditMask.Disable()
 #                 self.EditMask_title.Disable()
 #             else:
-#                 
-#                 ## Minimum value of data 
+#
+#                 ## Minimum value of data
 #                 data_min = 0
-#                 x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax)) 
+#                 x = max(math.fabs(self.data.xmin), math.fabs(self.data.xmax))
 #                 y = max(math.fabs(self.data.ymin), math.fabs(self.data.ymax))
-#                 ## Maximum value of data  
+#                 ## Maximum value of data
 #                 data_max = math.sqrt(x*x + y*y)
-#                 self.btEditMask.Enable()  
-#                 self.EditMask_title.Enable() 
-# 
+#                 self.btEditMask.Enable()
+#                 self.EditMask_title.Enable()
+#
 #         self.dataSource.SetValue(data_name)
 #         self.qmin_x = data_min
@@ -375,5 +376,5 @@
 #         self.state.qmin = self.qmin_x
 #         self.state.qmax = self.qmax_x
-#         
+#
 #         #update model plot with new data information
 #         if flag:
@@ -385,12 +386,12 @@
 #                 self.enable2D = False
 #                 self.model_view.SetLabel("1D Mode")
-#                 
+#
 #             self.model_view.Disable()
-#             
-#             wx.PostEvent(self._manager.parent, 
+#
+#             wx.PostEvent(self._manager.parent,
 #                              NewPlotEvent(group_id=group_id,
 #                                                action="delete"))
 #             #plot the current selected data
-#             wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data, 
+#             wx.PostEvent(self._manager.parent, NewPlotEvent(plot=self.data,
 #                                                     title=str(self.data.title)))
 #             self._manager.store_data(uid=self.uid, data=data,
Index: src/sas/sasgui/perspectives/fitting/fitpage.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/fitpage.py	(revision 9a5097cd1c76689d1f997b85ba43d12a95d8f243)
+++ src/sas/sasgui/perspectives/fitting/fitpage.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -14,4 +14,6 @@
 from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS
 
+from sas.sascalc.fit.qsmearing import smear_selection
+
 from sas.sasgui.guiframe.events import StatusEvent, NewPlotEvent, \
     PlotQrangeEvent
@@ -23,5 +25,4 @@
 from sas.sasgui.perspectives.fitting.basepage import PageInfoEvent as \
     PageInfoEvent
-from sas.sascalc.data_util.qsmearing import smear_selection
 from .basepage import ModelTextCtrl
 
@@ -289,5 +290,5 @@
         self.btFitHelp.SetToolTipString("General fitting help.")
         self.btFitHelp.Bind(wx.EVT_BUTTON, self._onFitHelp)
-        
+
         # Resolution Smearing Help button (for now use same technique as
         # used for dI help to get tiniest possible button that works
@@ -303,5 +304,5 @@
         self.btSmearHelp.SetToolTipString("Resolution smearing help.")
         self.btSmearHelp.Bind(wx.EVT_BUTTON, self._onSmearHelp)
-        
+
         # textcntrl for custom resolution
         self.smear_pinhole_percent = ModelTextCtrl(self, wx.ID_ANY,
@@ -564,5 +565,5 @@
         sizer.Add(self.draw_button, 0, 0)
         sizer.Add((-1, 5))
-        
+
         sizer.Add(self.tcChi, 0, 0)
         sizer.Add(self.Npts_fit, 0, 0)
@@ -570,5 +571,5 @@
         sizer.Add(self.btFit, 0, 0)
         sizer.Add(self.btFitHelp, 0, 0)
-        
+
         boxsizer_range.Add(sizer_chi2)
         boxsizer_range.Add(sizer)
@@ -2775,5 +2776,5 @@
             else:
                 return cmp(a.lower(), b.lower())
-        
+
         # keys obtained now from ordered dict, so commenting alphabetical
         # ordering keys.sort(custom_compare)
Index: src/sas/sasgui/perspectives/fitting/fitproblem.py
===================================================================
--- src/sas/sasgui/perspectives/fitting/fitproblem.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/perspectives/fitting/fitproblem.py	(revision 50fcb09b3ee47cf23c26b90d9c291f41415c0aa5)
@@ -14,5 +14,6 @@
 ################################################################################
 import copy
-from sas.sascalc.data_util.qsmearing import smear_selection
+
+from sas.sascalc.fit.qsmearing import smear_selection
 
 class FitProblemComponent(object):
@@ -622,6 +623,5 @@
         # fit data: used for fit and can be modified for convenience
         self.fit_data = copy.deepcopy(data)
-        self.smearer_computer_value = smear_selection(self.fit_data,
-                                                           self.model)
+        self.smearer_computer_value = smear_selection(self.fit_data, self.model)
         self.smearer_computed = True
         self.result = None
