SasView / sasmodels

Package for calculation of small angle scattering models using OpenCL.
BSD 3-Clause "New" or "Revised" License
15 stars 27 forks source link

Allow 2D calculations with qz ≠ 0 #514

Open pkienzle opened 2 years ago

pkienzle commented 2 years ago

Detector pixels in SAS measurements have a small $q_z$ component.

Using the definition $q = k_f - k_i$ with the beam is along $z$ then

$$k_i = 2π/λ_i [0, 0, 1]$$

$$k_f = 2π/λ_f [\sin 2θ \cos φ, \sin 2θ \sin φ, \cos 2θ]$$

Assume elastic scattering so $λ_i = λ_f = λ$. Therefore

$$q_x = 2π/λ (\sin 2θ \cos φ) = 4π/λ \sin θ \cos θ \cos φ = |q| \cos θ \cos φ$$

$$q_y = 2π/λ (\sin 2θ \sin φ) = 4π/λ \sin θ \cos θ \sin φ = |q| \cos θ \sin φ$$

$$q_z = 2π/λ (1 - \cos 2θ) = 4π/λ \sin² θ = |q| \sin θ$$

The existing code only uses $q_x$ and $q_y$. See here for example: https://github.com/SasView/sasmodels/blob/a00aa0f0331af43cd098b0bb7e78656505d30eb3/sasmodels/kernel_iq.c#L346-L357

This will only matter for large angles or high precision measurements. For small θ we have sin θ ≈ 0 and $[q_x, q_y, q_z] ≈ |q|[\cos φ, \sin φ, 0]$.

pkienzle commented 2 years ago

To put some numbers on this, look at the ring with nominal q = 0.5/Å for λ = 8 Å

from numpy import arcsin, sin, cos, pi, sqrt
nominal_q, L = 0.5, 8
theta = arcsin(nominal_q * L / (4*pi))
q = 4*pi/L*sin(theta)
qx, qz = q*cos(theta), q*sin(theta)
print(f"qx={qx:.5f} qz={qz:.5f} q={sqrt(qx**2+qz**2):.5f}")

produces:

qx=0.47399 qz=0.15915 q=0.50000

So for long wavelengths and close detector distances $q_z$ is substantial. Less so for q=0.05/Å, λ=6Å:

qx=0.04999 qz=0.00119 q=0.05000
butlerpd commented 2 months ago

NOTE that this requires that the sasdata object provides the qz. To date I think only the NIST 2D data format does that, but I'm not sure that the Data2D object actually picks that up either. A first step would be for sasdata to record qz in the data object if the date files provides it. This is of particular interest to the magnetic scattering community.