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
54import numpy as np
65import 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+
7278def 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 ),
@@ -310,35 +327,39 @@ def test_wavelength_from_energy_single_precision():
310327
311328@given (wavelength = space_variables (), two_theta = angle_variables ())
312329@settings (** global_settings )
313- def test_Q_from_wavelength (wavelength , two_theta ):
314- Q = tof_conv .Q_from_wavelength (wavelength = wavelength , two_theta = two_theta )
330+ def test_elastic_Q_from_wavelength (wavelength , two_theta ):
331+ Q = tof_conv .elastic_Q_from_wavelength (wavelength = wavelength , two_theta = two_theta )
315332 assert sc .allclose (Q , 4 * np .pi * sc .sin (two_theta / 2 ) / wavelength )
316333
317334
318335@pytest .mark .parametrize ('wavelength_dtype' , ['float64' , 'int64' ])
319336@pytest .mark .parametrize ('two_theta_dtype' , ['float64' , 'float32' , 'int64' ])
320- def test_Q_from_wavelength_double_precision (wavelength_dtype , two_theta_dtype ):
337+ def test_elastic_Q_from_wavelength_double_precision (wavelength_dtype , two_theta_dtype ):
321338 wavelength = sc .scalar (3.51 , unit = 's' , dtype = wavelength_dtype )
322339 two_theta = sc .scalar (0.041 , unit = 'deg' , dtype = two_theta_dtype )
323340 assert (
324- tof_conv .Q_from_wavelength (wavelength = wavelength , two_theta = two_theta ).dtype
341+ tof_conv .elastic_Q_from_wavelength (
342+ wavelength = wavelength , two_theta = two_theta
343+ ).dtype
325344 == 'float64'
326345 )
327346
328347
329348@pytest .mark .parametrize ('two_theta_dtype' , ['float64' , 'float32' , 'int64' ])
330- def test_Q_from_wavelength_single_precision (two_theta_dtype ):
349+ def test_elastic_Q_from_wavelength_single_precision (two_theta_dtype ):
331350 wavelength = sc .scalar (3.51 , unit = 's' , dtype = 'float32' )
332351 two_theta = sc .scalar (0.041 , unit = 'deg' , dtype = two_theta_dtype )
333352 assert (
334- tof_conv .Q_from_wavelength (wavelength = wavelength , two_theta = two_theta ).dtype
353+ tof_conv .elastic_Q_from_wavelength (
354+ wavelength = wavelength , two_theta = two_theta
355+ ).dtype
335356 == 'float32'
336357 )
337358
338359
339360@given (Q = space_variables (), two_theta = angle_variables ())
340361@settings (** global_settings )
341- def test_wavelength_from_Q (Q , two_theta ):
362+ def test_wavelength_from_elastic_Q (Q , two_theta ):
342363 Q .unit = f'1/{ Q .unit } '
343364 wavelength = tof_conv .wavelength_from_Q (Q = Q , two_theta = two_theta )
344365 assert sc .allclose (
@@ -348,24 +369,24 @@ def test_wavelength_from_Q(Q, two_theta):
348369
349370@pytest .mark .parametrize ('Q_dtype' , ['float64' , 'int64' ])
350371@pytest .mark .parametrize ('two_theta_dtype' , ['float64' , 'float32' , 'int64' ])
351- def test_wavelength_from_Q_double_precision (Q_dtype , two_theta_dtype ):
372+ def test_wavelength_from_elastic_Q_double_precision (Q_dtype , two_theta_dtype ):
352373 Q = sc .scalar (4.151 , unit = '1/nm' , dtype = Q_dtype )
353374 two_theta = sc .scalar (5.71 , unit = 'deg' , dtype = two_theta_dtype )
354375 assert tof_conv .wavelength_from_Q (Q = Q , two_theta = two_theta ).dtype == 'float64'
355376
356377
357378@pytest .mark .parametrize ('two_theta_dtype' , ['float64' , 'float32' , 'int64' ])
358- def test_wavelength_from_Q_single_precision (two_theta_dtype ):
379+ def test_wavelength_from_elastic_Q_single_precision (two_theta_dtype ):
359380 Q = sc .scalar (4.151 , unit = '1/nm' , dtype = 'float32' )
360381 two_theta = sc .scalar (5.71 , unit = 'deg' , dtype = two_theta_dtype )
361382 assert tof_conv .wavelength_from_Q (Q = Q , two_theta = two_theta ).dtype == 'float32'
362383
363384
364385@given (incident_beam = vector_variables (), wavelength = space_variables ())
365386@settings (** global_settings )
366- def test_Q_elements_from_wavelength_equal_beams (incident_beam , wavelength ):
387+ def test_elastic_Q_elements_from_wavelength_equal_beams (incident_beam , wavelength ):
367388 scattered_beam = incident_beam .copy ()
368- Q_elements = tof_conv .Q_elements_from_wavelength (
389+ Q_elements = tof_conv .elastic_Q_elements_from_wavelength (
369390 wavelength = wavelength ,
370391 incident_beam = incident_beam ,
371392 scattered_beam = scattered_beam ,
@@ -382,18 +403,18 @@ def test_Q_elements_from_wavelength_equal_beams(incident_beam, wavelength):
382403 wavelength = space_variables (),
383404)
384405@settings (** global_settings )
385- def test_Q_elements_from_wavelength_consistent_with_Q (
406+ def test_elastic_Q_elements_from_wavelength_consistent_with_Q (
386407 incident_beam , scattered_beam , wavelength
387408):
388409 wavelength = wavelength .rename ({wavelength .dim : 'wavelength' })
389- Q_elements = tof_conv .Q_elements_from_wavelength (
410+ Q_elements = tof_conv .elastic_Q_elements_from_wavelength (
390411 wavelength = wavelength ,
391412 incident_beam = incident_beam ,
392413 scattered_beam = scattered_beam ,
393414 )
394415 Qx , Qy , Qz = Q_elements ['Qx' ], Q_elements ['Qy' ], Q_elements ['Qz' ]
395416 Q_vec = sc .spatial .as_vectors (Qx , Qy , Qz )
396- Q = tof_conv .Q_from_wavelength (
417+ Q = tof_conv .elastic_Q_from_wavelength (
397418 wavelength = wavelength ,
398419 two_theta = beamline_conv .two_theta (
399420 incident_beam = incident_beam , scattered_beam = scattered_beam
@@ -402,15 +423,15 @@ def test_Q_elements_from_wavelength_consistent_with_Q(
402423 assert sc .allclose (sc .norm (Q_vec ), Q )
403424
404425
405- def test_Q_elements_from_wavelength ():
426+ def test_elastic_Q_elements_from_wavelength ():
406427 incident_beam = sc .vector ([0.0 , 0.0 , 10.0 ], unit = 'm' )
407428 scattered_beam = sc .vectors (
408429 dims = ['pos' ],
409430 values = [[1.0 , 0.0 , 0.0 ], [0.0 , 1.0 , 0.0 ], [0.0 , 1.0 , 2.0 ]],
410431 unit = 'cm' ,
411432 )
412433 wavelength = sc .array (dims = ['wavelength' ], values = [0.3 , 2.0 ], unit = 'angstrom' )
413- Q_elements = tof_conv .Q_elements_from_wavelength (
434+ Q_elements = tof_conv .elastic_Q_elements_from_wavelength (
414435 wavelength = wavelength ,
415436 incident_beam = incident_beam ,
416437 scattered_beam = scattered_beam ,
@@ -502,41 +523,41 @@ def test_dspacing_from_energy_single_precision(two_theta_dtype):
502523 )
503524
504525
505- def test_q_vec_from_q_elements ():
526+ def test_elastic_q_vec_from_q_elements ():
506527 Qx , Qy , Qz = (
507528 sc .array (dims = ['Q' ], values = [2.1 * i , i / 3 ], unit = '1/angstrom' )
508529 for i in range (3 )
509530 )
510- q_vec = tof_conv .Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
531+ q_vec = tof_conv .elastic_Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
511532 sc .testing .assert_identical (q_vec .fields .x , Qx )
512533 sc .testing .assert_identical (q_vec .fields .y , Qy )
513534 sc .testing .assert_identical (q_vec .fields .z , Qz )
514535
515536
516- def test_q_vec_from_q_elements_raises_for_shape_mismatch ():
537+ def test_elastic_q_vec_from_q_elements_raises_for_shape_mismatch ():
517538 Qx = sc .array (dims = ['q' ], values = [2.0 , 3.0 ])
518539 Qy = Qx .copy ()
519540 Qz = sc .array (dims = ['q' ], values = [2.0 , 3.0 , 4.0 ])
520541 with pytest .raises (sc .DimensionError ):
521- tof_conv .Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
542+ tof_conv .elastic_Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
522543
523544
524- def test_q_vec_from_q_elements_raises_for_dim_mismatch ():
545+ def test_elastic_q_vec_from_q_elements_raises_for_dim_mismatch ():
525546 Qx = sc .array (dims = ['q' ], values = [2.0 , 3.0 ])
526547 Qy = Qx .copy ()
527548 Qz = sc .array (dims = ['Q' ], values = [2.0 , 3.0 ])
528549 with pytest .raises (sc .DimensionError ):
529- tof_conv .Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
550+ tof_conv .elastic_Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
530551
531552
532- def test_q_vec_from_q_elements_raises_for_unit_mismatch ():
553+ def test_elastic_q_vec_from_q_elements_raises_for_unit_mismatch ():
533554 Qx , Qy , Qz = (
534555 sc .array (dims = ['Q' ], values = [2.1 * i , i / 3 ], unit = '1/angstrom' )
535556 for i in range (3 )
536557 )
537558 Qy .unit = '1/m'
538559 with pytest .raises (sc .UnitError ):
539- tof_conv .Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
560+ tof_conv .elastic_Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
540561
541562
542563def make_b_matrix () -> sc .Variable :
@@ -576,9 +597,9 @@ def test_ub_matrix_from_u_and_b():
576597
577598
578599@given (inv_q = n_space_variables (3 ))
579- def test_hkl_vec_from_Q_vec (inv_q ):
600+ def test_hkl_vec_from_elastic_Q_vec (inv_q ):
580601 Qx , Qy , Qz = (sc .reciprocal (x .to (dtype = 'float64' )) for x in inv_q )
581- Q_vec = tof_conv .Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
602+ Q_vec = tof_conv .elastic_Q_vec_from_Q_elements (Qx = Qx , Qy = Qy , Qz = Qz )
582603
583604 b_matrix = make_b_matrix ()
584605 u_coeffs = np .array ([0.5 , 0.1 , - 0.4 , 0.9 ])
@@ -590,7 +611,7 @@ def test_hkl_vec_from_Q_vec(inv_q):
590611 value = sample_rotation_coeffs / np .linalg .norm (sample_rotation_coeffs )
591612 )
592613
593- hkl_vec = tof_conv .hkl_vec_from_Q_vec (
614+ hkl_vec = tof_conv .hkl_vec_from_elastic_Q_vec (
594615 Q_vec = Q_vec , ub_matrix = ub_matrix , sample_rotation = sample_rotation_matrix
595616 )
596617
0 commit comments