5
5
from ..reflectometry .conversions import reflectometry_q
6
6
from ..reflectometry .types import (
7
7
BeamDivergenceLimits ,
8
- BeamSize ,
9
- RawDetectorData ,
10
- ReducibleData ,
11
- RunType ,
8
+ CoordTransformationGraph ,
12
9
WavelengthBins ,
13
10
YIndexLimits ,
14
11
ZIndexLimits ,
15
12
)
16
13
17
14
18
- def theta (divergence_angle , sample_rotation , detector_rotation ):
15
+ def theta (detector_position_relative_sample , sample_rotation ):
19
16
'''
20
17
Angle of reflection.
21
18
22
19
Computes the angle between the scattering direction of
23
20
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`.
24
24
'''
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' )
26
33
27
34
28
35
def angle_of_divergence (
@@ -35,12 +42,7 @@ def angle_of_divergence(
35
42
This is always in the interval [-0.75 deg, 0.75 deg],
36
43
but the divergence of the incident beam can also be reduced.
37
44
"""
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' )
44
46
45
47
46
48
def wavelength (
@@ -52,31 +54,52 @@ def wavelength(
52
54
pass
53
55
54
56
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
+
55
87
def _not_between (v , a , b ):
56
88
return (v < a ) | (v > b )
57
89
58
90
59
- def add_common_coords_and_masks (
60
- da : RawDetectorData [ RunType ] ,
91
+ def add_masks (
92
+ da : sc . DataArray ,
61
93
ylim : YIndexLimits ,
62
94
zlims : ZIndexLimits ,
63
95
bdlim : BeamDivergenceLimits ,
64
96
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
+ """
80
103
da .masks ["stripe_range" ] = _not_between (da .coords ["stripe" ], * ylim )
81
104
da .masks ['z_range' ] = _not_between (da .coords ["z_index" ], * zlims )
82
105
da .bins .masks ["divergence_too_large" ] = _not_between (
@@ -89,9 +112,7 @@ def add_common_coords_and_masks(
89
112
wbins [0 ],
90
113
wbins [- 1 ],
91
114
)
92
- # Correct for illumination of virtual source
93
- da /= sc .sin (da .bins .coords ['theta' ])
94
115
return da
95
116
96
117
97
- providers = (add_common_coords_and_masks ,)
118
+ providers = (coordinate_transformation_graph ,)
0 commit comments