Skip to content

Commit a6812db

Browse files
committed
Make empty can subtraction optional
1 parent 31d7336 commit a6812db

File tree

3 files changed

+115
-6
lines changed

3 files changed

+115
-6
lines changed

docs/user-guide/dream/dream-powder-reduction.ipynb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,10 @@
9494
"workflow[DspacingBins] = sc.linspace(\"dspacing\", 0.3, 2.3434, 201, unit=\"angstrom\")\n",
9595
"\n",
9696
"# Do not mask any pixels / voxels:\n",
97-
"workflow = powder.with_pixel_mask_filenames(workflow, [])"
97+
"workflow = powder.with_pixel_mask_filenames(workflow, [])\n",
98+
"\n",
99+
"# Enable subtraction by an empty can measurement:\n",
100+
"powder.correction.add_empty_can_subtraction(workflow)"
98101
]
99102
},
100103
{

src/ess/powder/correction.py

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,49 @@ def _normalize_by_vanadium(
157157
return normed
158158

159159

160-
def normalize_by_vanadium_dspacing(
160+
def normalize_by_vanadium_dspacing_removed_empty_can(
161161
data: BackgroundSubtractedData[SampleRun],
162162
vanadium: FocussedDataDspacing[VanadiumRun],
163163
uncertainty_broadcast_mode: UncertaintyBroadcastMode,
164164
) -> IofDspacing:
165165
"""
166-
Normalize sample data by a vanadium measurement and return intensity vs d-spacing.
166+
Normalize sample data by a vanadium measurement and return intensity vs. d-spacing.
167+
168+
Parameters
169+
----------
170+
data:
171+
Sample data where events from an empty can / empty instrument measurement
172+
have been subtracted.
173+
vanadium:
174+
Vanadium data.
175+
uncertainty_broadcast_mode:
176+
Choose how uncertainties of vanadium are broadcast to the sample data.
177+
Defaults to ``UncertaintyBroadcastMode.fail``.
178+
179+
Returns
180+
-------
181+
:
182+
``data / vanadium``.
183+
May contain a mask "zero_vanadium" which is ``True``
184+
for bins where vanadium is zero.
185+
186+
See also
187+
--------
188+
normalize_by_vanadium_dspacing:
189+
The same function but using data where no empty can has been subtracted.
190+
"""
191+
return IofDspacing(
192+
_normalize_by_vanadium(data, vanadium, uncertainty_broadcast_mode)
193+
)
194+
195+
196+
def normalize_by_vanadium_dspacing(
197+
data: FocussedDataDspacing[SampleRun],
198+
vanadium: FocussedDataDspacing[VanadiumRun],
199+
uncertainty_broadcast_mode: UncertaintyBroadcastMode,
200+
) -> IofDspacing:
201+
"""
202+
Normalize sample data by a vanadium measurement and return intensity vs. d-spacing.
167203
168204
Parameters
169205
----------
@@ -181,19 +217,62 @@ def normalize_by_vanadium_dspacing(
181217
``data / vanadium``.
182218
May contain a mask "zero_vanadium" which is ``True``
183219
for bins where vanadium is zero.
220+
221+
See also
222+
--------
223+
normalize_by_vanadium_dspacing_removed_empty_can:
224+
The same function but using data where events from an empty can /
225+
empty instrument measurement have been subtracted.
184226
"""
185227
return IofDspacing(
186228
_normalize_by_vanadium(data, vanadium, uncertainty_broadcast_mode)
187229
)
188230

189231

190-
def normalize_by_vanadium_dspacing_and_two_theta(
232+
def normalize_by_vanadium_dspacing_and_two_theta_removed_empty_can(
191233
data: BackgroundSubtractedDataTwoTheta[SampleRun],
192234
vanadium: FocussedDataDspacingTwoTheta[VanadiumRun],
193235
uncertainty_broadcast_mode: UncertaintyBroadcastMode,
194236
) -> IofDspacingTwoTheta:
195237
"""
196-
Normalize sample data by a vanadium measurement and return intensity vs
238+
Normalize sample data by a vanadium measurement and return intensity vs.
239+
(d-spacing, 2theta).
240+
241+
Parameters
242+
----------
243+
data:
244+
Sample data where events from an empty can / empty instrument measurement
245+
have been subtracted.
246+
vanadium:
247+
Vanadium data.
248+
uncertainty_broadcast_mode:
249+
Choose how uncertainties of vanadium are broadcast to the sample data.
250+
Defaults to ``UncertaintyBroadcastMode.fail``.
251+
252+
Returns
253+
-------
254+
:
255+
``data / vanadium``.
256+
May contain a mask "zero_vanadium" which is ``True``
257+
for bins where vanadium is zero.
258+
259+
See also
260+
--------
261+
normalize_by_vanadium_dspacing_and_two_theta:
262+
The same function but using data where no empty can has been subtracted.
263+
"""
264+
return IofDspacingTwoTheta(
265+
_normalize_by_vanadium(data, vanadium, uncertainty_broadcast_mode)
266+
)
267+
268+
269+
def normalize_by_vanadium_dspacing_and_two_theta(
270+
data: FocussedDataDspacingTwoTheta[SampleRun],
271+
vanadium: FocussedDataDspacingTwoTheta[VanadiumRun],
272+
uncertainty_broadcast_mode: UncertaintyBroadcastMode,
273+
) -> IofDspacingTwoTheta:
274+
"""
275+
Normalize sample data by a vanadium measurement and return intensity vs.
197276
(d-spacing, 2theta).
198277
199278
Parameters
@@ -212,6 +291,12 @@ def normalize_by_vanadium_dspacing_and_two_theta(
212291
``data / vanadium``.
213292
May contain a mask "zero_vanadium" which is ``True``
214293
for bins where vanadium is zero.
294+
295+
See also
296+
--------
297+
normalize_by_vanadium_dspacing_and_two_theta_removed_empty_can:
298+
The same function but using data where events from an empty can /
299+
empty instrument measurement have been subtracted.
215300
"""
216301
return IofDspacingTwoTheta(
217302
_normalize_by_vanadium(data, vanadium, uncertainty_broadcast_mode)
@@ -375,6 +460,12 @@ def insert_run_normalization(
375460
workflow.insert(normalize_by_proton_charge)
376461

377462

463+
def add_empty_can_subtraction(workflow: sciline.Pipeline) -> None:
464+
"""Insert providers to subtract empty can events from sample data."""
465+
workflow.insert(normalize_by_vanadium_dspacing_removed_empty_can)
466+
workflow.insert(normalize_by_vanadium_dspacing_and_two_theta_removed_empty_can)
467+
468+
378469
providers = (
379470
subtract_background,
380471
subtract_background_two_theta,

tests/dream/geant4_reduction_test.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,16 @@ def params_for_det(request):
101101

102102

103103
@pytest.fixture
104-
def workflow(params_for_det):
104+
def workflow_no_empy_can(params_for_det):
105105
return make_workflow(params_for_det, run_norm=powder.RunNormalization.proton_charge)
106106

107107

108+
@pytest.fixture
109+
def workflow(workflow_no_empy_can):
110+
powder.correction.add_empty_can_subtraction(workflow_no_empy_can)
111+
return workflow_no_empy_can
112+
113+
108114
def make_workflow(params_for_det, *, run_norm):
109115
wf = dream.DreamGeant4Workflow(run_norm=run_norm)
110116
for key, value in params_for_det.items():
@@ -119,6 +125,15 @@ def test_pipeline_can_compute_dspacing_result(workflow):
119125
assert sc.identical(result.coords['dspacing'], params[DspacingBins])
120126

121127

128+
def test_pipeline_can_compute_dspacing_result_without_empty_can(workflow_no_empy_can):
129+
workflow_no_empy_can[Filename[BackgroundRun]] = None
130+
workflow_no_empy_can[MonitorFilename[BackgroundRun]] = None
131+
workflow_no_empy_can = powder.with_pixel_mask_filenames(workflow_no_empy_can, [])
132+
result = workflow_no_empy_can.compute(IofDspacing)
133+
assert result.sizes == {'dspacing': len(params[DspacingBins]) - 1}
134+
assert sc.identical(result.coords['dspacing'], params[DspacingBins])
135+
136+
122137
def test_pipeline_can_compute_dspacing_result_using_lookup_table_filename(workflow):
123138
workflow = powder.with_pixel_mask_filenames(workflow, [])
124139
workflow[TimeOfFlightLookupTableFilename] = dream.data.tof_lookup_table_high_flux()

0 commit comments

Comments
 (0)