Index: sasmodels/compare.py
===================================================================
--- sasmodels/compare.py	(revision 65fbf7c6ec7049c9f802a1c656fdeb5e624b7596)
+++ sasmodels/compare.py	(revision 1fbadb20289a15dcd2b077eb8ef47e0dbda5eef1)
@@ -645,5 +645,5 @@
 
 def make_data(opts):
-    # type: (Dict[str, Any], float) -> Tuple[Data, np.ndarray]
+    # type: (Dict[str, Any]) -> Tuple[Data, np.ndarray]
     """
     Generate an empty dataset, used with the model to set Q points
@@ -667,8 +667,5 @@
         if opts['zero']:
             q = np.hstack((0, q))
-        # TODO: provide command line control of lambda and Delta lambda/lambda
-        #L, dLoL = 5, 0.14/np.sqrt(6)  # wavelength and 14% triangular FWHM
-        L, dLoL = 0, 0
-        data = empty_data1D(q, resolution=res, L=L, dL=L*dLoL)
+        data = empty_data1D(q, resolution=res)
         index = slice(None, None)
     return data, index
@@ -789,5 +786,5 @@
     base_n, comp_n = opts['count']
     base_pars, comp_pars = opts['pars']
-    base_data, comp_data = opts['data']
+    data = opts['data']
 
     comparison = comp is not None
@@ -803,5 +800,5 @@
             print("%s t=%.2f ms, intensity=%.0f"
                   % (base.engine, base_time, base_value.sum()))
-        _show_invalid(base_data, base_value)
+        _show_invalid(data, base_value)
     except ImportError:
         traceback.print_exc()
@@ -815,5 +812,5 @@
                 print("%s t=%.2f ms, intensity=%.0f"
                       % (comp.engine, comp_time, comp_value.sum()))
-            _show_invalid(base_data, comp_value)
+            _show_invalid(data, comp_value)
         except ImportError:
             traceback.print_exc()
@@ -869,10 +866,9 @@
     have_base, have_comp = (base_value is not None), (comp_value is not None)
     base, comp = opts['engines']
-    base_data, comp_data = opts['data']
+    data = opts['data']
     use_data = (opts['datafile'] is not None) and (have_base ^ have_comp)
 
     # Plot if requested
     view = opts['view']
-    #view = 'log'
     if limits is None:
         vmin, vmax = np.inf, -np.inf
@@ -888,5 +884,5 @@
         if have_comp:
             plt.subplot(131)
-        plot_theory(base_data, base_value, view=view, use_data=use_data, limits=limits)
+        plot_theory(data, base_value, view=view, use_data=use_data, limits=limits)
         plt.title("%s t=%.2f ms"%(base.engine, base_time))
         #cbar_title = "log I"
@@ -895,6 +891,6 @@
             plt.subplot(132)
         if not opts['is2d'] and have_base:
-            plot_theory(comp_data, base_value, view=view, use_data=use_data, limits=limits)
-        plot_theory(comp_data, comp_value, view=view, use_data=use_data, limits=limits)
+            plot_theory(data, base_value, view=view, use_data=use_data, limits=limits)
+        plot_theory(data, comp_value, view=view, use_data=use_data, limits=limits)
         plt.title("%s t=%.2f ms"%(comp.engine, comp_time))
         #cbar_title = "log I"
@@ -912,8 +908,5 @@
             err[err > cutoff] = cutoff
         #err,errstr = base/comp,"ratio"
-        # Note: base_data only since base and comp have same q values (though
-        # perhaps different resolution), and we are plotting the difference
-        # at each q
-        plot_theory(base_data, None, resid=err, view=errview, use_data=use_data)
+        plot_theory(data, None, resid=err, view=errview, use_data=use_data)
         plt.xscale('log' if view == 'log' and not opts['is2d'] else 'linear')
         plt.legend(['P%d'%(k+1) for k in range(setnum+1)], loc='best')
@@ -1082,5 +1075,5 @@
         'qmax'      : 0.05,
         'nq'        : 128,
-        'res'       : '0.0',
+        'res'       : 0.0,
         'noise'     : 0.0,
         'accuracy'  : 'Low',
@@ -1122,5 +1115,5 @@
         elif arg.startswith('-q='):
             opts['qmin'], opts['qmax'] = [float(v) for v in arg[3:].split(':')]
-        elif arg.startswith('-res='):      opts['res'] = arg[5:]
+        elif arg.startswith('-res='):      opts['res'] = float(arg[5:])
         elif arg.startswith('-noise='):    opts['noise'] = float(arg[7:])
         elif arg.startswith('-sets='):     opts['sets'] = int(arg[6:])
@@ -1180,4 +1173,8 @@
     if opts['qmin'] is None:
         opts['qmin'] = 0.001*opts['qmax']
+    if opts['datafile'] is not None:
+        data = load_data(os.path.expanduser(opts['datafile']))
+    else:
+        data, _ = make_data(opts)
 
     comparison = any(PAR_SPLIT in v for v in values)
@@ -1219,29 +1216,8 @@
         opts['cutoff'] = [float(opts['cutoff'])]*2
 
-    if PAR_SPLIT in opts['res']:
-        opts['res'] = [float(k) for k in opts['res'].split(PAR_SPLIT, 2)]
-        comparison = True
-    else:
-        opts['res'] = [float(opts['res'])]*2
-
-    if opts['datafile'] is not None:
-        data = load_data(os.path.expanduser(opts['datafile']))
-    else:
-        # Hack around the fact that make_data doesn't take a pair of resolutions
-        res = opts['res']
-        opts['res'] = res[0]
-        data0, _ = make_data(opts)
-        if res[0] != res[1]:
-            opts['res'] = res[1]
-            data1, _ = make_data(opts)
-        else:
-            data1 = data0
-        opts['res'] = res
-        data = data0, data1
-
-    base = make_engine(model_info[0], data[0], opts['engine'][0],
+    base = make_engine(model_info[0], data, opts['engine'][0],
                        opts['cutoff'][0], opts['ngauss'][0])
     if comparison:
-        comp = make_engine(model_info[1], data[1], opts['engine'][1],
+        comp = make_engine(model_info[1], data, opts['engine'][1],
                            opts['cutoff'][1], opts['ngauss'][1])
     else:
Index: sasmodels/data.py
===================================================================
--- sasmodels/data.py	(revision 65fbf7c6ec7049c9f802a1c656fdeb5e624b7596)
+++ sasmodels/data.py	(revision d86f0fc0fff835c5ddf398e64c046518fa4536fc)
@@ -36,5 +36,4 @@
 
 import numpy as np  # type: ignore
-from numpy import sqrt, sin, cos, pi
 
 # pylint: disable=unused-import
@@ -302,13 +301,10 @@
 
 
-def empty_data1D(q, resolution=0.0, L=0., dL=0.):
+def empty_data1D(q, resolution=0.0):
     # type: (np.ndarray, float) -> Data1D
-    r"""
+    """
     Create empty 1D data using the given *q* as the x value.
 
-    rms *resolution* $\Delta q/q$ defaults to 0%.  If wavelength *L* and rms
-    wavelength divergence *dL* are defined, then *resolution* defines
-    rms $\Delta \theta/\theta$ for the lowest *q*, with $\theta$ derived from
-    $q = 4\pi/\lambda \sin(\theta)$.
+    *resolution* dq/q defaults to 5%.
     """
 
@@ -317,18 +313,5 @@
     Iq, dIq = None, None
     q = np.asarray(q)
-    if L != 0 and resolution != 0:
-        theta = np.arcsin(q*L/(4*pi))
-        dtheta = theta[0]*resolution
-        ## Solving Gaussian error propagation from
-        ##   Dq^2 = (dq/dL)^2 DL^2 + (dq/dtheta)^2 Dtheta^2
-        ## gives
-        ##   (Dq/q)^2 = (DL/L)**2 + (Dtheta/tan(theta))**2
-        ## Take the square root and multiply by q, giving
-        ##   Dq = (4*pi/L) * sqrt((sin(theta)*dL/L)**2 + (cos(theta)*dtheta)**2)
-        dq = (4*pi/L) * sqrt((sin(theta)*dL/L)**2 + (cos(theta)*dtheta)**2)
-    else:
-        dq = resolution * q
-
-    data = Data1D(q, Iq, dx=dq, dy=dIq)
+    data = Data1D(q, Iq, dx=resolution * q, dy=dIq)
     data.filename = "fake data"
     return data
Index: sasmodels/jitter.py
===================================================================
--- sasmodels/jitter.py	(revision 1198f905febb85403d3b86dca3d2bec81af13029)
+++ sasmodels/jitter.py	(revision b3703f51bafe67afb8acefe986ad7466720f755b)
@@ -774,5 +774,5 @@
         # set small jitter as 0 if multiple pd dims
         dims = sum(v > 0 for v in jitter)
-        limit = [0, 0.5, 5][dims]
+        limit = [0, 0, 0.5, 5][dims]
         jitter = [0 if v < limit else v for v in jitter]
         axes.cla()
Index: sasmodels/resolution.py
===================================================================
--- sasmodels/resolution.py	(revision bbb887d21ceb13c020067968d0cdf7543a7ea2b0)
+++ sasmodels/resolution.py	(revision 2d81cfe3be42579d563407fb9275b7b516fee234)
@@ -20,5 +20,4 @@
 MINIMUM_RESOLUTION = 1e-8
 MINIMUM_ABSOLUTE_Q = 0.02  # relative to the minimum q in the data
-PINHOLE_N_SIGMA = 2.5 # From: Barker & Pedersen 1995 JAC
 
 class Resolution(object):
@@ -66,9 +65,6 @@
     *q_calc* is the list of points to calculate, or None if this should
     be estimated from the *q* and *q_width*.
-
-    *nsigma* is the width of the resolution function.  Should be 2.5.
-    See :func:`pinhole_resolution` for details.
-    """
-    def __init__(self, q, q_width, q_calc=None, nsigma=PINHOLE_N_SIGMA):
+    """
+    def __init__(self, q, q_width, q_calc=None, nsigma=3):
         #*min_step* is the minimum point spacing to use when computing the
         #underlying model.  It should be on the order of
@@ -86,15 +82,12 @@
 
         # Protect against models which are not defined for very low q.  Limit
-        # the smallest q value evaluated to 0.02*min.  Note that negative q
-        # values are trimmed even for broad resolution.  Although not possible
-        # from the geometry, they may appear since we are using a truncated
-        # gaussian to represent resolution rather than a skew distribution.
+        # the smallest q value evaluated (in absolute) to 0.02*min
         cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q)
-        self.q_calc = self.q_calc[self.q_calc >= cutoff]
+        self.q_calc = self.q_calc[abs(self.q_calc) >= cutoff]
 
         # Build weight matrix from calculated q values
         self.weight_matrix = pinhole_resolution(
-            self.q_calc, self.q, np.maximum(q_width, MINIMUM_RESOLUTION),
-            nsigma=nsigma)
+            self.q_calc, self.q, np.maximum(q_width, MINIMUM_RESOLUTION))
+        self.q_calc = abs(self.q_calc)
 
     def apply(self, theory):
@@ -108,7 +101,7 @@
     *q* points at which the data is measured.
 
-    *qx_width* slit width in qx
-
-    *qy_width* slit height in qy
+    *dqx* slit width in qx
+
+    *dqy* slit height in qy
 
     *q_calc* is the list of points to calculate, or None if this should
@@ -161,6 +154,6 @@
 
 
-def pinhole_resolution(q_calc, q, q_width, nsigma=PINHOLE_N_SIGMA):
-    r"""
+def pinhole_resolution(q_calc, q, q_width):
+    """
     Compute the convolution matrix *W* for pinhole resolution 1-D data.
 
@@ -169,16 +162,5 @@
     *W*, the resolution smearing can be computed using *dot(W,q)*.
 
-    Note that resolution is limited to $\pm 2.5 \sigma$.[1]  The true resolution
-    function is a broadened triangle, and does not extend over the entire
-    range $(-\infty, +\infty)$.  It is important to impose this limitation
-    since some models fall so steeply that the weighted value in gaussian
-    tails would otherwise dominate the integral.
-
     *q_calc* must be increasing.  *q_width* must be greater than zero.
-
-    [1] Barker, J. G., and J. S. Pedersen. 1995. Instrumental Smearing Effects
-    in Radially Symmetric Small-Angle Neutron Scattering by Numerical and
-    Analytical Methods. Journal of Applied Crystallography 28 (2): 105--14.
-    https://doi.org/10.1107/S0021889894010095.
     """
     # The current algorithm is a midpoint rectangle rule.  In the test case,
@@ -188,10 +170,4 @@
     cdf = erf((edges[:, None] - q[None, :]) / (sqrt(2.0)*q_width)[None, :])
     weights = cdf[1:] - cdf[:-1]
-    # Limit q range to +/- 2.5 sigma
-    qhigh = q + nsigma*q_width
-    #qlow = q - nsigma*q_width  # linear limits
-    qlow = q*q/qhigh  # log limits
-    weights[q_calc[:, None] < qlow[None, :]] = 0.
-    weights[q_calc[:, None] > qhigh[None, :]] = 0.
     weights /= np.sum(weights, axis=0)[None, :]
     return weights
@@ -518,14 +494,11 @@
 
 
-def gaussian(q, q0, dq, nsigma=2.5):
-    """
-    Return the truncated Gaussian resolution function.
+def gaussian(q, q0, dq):
+    """
+    Return the Gaussian resolution function.
 
     *q0* is the center, *dq* is the width and *q* are the points to evaluate.
     """
-    # Calculate the density of the tails; the resulting gaussian needs to be
-    # scaled by this amount in ordere to integrate to 1.0
-    two_tail_density = 2 * (1 + erf(-nsigma/sqrt(2)))/2
-    return exp(-0.5*((q-q0)/dq)**2)/(sqrt(2*pi)*dq)/(1-two_tail_density)
+    return exp(-0.5*((q-q0)/dq)**2)/(sqrt(2*pi)*dq)
 
 
@@ -585,5 +558,5 @@
 
 
-def romberg_pinhole_1d(q, q_width, form, pars, nsigma=2.5):
+def romberg_pinhole_1d(q, q_width, form, pars, nsigma=5):
     """
     Romberg integration for pinhole resolution.
@@ -705,6 +678,4 @@
         np.testing.assert_equal(output, self.y)
 
-    # TODO: turn pinhole/slit demos into tests
-
     def test_pinhole(self):
         """
@@ -715,11 +686,8 @@
         theory = 12.0-1000.0*resolution.q_calc
         output = resolution.apply(theory)
-        # Note: answer came from output of previous run.  Non-integer
-        # values at ends come from the fact that q_calc does not
-        # extend beyond q, and so the weights don't balance.
         answer = [
-            10.47037734, 9.86925860,
-            9., 8., 7., 6., 5., 4.,
-            3.13074140, 2.52962266,
+            10.44785079, 9.84991299, 8.98101708,
+            7.99906585, 6.99998311, 6.00001689,
+            5.00093415, 4.01898292, 3.15008701, 2.55214921,
             ]
         np.testing.assert_allclose(output, answer, atol=1e-8)
@@ -764,5 +732,4 @@
         self._compare(q, output, answer, 1e-6)
 
-    @unittest.skip("suppress comparison with old version; pinhole calc changed")
     def test_pinhole(self):
         """
@@ -779,5 +746,4 @@
         self._compare(q, output, answer, 3e-4)
 
-    @unittest.skip("suppress comparison with old version; pinhole calc changed")
     def test_pinhole_romberg(self):
         """
@@ -795,5 +761,5 @@
         #                     2*np.pi/pars['radius']/200)
         #tol = 0.001
-        ## The default 2.5 sigma and no extra points gets 1%
+        ## The default 3 sigma and no extra points gets 1%
         q_calc = None  # type: np.ndarray
         tol = 0.01
@@ -1114,5 +1080,5 @@
 
     if isinstance(resolution, Slit1D):
-        width, height = resolution.qx_width, resolution.qy_width
+        width, height = resolution.dqx, resolution.dqy
         Iq_romb = romberg_slit_1d(resolution.q, width, height, model, pars)
     else:
