|
3 | 3 | """Correction algorithms for powder diffraction.""" |
4 | 4 |
|
5 | 5 | import enum |
| 6 | +from collections.abc import Mapping, Sequence |
6 | 7 | from typing import TypeVar |
7 | 8 |
|
8 | 9 | import sciline |
|
31 | 32 | WavelengthMonitor, |
32 | 33 | ) |
33 | 34 |
|
| 35 | +_T = TypeVar("_T") |
| 36 | + |
34 | 37 |
|
35 | 38 | def normalize_by_monitor_histogram( |
36 | 39 | detector: CorrectedDspacing[RunType], |
@@ -146,15 +149,32 @@ def _mask_out_of_monitor_range_data( |
146 | 149 | return detector, False |
147 | 150 |
|
148 | 151 |
|
| 152 | +def _filter_keys(mapping: Mapping[str, _T], keys: Sequence[str]) -> dict[str, _T]: |
| 153 | + return {key: value for key, value in mapping.items() if key in keys} |
| 154 | + |
| 155 | + |
| 156 | +def _histogram_vanadium(vanadium: sc.DataArray, sample: sc.DataArray) -> sc.DataArray: |
| 157 | + target_coords = _filter_keys(sample.coords, ("dspacing", "two_theta")) |
| 158 | + if "two_theta" in target_coords and "two_theta" not in vanadium.bins.coords: |
| 159 | + # Need to provide a two_theta event coord so we can histogram. |
| 160 | + if sc.identical(vanadium.coords["two_theta"], target_coords["two_theta"]): |
| 161 | + # Skip the expensive event coord if possible: |
| 162 | + return vanadium.hist(dspacing=sample.coords["dspacing"]) |
| 163 | + return vanadium.bins.assign_coords( |
| 164 | + two_theta=sc.bins_like(vanadium, vanadium.coords["two_theta"]) |
| 165 | + ).hist(target_coords) |
| 166 | + return vanadium.hist(target_coords) |
| 167 | + |
| 168 | + |
149 | 169 | def _normalize_by_vanadium( |
150 | 170 | data: sc.DataArray, |
151 | 171 | vanadium: sc.DataArray, |
152 | 172 | uncertainty_broadcast_mode: UncertaintyBroadcastMode, |
153 | 173 | ) -> sc.DataArray: |
154 | 174 | norm = ( |
155 | | - vanadium.hist(data.coords) |
| 175 | + _histogram_vanadium(vanadium, sample=data) |
156 | 176 | if vanadium.is_binned |
157 | | - else vanadium.rebin(data.coords) |
| 177 | + else vanadium.rebin(_filter_keys(data.coords, ("dspacing", "two_theta"))) |
158 | 178 | ) |
159 | 179 | norm = broadcast_uncertainties( |
160 | 180 | norm, prototype=data, mode=uncertainty_broadcast_mode |
|
0 commit comments