essreduce 25.5.0__py3-none-any.whl → 25.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ess/reduce/data.py +17 -0
- ess/reduce/nexus/types.py +28 -70
- ess/reduce/nexus/workflow.py +83 -42
- ess/reduce/streaming.py +24 -0
- ess/reduce/time_of_flight/__init__.py +4 -1
- ess/reduce/time_of_flight/eto_to_tof.py +1 -2
- ess/reduce/time_of_flight/simulation.py +25 -1
- ess/reduce/time_of_flight/types.py +10 -0
- ess/reduce/time_of_flight/workflow.py +43 -15
- ess/reduce/workflow.py +4 -2
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/METADATA +2 -2
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/RECORD +16 -17
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/WHEEL +1 -1
- ess/reduce/utils.py +0 -36
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/entry_points.txt +0 -0
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/licenses/LICENSE +0 -0
- {essreduce-25.5.0.dist-info → essreduce-25.5.2.dist-info}/top_level.txt +0 -0
ess/reduce/data.py
CHANGED
|
@@ -40,6 +40,15 @@ _bifrost_registry = Registry(
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
_dream_registry = Registry(
|
|
44
|
+
instrument='dream',
|
|
45
|
+
files={
|
|
46
|
+
"TEST_977695_00068064.hdf": "md5:9e6ee9ec70d7c5e8c0c93b9e07e8949f",
|
|
47
|
+
},
|
|
48
|
+
version='2',
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
43
52
|
_loki_registry = Registry(
|
|
44
53
|
instrument='loki',
|
|
45
54
|
files={
|
|
@@ -94,3 +103,11 @@ def loki_tutorial_background_run_60393() -> str:
|
|
|
94
103
|
def loki_tutorial_sample_transmission_run() -> str:
|
|
95
104
|
"""Sample transmission run (sample + sample holder/can + transmission monitor)."""
|
|
96
105
|
return _loki_registry.get_path('60394-2022-02-28_2215.nxs')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def dream_coda_test_file() -> str:
|
|
109
|
+
"""CODA file for DREAM where most pulses have been removed.
|
|
110
|
+
|
|
111
|
+
See ``tools/shrink_nexus.py``.
|
|
112
|
+
"""
|
|
113
|
+
return _dream_registry.get_path('TEST_977695_00068064.hdf')
|
ess/reduce/nexus/types.py
CHANGED
|
@@ -8,6 +8,7 @@ import sciline
|
|
|
8
8
|
import scipp as sc
|
|
9
9
|
import scippnexus as snx
|
|
10
10
|
from scippneutron import metadata as scn_meta
|
|
11
|
+
from scippneutron.chopper import DiskChopper
|
|
11
12
|
|
|
12
13
|
FilePath = NewType('FilePath', Path)
|
|
13
14
|
"""Full path to a NeXus file on disk."""
|
|
@@ -69,19 +70,13 @@ class TransmissionRun(Generic[ScatteringRunType]):
|
|
|
69
70
|
"""
|
|
70
71
|
|
|
71
72
|
|
|
72
|
-
RunType = TypeVar(
|
|
73
|
-
'RunType',
|
|
74
|
-
BackgroundRun,
|
|
75
|
-
EmptyBeamRun,
|
|
76
|
-
SampleRun,
|
|
77
|
-
# Note that mypy does not seem to like this nesting, may need to find a workaround
|
|
78
|
-
TransmissionRun[SampleRun],
|
|
79
|
-
TransmissionRun[BackgroundRun],
|
|
80
|
-
VanadiumRun,
|
|
81
|
-
)
|
|
73
|
+
RunType = TypeVar('RunType')
|
|
82
74
|
"""TypeVar for specifying what run some data belongs to.
|
|
83
75
|
|
|
84
|
-
|
|
76
|
+
This type must be constrained when used in a Sciline pipeline.
|
|
77
|
+
E.g., by passing ``run_types`` to :class:`ess.reduce.nexus.GenericNeXusWorkflow`.
|
|
78
|
+
|
|
79
|
+
ESSreduce provides the following but custom types can be used:
|
|
85
80
|
|
|
86
81
|
- :class:`BackgroundRun`
|
|
87
82
|
- :class:`EmptyBeamRun`
|
|
@@ -92,58 +87,28 @@ Possible values:
|
|
|
92
87
|
|
|
93
88
|
|
|
94
89
|
# 1.2 Monitor types
|
|
95
|
-
Monitor1 = NewType('Monitor1', int)
|
|
96
|
-
"""Identifier for an arbitrary monitor"""
|
|
97
|
-
Monitor2 = NewType('Monitor2', int)
|
|
98
|
-
"""Identifier for an arbitrary monitor"""
|
|
99
|
-
Monitor3 = NewType('Monitor3', int)
|
|
100
|
-
"""Identifier for an arbitrary monitor"""
|
|
101
|
-
Monitor4 = NewType('Monitor4', int)
|
|
102
|
-
"""Identifier for an arbitrary monitor"""
|
|
103
|
-
Monitor5 = NewType('Monitor5', int)
|
|
104
|
-
"""Identifier for an arbitrary monitor"""
|
|
105
|
-
Monitor6 = NewType('Monitor6', int)
|
|
106
|
-
"""Identifier for an arbitrary monitor"""
|
|
107
90
|
IncidentMonitor = NewType('IncidentMonitor', int)
|
|
108
91
|
"""Incident monitor"""
|
|
109
92
|
TransmissionMonitor = NewType('TransmissionMonitor', int)
|
|
110
93
|
"""Transmission monitor"""
|
|
111
|
-
FrameMonitor0 = NewType('
|
|
94
|
+
FrameMonitor0 = NewType('FrameMonitor0', int)
|
|
112
95
|
"""Frame monitor number 0"""
|
|
113
|
-
FrameMonitor1 = NewType('
|
|
96
|
+
FrameMonitor1 = NewType('FrameMonitor1', int)
|
|
114
97
|
"""Frame monitor number 1"""
|
|
115
|
-
FrameMonitor2 = NewType('
|
|
98
|
+
FrameMonitor2 = NewType('FrameMonitor2', int)
|
|
116
99
|
"""Frame monitor number 2"""
|
|
117
|
-
FrameMonitor3 = NewType('
|
|
100
|
+
FrameMonitor3 = NewType('FrameMonitor3', int)
|
|
118
101
|
"""Frame monitor number 3"""
|
|
119
102
|
CaveMonitor = NewType('CaveMonitor', int)
|
|
120
103
|
"""A monitor located in the instrument cave"""
|
|
121
|
-
MonitorType = TypeVar(
|
|
122
|
-
'MonitorType',
|
|
123
|
-
Monitor1,
|
|
124
|
-
Monitor2,
|
|
125
|
-
Monitor3,
|
|
126
|
-
Monitor4,
|
|
127
|
-
Monitor5,
|
|
128
|
-
Monitor6,
|
|
129
|
-
IncidentMonitor,
|
|
130
|
-
TransmissionMonitor,
|
|
131
|
-
FrameMonitor0,
|
|
132
|
-
FrameMonitor1,
|
|
133
|
-
FrameMonitor2,
|
|
134
|
-
FrameMonitor3,
|
|
135
|
-
CaveMonitor,
|
|
136
|
-
)
|
|
104
|
+
MonitorType = TypeVar('MonitorType')
|
|
137
105
|
"""TypeVar for specifying what monitor some data belongs to.
|
|
138
106
|
|
|
139
|
-
|
|
107
|
+
This type must be constrained when used in a Sciline pipeline.
|
|
108
|
+
E.g., by passing ``monitor_types`` to :class:`ess.reduce.nexus.GenericNeXusWorkflow`.
|
|
109
|
+
|
|
110
|
+
ESSreduce provides the following but custom types can be used:
|
|
140
111
|
|
|
141
|
-
- :class:`Monitor1`
|
|
142
|
-
- :class:`Monitor2`
|
|
143
|
-
- :class:`Monitor3`
|
|
144
|
-
- :class:`Monitor4`
|
|
145
|
-
- :class:`Monitor5`
|
|
146
|
-
- :class:`Monitor6`
|
|
147
112
|
- :class:`IncidentMonitor`
|
|
148
113
|
- :class:`TransmissionMonitor`
|
|
149
114
|
- :class:`FrameMonitor0`
|
|
@@ -154,27 +119,20 @@ Possible values:
|
|
|
154
119
|
"""
|
|
155
120
|
|
|
156
121
|
|
|
157
|
-
Component = TypeVar(
|
|
158
|
-
|
|
122
|
+
Component = TypeVar('Component')
|
|
123
|
+
"""A beamline component in a neXus file."""
|
|
124
|
+
COMPONENT_CONSTRAINTS = (
|
|
159
125
|
snx.NXdetector,
|
|
160
126
|
snx.NXsample,
|
|
161
127
|
snx.NXsource,
|
|
162
128
|
snx.NXdisk_chopper,
|
|
163
129
|
snx.NXcrystal,
|
|
164
|
-
Monitor1,
|
|
165
|
-
Monitor2,
|
|
166
|
-
Monitor3,
|
|
167
|
-
Monitor4,
|
|
168
|
-
Monitor5,
|
|
169
|
-
Monitor6,
|
|
170
|
-
IncidentMonitor,
|
|
171
|
-
TransmissionMonitor,
|
|
172
|
-
FrameMonitor0,
|
|
173
|
-
FrameMonitor1,
|
|
174
|
-
FrameMonitor2,
|
|
175
|
-
FrameMonitor3,
|
|
176
|
-
CaveMonitor,
|
|
177
130
|
)
|
|
131
|
+
"""Base constraints for the Component type variable.
|
|
132
|
+
|
|
133
|
+
This list will be supplemented with monitor types when creating a pipeline.
|
|
134
|
+
"""
|
|
135
|
+
|
|
178
136
|
UniqueComponent = TypeVar('UniqueComponent', snx.NXsample, snx.NXsource)
|
|
179
137
|
"""Components that can be identified by their type as there will only be one."""
|
|
180
138
|
|
|
@@ -336,15 +294,15 @@ class NeXusTransformation(Generic[Component, RunType]):
|
|
|
336
294
|
return NeXusTransformation(value=transform)
|
|
337
295
|
|
|
338
296
|
|
|
339
|
-
class
|
|
297
|
+
class RawChoppers(
|
|
340
298
|
sciline.Scope[RunType, sc.DataGroup[sc.DataGroup[Any]]],
|
|
341
299
|
sc.DataGroup[sc.DataGroup[Any]],
|
|
342
300
|
):
|
|
343
301
|
"""All choppers in a NeXus file."""
|
|
344
302
|
|
|
345
303
|
|
|
346
|
-
class
|
|
347
|
-
sciline.Scope[RunType, sc.DataGroup[
|
|
348
|
-
sc.DataGroup[
|
|
304
|
+
class DiskChoppers(
|
|
305
|
+
sciline.Scope[RunType, sc.DataGroup[DiskChopper]],
|
|
306
|
+
sc.DataGroup[DiskChopper],
|
|
349
307
|
):
|
|
350
|
-
"""All
|
|
308
|
+
"""All disk choppers parsed from a NeXus file."""
|
ess/reduce/nexus/workflow.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
from collections.abc import Iterable
|
|
7
7
|
from copy import deepcopy
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any, TypeVar
|
|
9
9
|
|
|
10
10
|
import sciline
|
|
11
11
|
import sciline.typing
|
|
@@ -15,16 +15,14 @@ from scipp.constants import g
|
|
|
15
15
|
from scipp.core import label_based_index_to_positional_index
|
|
16
16
|
from scippneutron.chopper import extract_chopper_from_nexus
|
|
17
17
|
|
|
18
|
-
from ..utils import prune_type_vars
|
|
19
18
|
from . import _nexus_loader as nexus
|
|
20
19
|
from .types import (
|
|
20
|
+
COMPONENT_CONSTRAINTS,
|
|
21
21
|
AllNeXusComponents,
|
|
22
|
-
Analyzers,
|
|
23
22
|
Beamline,
|
|
24
23
|
CalibratedBeamline,
|
|
25
24
|
CalibratedDetector,
|
|
26
25
|
CalibratedMonitor,
|
|
27
|
-
Choppers,
|
|
28
26
|
Component,
|
|
29
27
|
DetectorBankSizes,
|
|
30
28
|
DetectorData,
|
|
@@ -47,6 +45,7 @@ from .types import (
|
|
|
47
45
|
NeXusTransformationChain,
|
|
48
46
|
Position,
|
|
49
47
|
PreopenNeXusFile,
|
|
48
|
+
RawChoppers,
|
|
50
49
|
RunType,
|
|
51
50
|
SampleRun,
|
|
52
51
|
TimeInterval,
|
|
@@ -514,9 +513,18 @@ def assemble_monitor_data(
|
|
|
514
513
|
|
|
515
514
|
def parse_disk_choppers(
|
|
516
515
|
choppers: AllNeXusComponents[snx.NXdisk_chopper, RunType],
|
|
517
|
-
) ->
|
|
518
|
-
"""Convert the NeXus representation of a chopper to ours.
|
|
519
|
-
|
|
516
|
+
) -> RawChoppers[RunType]:
|
|
517
|
+
"""Convert the NeXus representation of a chopper to ours.
|
|
518
|
+
|
|
519
|
+
Returns
|
|
520
|
+
-------
|
|
521
|
+
:
|
|
522
|
+
A nested data group containing the loaded choppers.
|
|
523
|
+
The elements may be time-dependent arrays that first need to be processed
|
|
524
|
+
before they can be passed to other functions as
|
|
525
|
+
:class:`ess.reduce.nexus.types.DiskChoppers`.
|
|
526
|
+
"""
|
|
527
|
+
return RawChoppers[RunType](
|
|
520
528
|
choppers.apply(
|
|
521
529
|
lambda chopper: extract_chopper_from_nexus(
|
|
522
530
|
nexus.compute_component_position(chopper)
|
|
@@ -525,13 +533,6 @@ def parse_disk_choppers(
|
|
|
525
533
|
)
|
|
526
534
|
|
|
527
535
|
|
|
528
|
-
def parse_analyzers(
|
|
529
|
-
analyzers: AllNeXusComponents[snx.NXcrystal, RunType],
|
|
530
|
-
) -> Analyzers[RunType]:
|
|
531
|
-
"""Convert the NeXus representation of an analyzer to ours."""
|
|
532
|
-
return Analyzers[RunType](analyzers.apply(nexus.compute_component_position))
|
|
533
|
-
|
|
534
|
-
|
|
535
536
|
def _drop(
|
|
536
537
|
children: dict[str, snx.Field | snx.Group], classes: tuple[snx.NXobject, ...]
|
|
537
538
|
) -> dict[str, snx.Field | snx.Group]:
|
|
@@ -559,10 +560,10 @@ class _StrippedDetector(snx.NXdetector):
|
|
|
559
560
|
class _DummyField:
|
|
560
561
|
"""Dummy field that can replace snx.Field in NXmonitor."""
|
|
561
562
|
|
|
562
|
-
def __init__(self):
|
|
563
|
+
def __init__(self, dim: str):
|
|
563
564
|
self.attrs = {}
|
|
564
|
-
self.sizes = {
|
|
565
|
-
self.dims = (
|
|
565
|
+
self.sizes = {dim: 0}
|
|
566
|
+
self.dims = (dim,)
|
|
566
567
|
self.shape = (0,)
|
|
567
568
|
|
|
568
569
|
def __getitem__(self, key: Any) -> sc.Variable:
|
|
@@ -572,14 +573,17 @@ class _DummyField:
|
|
|
572
573
|
class _StrippedMonitor(snx.NXmonitor):
|
|
573
574
|
"""Monitor definition without event data for ScippNexus.
|
|
574
575
|
|
|
575
|
-
Drops NXevent_data
|
|
576
|
+
Drops NXevent_data and NXdata groups, data is replaced by a dummy field.
|
|
576
577
|
"""
|
|
577
578
|
|
|
578
579
|
def __init__(
|
|
579
580
|
self, attrs: dict[str, Any], children: dict[str, snx.Field | snx.Group]
|
|
580
581
|
):
|
|
581
|
-
|
|
582
|
-
|
|
582
|
+
is_dense = snx.NXdata in (
|
|
583
|
+
getattr(child, 'nx_class', None) for child in children
|
|
584
|
+
)
|
|
585
|
+
children = _drop(children, (snx.NXevent_data, snx.NXdata))
|
|
586
|
+
children['data'] = _DummyField(dim='time' if is_dense else 'event_time_zero')
|
|
583
587
|
super().__init__(attrs=attrs, children=children)
|
|
584
588
|
|
|
585
589
|
|
|
@@ -587,11 +591,21 @@ def _add_variances(da: sc.DataArray) -> sc.DataArray:
|
|
|
587
591
|
out = da.copy(deep=False)
|
|
588
592
|
if out.bins is not None:
|
|
589
593
|
content = out.bins.constituents['data']
|
|
590
|
-
|
|
591
|
-
|
|
594
|
+
content.data = _assign_values_as_variances(content.data)
|
|
595
|
+
elif out.variances is None:
|
|
596
|
+
out.data = _assign_values_as_variances(out.data)
|
|
592
597
|
return out
|
|
593
598
|
|
|
594
599
|
|
|
600
|
+
def _assign_values_as_variances(var: sc.Variable) -> sc.Variable:
|
|
601
|
+
try:
|
|
602
|
+
var.variances = var.values
|
|
603
|
+
except sc.VariancesError:
|
|
604
|
+
var = var.to(dtype=sc.DType.float64)
|
|
605
|
+
var.variances = var.values
|
|
606
|
+
return var
|
|
607
|
+
|
|
608
|
+
|
|
595
609
|
def load_beamline_metadata_from_nexus(file_spec: NeXusFileSpec[SampleRun]) -> Beamline:
|
|
596
610
|
"""Load beamline metadata from a sample NeXus file."""
|
|
597
611
|
return nexus.load_metadata(file_spec.value, Beamline)
|
|
@@ -628,7 +642,6 @@ _common_providers = (
|
|
|
628
642
|
nx_class_for_source,
|
|
629
643
|
nx_class_for_sample,
|
|
630
644
|
nx_class_for_disk_chopper,
|
|
631
|
-
nx_class_for_crystal,
|
|
632
645
|
)
|
|
633
646
|
|
|
634
647
|
_monitor_providers = (
|
|
@@ -647,24 +660,40 @@ _detector_providers = (
|
|
|
647
660
|
|
|
648
661
|
_chopper_providers = (parse_disk_choppers,)
|
|
649
662
|
|
|
650
|
-
_analyzer_providers = (parse_analyzers,)
|
|
651
|
-
|
|
652
663
|
_metadata_providers = (
|
|
653
664
|
load_beamline_metadata_from_nexus,
|
|
654
665
|
load_measurement_metadata_from_nexus,
|
|
655
666
|
)
|
|
656
667
|
|
|
657
668
|
|
|
658
|
-
def LoadMonitorWorkflow(
|
|
669
|
+
def LoadMonitorWorkflow(
|
|
670
|
+
*,
|
|
671
|
+
run_types: Iterable[sciline.typing.Key],
|
|
672
|
+
monitor_types: Iterable[sciline.typing.Key],
|
|
673
|
+
) -> sciline.Pipeline:
|
|
659
674
|
"""Generic workflow for loading monitor data from a NeXus file."""
|
|
660
|
-
wf = sciline.Pipeline(
|
|
675
|
+
wf = sciline.Pipeline(
|
|
676
|
+
(*_common_providers, *_monitor_providers),
|
|
677
|
+
constraints=_gather_constraints(
|
|
678
|
+
run_types=run_types, monitor_types=monitor_types
|
|
679
|
+
),
|
|
680
|
+
)
|
|
661
681
|
wf[PreopenNeXusFile] = PreopenNeXusFile(False)
|
|
662
682
|
return wf
|
|
663
683
|
|
|
664
684
|
|
|
665
|
-
def LoadDetectorWorkflow(
|
|
685
|
+
def LoadDetectorWorkflow(
|
|
686
|
+
*,
|
|
687
|
+
run_types: Iterable[sciline.typing.Key],
|
|
688
|
+
monitor_types: Iterable[sciline.typing.Key],
|
|
689
|
+
) -> sciline.Pipeline:
|
|
666
690
|
"""Generic workflow for loading detector data from a NeXus file."""
|
|
667
|
-
wf = sciline.Pipeline(
|
|
691
|
+
wf = sciline.Pipeline(
|
|
692
|
+
(*_common_providers, *_detector_providers),
|
|
693
|
+
constraints=_gather_constraints(
|
|
694
|
+
run_types=run_types, monitor_types=monitor_types
|
|
695
|
+
),
|
|
696
|
+
)
|
|
668
697
|
wf[DetectorBankSizes] = DetectorBankSizes({})
|
|
669
698
|
wf[PreopenNeXusFile] = PreopenNeXusFile(False)
|
|
670
699
|
return wf
|
|
@@ -672,8 +701,8 @@ def LoadDetectorWorkflow() -> sciline.Pipeline:
|
|
|
672
701
|
|
|
673
702
|
def GenericNeXusWorkflow(
|
|
674
703
|
*,
|
|
675
|
-
run_types: Iterable[sciline.typing.Key]
|
|
676
|
-
monitor_types: Iterable[sciline.typing.Key]
|
|
704
|
+
run_types: Iterable[sciline.typing.Key],
|
|
705
|
+
monitor_types: Iterable[sciline.typing.Key],
|
|
677
706
|
) -> sciline.Pipeline:
|
|
678
707
|
"""
|
|
679
708
|
Generic workflow for loading detector and monitor data from a NeXus file.
|
|
@@ -692,13 +721,12 @@ def GenericNeXusWorkflow(
|
|
|
692
721
|
Parameters
|
|
693
722
|
----------
|
|
694
723
|
run_types:
|
|
695
|
-
List of run types to include in the workflow.
|
|
696
|
-
|
|
697
|
-
Must be a possible value of :class:`ess.reduce.nexus.types.RunType`.
|
|
724
|
+
List of run types to include in the workflow.
|
|
725
|
+
Constrains the possible values of :class:`ess.reduce.nexus.types.RunType`.
|
|
698
726
|
monitor_types:
|
|
699
|
-
List of monitor types to include in the workflow.
|
|
700
|
-
|
|
701
|
-
|
|
727
|
+
List of monitor types to include in the workflow.
|
|
728
|
+
Constrains the possible values of :class:`ess.reduce.nexus.types.MonitorType`
|
|
729
|
+
and :class:`ess.reduce.nexus.types.Component`.
|
|
702
730
|
|
|
703
731
|
Returns
|
|
704
732
|
-------
|
|
@@ -711,14 +739,27 @@ def GenericNeXusWorkflow(
|
|
|
711
739
|
*_monitor_providers,
|
|
712
740
|
*_detector_providers,
|
|
713
741
|
*_chopper_providers,
|
|
714
|
-
*_analyzer_providers,
|
|
715
742
|
*_metadata_providers,
|
|
716
|
-
)
|
|
743
|
+
),
|
|
744
|
+
constraints=_gather_constraints(
|
|
745
|
+
run_types=run_types, monitor_types=monitor_types
|
|
746
|
+
),
|
|
717
747
|
)
|
|
718
748
|
wf[DetectorBankSizes] = DetectorBankSizes({})
|
|
719
749
|
wf[PreopenNeXusFile] = PreopenNeXusFile(False)
|
|
720
750
|
|
|
721
|
-
if run_types is not None or monitor_types is not None:
|
|
722
|
-
prune_type_vars(wf, run_types=run_types, monitor_types=monitor_types)
|
|
723
|
-
|
|
724
751
|
return wf
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
def _gather_constraints(
|
|
755
|
+
*,
|
|
756
|
+
run_types: Iterable[sciline.typing.Key],
|
|
757
|
+
monitor_types: Iterable[sciline.typing.Key],
|
|
758
|
+
) -> dict[TypeVar, Iterable[type]]:
|
|
759
|
+
mon = tuple(iter(monitor_types))
|
|
760
|
+
constraints = {
|
|
761
|
+
RunType: run_types,
|
|
762
|
+
MonitorType: mon,
|
|
763
|
+
Component: (*COMPONENT_CONSTRAINTS, *mon),
|
|
764
|
+
}
|
|
765
|
+
return constraints
|
ess/reduce/streaming.py
CHANGED
|
@@ -138,6 +138,30 @@ class EternalAccumulator(Accumulator[T]):
|
|
|
138
138
|
self._value = None
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
class MeanAccumulator(EternalAccumulator[T]):
|
|
142
|
+
"""
|
|
143
|
+
Accumulator that computes the mean of pushed values.
|
|
144
|
+
|
|
145
|
+
Does not support event data.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
149
|
+
super().__init__(**kwargs)
|
|
150
|
+
self._count = 0
|
|
151
|
+
|
|
152
|
+
def _do_push(self, value: T) -> None:
|
|
153
|
+
super()._do_push(value)
|
|
154
|
+
self._count += 1
|
|
155
|
+
|
|
156
|
+
def _get_value(self) -> T:
|
|
157
|
+
return super()._get_value() / self._count
|
|
158
|
+
|
|
159
|
+
def clear(self) -> None:
|
|
160
|
+
"""Clear the accumulated value and count."""
|
|
161
|
+
super().clear()
|
|
162
|
+
self._count = 0
|
|
163
|
+
|
|
164
|
+
|
|
141
165
|
class RollingAccumulator(Accumulator[T]):
|
|
142
166
|
"""
|
|
143
167
|
Accumulator that adds pushed values to a rolling window.
|
|
@@ -29,9 +29,10 @@ from .types import (
|
|
|
29
29
|
ResampledMonitorTofData,
|
|
30
30
|
SimulationResults,
|
|
31
31
|
TimeOfFlightLookupTable,
|
|
32
|
+
TimeOfFlightLookupTableFilename,
|
|
32
33
|
TimeResolution,
|
|
33
34
|
)
|
|
34
|
-
from .workflow import GenericTofWorkflow
|
|
35
|
+
from .workflow import GenericTofWorkflow, TofLutProvider
|
|
35
36
|
|
|
36
37
|
__all__ = [
|
|
37
38
|
"DetectorLtotal",
|
|
@@ -49,7 +50,9 @@ __all__ = [
|
|
|
49
50
|
"ResampledMonitorTofData",
|
|
50
51
|
"SimulationResults",
|
|
51
52
|
"TimeOfFlightLookupTable",
|
|
53
|
+
"TimeOfFlightLookupTableFilename",
|
|
52
54
|
"TimeResolution",
|
|
55
|
+
"TofLutProvider",
|
|
53
56
|
"default_parameters",
|
|
54
57
|
"providers",
|
|
55
58
|
"resample_detector_time_of_flight_data",
|
|
@@ -12,7 +12,6 @@ from collections.abc import Callable
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
import scipp as sc
|
|
14
14
|
import scippneutron as scn
|
|
15
|
-
from scipp._scipp.core import _bins_no_validate
|
|
16
15
|
from scippneutron._utils import elem_unit
|
|
17
16
|
|
|
18
17
|
try:
|
|
@@ -532,7 +531,7 @@ def _time_of_flight_data_events(
|
|
|
532
531
|
|
|
533
532
|
parts = da.bins.constituents
|
|
534
533
|
parts["data"] = tofs
|
|
535
|
-
return da.bins.assign_coords(tof=
|
|
534
|
+
return da.bins.assign_coords(tof=sc.bins(**parts, validate_indices=False))
|
|
536
535
|
|
|
537
536
|
|
|
538
537
|
def detector_ltotal_from_straight_line_approximation(
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
from collections.abc import Mapping
|
|
4
4
|
|
|
5
5
|
import scipp as sc
|
|
6
|
+
import scippnexus as snx
|
|
6
7
|
from scippneutron.chopper import DiskChopper
|
|
7
8
|
|
|
8
|
-
from .types import
|
|
9
|
+
from ..nexus.types import DiskChoppers, Position, SampleRun
|
|
10
|
+
from .types import NumberOfSimulatedNeutrons, SimulationResults
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
def simulate_beamline(
|
|
@@ -82,3 +84,25 @@ def simulate_beamline(
|
|
|
82
84
|
weight=events.data,
|
|
83
85
|
distance=furthest_chopper.distance,
|
|
84
86
|
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def simulate_chopper_cascade_using_tof(
|
|
90
|
+
choppers: DiskChoppers[SampleRun],
|
|
91
|
+
neutrons: NumberOfSimulatedNeutrons,
|
|
92
|
+
source_position: Position[snx.NXsource, SampleRun],
|
|
93
|
+
) -> SimulationResults:
|
|
94
|
+
"""
|
|
95
|
+
Simulate neutrons traveling through the chopper cascade using the ``tof`` package.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
choppers:
|
|
100
|
+
Chopper settings.
|
|
101
|
+
neutrons:
|
|
102
|
+
Number of neutrons to simulate.
|
|
103
|
+
source_position:
|
|
104
|
+
Position of the source.
|
|
105
|
+
"""
|
|
106
|
+
return simulate_beamline(
|
|
107
|
+
choppers=choppers, neutrons=neutrons, source_position=source_position
|
|
108
|
+
)
|
|
@@ -46,6 +46,12 @@ class SimulationResults:
|
|
|
46
46
|
distance: sc.Variable
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
NumberOfSimulatedNeutrons = NewType("NumberOfSimulatedNeutrons", int)
|
|
50
|
+
"""
|
|
51
|
+
Number of neutrons simulated in the simulation that is used to create the lookup table.
|
|
52
|
+
This is typically a large number, e.g., 1e6 or 1e7.
|
|
53
|
+
"""
|
|
54
|
+
|
|
49
55
|
LtotalRange = NewType("LtotalRange", tuple[sc.Variable, sc.Variable])
|
|
50
56
|
"""
|
|
51
57
|
Range (min, max) of the total length of the flight path from the source to the detector.
|
|
@@ -78,6 +84,10 @@ resolution in the lookup table will be at least the supplied value here, but may
|
|
|
78
84
|
smaller if the pulse period is not an integer multiple of the time resolution.
|
|
79
85
|
"""
|
|
80
86
|
|
|
87
|
+
TimeOfFlightLookupTableFilename = NewType("TimeOfFlightLookupTableFilename", str)
|
|
88
|
+
"""Filename of the time-of-flight lookup table."""
|
|
89
|
+
|
|
90
|
+
|
|
81
91
|
TimeOfFlightLookupTable = NewType("TimeOfFlightLookupTable", sc.DataArray)
|
|
82
92
|
"""
|
|
83
93
|
Lookup table giving time-of-flight as a function of distance and time of arrival.
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
2
2
|
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
|
|
3
3
|
from collections.abc import Iterable
|
|
4
|
+
from enum import Enum, auto
|
|
4
5
|
|
|
5
6
|
import sciline
|
|
7
|
+
import scipp as sc
|
|
6
8
|
|
|
7
9
|
from ..nexus import GenericNeXusWorkflow
|
|
8
|
-
from
|
|
9
|
-
from .
|
|
10
|
+
from . import eto_to_tof, simulation
|
|
11
|
+
from .types import TimeOfFlightLookupTable, TimeOfFlightLookupTableFilename
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TofLutProvider(Enum):
|
|
15
|
+
"""Provider for the time-of-flight lookup table."""
|
|
16
|
+
|
|
17
|
+
FILE = auto() # From file
|
|
18
|
+
TOF = auto() # Computed with 'tof' package from chopper settings
|
|
19
|
+
MCSTAS = auto() # McStas simulation (not implemented yet)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def load_tof_lookup_table(
|
|
23
|
+
filename: TimeOfFlightLookupTableFilename,
|
|
24
|
+
) -> TimeOfFlightLookupTable:
|
|
25
|
+
return TimeOfFlightLookupTable(sc.io.load_hdf5(filename))
|
|
10
26
|
|
|
11
27
|
|
|
12
28
|
def GenericTofWorkflow(
|
|
13
29
|
*,
|
|
14
|
-
run_types: Iterable[sciline.typing.Key]
|
|
15
|
-
monitor_types: Iterable[sciline.typing.Key]
|
|
30
|
+
run_types: Iterable[sciline.typing.Key],
|
|
31
|
+
monitor_types: Iterable[sciline.typing.Key],
|
|
32
|
+
tof_lut_provider: TofLutProvider = TofLutProvider.FILE,
|
|
16
33
|
) -> sciline.Pipeline:
|
|
17
34
|
"""
|
|
18
35
|
Generic workflow for computing the neutron time-of-flight for detector and monitor
|
|
@@ -35,13 +52,17 @@ def GenericTofWorkflow(
|
|
|
35
52
|
Parameters
|
|
36
53
|
----------
|
|
37
54
|
run_types:
|
|
38
|
-
List of run types to include in the workflow.
|
|
39
|
-
|
|
40
|
-
Must be a possible value of :class:`ess.reduce.nexus.types.RunType`.
|
|
55
|
+
List of run types to include in the workflow.
|
|
56
|
+
Constrains the possible values of :class:`ess.reduce.nexus.types.RunType`.
|
|
41
57
|
monitor_types:
|
|
42
|
-
List of monitor types to include in the workflow.
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
List of monitor types to include in the workflow.
|
|
59
|
+
Constrains the possible values of :class:`ess.reduce.nexus.types.MonitorType`
|
|
60
|
+
and :class:`ess.reduce.nexus.types.Component`.
|
|
61
|
+
tof_lut_provider:
|
|
62
|
+
Specifies how the time-of-flight lookup table is provided:
|
|
63
|
+
- FILE: Read from a file
|
|
64
|
+
- TOF: Computed from chopper settings using the 'tof' package
|
|
65
|
+
- MCSTAS: From McStas simulation (not implemented yet)
|
|
45
66
|
|
|
46
67
|
Returns
|
|
47
68
|
-------
|
|
@@ -50,12 +71,19 @@ def GenericTofWorkflow(
|
|
|
50
71
|
"""
|
|
51
72
|
wf = GenericNeXusWorkflow(run_types=run_types, monitor_types=monitor_types)
|
|
52
73
|
|
|
53
|
-
for provider in providers():
|
|
74
|
+
for provider in eto_to_tof.providers():
|
|
54
75
|
wf.insert(provider)
|
|
55
|
-
for key, value in default_parameters().items():
|
|
56
|
-
wf[key] = value
|
|
57
76
|
|
|
58
|
-
if
|
|
59
|
-
|
|
77
|
+
if tof_lut_provider == TofLutProvider.FILE:
|
|
78
|
+
wf.insert(load_tof_lookup_table)
|
|
79
|
+
else:
|
|
80
|
+
wf.insert(eto_to_tof.compute_tof_lookup_table)
|
|
81
|
+
if tof_lut_provider == TofLutProvider.TOF:
|
|
82
|
+
wf.insert(simulation.simulate_chopper_cascade_using_tof)
|
|
83
|
+
if tof_lut_provider == TofLutProvider.MCSTAS:
|
|
84
|
+
raise NotImplementedError("McStas simulation not implemented yet")
|
|
85
|
+
|
|
86
|
+
for key, value in eto_to_tof.default_parameters().items():
|
|
87
|
+
wf[key] = value
|
|
60
88
|
|
|
61
89
|
return wf
|
ess/reduce/workflow.py
CHANGED
|
@@ -53,12 +53,14 @@ def get_typical_outputs(pipeline: Pipeline) -> tuple[Key, ...]:
|
|
|
53
53
|
if (typical_outputs := getattr(pipeline, "typical_outputs", None)) is None:
|
|
54
54
|
graph = pipeline.underlying_graph
|
|
55
55
|
sink_nodes = [node for node, degree in graph.out_degree if degree == 0]
|
|
56
|
-
return sorted(_with_pretty_names(sink_nodes))
|
|
56
|
+
return sorted(_with_pretty_names(sink_nodes), key=lambda x: x[0])
|
|
57
57
|
return _with_pretty_names(typical_outputs)
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
def get_possible_outputs(pipeline: Pipeline) -> tuple[Key, ...]:
|
|
61
|
-
return sorted(
|
|
61
|
+
return sorted(
|
|
62
|
+
_with_pretty_names(tuple(pipeline.underlying_graph.nodes)), key=lambda x: x[0]
|
|
63
|
+
)
|
|
62
64
|
|
|
63
65
|
|
|
64
66
|
def _with_pretty_names(outputs: Sequence[Key]) -> tuple[tuple[str, Key], ...]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: essreduce
|
|
3
|
-
Version: 25.5.
|
|
3
|
+
Version: 25.5.2
|
|
4
4
|
Summary: Common data reduction tools for the ESS facility
|
|
5
5
|
Author: Scipp contributors
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -51,7 +51,7 @@ Classifier: Typing :: Typed
|
|
|
51
51
|
Requires-Python: >=3.10
|
|
52
52
|
Description-Content-Type: text/markdown
|
|
53
53
|
License-File: LICENSE
|
|
54
|
-
Requires-Dist: sciline>=25.
|
|
54
|
+
Requires-Dist: sciline>=25.05.1
|
|
55
55
|
Requires-Dist: scipp>=25.01.0
|
|
56
56
|
Requires-Dist: scippneutron>=25.02.0
|
|
57
57
|
Requires-Dist: scippnexus>=24.11.0
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
ess/reduce/__init__.py,sha256=o1pWRP9YGwTukM_k-qlG6KcoXOpMb0PDVH59vod12lw,419
|
|
2
|
-
ess/reduce/data.py,sha256=
|
|
2
|
+
ess/reduce/data.py,sha256=0N7iq1363tO16ntMztTNjxkQDFst-Gnp9awpgUOBVdY,4133
|
|
3
3
|
ess/reduce/logging.py,sha256=6n8Czq4LZ3OK9ENlKsWSI1M3KvKv6_HSoUiV4__IUlU,357
|
|
4
4
|
ess/reduce/parameter.py,sha256=4sCfoKOI2HuO_Q7JLH_jAXnEOFANSn5P3NdaOBzhJxc,4635
|
|
5
5
|
ess/reduce/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
ess/reduce/streaming.py,sha256=
|
|
6
|
+
ess/reduce/streaming.py,sha256=zbqxQz5dASDq4ZVyx-TdbapBXMyBttImCYz_6WOj4pg,17978
|
|
7
7
|
ess/reduce/ui.py,sha256=zmorAbDwX1cU3ygDT--OP58o0qU7OBcmJz03jPeYSLA,10884
|
|
8
8
|
ess/reduce/uncertainty.py,sha256=LR4O6ApB6Z-W9gC_XW0ajupl8yFG-du0eee1AX_R-gk,6990
|
|
9
|
-
ess/reduce/
|
|
10
|
-
ess/reduce/workflow.py,sha256=sL34T_2Cjl_8iFlegujxI9VyOUwo6erVC8pOXnfWgYw,3060
|
|
9
|
+
ess/reduce/workflow.py,sha256=738-lcdgsORYfQ4A0UTk2IgnbVxC3jBdpscpaOFIpdc,3114
|
|
11
10
|
ess/reduce/live/__init__.py,sha256=jPQVhihRVNtEDrE20PoKkclKV2aBF1lS7cCHootgFgI,204
|
|
12
11
|
ess/reduce/live/raw.py,sha256=66qV0G2rP8gK5tXuk-syTlDLE2jT3ehfmSnET7Xzfd0,24392
|
|
13
12
|
ess/reduce/live/roi.py,sha256=Hs-pW98k41WU6Kl3UQ41kQawk80c2QNOQ_WNctLzDPE,3795
|
|
@@ -16,18 +15,18 @@ ess/reduce/nexus/__init__.py,sha256=59bxKkNYg8DYcSykNvH6nCa5SYchJC4SbgZEKhkNdYc,
|
|
|
16
15
|
ess/reduce/nexus/_nexus_loader.py,sha256=5N48AMJx1AaFZb6WZPPbVKUlXyFMVVtZrn7Bae57O3A,19842
|
|
17
16
|
ess/reduce/nexus/json_generator.py,sha256=ME2Xn8L7Oi3uHJk9ZZdCRQTRX-OV_wh9-DJn07Alplk,2529
|
|
18
17
|
ess/reduce/nexus/json_nexus.py,sha256=QrVc0p424nZ5dHX9gebAJppTw6lGZq9404P_OFl1giA,10282
|
|
19
|
-
ess/reduce/nexus/types.py,sha256=
|
|
20
|
-
ess/reduce/nexus/workflow.py,sha256=
|
|
18
|
+
ess/reduce/nexus/types.py,sha256=DE82JnbgpTlQnt7UN2a2Gur2N9QupV3CDL9j4Iy4lsE,9178
|
|
19
|
+
ess/reduce/nexus/workflow.py,sha256=Ytt80-muk5EiXmip890ahb_m5DQqlTGRQUyaTVXRNzo,24568
|
|
21
20
|
ess/reduce/scripts/grow_nexus.py,sha256=hET3h06M0xlJd62E3palNLFvJMyNax2kK4XyJcOhl-I,3387
|
|
22
|
-
ess/reduce/time_of_flight/__init__.py,sha256=
|
|
23
|
-
ess/reduce/time_of_flight/eto_to_tof.py,sha256=
|
|
21
|
+
ess/reduce/time_of_flight/__init__.py,sha256=UxMvY4aFkhZQmIbGSo4FBpBGRD2wDJbczLMVqcEhCSg,1583
|
|
22
|
+
ess/reduce/time_of_flight/eto_to_tof.py,sha256=JCu7C3AmJnB7GDJrL76oPjgxGesp67nct9xXRp3O8E4,28204
|
|
24
23
|
ess/reduce/time_of_flight/fakes.py,sha256=0gtbSX3ZQilaM4ZP5dMr3fqbnhpyoVsZX2YEb8GgREE,4489
|
|
25
24
|
ess/reduce/time_of_flight/interpolator_numba.py,sha256=wh2YS3j2rOu30v1Ok3xNHcwS7t8eEtZyZvbfXOCtgrQ,3835
|
|
26
25
|
ess/reduce/time_of_flight/interpolator_scipy.py,sha256=_InoAPuMm2qhJKZQBAHOGRFqtvvuQ8TStoN7j_YgS4M,1853
|
|
27
|
-
ess/reduce/time_of_flight/simulation.py,sha256=
|
|
26
|
+
ess/reduce/time_of_flight/simulation.py,sha256=vo-zjG6t-PLetv2_nj4dhMSTEyTQ1MsrhlM2XkhOtf8,3632
|
|
28
27
|
ess/reduce/time_of_flight/to_events.py,sha256=w9mHpnWd3vwN2ouob-GK_1NPrTjCaOzPuC2QuEey-m0,4342
|
|
29
|
-
ess/reduce/time_of_flight/types.py,sha256=
|
|
30
|
-
ess/reduce/time_of_flight/workflow.py,sha256
|
|
28
|
+
ess/reduce/time_of_flight/types.py,sha256=OQeMYNN7QinXs_HDcoE6kkh_xNcyD0dEJWtnHQy5-uA,6675
|
|
29
|
+
ess/reduce/time_of_flight/workflow.py,sha256=mwNEXwvOnm-M8n4G9Cau1Vuyqzo4qMrhCbZ-S5vszW4,3181
|
|
31
30
|
ess/reduce/widgets/__init__.py,sha256=SoSHBv8Dc3QXV9HUvPhjSYWMwKTGYZLpsWwsShIO97Q,5325
|
|
32
31
|
ess/reduce/widgets/_base.py,sha256=_wN3FOlXgx_u0c-A_3yyoIH-SdUvDENGgquh9S-h5GI,4852
|
|
33
32
|
ess/reduce/widgets/_binedges_widget.py,sha256=ZCQsGjYHnJr9GFUn7NjoZc1CdsnAzm_fMzyF-fTKKVY,2785
|
|
@@ -40,9 +39,9 @@ ess/reduce/widgets/_spinner.py,sha256=2VY4Fhfa7HMXox2O7UbofcdKsYG-AJGrsgGJB85nDX
|
|
|
40
39
|
ess/reduce/widgets/_string_widget.py,sha256=iPAdfANyXHf-nkfhgkyH6gQDklia0LebLTmwi3m-iYQ,1482
|
|
41
40
|
ess/reduce/widgets/_switchable_widget.py,sha256=fjKz99SKLhIF1BLgGVBSKKn3Lu_jYBwDYGeAjbJY3Q8,2390
|
|
42
41
|
ess/reduce/widgets/_vector_widget.py,sha256=aTaBqCFHZQhrIoX6-sSqFWCPePEW8HQt5kUio8jP1t8,1203
|
|
43
|
-
essreduce-25.5.
|
|
44
|
-
essreduce-25.5.
|
|
45
|
-
essreduce-25.5.
|
|
46
|
-
essreduce-25.5.
|
|
47
|
-
essreduce-25.5.
|
|
48
|
-
essreduce-25.5.
|
|
42
|
+
essreduce-25.5.2.dist-info/licenses/LICENSE,sha256=nVEiume4Qj6jMYfSRjHTM2jtJ4FGu0g-5Sdh7osfEYw,1553
|
|
43
|
+
essreduce-25.5.2.dist-info/METADATA,sha256=LNEHFWDdswQNdu6s_5_eVHlmkVz35siN2fvirZ0KhFI,3768
|
|
44
|
+
essreduce-25.5.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
45
|
+
essreduce-25.5.2.dist-info/entry_points.txt,sha256=PMZOIYzCifHMTe4pK3HbhxUwxjFaZizYlLD0td4Isb0,66
|
|
46
|
+
essreduce-25.5.2.dist-info/top_level.txt,sha256=0JxTCgMKPLKtp14wb1-RKisQPQWX7i96innZNvHBr-s,4
|
|
47
|
+
essreduce-25.5.2.dist-info/RECORD,,
|
ess/reduce/utils.py
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
-
# Copyright (c) 2025 Scipp contributors (https://github.com/scipp)
|
|
3
|
-
|
|
4
|
-
from collections.abc import Iterable
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
import sciline
|
|
8
|
-
|
|
9
|
-
from .nexus.types import MonitorType, RunType
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def prune_type_vars(
|
|
13
|
-
workflow: sciline.Pipeline,
|
|
14
|
-
*,
|
|
15
|
-
run_types: Iterable[sciline.typing.Key] | None,
|
|
16
|
-
monitor_types: Iterable[sciline.typing.Key] | None,
|
|
17
|
-
) -> None:
|
|
18
|
-
# Remove all nodes that use a run type or monitor types that is
|
|
19
|
-
# not listed in the function arguments.
|
|
20
|
-
excluded_run_types = excluded_type_args(RunType, run_types)
|
|
21
|
-
excluded_monitor_types = excluded_type_args(MonitorType, monitor_types)
|
|
22
|
-
excluded_types = excluded_run_types | excluded_monitor_types
|
|
23
|
-
|
|
24
|
-
graph = workflow.underlying_graph
|
|
25
|
-
to_remove = [
|
|
26
|
-
node for node in graph if excluded_types & set(getattr(node, "__args__", set()))
|
|
27
|
-
]
|
|
28
|
-
graph.remove_nodes_from(to_remove)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def excluded_type_args(
|
|
32
|
-
type_var: Any, keep: Iterable[sciline.typing.Key] | None
|
|
33
|
-
) -> set[sciline.typing.Key]:
|
|
34
|
-
if keep is None:
|
|
35
|
-
return set()
|
|
36
|
-
return set(type_var.__constraints__) - set(keep)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|