def test_resolution_kernel(self): # check that resolution kernel works, use constant dq/q of 5% as # comparison slabs = self.structure361.slabs()[:, :4] npnts = 1000 q = np.linspace(0.005, 0.3, npnts) # use constant dq/q for comparison const_R = reflectivity( q, slabs, scale=1.01, bkg=1e-6, dq=0.05 * q, quad_order=101, threads=-1, ) # lets create a kernel. kernel = np.zeros((npnts, 2, 501), float) sd = 0.05 * q / (2 * np.sqrt(2 * np.log(2))) for i in range(npnts): kernel[i, 0, :] = np.linspace(q[i] - 3.5 * sd[i], q[i] + 3.5 * sd[i], 501) kernel[i, 1, :] = stats.norm.pdf(kernel[i, 0, :], loc=q[i], scale=sd[i]) kernel_R = reflectivity(q, slabs, scale=1.01, bkg=1e-6, dq=kernel) assert_allclose(kernel_R, const_R, rtol=0.002)
def res(qq, layer, resolution=5): resolution /= 100 gaussnum = 51 gaussgpoint = (gaussnum - 1) / 2 def gauss(x, s): return 1. / s / np.sqrt(2 * np.pi) * np.exp(-0.5 * x**2 / s / s) lowQ = np.min(qq) highQ = np.max(qq) if lowQ <= 0: lowQ = 1e-6 start = np.log10(lowQ) - 6 * resolution / 2.35482 finish = np.log10(highQ * (1 + 6 * resolution / 2.35482)) interpnum = np.round(np.abs(1 * (np.abs(start - finish)) / (1.7 * resolution / 2.35482 / gaussgpoint))) xtemp = np.linspace(start, finish, int(interpnum)) gauss_x = np.linspace(-1.7 * resolution, 1.7 * resolution, gaussnum) gauss_y = gauss(gauss_x, resolution / (2 * np.sqrt(2 * np.log(2)))) rvals = reflectivity(np.power(10, xtemp), layer) smeared_rvals = fftconvolve(rvals, gauss_y, mode='same') interpolator = interp1d(np.power(10, xtemp), smeared_rvals) smeared_output = interpolator(qq) smeared_output /= np.sum(gauss_y) return smeared_output
def test_FresnelTransform(self): t = FresnelTransform(2.07, 6.36, dq=5) slabs = np.array([[0, 2.07, 0, 0], [0, 6.36, 0, 0]]) q = np.linspace(0.01, 1.0, 1000) r = reflectivity(q, slabs, dq=5) rt, et = t(q, r) assert_almost_equal(rt, 1.0) # test errors are transformed rt, et = t(q, r, y_err=1.0) assert_almost_equal(et, 1.0 / r) # check that you can use an SLD object t = FresnelTransform(SLD(2.07), SLD(6.36), dq=5) rt, et = t(q, r) assert_almost_equal(rt, 1.0) # reconstitute a repr'd transform and check it works s = repr(t) st = eval(s) rt, et = st(q, r) assert_almost_equal(rt, 1.0)
def dyna(): # a comparison of dynamical + kinematic approaches. fig = plt.figure(constrained_layout=True, figsize=(10, 7.5 / 2)) spec = gridspec.GridSpec(ncols=2, nrows=1, figure=fig) ax3 = fig.add_subplot(spec[0, :]) # kinematic reflectivity q = np.linspace(0.002, 0.05, 500) kinematic_r = 16 * np.pi**2 * 2.074e-6**2 / (q**4) ax3.plot(q, kinematic_r, c=c[0]) # dynamical reflectivity q2 = np.linspace(0, 0.05, 1000) layers = np.array([[ 0, 0, 0, 0, ], [0, 2.074, 0, 0]]) ax3.plot(q2, reflectivity(q2, layers, dq=0), c=c[2], zorder=10) ax3.axhline(1, c=c[1]) ax3.set_yscale('log') ax3.set_xlabel(r"$q$/Å$^{-1}$") ax3.set_ylabel(r"$R(q)$") ax3.set_xlim(0, 0.05) plt.savefig('dyna.pdf') plt.close()
def likelihood(): def abeles_build(q, thick, sld1, sld2): layers = np.array([[0, 0, 0, 0], [thick, sld1, 0, 0], [0, sld2, 0, 0]]) return reflectivity(q, layers, dq=0.0) q2 = np.logspace(-3, -0.5, 40) layers = np.array([[0, 0, 0, 0], [40, 6.335, 0, 0], [0, 2.074, 0, 0]]) r = reflectivity(q2, layers, dq=0) r += np.abs((np.random.random((q2.size)) - 0.5) * q2 * r) dr = np.abs(1 / r) * 1e-9 popt, pcov = curve_fit(abeles_build, q2, r, sigma=dr, p0=[40, 6.335, 2.074]) fig = plt.figure(constrained_layout=True, figsize=(10, 7.5 / 2)) spec = gridspec.GridSpec(ncols=2, nrows=1, figure=fig) ax3 = fig.add_subplot(spec[0, :]) q3 = np.logspace(-3, -0.5, 1000) rr = np.random.randn(len(popt)) * 10 rr[-1] = 0 rm = abeles_build(q2, *popt) rm2 = abeles_build(q2, *(np.array(popt) + rr)) Lm = -0.5 * np.sum(np.square((r - rm) / dr) + np.log(2 * np.pi * dr)) Lm2 = -0.5 * np.sum(np.square((r - rm2) / dr) + np.log(2 * np.pi * dr)) rm = abeles_build(q3, *popt) rm2 = abeles_build(q3, *(np.array(popt) + rr)) ax3.errorbar(q2, r, dr, c=c[0], zorder=10, marker='o', ls='') ax3.plot(q3, rm, c=c[1], zorder=10, label='{:.2e}'.format(Lm)) ax3.plot(q3, rm2, c=c[2], zorder=10, label='{:.2e}'.format(Lm2)) ax3.set_yscale('log') ax3.set_xlabel(r"$q$/Å$^{-1}$") ax3.set_ylabel(r"$R(q)$") ax3.legend(title=r"$\ln\;{\hat{L}}$") ax3.set_xlim(0, 0.3) plt.savefig('likelihood.pdf') plt.close()
def model(self, x, p=None, x_err=None): r""" Calculate the reflectivity of this model Parameters ---------- x : float or np.ndarray q values for the calculation. p : refnx.analysis.Parameter, optional parameters required to calculate the model x_err : np.ndarray dq resolution smearing values for the dataset being considered. Returns ------- reflectivity : np.ndarray """ self.generate_thicknesses() if p is not None: self.parameters.pvals = np.array(p) if x_err is None: # fallback to what this object was constructed with x_err = float(self.dq) scales = np.array(self.scales) y = np.zeros_like(x) for scale, structure in zip(scales, self.structures): y += reflectivity(x, structure.slabs()[..., :4], scale=scale, dq=x_err, threads=self.threads, quad_order=self.quad_order) return self._scale*y + self.bkg.value
def time_reflectivity(self): reflectivity(self.q, self.layers)
def abeles_build(q, thick, sld1, sld2): layers = np.array([[0, 0, 0, 0], [thick, sld1, 0, 0], [0, sld2, 0, 0]]) return reflectivity(q, layers, dq=0.0)
def time_reflectivity_pointwise_dq(self): reflectivity(self.q, self.layers, dq=0.05 * self.q)
def time_reflectivity_constant_dq_q(self): reflectivity(self.q, self.layers)