Changes in sasmodels/resolution.py [bbb887d:2d81cfe] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/resolution.py
rbbb887d r2d81cfe 20 20 MINIMUM_RESOLUTION = 1e-8 21 21 MINIMUM_ABSOLUTE_Q = 0.02 # relative to the minimum q in the data 22 PINHOLE_N_SIGMA = 2.5 # From: Barker & Pedersen 1995 JAC23 22 24 23 class Resolution(object): … … 66 65 *q_calc* is the list of points to calculate, or None if this should 67 66 be estimated from the *q* and *q_width*. 68 69 *nsigma* is the width of the resolution function. Should be 2.5. 70 See :func:`pinhole_resolution` for details. 71 """ 72 def __init__(self, q, q_width, q_calc=None, nsigma=PINHOLE_N_SIGMA): 67 """ 68 def __init__(self, q, q_width, q_calc=None, nsigma=3): 73 69 #*min_step* is the minimum point spacing to use when computing the 74 70 #underlying model. It should be on the order of … … 86 82 87 83 # Protect against models which are not defined for very low q. Limit 88 # the smallest q value evaluated to 0.02*min. Note that negative q 89 # values are trimmed even for broad resolution. Although not possible 90 # from the geometry, they may appear since we are using a truncated 91 # gaussian to represent resolution rather than a skew distribution. 84 # the smallest q value evaluated (in absolute) to 0.02*min 92 85 cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q) 93 self.q_calc = self.q_calc[ self.q_calc>= cutoff]86 self.q_calc = self.q_calc[abs(self.q_calc) >= cutoff] 94 87 95 88 # Build weight matrix from calculated q values 96 89 self.weight_matrix = pinhole_resolution( 97 self.q_calc, self.q, np.maximum(q_width, MINIMUM_RESOLUTION) ,98 nsigma=nsigma)90 self.q_calc, self.q, np.maximum(q_width, MINIMUM_RESOLUTION)) 91 self.q_calc = abs(self.q_calc) 99 92 100 93 def apply(self, theory): … … 108 101 *q* points at which the data is measured. 109 102 110 * qx_width* slit width in qx111 112 * qy_width* slit height in qy103 *dqx* slit width in qx 104 105 *dqy* slit height in qy 113 106 114 107 *q_calc* is the list of points to calculate, or None if this should … … 161 154 162 155 163 def pinhole_resolution(q_calc, q, q_width , nsigma=PINHOLE_N_SIGMA):164 r"""156 def pinhole_resolution(q_calc, q, q_width): 157 """ 165 158 Compute the convolution matrix *W* for pinhole resolution 1-D data. 166 159 … … 169 162 *W*, the resolution smearing can be computed using *dot(W,q)*. 170 163 171 Note that resolution is limited to $\pm 2.5 \sigma$.[1] The true resolution172 function is a broadened triangle, and does not extend over the entire173 range $(-\infty, +\infty)$. It is important to impose this limitation174 since some models fall so steeply that the weighted value in gaussian175 tails would otherwise dominate the integral.176 177 164 *q_calc* must be increasing. *q_width* must be greater than zero. 178 179 [1] Barker, J. G., and J. S. Pedersen. 1995. Instrumental Smearing Effects180 in Radially Symmetric Small-Angle Neutron Scattering by Numerical and181 Analytical Methods. Journal of Applied Crystallography 28 (2): 105--14.182 https://doi.org/10.1107/S0021889894010095.183 165 """ 184 166 # The current algorithm is a midpoint rectangle rule. In the test case, … … 188 170 cdf = erf((edges[:, None] - q[None, :]) / (sqrt(2.0)*q_width)[None, :]) 189 171 weights = cdf[1:] - cdf[:-1] 190 # Limit q range to +/- 2.5 sigma191 qhigh = q + nsigma*q_width192 #qlow = q - nsigma*q_width # linear limits193 qlow = q*q/qhigh # log limits194 weights[q_calc[:, None] < qlow[None, :]] = 0.195 weights[q_calc[:, None] > qhigh[None, :]] = 0.196 172 weights /= np.sum(weights, axis=0)[None, :] 197 173 return weights … … 518 494 519 495 520 def gaussian(q, q0, dq , nsigma=2.5):521 """ 522 Return the truncatedGaussian resolution function.496 def gaussian(q, q0, dq): 497 """ 498 Return the Gaussian resolution function. 523 499 524 500 *q0* is the center, *dq* is the width and *q* are the points to evaluate. 525 501 """ 526 # Calculate the density of the tails; the resulting gaussian needs to be 527 # scaled by this amount in ordere to integrate to 1.0 528 two_tail_density = 2 * (1 + erf(-nsigma/sqrt(2)))/2 529 return exp(-0.5*((q-q0)/dq)**2)/(sqrt(2*pi)*dq)/(1-two_tail_density) 502 return exp(-0.5*((q-q0)/dq)**2)/(sqrt(2*pi)*dq) 530 503 531 504 … … 585 558 586 559 587 def romberg_pinhole_1d(q, q_width, form, pars, nsigma= 2.5):560 def romberg_pinhole_1d(q, q_width, form, pars, nsigma=5): 588 561 """ 589 562 Romberg integration for pinhole resolution. … … 705 678 np.testing.assert_equal(output, self.y) 706 679 707 # TODO: turn pinhole/slit demos into tests708 709 680 def test_pinhole(self): 710 681 """ … … 715 686 theory = 12.0-1000.0*resolution.q_calc 716 687 output = resolution.apply(theory) 717 # Note: answer came from output of previous run. Non-integer718 # values at ends come from the fact that q_calc does not719 # extend beyond q, and so the weights don't balance.720 688 answer = [ 721 10.4 7037734, 9.86925860,722 9., 8., 7., 6., 5., 4.,723 3.13074140, 2.52962266,689 10.44785079, 9.84991299, 8.98101708, 690 7.99906585, 6.99998311, 6.00001689, 691 5.00093415, 4.01898292, 3.15008701, 2.55214921, 724 692 ] 725 693 np.testing.assert_allclose(output, answer, atol=1e-8) … … 764 732 self._compare(q, output, answer, 1e-6) 765 733 766 @unittest.skip("suppress comparison with old version; pinhole calc changed")767 734 def test_pinhole(self): 768 735 """ … … 779 746 self._compare(q, output, answer, 3e-4) 780 747 781 @unittest.skip("suppress comparison with old version; pinhole calc changed")782 748 def test_pinhole_romberg(self): 783 749 """ … … 795 761 # 2*np.pi/pars['radius']/200) 796 762 #tol = 0.001 797 ## The default 2.5sigma and no extra points gets 1%763 ## The default 3 sigma and no extra points gets 1% 798 764 q_calc = None # type: np.ndarray 799 765 tol = 0.01 … … 1114 1080 1115 1081 if isinstance(resolution, Slit1D): 1116 width, height = resolution. qx_width, resolution.qy_width1082 width, height = resolution.dqx, resolution.dqy 1117 1083 Iq_romb = romberg_slit_1d(resolution.q, width, height, model, pars) 1118 1084 else:
Note: See TracChangeset
for help on using the changeset viewer.