essreduce 25.10.2__tar.gz → 25.11.1__tar.gz

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.
Files changed (147) hide show
  1. {essreduce-25.10.2 → essreduce-25.11.1}/PKG-INFO +2 -2
  2. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/reduction-workflow-guidelines.md +63 -0
  3. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/tof/dream.ipynb +10 -22
  4. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/tof/frame-unwrapping.ipynb +9 -27
  5. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/tof/wfm.ipynb +6 -24
  6. {essreduce-25.10.2 → essreduce-25.11.1}/pyproject.toml +1 -1
  7. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/base.in +1 -1
  8. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/base.txt +4 -4
  9. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/basetest.txt +5 -5
  10. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/ci.txt +1 -1
  11. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/dev.txt +2 -2
  12. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/docs.txt +4 -4
  13. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/nightly.txt +4 -4
  14. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/static.txt +1 -1
  15. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/live/raw.py +5 -5
  16. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/types.py +25 -18
  17. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/workflow.py +77 -69
  18. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/__init__.py +4 -4
  19. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/eto_to_tof.py +37 -22
  20. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/lut.py +2 -2
  21. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/types.py +2 -2
  22. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/PKG-INFO +2 -2
  23. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/requires.txt +1 -1
  24. {essreduce-25.10.2 → essreduce-25.11.1}/tests/conftest.py +2 -2
  25. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/workflow_test.py +65 -43
  26. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/lut_test.py +5 -4
  27. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/unwrap_test.py +19 -19
  28. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/wfm_test.py +8 -8
  29. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/workflow_test.py +24 -12
  30. {essreduce-25.10.2 → essreduce-25.11.1}/.copier-answers.ess.yml +0 -0
  31. {essreduce-25.10.2 → essreduce-25.11.1}/.copier-answers.yml +0 -0
  32. {essreduce-25.10.2 → essreduce-25.11.1}/.github/ISSUE_TEMPLATE/high-level-requirement.yml +0 -0
  33. {essreduce-25.10.2 → essreduce-25.11.1}/.github/dependabot.yml +0 -0
  34. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/ci.yml +0 -0
  35. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/docs.yml +0 -0
  36. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/nightly_at_main.yml +0 -0
  37. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/nightly_at_main_lower_bound.yml +0 -0
  38. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/nightly_at_release.yml +0 -0
  39. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/python-version-ci +0 -0
  40. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/release.yml +0 -0
  41. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/test.yml +0 -0
  42. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/unpinned.yml +0 -0
  43. {essreduce-25.10.2 → essreduce-25.11.1}/.github/workflows/weekly_windows_macos.yml +0 -0
  44. {essreduce-25.10.2 → essreduce-25.11.1}/.gitignore +0 -0
  45. {essreduce-25.10.2 → essreduce-25.11.1}/.pre-commit-config.yaml +0 -0
  46. {essreduce-25.10.2 → essreduce-25.11.1}/.python-version +0 -0
  47. {essreduce-25.10.2 → essreduce-25.11.1}/CODE_OF_CONDUCT.md +0 -0
  48. {essreduce-25.10.2 → essreduce-25.11.1}/CONTRIBUTING.md +0 -0
  49. {essreduce-25.10.2 → essreduce-25.11.1}/LICENSE +0 -0
  50. {essreduce-25.10.2 → essreduce-25.11.1}/MANIFEST.in +0 -0
  51. {essreduce-25.10.2 → essreduce-25.11.1}/README.md +0 -0
  52. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_static/anaconda-icon.js +0 -0
  53. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_static/favicon.svg +0 -0
  54. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_static/logo-dark.svg +0 -0
  55. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_static/logo.svg +0 -0
  56. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_templates/class-template.rst +0 -0
  57. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_templates/doc_version.html +0 -0
  58. {essreduce-25.10.2 → essreduce-25.11.1}/docs/_templates/module-template.rst +0 -0
  59. {essreduce-25.10.2 → essreduce-25.11.1}/docs/about/index.md +0 -0
  60. {essreduce-25.10.2 → essreduce-25.11.1}/docs/api-reference/index.md +0 -0
  61. {essreduce-25.10.2 → essreduce-25.11.1}/docs/conf.py +0 -0
  62. {essreduce-25.10.2 → essreduce-25.11.1}/docs/developer/coding-conventions.md +0 -0
  63. {essreduce-25.10.2 → essreduce-25.11.1}/docs/developer/dependency-management.md +0 -0
  64. {essreduce-25.10.2 → essreduce-25.11.1}/docs/developer/getting-started.md +0 -0
  65. {essreduce-25.10.2 → essreduce-25.11.1}/docs/developer/gui.ipynb +0 -0
  66. {essreduce-25.10.2 → essreduce-25.11.1}/docs/developer/index.md +0 -0
  67. {essreduce-25.10.2 → essreduce-25.11.1}/docs/index.md +0 -0
  68. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/index.md +0 -0
  69. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/installation.md +0 -0
  70. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/tof/index.md +0 -0
  71. {essreduce-25.10.2 → essreduce-25.11.1}/docs/user-guide/widget.md +0 -0
  72. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/basetest.in +0 -0
  73. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/ci.in +0 -0
  74. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/dev.in +0 -0
  75. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/docs.in +0 -0
  76. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/make_base.py +0 -0
  77. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/mypy.in +0 -0
  78. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/mypy.txt +0 -0
  79. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/nightly.in +0 -0
  80. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/static.in +0 -0
  81. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/test.in +0 -0
  82. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/test.txt +0 -0
  83. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/wheels.in +0 -0
  84. {essreduce-25.10.2 → essreduce-25.11.1}/requirements/wheels.txt +0 -0
  85. {essreduce-25.10.2 → essreduce-25.11.1}/resources/logo.svg +0 -0
  86. {essreduce-25.10.2 → essreduce-25.11.1}/setup.cfg +0 -0
  87. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/__init__.py +0 -0
  88. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/data/__init__.py +0 -0
  89. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/data/_registry.py +0 -0
  90. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/live/__init__.py +0 -0
  91. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/live/roi.py +0 -0
  92. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/live/workflow.py +0 -0
  93. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/logging.py +0 -0
  94. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/__init__.py +0 -0
  95. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/_nexus_loader.py +0 -0
  96. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/json_generator.py +0 -0
  97. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/nexus/json_nexus.py +0 -0
  98. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/parameter.py +0 -0
  99. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/py.typed +0 -0
  100. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/scripts/grow_nexus.py +0 -0
  101. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/streaming.py +0 -0
  102. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/fakes.py +0 -0
  103. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/interpolator_numba.py +0 -0
  104. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/interpolator_scipy.py +0 -0
  105. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/resample.py +0 -0
  106. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/time_of_flight/workflow.py +0 -0
  107. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/ui.py +0 -0
  108. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/uncertainty.py +0 -0
  109. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/__init__.py +0 -0
  110. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_base.py +0 -0
  111. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_binedges_widget.py +0 -0
  112. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_bounds_widget.py +0 -0
  113. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_config.py +0 -0
  114. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_filename_widget.py +0 -0
  115. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_linspace_widget.py +0 -0
  116. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_optional_widget.py +0 -0
  117. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_spinner.py +0 -0
  118. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_string_widget.py +0 -0
  119. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_switchable_widget.py +0 -0
  120. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/widgets/_vector_widget.py +0 -0
  121. {essreduce-25.10.2 → essreduce-25.11.1}/src/ess/reduce/workflow.py +0 -0
  122. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/SOURCES.txt +0 -0
  123. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/dependency_links.txt +0 -0
  124. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/entry_points.txt +0 -0
  125. {essreduce-25.10.2 → essreduce-25.11.1}/src/essreduce.egg-info/top_level.txt +0 -0
  126. {essreduce-25.10.2 → essreduce-25.11.1}/tests/accumulators_test.py +0 -0
  127. {essreduce-25.10.2 → essreduce-25.11.1}/tests/live/raw_test.py +0 -0
  128. {essreduce-25.10.2 → essreduce-25.11.1}/tests/live/roi_test.py +0 -0
  129. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_generator_test.py +0 -0
  130. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/array_dataset.json +0 -0
  131. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/dataset.json +0 -0
  132. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/detector.json +0 -0
  133. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/entry.json +0 -0
  134. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/event_data.json +0 -0
  135. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/instrument.json +0 -0
  136. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_examples/log.json +0 -0
  137. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/json_nexus_test.py +0 -0
  138. {essreduce-25.10.2 → essreduce-25.11.1}/tests/nexus/nexus_loader_test.py +0 -0
  139. {essreduce-25.10.2 → essreduce-25.11.1}/tests/package_test.py +0 -0
  140. {essreduce-25.10.2 → essreduce-25.11.1}/tests/scripts/test_grow_nexus.py +0 -0
  141. {essreduce-25.10.2 → essreduce-25.11.1}/tests/streaming_test.py +0 -0
  142. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/interpolator_test.py +0 -0
  143. {essreduce-25.10.2 → essreduce-25.11.1}/tests/time_of_flight/resample_tests.py +0 -0
  144. {essreduce-25.10.2 → essreduce-25.11.1}/tests/uncertainty_test.py +0 -0
  145. {essreduce-25.10.2 → essreduce-25.11.1}/tests/widget_test.py +0 -0
  146. {essreduce-25.10.2 → essreduce-25.11.1}/tools/shrink_nexus.py +0 -0
  147. {essreduce-25.10.2 → essreduce-25.11.1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: essreduce
3
- Version: 25.10.2
3
+ Version: 25.11.1
4
4
  Summary: Common data reduction tools for the ESS facility
5
5
  Author: Scipp contributors
6
6
  License-Expression: BSD-3-Clause
@@ -20,7 +20,7 @@ Classifier: Typing :: Typed
20
20
  Requires-Python: >=3.11
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: sciline>=25.05.1
23
+ Requires-Dist: sciline>=25.11.0
24
24
  Requires-Dist: scipp>=25.04.0
25
25
  Requires-Dist: scippneutron>=25.02.0
26
26
  Requires-Dist: scippnexus>=25.06.0
@@ -146,6 +146,69 @@ workflow.visualize(Result)
146
146
  workflow.compute(Result)
147
147
  ```
148
148
 
149
+ ### C.6: Domain types for data products
150
+
151
+ Data types that flow through the reduction workflow should follow a systematic naming convention that reflects their processing stage and coordinate space. This ensures consistency across instruments and techniques, making workflows more transferable and easier to understand.
152
+
153
+ **Type structure**
154
+
155
+ Domain types use a **prefix-suffix** pattern:
156
+ - **Prefix**: Describes the processing stage (e.g., `Raw`, `Tof`, `Corrected`, `Normalized`)
157
+ - **Suffix**: Describes the coordinate space or component (e.g., `Monitor`, `Detector`, `Q`, `Dspacing`, `Energy`)
158
+
159
+ **Monitor types**
160
+
161
+ Monitors follow a linear progression through processing stages:
162
+
163
+ ```
164
+ EmptyMonitor # Geometry only, calibrated
165
+ RawMonitor # With counts
166
+ TofMonitor # Time-of-flight domain
167
+ WavelengthMonitor # Wavelength domain (end of monitor chain)
168
+ ```
169
+
170
+ **Detector types**
171
+
172
+ Detectors progress through both processing stages and move from "detector space" (pixel space) to, e.g., Q-space:
173
+
174
+ ```
175
+ EmptyDetector # Geometry only, calibrated, pixel-masked
176
+ RawDetector # With counts
177
+ TofDetector # With added time-of-flight coord
178
+ WavelengthDetector # With added wavelength coord
179
+ CorrectedDetector # Corrections applied (masking, filtering, efficiency, Lorentz, absorption)
180
+ CorrectedQ # Transformed to Q-space, pixels reduced
181
+ NormalizedQ # Normalized (to monitor, proton charge)
182
+ IntensityQ # Absolute intensity, e.g., normalized to vanadium
183
+ ```
184
+
185
+ Alternative domain-specific names to, e.g., `IntensityQ` such as `ReflectivityQ` are also valid.
186
+
187
+ **Coordinate space variants**
188
+
189
+ The final coordinate space (`Q` in the example above) should be replaced with the appropriate space for the technique:
190
+ - `Dspacing` for d-spacing coordinates
191
+ - `EnergyTransfer` for energy transfer
192
+ - `TwoTheta` for scattering angle
193
+ - Multiple dimensions can be combined: `DspacingTwoTheta`
194
+
195
+ For example, a powder diffraction workflow might use:
196
+ ```
197
+ CorrectedDetector → CorrectedDspacing → NormalizedDspacing → IntensityDspacing
198
+ ```
199
+
200
+ **Guidelines**
201
+
202
+ 1. **Maintain the standard progression**: Keep processing stages separate unless there's a scientific reason to combine them (e.g., computational efficiency for a specific technique).
203
+
204
+ 2. **Prefix carries forward**: When transforming coordinate spaces without additional processing, the prefix carries forward (e.g., `CorrectedDetector` → `CorrectedQ`).
205
+
206
+ 3. **Skip only when appropriate**: Stages can be skipped if they don't exist for a particular technique, but avoid skipping for convenience alone.
207
+
208
+ 4. **Be explicit about the space**: Always include the coordinate space or component in the suffix to make the data's nature clear.
209
+
210
+ 5. **Consistency across instruments**: Use the same type names for equivalent processing stages across different instruments and techniques to facilitate knowledge transfer.
211
+
149
212
  ## D: Documentation
150
213
 
151
214
  ### D.1: Document math and references in docstrings
@@ -24,7 +24,7 @@
24
24
  "import plopp as pp\n",
25
25
  "import scipp as sc\n",
26
26
  "from scippneutron.chopper import DiskChopper\n",
27
- "from ess.reduce.nexus.types import DetectorData, SampleRun\n",
27
+ "from ess.reduce.nexus.types import AnyRun, RawDetector, SampleRun\n",
28
28
  "from ess.reduce.time_of_flight import *"
29
29
  ]
30
30
  },
@@ -300,10 +300,10 @@
300
300
  "source": [
301
301
  "wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])\n",
302
302
  "\n",
303
- "wf[DetectorData[SampleRun]] = raw_data\n",
303
+ "wf[RawDetector[SampleRun]] = raw_data\n",
304
304
  "wf[DetectorLtotal[SampleRun]] = Ltotal\n",
305
305
  "\n",
306
- "wf.visualize(DetectorTofData[SampleRun])"
306
+ "wf.visualize(TofDetector[SampleRun])"
307
307
  ]
308
308
  },
309
309
  {
@@ -340,7 +340,7 @@
340
340
  "outputs": [],
341
341
  "source": [
342
342
  "lut_wf = TofLookupTableWorkflow()\n",
343
- "lut_wf[DiskChoppers] = disk_choppers\n",
343
+ "lut_wf[DiskChoppers[AnyRun]] = disk_choppers\n",
344
344
  "lut_wf[SourcePosition] = source_position\n",
345
345
  "lut_wf[LtotalRange] = (\n",
346
346
  " sc.scalar(75.5, unit=\"m\"),\n",
@@ -436,7 +436,6 @@
436
436
  ]
437
437
  },
438
438
  {
439
- "attachments": {},
440
439
  "cell_type": "markdown",
441
440
  "id": "30",
442
441
  "metadata": {},
@@ -457,7 +456,7 @@
457
456
  "wf[TimeOfFlightLookupTable] = table\n",
458
457
  "\n",
459
458
  "# Compute time-of-flight of neutron events\n",
460
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
459
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
461
460
  "tofs"
462
461
  ]
463
462
  },
@@ -616,11 +615,11 @@
616
615
  "outputs": [],
617
616
  "source": [
618
617
  "# Update workflow\n",
619
- "wf[DetectorData[SampleRun]] = raw_data\n",
618
+ "wf[RawDetector[SampleRun]] = raw_data\n",
620
619
  "wf[DetectorLtotal[SampleRun]] = Ltotal\n",
621
620
  "\n",
622
621
  "# Compute tofs and wavelengths\n",
623
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
622
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
624
623
  "wav_wfm = tofs.transform_coords(\"wavelength\", graph=graph)\n",
625
624
  "\n",
626
625
  "# Compare in plot\n",
@@ -713,7 +712,7 @@
713
712
  "outputs": [],
714
713
  "source": [
715
714
  "# Update workflow\n",
716
- "lut_wf[DiskChoppers] = disk_choppers\n",
715
+ "lut_wf[DiskChoppers[AnyRun]] = disk_choppers\n",
717
716
  "\n",
718
717
  "sim = lut_wf.compute(SimulationResults)\n",
719
718
  "\n",
@@ -795,13 +794,13 @@
795
794
  "metadata": {},
796
795
  "outputs": [],
797
796
  "source": [
798
- "wf[DetectorData[SampleRun]] = ess_beamline.get_monitor(\"detector\")[0]\n",
797
+ "wf[RawDetector[SampleRun]] = ess_beamline.get_monitor(\"detector\")[0]\n",
799
798
  "wf[DetectorLtotal[SampleRun]] = Ltotal\n",
800
799
  "\n",
801
800
  "wf[TimeOfFlightLookupTable] = table\n",
802
801
  "\n",
803
802
  "# Compute time-of-flight\n",
804
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
803
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
805
804
  "# Compute wavelength\n",
806
805
  "wav_wfm = tofs.transform_coords(\"wavelength\", graph=graph)\n",
807
806
  "\n",
@@ -823,17 +822,6 @@
823
822
  "display_name": "Python 3 (ipykernel)",
824
823
  "language": "python",
825
824
  "name": "python3"
826
- },
827
- "language_info": {
828
- "codemirror_mode": {
829
- "name": "ipython",
830
- "version": 3
831
- },
832
- "file_extension": ".py",
833
- "mimetype": "text/x-python",
834
- "name": "python",
835
- "nbconvert_exporter": "python",
836
- "pygments_lexer": "ipython3"
837
825
  }
838
826
  },
839
827
  "nbformat": 4,
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "cells": [
3
3
  {
4
- "attachments": {},
5
4
  "cell_type": "markdown",
6
5
  "id": "0",
7
6
  "metadata": {},
@@ -32,7 +31,7 @@
32
31
  "import plopp as pp\n",
33
32
  "import scipp as sc\n",
34
33
  "from scippneutron.chopper import DiskChopper\n",
35
- "from ess.reduce.nexus.types import DetectorData, SampleRun\n",
34
+ "from ess.reduce.nexus.types import AnyRun, RawDetector, SampleRun\n",
36
35
  "from ess.reduce.time_of_flight import *\n",
37
36
  "import tof\n",
38
37
  "\n",
@@ -161,10 +160,10 @@
161
160
  "source": [
162
161
  "wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])\n",
163
162
  "\n",
164
- "wf[DetectorData[SampleRun]] = nxevent_data\n",
163
+ "wf[RawDetector[SampleRun]] = nxevent_data\n",
165
164
  "wf[DetectorLtotal[SampleRun]] = nxevent_data.coords[\"Ltotal\"]\n",
166
165
  "\n",
167
- "wf.visualize(DetectorTofData[SampleRun])"
166
+ "wf.visualize(TofDetector[SampleRun])"
168
167
  ]
169
168
  },
170
169
  {
@@ -212,7 +211,7 @@
212
211
  "source": [
213
212
  "lut_wf = TofLookupTableWorkflow()\n",
214
213
  "lut_wf[LtotalRange] = detectors[0].distance, detectors[-1].distance\n",
215
- "lut_wf[DiskChoppers] = {\n",
214
+ "lut_wf[DiskChoppers[AnyRun]] = {\n",
216
215
  " \"chopper\": DiskChopper(\n",
217
216
  " frequency=-chopper.frequency,\n",
218
217
  " beam_position=sc.scalar(0.0, unit=\"deg\"),\n",
@@ -271,7 +270,7 @@
271
270
  "wf[TimeOfFlightLookupTable] = table\n",
272
271
  "\n",
273
272
  "# Compute neutron tofs\n",
274
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
273
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
275
274
  "\n",
276
275
  "tof_hist = tofs.hist(tof=sc.scalar(500.0, unit=\"us\"))\n",
277
276
  "pp.plot({det.name: tof_hist[\"detector_number\", i] for i, det in enumerate(detectors)})"
@@ -399,7 +398,7 @@
399
398
  "lut_wf = TofLookupTableWorkflow()\n",
400
399
  "lut_wf[PulseStride] = 2\n",
401
400
  "lut_wf[LtotalRange] = detectors[0].distance, detectors[-1].distance\n",
402
- "lut_wf[DiskChoppers] = {\n",
401
+ "lut_wf[DiskChoppers[AnyRun]] = {\n",
403
402
  " ch.name: DiskChopper(\n",
404
403
  " frequency=-ch.frequency,\n",
405
404
  " beam_position=sc.scalar(0.0, unit=\"deg\"),\n",
@@ -456,11 +455,11 @@
456
455
  "# Reduction workflow\n",
457
456
  "wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])\n",
458
457
  "nxevent_data = results.to_nxevent_data()\n",
459
- "wf[DetectorData[SampleRun]] = nxevent_data\n",
458
+ "wf[RawDetector[SampleRun]] = nxevent_data\n",
460
459
  "wf[DetectorLtotal[SampleRun]] = nxevent_data.coords[\"Ltotal\"]\n",
461
460
  "wf[TimeOfFlightLookupTable] = table\n",
462
461
  "\n",
463
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
462
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
464
463
  "\n",
465
464
  "tof_hist = tofs.hist(tof=sc.scalar(500.0, unit=\"us\"))\n",
466
465
  "pp.plot({det.name: tof_hist[\"detector_number\", i] for i, det in enumerate(detectors)})"
@@ -500,24 +499,7 @@
500
499
  ]
501
500
  }
502
501
  ],
503
- "metadata": {
504
- "kernelspec": {
505
- "display_name": "Python 3 (ipykernel)",
506
- "language": "python",
507
- "name": "python3"
508
- },
509
- "language_info": {
510
- "codemirror_mode": {
511
- "name": "ipython",
512
- "version": 3
513
- },
514
- "file_extension": ".py",
515
- "mimetype": "text/x-python",
516
- "name": "python",
517
- "nbconvert_exporter": "python",
518
- "pygments_lexer": "ipython3"
519
- }
520
- },
502
+ "metadata": {},
521
503
  "nbformat": 4,
522
504
  "nbformat_minor": 5
523
505
  }
@@ -25,7 +25,7 @@
25
25
  "import plopp as pp\n",
26
26
  "import scipp as sc\n",
27
27
  "from scippneutron.chopper import DiskChopper\n",
28
- "from ess.reduce.nexus.types import DetectorData, SampleRun\n",
28
+ "from ess.reduce.nexus.types import AnyRun, RawDetector, SampleRun\n",
29
29
  "from ess.reduce.time_of_flight import *"
30
30
  ]
31
31
  },
@@ -321,10 +321,10 @@
321
321
  "source": [
322
322
  "wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])\n",
323
323
  "\n",
324
- "wf[DetectorData[SampleRun]] = raw_data\n",
324
+ "wf[RawDetector[SampleRun]] = raw_data\n",
325
325
  "wf[DetectorLtotal[SampleRun]] = Ltotal\n",
326
326
  "\n",
327
- "wf.visualize(DetectorTofData[SampleRun])"
327
+ "wf.visualize(TofDetector[SampleRun])"
328
328
  ]
329
329
  },
330
330
  {
@@ -361,7 +361,7 @@
361
361
  "outputs": [],
362
362
  "source": [
363
363
  "lut_wf = TofLookupTableWorkflow()\n",
364
- "lut_wf[DiskChoppers] = disk_choppers\n",
364
+ "lut_wf[DiskChoppers[AnyRun]] = disk_choppers\n",
365
365
  "lut_wf[SourcePosition] = source_position\n",
366
366
  "lut_wf[LtotalRange] = Ltotal, Ltotal\n",
367
367
  "lut_wf[LookupTableRelativeErrorThreshold] = 0.1\n",
@@ -442,7 +442,6 @@
442
442
  ]
443
443
  },
444
444
  {
445
- "attachments": {},
446
445
  "cell_type": "markdown",
447
446
  "id": "27",
448
447
  "metadata": {},
@@ -466,7 +465,7 @@
466
465
  "source": [
467
466
  "wf[TimeOfFlightLookupTable] = table\n",
468
467
  "\n",
469
- "tofs = wf.compute(DetectorTofData[SampleRun])\n",
468
+ "tofs = wf.compute(TofDetector[SampleRun])\n",
470
469
  "tofs"
471
470
  ]
472
471
  },
@@ -549,24 +548,7 @@
549
548
  ]
550
549
  }
551
550
  ],
552
- "metadata": {
553
- "kernelspec": {
554
- "display_name": "Python 3 (ipykernel)",
555
- "language": "python",
556
- "name": "python3"
557
- },
558
- "language_info": {
559
- "codemirror_mode": {
560
- "name": "ipython",
561
- "version": 3
562
- },
563
- "file_extension": ".py",
564
- "mimetype": "text/x-python",
565
- "name": "python",
566
- "nbconvert_exporter": "python",
567
- "pygments_lexer": "ipython3"
568
- }
569
- },
551
+ "metadata": {},
570
552
  "nbformat": 4,
571
553
  "nbformat_minor": 5
572
554
  }
@@ -30,7 +30,7 @@ requires-python = ">=3.11"
30
30
  # Run 'tox -e deps' after making changes here. This will update requirement files.
31
31
  # Make sure to list one dependency per line.
32
32
  dependencies = [
33
- "sciline>=25.05.1",
33
+ "sciline>=25.11.0",
34
34
  "scipp>=25.04.0",
35
35
  "scippneutron>=25.02.0",
36
36
  "scippnexus>=25.06.0",
@@ -2,7 +2,7 @@
2
2
  # will not be touched by ``make_base.py``
3
3
  # --- END OF CUSTOM SECTION ---
4
4
  # The following was generated by 'tox -e deps', DO NOT EDIT MANUALLY!
5
- sciline>=25.05.1
5
+ sciline>=25.11.0
6
6
  scipp>=25.04.0
7
7
  scippneutron>=25.02.0
8
8
  scippnexus>=25.06.0
@@ -1,4 +1,4 @@
1
- # SHA1:99f16c205324f8050cb96af707a607064a1a39a3
1
+ # SHA1:e86f9d2876cf304569910ff89826c8e5aac84bf8
2
2
  #
3
3
  # This file was generated by pip-compile-multi.
4
4
  # To update, run:
@@ -66,9 +66,9 @@ python-dateutil==2.9.0.post0
66
66
  # matplotlib
67
67
  # scippneutron
68
68
  # scippnexus
69
- sciline==25.8.0
69
+ sciline==25.11.0
70
70
  # via -r base.in
71
- scipp==25.8.0
71
+ scipp==25.11.0
72
72
  # via
73
73
  # -r base.in
74
74
  # scippneutron
@@ -79,7 +79,7 @@ scippnexus==25.6.0
79
79
  # via
80
80
  # -r base.in
81
81
  # scippneutron
82
- scipy==1.16.2
82
+ scipy==1.16.3
83
83
  # via
84
84
  # scippneutron
85
85
  # scippnexus
@@ -31,11 +31,11 @@ ipython==9.6.0
31
31
  # via ipywidgets
32
32
  ipython-pygments-lexers==1.1.1
33
33
  # via ipython
34
- ipywidgets==8.1.7
34
+ ipywidgets==8.1.8
35
35
  # via -r basetest.in
36
36
  jedi==0.19.2
37
37
  # via ipython
38
- jupyterlab-widgets==3.0.15
38
+ jupyterlab-widgets==3.0.16
39
39
  # via ipywidgets
40
40
  kiwisolver==1.4.9
41
41
  # via matplotlib
@@ -97,9 +97,9 @@ python-dateutil==2.9.0.post0
97
97
  # via matplotlib
98
98
  requests==2.32.5
99
99
  # via pooch
100
- scipp==25.8.0
100
+ scipp==25.11.0
101
101
  # via tof
102
- scipy==1.16.2
102
+ scipy==1.16.3
103
103
  # via
104
104
  # -r basetest.in
105
105
  # tof
@@ -120,5 +120,5 @@ urllib3==2.5.0
120
120
  # via requests
121
121
  wcwidth==0.2.14
122
122
  # via prompt-toolkit
123
- widgetsnbextension==4.0.14
123
+ widgetsnbextension==4.0.15
124
124
  # via ipywidgets
@@ -48,5 +48,5 @@ tox==4.32.0
48
48
  # via -r ci.in
49
49
  urllib3==2.5.0
50
50
  # via requests
51
- virtualenv==20.35.3
51
+ virtualenv==20.35.4
52
52
  # via tox
@@ -83,7 +83,7 @@ pip-compile-multi==3.2.2
83
83
  # via -r dev.in
84
84
  pip-tools==7.5.1
85
85
  # via pip-compile-multi
86
- plumbum==1.9.0
86
+ plumbum==1.10.0
87
87
  # via copier
88
88
  prometheus-client==0.23.1
89
89
  # via jupyter-server
@@ -117,7 +117,7 @@ tzdata==2025.2
117
117
  # via arrow
118
118
  uri-template==1.3.0
119
119
  # via jsonschema
120
- webcolors==24.11.1
120
+ webcolors==25.10.0
121
121
  # via jsonschema
122
122
  websocket-client==1.9.0
123
123
  # via jupyter-server
@@ -65,7 +65,7 @@ ipython==9.6.0
65
65
  # ipywidgets
66
66
  ipython-pygments-lexers==1.1.1
67
67
  # via ipython
68
- ipywidgets==8.1.7
68
+ ipywidgets==8.1.8
69
69
  # via -r docs.in
70
70
  jedi==0.19.2
71
71
  # via ipython
@@ -92,7 +92,7 @@ jupyter-core==5.9.1
92
92
  # nbformat
93
93
  jupyterlab-pygments==0.3.0
94
94
  # via nbconvert
95
- jupyterlab-widgets==3.0.15
95
+ jupyterlab-widgets==3.0.16
96
96
  # via ipywidgets
97
97
  llvmlite==0.45.1
98
98
  # via numba
@@ -141,7 +141,7 @@ platformdirs==4.5.0
141
141
  # via jupyter-core
142
142
  prompt-toolkit==3.0.52
143
143
  # via ipython
144
- psutil==7.1.2
144
+ psutil==7.1.3
145
145
  # via ipykernel
146
146
  ptyprocess==0.7.0
147
147
  # via pexpect
@@ -239,5 +239,5 @@ webencodings==0.5.1
239
239
  # via
240
240
  # bleach
241
241
  # tinycss2
242
- widgetsnbextension==4.0.14
242
+ widgetsnbextension==4.0.15
243
243
  # via ipywidgets
@@ -50,11 +50,11 @@ ipython==9.6.0
50
50
  # via ipywidgets
51
51
  ipython-pygments-lexers==1.1.1
52
52
  # via ipython
53
- ipywidgets==8.1.7
53
+ ipywidgets==8.1.8
54
54
  # via -r nightly.in
55
55
  jedi==0.19.2
56
56
  # via ipython
57
- jupyterlab-widgets==3.0.15
57
+ jupyterlab-widgets==3.0.16
58
58
  # via ipywidgets
59
59
  kiwisolver==1.4.10rc0
60
60
  # via matplotlib
@@ -147,7 +147,7 @@ scippnexus @ git+https://github.com/scipp/scippnexus@main
147
147
  # via
148
148
  # -r nightly.in
149
149
  # scippneutron
150
- scipy==1.16.2
150
+ scipy==1.16.3
151
151
  # via
152
152
  # -r nightly.in
153
153
  # scippneutron
@@ -177,5 +177,5 @@ urllib3==2.5.0
177
177
  # via requests
178
178
  wcwidth==0.2.14
179
179
  # via prompt-toolkit
180
- widgetsnbextension==4.0.14
180
+ widgetsnbextension==4.0.15
181
181
  # via ipywidgets
@@ -21,5 +21,5 @@ pre-commit==4.3.0
21
21
  # via -r static.in
22
22
  pyyaml==6.0.3
23
23
  # via pre-commit
24
- virtualenv==20.35.3
24
+ virtualenv==20.35.4
25
25
  # via pre-commit
@@ -29,7 +29,7 @@ import scipp as sc
29
29
  import scippnexus as snx
30
30
 
31
31
  from ess.reduce.nexus.types import (
32
- CalibratedDetector,
32
+ EmptyDetector,
33
33
  Filename,
34
34
  NeXusComponent,
35
35
  NeXusDetectorName,
@@ -305,7 +305,7 @@ class RollingDetectorView(Detector):
305
305
 
306
306
  @staticmethod
307
307
  def from_detector_and_histogrammer(
308
- detector: CalibratedDetector[SampleRun],
308
+ detector: EmptyDetector[SampleRun],
309
309
  window: RollingDetectorViewWindow,
310
310
  projection: Histogrammer,
311
311
  ) -> RollingDetectorView:
@@ -320,10 +320,10 @@ class RollingDetectorView(Detector):
320
320
  def from_detector_with_projection(
321
321
  projection: Callable[[sc.DataArray], sc.DataArray] | None,
322
322
  ) -> Callable[
323
- [CalibratedDetector[SampleRun], RollingDetectorViewWindow], RollingDetectorView
323
+ [EmptyDetector[SampleRun], RollingDetectorViewWindow], RollingDetectorView
324
324
  ]:
325
325
  def factory(
326
- detector: CalibratedDetector[SampleRun],
326
+ detector: EmptyDetector[SampleRun],
327
327
  window: RollingDetectorViewWindow,
328
328
  ) -> RollingDetectorView:
329
329
  """Helper for constructing via a Sciline workflow."""
@@ -591,7 +591,7 @@ def gaussian_position_noise(sigma: PositionNoiseSigma) -> PositionNoise:
591
591
 
592
592
  def position_with_noisy_replicas(
593
593
  *,
594
- detector: CalibratedDetector[SampleRun],
594
+ detector: EmptyDetector[SampleRun],
595
595
  position_noise: PositionNoise,
596
596
  replicas: PositionNoiseReplicaCount,
597
597
  ) -> CalibratedPositionWithNoisyReplicas:
@@ -40,6 +40,14 @@ PreopenNeXusFile = NewType('PreopenNeXusFile', bool)
40
40
  # 1 TypeVars used to parametrize the generic parts of the workflow
41
41
 
42
42
  # 1.1 Run types
43
+
44
+ AnyRun = NewType("AnyRun", int)
45
+ """RunType that does not represent a specific measurement run.
46
+
47
+ This can be used in cases where it makes no sense to use an 'actual' run type
48
+ like ``SampleRun`` or ``BackgroundRun``.
49
+ """
50
+
43
51
  BackgroundRun = NewType('BackgroundRun', int)
44
52
  """Background run such as a run with only a solvent which the sample is placed in."""
45
53
  EmptyBeamRun = NewType('EmptyBeamRun', int)
@@ -136,12 +144,17 @@ This list will be supplemented with monitor types when creating a pipeline.
136
144
  UniqueComponent = TypeVar('UniqueComponent', snx.NXsample, snx.NXsource)
137
145
  """Components that can be identified by their type as there will only be one."""
138
146
 
139
- Beamline = scn_meta.Beamline
140
- """Beamline metadata."""
141
- Measurement = scn_meta.Measurement
142
- """measurement metadata."""
143
- Source = scn_meta.Source
144
- """Neutron source metadata."""
147
+
148
+ class Beamline(scn_meta.Beamline, Generic[RunType]):
149
+ """Beamline metadata."""
150
+
151
+
152
+ class Measurement(scn_meta.Measurement, Generic[RunType]):
153
+ """measurement metadata."""
154
+
155
+
156
+ class Source(scn_meta.Source, Generic[RunType]):
157
+ """Neutron source metadata."""
145
158
 
146
159
 
147
160
  class NeXusName(sciline.Scope[Component, str], str):
@@ -186,25 +199,19 @@ class MonitorPositionOffset(
186
199
  """Offset for the monitor position, added to base position."""
187
200
 
188
201
 
189
- class CalibratedDetector(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
190
- """Calibrated data from a detector."""
202
+ class EmptyDetector(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
203
+ """Detector without neutron data."""
191
204
 
192
205
 
193
- class CalibratedBeamline(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
194
- """Calibrated beamline with detector and other components."""
195
-
196
-
197
- class CalibratedMonitor(
198
- sciline.Scope[RunType, MonitorType, sc.DataArray], sc.DataArray
199
- ):
200
- """Calibrated data from a monitor."""
206
+ class EmptyMonitor(sciline.Scope[RunType, MonitorType, sc.DataArray], sc.DataArray):
207
+ """Monitor without neutron data."""
201
208
 
202
209
 
203
- class DetectorData(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
210
+ class RawDetector(sciline.Scope[RunType, sc.DataArray], sc.DataArray):
204
211
  """Calibrated detector merged with neutron event or histogram data."""
205
212
 
206
213
 
207
- class MonitorData(sciline.Scope[RunType, MonitorType, sc.DataArray], sc.DataArray):
214
+ class RawMonitor(sciline.Scope[RunType, MonitorType, sc.DataArray], sc.DataArray):
208
215
  """Calibrated monitor merged with neutron event or histogram data."""
209
216
 
210
217