Skip to content

Commit 5f4802f

Browse files
committed
Add wavevector_from_wavelength
1 parent e3beb27 commit 5f4802f

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/scippneutron/conversion/tof.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,37 @@ def wavelength_from_energy(*, energy: Variable) -> Variable:
312312
return sc.sqrt(c / energy)
313313

314314

315+
def wavevector_from_wavelength(*, wavelength: Variable, beam: Variable) -> Variable:
316+
r"""Compute a wavevector from a wavelength.
317+
318+
The result is
319+
320+
.. math::
321+
322+
Q = 2 \pi \frac{\hat{b}}{\lambda}
323+
324+
where :math:`\hat{b}` is the normalized beam vector.
325+
326+
Parameters
327+
----------
328+
wavelength:
329+
De Broglie wavelength :math:`\lambda`.
330+
beam:
331+
The direction the neutron travels :math:`\vec{b}`.
332+
It does not have to be normalized.
333+
334+
Returns
335+
-------
336+
:
337+
Wavevector :math:`k`.
338+
Has unit 1/ångström.
339+
"""
340+
c = sc.scalar(2 * np.pi).to(
341+
unit=elem_unit(wavelength) / sc.units.angstrom,
342+
)
343+
return c * (beam / sc.norm(beam)) / wavelength
344+
345+
315346
def _wavelength_Q_conversions(x: Variable, two_theta: Variable) -> Variable:
316347
"""Convert either from Q to wavelength or vice-versa."""
317348
c = as_float_type(4 * const.pi, x)

tests/conversion/tof_conversions_test.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# SPDX-License-Identifier: BSD-3-Clause
2-
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
3-
# @author Jan-Lukas Wynen
2+
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
43

54
import numpy as np
65
import pytest
@@ -69,6 +68,13 @@ def time_variables():
6968
)
7069

7170

71+
def wavelength_variables():
72+
return simple_variables(
73+
dims=st.sampled_from(('wavelength', 'lambda', 'tof')),
74+
unit=st.sampled_from(('angstrom', 'mÅ', 'nm')),
75+
)
76+
77+
7278
def space_variables():
7379
return simple_variables(
7480
dims=st.sampled_from(('position', 'spectrum', 'x')),
@@ -146,6 +152,17 @@ def test_wavelength_from_tof_single_precision(Ltotal_dtype):
146152
assert tof_conv.wavelength_from_tof(tof=tof, Ltotal=Ltotal).dtype == 'float32'
147153

148154

155+
@given(wavelength=wavelength_variables(), beam=vector_variables())
156+
@settings(**global_settings)
157+
def test_wavevector_from_wavelength(wavelength: sc.Variable, beam: sc.Variable) -> None:
158+
wavevector = tof_conv.wavevector_from_wavelength(wavelength=wavelength, beam=beam)
159+
naive = sc.to_unit(
160+
2 * np.pi * beam / sc.norm(beam) / wavelength,
161+
'1/angstrom',
162+
)
163+
sc.testing.assert_allclose(wavevector, naive)
164+
165+
149166
@given(
150167
tof=time_variables(),
151168
Ltotal_and_two_theta=n_space_variables(2),

0 commit comments

Comments
 (0)