# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
import scipp as sc
from scippneutron.conversion.tof import wavelength_from_tof
from scippnexus import NXsample, NXsource
from ess.reduce.nexus.types import DetectorBankSizes, Position
from ..reflectometry.conversions import reflectometry_q
from ..reflectometry.types import (
CoordTransformationGraph,
DetectorRotation,
RunType,
SampleRotation,
)
[docs]
def theta(
divergence_angle: sc.Variable,
sample_rotation: sc.Variable,
):
'''
Angle of reflection.
Computes the angle between the scattering direction of
the neutron and the sample surface.
Parameters
------------
divergence_angle:
Divergence angle of the scattered beam.
sample_rotation:
Rotation of the sample from to its zero position.
Returns
-----------
The reflection angle of the neutron.
'''
return divergence_angle + sample_rotation.to(unit=divergence_angle.unit)
[docs]
def divergence_angle(
position: sc.Variable,
sample_position: sc.Variable,
detector_rotation: sc.Variable,
):
"""
Angle between the scattering ray and
the ray that travels parallel to the sample surface
when the sample rotation is zero.
Parameters
------------
position:
Detector position where the neutron was detected.
sample_position:
Position of the sample.
detector_rotation:
Rotation of the detector from its zero position.
Returns
----------
The divergence angle of the scattered beam.
"""
p = position - sample_position.to(unit=position.unit)
return sc.atan2(y=p.fields.x, x=p.fields.z) - detector_rotation.to(unit='rad')
[docs]
def add_coords(
da: sc.DataArray,
graph: dict,
) -> sc.DataArray:
"Adds scattering coordinates to the raw detector data."
return da.transform_coords(
(
"wavelength",
"theta",
"divergence_angle",
"Q",
"L1",
"L2",
"blade",
"wire",
"strip",
"z_index",
"sample_rotation",
"detector_rotation",
"sample_size",
),
graph,
rename_dims=False,
keep_intermediate=False,
keep_aliases=False,
)
providers = (coordinate_transformation_graph,)