Skip to content

Commit 8d08727

Browse files
committed
feat: compute angle without divergence angle per pixel
1 parent 8cb0649 commit 8d08727

File tree

1 file changed

+53
-32
lines changed

1 file changed

+53
-32
lines changed

src/ess/estia/conversions.py

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,31 @@
55
from ..reflectometry.conversions import reflectometry_q
66
from ..reflectometry.types import (
77
BeamDivergenceLimits,
8-
BeamSize,
9-
RawDetectorData,
10-
ReducibleData,
11-
RunType,
8+
CoordTransformationGraph,
129
WavelengthBins,
1310
YIndexLimits,
1411
ZIndexLimits,
1512
)
1613

1714

18-
def theta(divergence_angle, sample_rotation, detector_rotation):
15+
def theta(detector_position_relative_sample, sample_rotation):
1916
'''
2017
Angle of reflection.
2118
2219
Computes the angle between the scattering direction of
2320
the neutron and the sample surface.
21+
22+
Assumes that the sample is oriented almost parallel to yz plane
23+
but rotated around the y-axis by :code:`sample_rotation`.
2424
'''
25-
return divergence_angle + detector_rotation - sample_rotation
25+
p = detector_position_relative_sample
26+
# Normal of yz plane.
27+
n = sc.vector([1.0, 0, 0], unit='dimensionless')
28+
np = sc.norm(p)
29+
pp = p - sc.dot(p, n) * n
30+
npp = sc.norm(pp)
31+
angle_to_zy_plane = sc.acos(sc.dot(p, pp) / (np * npp))
32+
return angle_to_zy_plane - sample_rotation.to(unit='rad')
2633

2734

2835
def angle_of_divergence(
@@ -35,12 +42,7 @@ def angle_of_divergence(
3542
This is always in the interval [-0.75 deg, 0.75 deg],
3643
but the divergence of the incident beam can also be reduced.
3744
"""
38-
return (
39-
theta
40-
- sample_rotation
41-
- angle_to_center_of_beam
42-
- natural_incidence_angle.to(unit='rad')
43-
)
45+
return theta - sample_rotation - angle_to_center_of_beam.to(unit='rad')
4446

4547

4648
def wavelength(
@@ -52,31 +54,52 @@ def wavelength(
5254
pass
5355

5456

57+
def coordinate_transformation_graph() -> CoordTransformationGraph:
58+
return {
59+
"detector_position_relative_sample": (
60+
lambda detector, sample: detector.position - sample.position
61+
),
62+
"wavelength": wavelength,
63+
"theta": theta,
64+
"angle_of_divergence": angle_of_divergence,
65+
"Q": reflectometry_q,
66+
"L1": lambda source, sample: sample.position - source.position,
67+
"L2": lambda detector_position_relative_sample: sc.norm(
68+
detector_position_relative_sample
69+
),
70+
}
71+
72+
73+
def add_coords(
74+
da: sc.DataArray,
75+
graph: dict,
76+
) -> sc.DataArray:
77+
"Adds scattering coordinates to the raw detector data."
78+
return da.transform_coords(
79+
("wavelength", "theta", "angle_of_divergence", "Q", "L1", "L2"),
80+
graph,
81+
rename_dims=False,
82+
keep_intermediate=False,
83+
keep_aliases=False,
84+
)
85+
86+
5587
def _not_between(v, a, b):
5688
return (v < a) | (v > b)
5789

5890

59-
def add_common_coords_and_masks(
60-
da: RawDetectorData[RunType],
91+
def add_masks(
92+
da: sc.DataArray,
6193
ylim: YIndexLimits,
6294
zlims: ZIndexLimits,
6395
bdlim: BeamDivergenceLimits,
6496
wbins: WavelengthBins,
65-
beam_size: BeamSize[RunType],
66-
) -> ReducibleData[RunType]:
67-
"Adds coords and masks that are useful for both reference and sample measurements."
68-
da = da.transform_coords(
69-
("wavelength", "theta", "angle_of_divergence", "Q"),
70-
{
71-
"divergence_angle": "pixel_divergence_angle",
72-
"wavelength": wavelength,
73-
"theta": theta,
74-
"angle_of_divergence": angle_of_divergence,
75-
"Q": reflectometry_q,
76-
},
77-
rename_dims=False,
78-
keep_intermediate=False,
79-
)
97+
):
98+
"""
99+
Masks the data by ranges in the detector
100+
coordinates ``z`` and ``y``, and by the divergence of the beam,
101+
and by wavelength.
102+
"""
80103
da.masks["stripe_range"] = _not_between(da.coords["stripe"], *ylim)
81104
da.masks['z_range'] = _not_between(da.coords["z_index"], *zlims)
82105
da.bins.masks["divergence_too_large"] = _not_between(
@@ -89,9 +112,7 @@ def add_common_coords_and_masks(
89112
wbins[0],
90113
wbins[-1],
91114
)
92-
# Correct for illumination of virtual source
93-
da /= sc.sin(da.bins.coords['theta'])
94115
return da
95116

96117

97-
providers = (add_common_coords_and_masks,)
118+
providers = (coordinate_transformation_graph,)

0 commit comments

Comments
 (0)