Skip to content

Commit 9cbe154

Browse files
authored
Merge pull request #185 from scipp/reorganise-workflows
Reorganise Dream reduction workflows
2 parents eb2e4c7 + b382238 commit 9cbe154

File tree

8 files changed

+140
-169
lines changed

8 files changed

+140
-169
lines changed

src/ess/dream/__init__.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@
99

1010
from .beamline import InstrumentConfiguration
1111
from .instrument_view import instrument_view
12-
from .io import load_geant4_csv, nexus
13-
from .workflow import DreamGeant4Workflow, default_parameters
12+
from .io import load_geant4_csv
13+
from .workflows import (
14+
DreamGeant4MonitorHistogramWorkflow,
15+
DreamGeant4MonitorIntegratedWorkflow,
16+
DreamGeant4ProtonChargeWorkflow,
17+
DreamGeant4Workflow,
18+
DreamPowderWorkflow,
19+
DreamWorkflow,
20+
)
1421

1522
try:
1623
__version__ = importlib.metadata.version("essdiffraction")
@@ -20,11 +27,14 @@
2027
del importlib
2128

2229
__all__ = [
30+
'DreamGeant4MonitorHistogramWorkflow',
31+
'DreamGeant4MonitorIntegratedWorkflow',
32+
'DreamGeant4ProtonChargeWorkflow',
2333
'DreamGeant4Workflow',
34+
'DreamPowderWorkflow',
35+
'DreamWorkflow',
2436
'InstrumentConfiguration',
2537
'__version__',
26-
'default_parameters',
2738
'instrument_view',
2839
'load_geant4_csv',
29-
'nexus',
3040
]

src/ess/dream/io/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33

44
"""Input/output for DREAM."""
55

6-
from . import nexus
76
from .cif import prepare_reduced_tof_cif
87
from .geant4 import load_geant4_csv
98

109
providers = (prepare_reduced_tof_cif,)
1110

12-
__all__ = ["load_geant4_csv", "nexus", "prepare_reduced_tof_cif", "providers"]
11+
__all__ = ["load_geant4_csv", "prepare_reduced_tof_cif", "providers"]

src/ess/dream/io/geant4.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
CaveMonitor,
1818
CaveMonitorPosition,
1919
DetectorData,
20-
EmptyCanRun,
2120
Filename,
2221
MonitorData,
2322
MonitorFilename,
@@ -26,11 +25,8 @@
2625
NeXusDetectorName,
2726
Position,
2827
RunType,
29-
SampleRun,
3028
Source,
31-
VanadiumRun,
3229
)
33-
from ess.reduce.time_of_flight.workflow import GenericTofWorkflow
3430

3531
MANTLE_DETECTOR_ID = sc.index(7)
3632
HIGH_RES_DETECTOR_ID = sc.index(8)
@@ -316,22 +312,16 @@ def ess_source() -> Source:
316312
return ESS_SOURCE
317313

318314

319-
def LoadGeant4Workflow() -> sciline.Pipeline:
320-
"""
321-
Workflow for loading NeXus data.
322-
"""
323-
wf = GenericTofWorkflow(
324-
run_types=[SampleRun, VanadiumRun, EmptyCanRun], monitor_types=[CaveMonitor]
325-
)
326-
wf.insert(extract_geant4_detector)
327-
wf.insert(load_geant4_csv)
328-
wf.insert(load_mcstas_monitor)
329-
wf.insert(geant4_load_calibration)
330-
wf.insert(get_calibrated_geant4_detector)
331-
wf.insert(assemble_detector_data)
332-
wf.insert(assemble_monitor_data)
333-
wf.insert(dummy_source_position)
334-
wf.insert(dummy_sample_position)
335-
wf.insert(dream_beamline)
336-
wf.insert(ess_source)
337-
return wf
315+
providers = (
316+
load_geant4_csv,
317+
extract_geant4_detector,
318+
get_calibrated_geant4_detector,
319+
assemble_detector_data,
320+
assemble_monitor_data,
321+
load_mcstas_monitor,
322+
geant4_load_calibration,
323+
dummy_source_position,
324+
dummy_sample_position,
325+
dream_beamline,
326+
ess_source,
327+
)

src/ess/dream/io/nexus.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

src/ess/dream/workflow.py renamed to src/ess/dream/workflows.py

Lines changed: 93 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# SPDX-License-Identifier: BSD-3-Clause
2-
# Copyright (c) 2024 Scipp contributors (https://github.com/scipp)
3-
4-
from __future__ import annotations
2+
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
53

64
import itertools
75

@@ -12,12 +10,10 @@
1210

1311
from ess.powder import providers as powder_providers
1412
from ess.powder import with_pixel_mask_filenames
15-
from ess.powder.correction import (
16-
RunNormalization,
17-
insert_run_normalization,
18-
)
13+
from ess.powder.correction import RunNormalization, insert_run_normalization
1914
from ess.powder.types import (
2015
AccumulatedProtonCharge,
16+
BunkerMonitor,
2117
CaveMonitor,
2218
CaveMonitorPosition, # Should this be a DREAM-only parameter?
2319
EmptyCanRun,
@@ -32,8 +28,7 @@
3228
VanadiumRun,
3329
WavelengthMask,
3430
)
35-
from ess.reduce import time_of_flight
36-
from ess.reduce.nexus.types import NeXusName
31+
from ess.reduce.nexus.types import DetectorBankSizes, NeXusName
3732
from ess.reduce.parameter import parameter_mappers
3833
from ess.reduce.time_of_flight import GenericTofWorkflow
3934
from ess.reduce.workflow import register_workflow
@@ -44,9 +39,35 @@
4439
prepare_reduced_empty_can_subtracted_tof_cif,
4540
prepare_reduced_tof_cif,
4641
)
47-
from .io.geant4 import LoadGeant4Workflow
42+
from .io.geant4 import providers as geant4_providers
4843
from .parameters import typical_outputs
4944

45+
DETECTOR_BANK_SIZES = {
46+
"endcap_backward_detector": {
47+
"strip": 16,
48+
"wire": 16,
49+
"module": 11,
50+
"segment": 28,
51+
"counter": 2,
52+
},
53+
"endcap_forward_detector": {
54+
"strip": 16,
55+
"wire": 16,
56+
"module": 5,
57+
"segment": 28,
58+
"counter": 2,
59+
},
60+
"mantle_detector": {
61+
"wire": 32,
62+
"module": 5,
63+
"segment": 6,
64+
"strip": 256,
65+
"counter": 2,
66+
},
67+
"high_resolution_detector": {"strip": 32, "other": -1},
68+
"sans_detector": {"strip": 32, "other": -1},
69+
}
70+
5071

5172
def _get_lookup_table_filename_from_configuration(
5273
configuration: InstrumentConfiguration,
@@ -64,52 +85,58 @@ def _get_lookup_table_filename_from_configuration(
6485
return TimeOfFlightLookupTableFilename(out)
6586

6687

67-
_dream_providers = (
88+
def _collect_reducer_software() -> ReducerSoftware:
89+
return ReducerSoftware(
90+
[
91+
Software.from_package_metadata('essdiffraction'),
92+
Software.from_package_metadata('scippneutron'),
93+
Software.from_package_metadata('scipp'),
94+
]
95+
)
96+
97+
98+
def DreamWorkflow() -> sciline.Pipeline:
99+
"""
100+
Dream generic workflow with default parameters.
101+
The workflow is based on the GenericTofWorkflow.
102+
It can load data from a NeXus file recorded on the DREAM instrument, and can
103+
compute time-of-flight for the neutron events.
104+
105+
It can be used as is, or as a base for more specific workflows, such as
106+
``DreamPowderWorkflow``.
107+
"""
108+
wf = GenericTofWorkflow(
109+
run_types=[SampleRun, VanadiumRun, EmptyCanRun],
110+
monitor_types=[BunkerMonitor, CaveMonitor],
111+
)
112+
wf[DetectorBankSizes] = DETECTOR_BANK_SIZES
113+
wf[NeXusName[BunkerMonitor]] = "monitor_bunker"
114+
wf[NeXusName[CaveMonitor]] = "monitor_cave"
115+
wf.insert(_get_lookup_table_filename_from_configuration)
116+
wf[ReducerSoftware] = _collect_reducer_software()
117+
return wf
118+
119+
120+
_cif_providers = (
68121
prepare_reduced_tof_cif,
69122
prepare_reduced_empty_can_subtracted_tof_cif,
70-
_get_lookup_table_filename_from_configuration,
71123
)
72124

73125
parameter_mappers[PixelMaskFilename] = with_pixel_mask_filenames
74126

75127

76128
def default_parameters() -> dict:
77-
# Quantities not available in the simulated data
78-
sample_position = sc.vector([0.0, 0.0, 0.0], unit="mm")
79-
source_position = sc.vector([-3.478, 0.0, -76550], unit="mm")
80-
charge = sc.scalar(1.0, unit="µAh")
81129
return {
82130
KeepEvents[SampleRun]: KeepEvents[SampleRun](True),
83131
KeepEvents[VanadiumRun]: KeepEvents[VanadiumRun](False),
84132
KeepEvents[EmptyCanRun]: KeepEvents[EmptyCanRun](True),
85-
Position[snx.NXsample, SampleRun]: sample_position,
86-
Position[snx.NXsample, VanadiumRun]: sample_position,
87-
Position[snx.NXsample, EmptyCanRun]: sample_position,
88-
Position[snx.NXsource, SampleRun]: source_position,
89-
Position[snx.NXsource, VanadiumRun]: source_position,
90-
Position[snx.NXsource, EmptyCanRun]: source_position,
91-
AccumulatedProtonCharge[SampleRun]: charge,
92-
AccumulatedProtonCharge[VanadiumRun]: charge,
93-
AccumulatedProtonCharge[EmptyCanRun]: charge,
94133
TofMask: None,
95134
WavelengthMask: None,
96135
TwoThetaMask: None,
97-
CaveMonitorPosition: sc.vector([0.0, 0.0, -4220.0], unit='mm'),
98136
CIFAuthors: CIFAuthors([]),
99-
ReducerSoftware: _collect_reducer_software(),
100137
}
101138

102139

103-
def _collect_reducer_software() -> ReducerSoftware:
104-
return ReducerSoftware(
105-
[
106-
Software.from_package_metadata('essdiffraction'),
107-
Software.from_package_metadata('scippneutron'),
108-
Software.from_package_metadata('scipp'),
109-
]
110-
)
111-
112-
113140
def DreamPowderWorkflow(*, run_norm: RunNormalization) -> sciline.Pipeline:
114141
"""
115142
Dream powder workflow with default parameters.
@@ -124,14 +151,11 @@ def DreamPowderWorkflow(*, run_norm: RunNormalization) -> sciline.Pipeline:
124151
:
125152
A workflow object for DREAM.
126153
"""
127-
wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[CaveMonitor])
128-
for provider in itertools.chain(powder_providers, _dream_providers):
154+
wf = DreamWorkflow()
155+
for provider in itertools.chain(powder_providers, _cif_providers):
129156
wf.insert(provider)
130-
wf[NeXusName[CaveMonitor]] = "monitor_cave"
131157
insert_run_normalization(wf, run_norm)
132-
for key, value in itertools.chain(
133-
default_parameters().items(), time_of_flight.default_parameters().items()
134-
):
158+
for key, value in default_parameters().items():
135159
wf[key] = value
136160
wf.typical_outputs = typical_outputs
137161
return wf
@@ -151,14 +175,33 @@ def DreamGeant4Workflow(*, run_norm: RunNormalization) -> sciline.Pipeline:
151175
:
152176
A workflow object for DREAM.
153177
"""
154-
wf = LoadGeant4Workflow()
155-
for provider in itertools.chain(powder_providers, _dream_providers):
178+
wf = DreamWorkflow()
179+
for provider in itertools.chain(geant4_providers, powder_providers, _cif_providers):
156180
wf.insert(provider)
157181
insert_run_normalization(wf, run_norm)
158-
for key, value in itertools.chain(
159-
default_parameters().items(), time_of_flight.default_parameters().items()
160-
):
182+
for key, value in default_parameters().items():
183+
wf[key] = value
184+
185+
# Quantities not available in the simulated data
186+
sample_position = sc.vector([0.0, 0.0, 0.0], unit="mm")
187+
source_position = sc.vector([-3.478, 0.0, -76550], unit="mm")
188+
charge = sc.scalar(1.0, unit="µAh")
189+
190+
additional_parameters = {
191+
Position[snx.NXsample, SampleRun]: sample_position,
192+
Position[snx.NXsample, VanadiumRun]: sample_position,
193+
Position[snx.NXsample, EmptyCanRun]: sample_position,
194+
Position[snx.NXsource, SampleRun]: source_position,
195+
Position[snx.NXsource, VanadiumRun]: source_position,
196+
Position[snx.NXsource, EmptyCanRun]: source_position,
197+
AccumulatedProtonCharge[SampleRun]: charge,
198+
AccumulatedProtonCharge[VanadiumRun]: charge,
199+
AccumulatedProtonCharge[EmptyCanRun]: charge,
200+
CaveMonitorPosition: sc.vector([0.0, 0.0, -4220.0], unit='mm'),
201+
}
202+
for key, value in additional_parameters.items():
161203
wf[key] = value
204+
162205
wf.typical_outputs = typical_outputs
163206
return wf
164207

@@ -195,5 +238,7 @@ def DreamGeant4ProtonChargeWorkflow() -> sciline.Pipeline:
195238
'DreamGeant4MonitorIntegratedWorkflow',
196239
'DreamGeant4ProtonChargeWorkflow',
197240
'DreamGeant4Workflow',
241+
'DreamPowderWorkflow',
242+
'DreamWorkflow',
198243
'default_parameters',
199244
]

0 commit comments

Comments
 (0)