essreduce 25.12.1__tar.gz → 26.1.0__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 (149) hide show
  1. {essreduce-25.12.1 → essreduce-26.1.0}/PKG-INFO +1 -1
  2. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/tof/dream.ipynb +7 -7
  3. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/tof/frame-unwrapping.ipynb +6 -6
  4. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/tof/wfm.ipynb +4 -4
  5. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/base.txt +1 -1
  6. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/basetest.txt +1 -1
  7. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/__init__.py +4 -0
  8. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/eto_to_tof.py +8 -8
  9. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/lut.py +5 -5
  10. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/types.py +9 -2
  11. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/workflow.py +5 -5
  12. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/PKG-INFO +1 -1
  13. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/lut_test.py +4 -4
  14. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/unwrap_test.py +3 -9
  15. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/wfm_test.py +1 -3
  16. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/workflow_test.py +76 -11
  17. {essreduce-25.12.1 → essreduce-26.1.0}/.copier-answers.ess.yml +0 -0
  18. {essreduce-25.12.1 → essreduce-26.1.0}/.copier-answers.yml +0 -0
  19. {essreduce-25.12.1 → essreduce-26.1.0}/.github/ISSUE_TEMPLATE/high-level-requirement.yml +0 -0
  20. {essreduce-25.12.1 → essreduce-26.1.0}/.github/dependabot.yml +0 -0
  21. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/ci.yml +0 -0
  22. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/docs.yml +0 -0
  23. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/nightly_at_main.yml +0 -0
  24. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/nightly_at_main_lower_bound.yml +0 -0
  25. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/nightly_at_release.yml +0 -0
  26. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/python-version-ci +0 -0
  27. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/release.yml +0 -0
  28. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/test.yml +0 -0
  29. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/unpinned.yml +0 -0
  30. {essreduce-25.12.1 → essreduce-26.1.0}/.github/workflows/weekly_windows_macos.yml +0 -0
  31. {essreduce-25.12.1 → essreduce-26.1.0}/.gitignore +0 -0
  32. {essreduce-25.12.1 → essreduce-26.1.0}/.pre-commit-config.yaml +0 -0
  33. {essreduce-25.12.1 → essreduce-26.1.0}/.python-version +0 -0
  34. {essreduce-25.12.1 → essreduce-26.1.0}/CODE_OF_CONDUCT.md +0 -0
  35. {essreduce-25.12.1 → essreduce-26.1.0}/CONTRIBUTING.md +0 -0
  36. {essreduce-25.12.1 → essreduce-26.1.0}/LICENSE +0 -0
  37. {essreduce-25.12.1 → essreduce-26.1.0}/MANIFEST.in +0 -0
  38. {essreduce-25.12.1 → essreduce-26.1.0}/README.md +0 -0
  39. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_static/anaconda-icon.js +0 -0
  40. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_static/favicon.svg +0 -0
  41. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_static/logo-dark.svg +0 -0
  42. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_static/logo.svg +0 -0
  43. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_templates/class-template.rst +0 -0
  44. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_templates/doc_version.html +0 -0
  45. {essreduce-25.12.1 → essreduce-26.1.0}/docs/_templates/module-template.rst +0 -0
  46. {essreduce-25.12.1 → essreduce-26.1.0}/docs/about/index.md +0 -0
  47. {essreduce-25.12.1 → essreduce-26.1.0}/docs/api-reference/index.md +0 -0
  48. {essreduce-25.12.1 → essreduce-26.1.0}/docs/conf.py +0 -0
  49. {essreduce-25.12.1 → essreduce-26.1.0}/docs/developer/coding-conventions.md +0 -0
  50. {essreduce-25.12.1 → essreduce-26.1.0}/docs/developer/dependency-management.md +0 -0
  51. {essreduce-25.12.1 → essreduce-26.1.0}/docs/developer/getting-started.md +0 -0
  52. {essreduce-25.12.1 → essreduce-26.1.0}/docs/developer/gui.ipynb +0 -0
  53. {essreduce-25.12.1 → essreduce-26.1.0}/docs/developer/index.md +0 -0
  54. {essreduce-25.12.1 → essreduce-26.1.0}/docs/index.md +0 -0
  55. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/index.md +0 -0
  56. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/installation.md +0 -0
  57. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/reduction-workflow-guidelines.md +0 -0
  58. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/tof/index.md +0 -0
  59. {essreduce-25.12.1 → essreduce-26.1.0}/docs/user-guide/widget.md +0 -0
  60. {essreduce-25.12.1 → essreduce-26.1.0}/pyproject.toml +0 -0
  61. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/base.in +0 -0
  62. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/basetest.in +0 -0
  63. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/ci.in +0 -0
  64. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/ci.txt +0 -0
  65. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/dev.in +0 -0
  66. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/dev.txt +0 -0
  67. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/docs.in +0 -0
  68. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/docs.txt +0 -0
  69. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/make_base.py +0 -0
  70. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/mypy.in +0 -0
  71. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/mypy.txt +0 -0
  72. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/nightly.in +0 -0
  73. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/nightly.txt +0 -0
  74. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/static.in +0 -0
  75. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/static.txt +0 -0
  76. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/test.in +0 -0
  77. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/test.txt +0 -0
  78. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/wheels.in +0 -0
  79. {essreduce-25.12.1 → essreduce-26.1.0}/requirements/wheels.txt +0 -0
  80. {essreduce-25.12.1 → essreduce-26.1.0}/resources/logo.svg +0 -0
  81. {essreduce-25.12.1 → essreduce-26.1.0}/setup.cfg +0 -0
  82. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/__init__.py +0 -0
  83. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/data/__init__.py +0 -0
  84. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/data/_registry.py +0 -0
  85. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/live/__init__.py +0 -0
  86. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/live/raw.py +0 -0
  87. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/live/roi.py +0 -0
  88. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/live/workflow.py +0 -0
  89. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/logging.py +0 -0
  90. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/__init__.py +0 -0
  91. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/_nexus_loader.py +0 -0
  92. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/json_generator.py +0 -0
  93. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/json_nexus.py +0 -0
  94. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/types.py +0 -0
  95. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/nexus/workflow.py +0 -0
  96. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/normalization.py +0 -0
  97. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/parameter.py +0 -0
  98. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/py.typed +0 -0
  99. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/scripts/grow_nexus.py +0 -0
  100. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/streaming.py +0 -0
  101. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/fakes.py +0 -0
  102. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/interpolator_numba.py +0 -0
  103. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/interpolator_scipy.py +0 -0
  104. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/time_of_flight/resample.py +0 -0
  105. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/ui.py +0 -0
  106. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/uncertainty.py +0 -0
  107. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/__init__.py +0 -0
  108. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_base.py +0 -0
  109. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_binedges_widget.py +0 -0
  110. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_bounds_widget.py +0 -0
  111. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_config.py +0 -0
  112. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_filename_widget.py +0 -0
  113. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_linspace_widget.py +0 -0
  114. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_optional_widget.py +0 -0
  115. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_spinner.py +0 -0
  116. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_string_widget.py +0 -0
  117. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_switchable_widget.py +0 -0
  118. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/widgets/_vector_widget.py +0 -0
  119. {essreduce-25.12.1 → essreduce-26.1.0}/src/ess/reduce/workflow.py +0 -0
  120. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/SOURCES.txt +0 -0
  121. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/dependency_links.txt +0 -0
  122. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/entry_points.txt +0 -0
  123. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/requires.txt +0 -0
  124. {essreduce-25.12.1 → essreduce-26.1.0}/src/essreduce.egg-info/top_level.txt +0 -0
  125. {essreduce-25.12.1 → essreduce-26.1.0}/tests/accumulators_test.py +0 -0
  126. {essreduce-25.12.1 → essreduce-26.1.0}/tests/conftest.py +0 -0
  127. {essreduce-25.12.1 → essreduce-26.1.0}/tests/live/raw_test.py +0 -0
  128. {essreduce-25.12.1 → essreduce-26.1.0}/tests/live/roi_test.py +0 -0
  129. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_generator_test.py +0 -0
  130. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/array_dataset.json +0 -0
  131. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/dataset.json +0 -0
  132. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/detector.json +0 -0
  133. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/entry.json +0 -0
  134. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/event_data.json +0 -0
  135. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/instrument.json +0 -0
  136. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_examples/log.json +0 -0
  137. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/json_nexus_test.py +0 -0
  138. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/nexus_loader_test.py +0 -0
  139. {essreduce-25.12.1 → essreduce-26.1.0}/tests/nexus/workflow_test.py +0 -0
  140. {essreduce-25.12.1 → essreduce-26.1.0}/tests/normalization_test.py +0 -0
  141. {essreduce-25.12.1 → essreduce-26.1.0}/tests/package_test.py +0 -0
  142. {essreduce-25.12.1 → essreduce-26.1.0}/tests/scripts/test_grow_nexus.py +0 -0
  143. {essreduce-25.12.1 → essreduce-26.1.0}/tests/streaming_test.py +0 -0
  144. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/interpolator_test.py +0 -0
  145. {essreduce-25.12.1 → essreduce-26.1.0}/tests/time_of_flight/resample_tests.py +0 -0
  146. {essreduce-25.12.1 → essreduce-26.1.0}/tests/uncertainty_test.py +0 -0
  147. {essreduce-25.12.1 → essreduce-26.1.0}/tests/widget_test.py +0 -0
  148. {essreduce-25.12.1 → essreduce-26.1.0}/tools/shrink_nexus.py +0 -0
  149. {essreduce-25.12.1 → essreduce-26.1.0}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: essreduce
3
- Version: 25.12.1
3
+ Version: 26.1.0
4
4
  Summary: Common data reduction tools for the ESS facility
5
5
  Author: Scipp contributors
6
6
  License-Expression: BSD-3-Clause
@@ -311,7 +311,7 @@
311
311
  "id": "21",
312
312
  "metadata": {},
313
313
  "source": [
314
- "By default, the workflow tries to load a `TimeOfFlightLookupTable` from a file.\n",
314
+ "By default, the workflow tries to load a `TofLookupTable` from a file.\n",
315
315
  "\n",
316
316
  "In this notebook, instead of using such a pre-made file,\n",
317
317
  "we will build our own lookup table from the chopper information and apply it to the workflow."
@@ -346,7 +346,7 @@
346
346
  " sc.scalar(75.5, unit=\"m\"),\n",
347
347
  " sc.scalar(78.0, unit=\"m\"),\n",
348
348
  ")\n",
349
- "lut_wf.visualize(TimeOfFlightLookupTable)"
349
+ "lut_wf.visualize(TofLookupTable)"
350
350
  ]
351
351
  },
352
352
  {
@@ -411,7 +411,7 @@
411
411
  "metadata": {},
412
412
  "outputs": [],
413
413
  "source": [
414
- "table = lut_wf.compute(TimeOfFlightLookupTable)\n",
414
+ "table = lut_wf.compute(TofLookupTable)\n",
415
415
  "\n",
416
416
  "# Overlay mean on the figure above\n",
417
417
  "table.array[\"distance\", 13].plot(ax=fig2.ax, color=\"C1\", ls=\"-\", marker=None)"
@@ -453,7 +453,7 @@
453
453
  "outputs": [],
454
454
  "source": [
455
455
  "# Set the computed lookup table onto the original workflow\n",
456
- "wf[TimeOfFlightLookupTable] = table\n",
456
+ "wf[TofLookupTable] = table\n",
457
457
  "\n",
458
458
  "# Compute time-of-flight of neutron events\n",
459
459
  "tofs = wf.compute(TofDetector[SampleRun])\n",
@@ -743,7 +743,7 @@
743
743
  "metadata": {},
744
744
  "outputs": [],
745
745
  "source": [
746
- "table = lut_wf.compute(TimeOfFlightLookupTable).array\n",
746
+ "table = lut_wf.compute(TofLookupTable).array\n",
747
747
  "table.plot() / (sc.stddevs(table) / sc.values(table)).plot(norm=\"log\")"
748
748
  ]
749
749
  },
@@ -769,7 +769,7 @@
769
769
  "source": [
770
770
  "lut_wf[LookupTableRelativeErrorThreshold] = 0.01\n",
771
771
  "\n",
772
- "table = lut_wf.compute(TimeOfFlightLookupTable)\n",
772
+ "table = lut_wf.compute(TofLookupTable)\n",
773
773
  "table.plot()"
774
774
  ]
775
775
  },
@@ -797,7 +797,7 @@
797
797
  "wf[RawDetector[SampleRun]] = ess_beamline.get_monitor(\"detector\")[0]\n",
798
798
  "wf[DetectorLtotal[SampleRun]] = Ltotal\n",
799
799
  "\n",
800
- "wf[TimeOfFlightLookupTable] = table\n",
800
+ "wf[TofLookupTable] = table\n",
801
801
  "\n",
802
802
  "# Compute time-of-flight\n",
803
803
  "tofs = wf.compute(TofDetector[SampleRun])\n",
@@ -171,7 +171,7 @@
171
171
  "id": "9",
172
172
  "metadata": {},
173
173
  "source": [
174
- "By default, the workflow tries to load a `TimeOfFlightLookupTable` from a file.\n",
174
+ "By default, the workflow tries to load a `TofLookupTable` from a file.\n",
175
175
  "\n",
176
176
  "In this notebook, instead of using such a pre-made file,\n",
177
177
  "we will build our own lookup table from the chopper information and apply it to the workflow.\n",
@@ -227,7 +227,7 @@
227
227
  "}\n",
228
228
  "lut_wf[SourcePosition] = sc.vector([0, 0, 0], unit=\"m\")\n",
229
229
  "\n",
230
- "lut_wf.visualize(TimeOfFlightLookupTable)"
230
+ "lut_wf.visualize(TofLookupTable)"
231
231
  ]
232
232
  },
233
233
  {
@@ -245,7 +245,7 @@
245
245
  "metadata": {},
246
246
  "outputs": [],
247
247
  "source": [
248
- "table = lut_wf.compute(TimeOfFlightLookupTable)\n",
248
+ "table = lut_wf.compute(TofLookupTable)\n",
249
249
  "table.plot()"
250
250
  ]
251
251
  },
@@ -267,7 +267,7 @@
267
267
  "outputs": [],
268
268
  "source": [
269
269
  "# Set the computed lookup table on the original workflow\n",
270
- "wf[TimeOfFlightLookupTable] = table\n",
270
+ "wf[TofLookupTable] = table\n",
271
271
  "\n",
272
272
  "# Compute neutron tofs\n",
273
273
  "tofs = wf.compute(TofDetector[SampleRun])\n",
@@ -432,7 +432,7 @@
432
432
  "metadata": {},
433
433
  "outputs": [],
434
434
  "source": [
435
- "table = lut_wf.compute(TimeOfFlightLookupTable)\n",
435
+ "table = lut_wf.compute(TofLookupTable)\n",
436
436
  "\n",
437
437
  "table.plot(figsize=(9, 4))"
438
438
  ]
@@ -457,7 +457,7 @@
457
457
  "nxevent_data = results.to_nxevent_data()\n",
458
458
  "wf[RawDetector[SampleRun]] = nxevent_data\n",
459
459
  "wf[DetectorLtotal[SampleRun]] = nxevent_data.coords[\"Ltotal\"]\n",
460
- "wf[TimeOfFlightLookupTable] = table\n",
460
+ "wf[TofLookupTable] = table\n",
461
461
  "\n",
462
462
  "tofs = wf.compute(TofDetector[SampleRun])\n",
463
463
  "\n",
@@ -332,7 +332,7 @@
332
332
  "id": "20",
333
333
  "metadata": {},
334
334
  "source": [
335
- "By default, the workflow tries to load a `TimeOfFlightLookupTable` from a file.\n",
335
+ "By default, the workflow tries to load a `TofLookupTable` from a file.\n",
336
336
  "\n",
337
337
  "In this notebook, instead of using such a pre-made file,\n",
338
338
  "we will build our own lookup table from the chopper information and apply it to the workflow."
@@ -365,7 +365,7 @@
365
365
  "lut_wf[SourcePosition] = source_position\n",
366
366
  "lut_wf[LtotalRange] = Ltotal, Ltotal\n",
367
367
  "lut_wf[LookupTableRelativeErrorThreshold] = 0.1\n",
368
- "lut_wf.visualize(TimeOfFlightLookupTable)"
368
+ "lut_wf.visualize(TofLookupTable)"
369
369
  ]
370
370
  },
371
371
  {
@@ -430,7 +430,7 @@
430
430
  "metadata": {},
431
431
  "outputs": [],
432
432
  "source": [
433
- "table = lut_wf.compute(TimeOfFlightLookupTable)\n",
433
+ "table = lut_wf.compute(TofLookupTable)\n",
434
434
  "\n",
435
435
  "# Overlay mean on the figure above\n",
436
436
  "table.array[\"distance\", 1].plot(ax=fig2.ax, color=\"C1\", ls=\"-\", marker=None)\n",
@@ -463,7 +463,7 @@
463
463
  "metadata": {},
464
464
  "outputs": [],
465
465
  "source": [
466
- "wf[TimeOfFlightLookupTable] = table\n",
466
+ "wf[TofLookupTable] = table\n",
467
467
  "\n",
468
468
  "tofs = wf.compute(TofDetector[SampleRun])\n",
469
469
  "tofs"
@@ -67,7 +67,7 @@ python-dateutil==2.9.0.post0
67
67
  # scippneutron
68
68
  sciline==25.11.1
69
69
  # via -r base.in
70
- scipp==25.11.0
70
+ scipp==25.12.0
71
71
  # via
72
72
  # -r base.in
73
73
  # scippneutron
@@ -99,7 +99,7 @@ python-dateutil==2.9.0.post0
99
99
  # via matplotlib
100
100
  requests==2.32.5
101
101
  # via pooch
102
- scipp==25.11.0
102
+ scipp==25.12.0
103
103
  # via tof
104
104
  scipy==1.16.3
105
105
  # via -r basetest.in
@@ -30,6 +30,8 @@ from .types import (
30
30
  TimeOfFlightLookupTableFilename,
31
31
  ToaDetector,
32
32
  TofDetector,
33
+ TofLookupTable,
34
+ TofLookupTableFilename,
33
35
  TofMonitor,
34
36
  )
35
37
  from .workflow import GenericTofWorkflow
@@ -54,6 +56,8 @@ __all__ = [
54
56
  "TimeResolution",
55
57
  "ToaDetector",
56
58
  "TofDetector",
59
+ "TofLookupTable",
60
+ "TofLookupTableFilename",
57
61
  "TofLookupTableWorkflow",
58
62
  "TofMonitor",
59
63
  "providers",
@@ -35,9 +35,9 @@ from .types import (
35
35
  DetectorLtotal,
36
36
  MonitorLtotal,
37
37
  PulseStrideOffset,
38
- TimeOfFlightLookupTable,
39
38
  ToaDetector,
40
39
  TofDetector,
40
+ TofLookupTable,
41
41
  TofMonitor,
42
42
  )
43
43
 
@@ -96,7 +96,7 @@ class TofInterpolator:
96
96
 
97
97
 
98
98
  def _time_of_flight_data_histogram(
99
- da: sc.DataArray, lookup: TimeOfFlightLookupTable, ltotal: sc.Variable
99
+ da: sc.DataArray, lookup: TofLookupTable, ltotal: sc.Variable
100
100
  ) -> sc.DataArray:
101
101
  # In NeXus, 'time_of_flight' is the canonical name in NXmonitor, but in some files,
102
102
  # it may be called 'tof' or 'frame_time'.
@@ -201,7 +201,7 @@ def _guess_pulse_stride_offset(
201
201
 
202
202
  def _prepare_tof_interpolation_inputs(
203
203
  da: sc.DataArray,
204
- lookup: TimeOfFlightLookupTable,
204
+ lookup: TofLookupTable,
205
205
  ltotal: sc.Variable,
206
206
  pulse_stride_offset: int | None,
207
207
  ) -> dict:
@@ -295,7 +295,7 @@ def _prepare_tof_interpolation_inputs(
295
295
 
296
296
  def _time_of_flight_data_events(
297
297
  da: sc.DataArray,
298
- lookup: TimeOfFlightLookupTable,
298
+ lookup: TofLookupTable,
299
299
  ltotal: sc.Variable,
300
300
  pulse_stride_offset: int | None,
301
301
  ) -> sc.DataArray:
@@ -395,7 +395,7 @@ def monitor_ltotal_from_straight_line_approximation(
395
395
 
396
396
  def _compute_tof_data(
397
397
  da: sc.DataArray,
398
- lookup: TimeOfFlightLookupTable,
398
+ lookup: TofLookupTable,
399
399
  ltotal: sc.Variable,
400
400
  pulse_stride_offset: int,
401
401
  ) -> sc.DataArray:
@@ -413,7 +413,7 @@ def _compute_tof_data(
413
413
 
414
414
  def detector_time_of_flight_data(
415
415
  detector_data: RawDetector[RunType],
416
- lookup: TimeOfFlightLookupTable,
416
+ lookup: TofLookupTable,
417
417
  ltotal: DetectorLtotal[RunType],
418
418
  pulse_stride_offset: PulseStrideOffset,
419
419
  ) -> TofDetector[RunType]:
@@ -447,7 +447,7 @@ def detector_time_of_flight_data(
447
447
 
448
448
  def monitor_time_of_flight_data(
449
449
  monitor_data: RawMonitor[RunType, MonitorType],
450
- lookup: TimeOfFlightLookupTable,
450
+ lookup: TofLookupTable,
451
451
  ltotal: MonitorLtotal[RunType, MonitorType],
452
452
  pulse_stride_offset: PulseStrideOffset,
453
453
  ) -> TofMonitor[RunType, MonitorType]:
@@ -481,7 +481,7 @@ def monitor_time_of_flight_data(
481
481
 
482
482
  def detector_time_of_arrival_data(
483
483
  detector_data: RawDetector[RunType],
484
- lookup: TimeOfFlightLookupTable,
484
+ lookup: TofLookupTable,
485
485
  ltotal: DetectorLtotal[RunType],
486
486
  pulse_stride_offset: PulseStrideOffset,
487
487
  ) -> ToaDetector[RunType]:
@@ -13,7 +13,7 @@ import sciline as sl
13
13
  import scipp as sc
14
14
 
15
15
  from ..nexus.types import AnyRun, DiskChoppers
16
- from .types import TimeOfFlightLookupTable
16
+ from .types import TofLookupTable
17
17
 
18
18
 
19
19
  @dataclass
@@ -230,7 +230,7 @@ def make_tof_lookup_table(
230
230
  pulse_period: PulsePeriod,
231
231
  pulse_stride: PulseStride,
232
232
  error_threshold: LookupTableRelativeErrorThreshold,
233
- ) -> TimeOfFlightLookupTable:
233
+ ) -> TofLookupTable:
234
234
  """
235
235
  Compute a lookup table for time-of-flight as a function of distance and
236
236
  time-of-arrival.
@@ -372,7 +372,7 @@ def make_tof_lookup_table(
372
372
  # In-place masking for better performance
373
373
  _mask_large_uncertainty(table, error_threshold)
374
374
 
375
- return TimeOfFlightLookupTable(
375
+ return TofLookupTable(
376
376
  array=table,
377
377
  pulse_period=pulse_period,
378
378
  pulse_stride=pulse_stride,
@@ -398,13 +398,13 @@ def simulate_chopper_cascade_using_tof(
398
398
  ) -> SimulationResults:
399
399
  """
400
400
  Simulate a pulse of neutrons propagating through a chopper cascade using the
401
- ``tof`` package (https://tof.readthedocs.io).
401
+ ``tof`` package (https://scipp.github.io/tof).
402
402
 
403
403
  Parameters
404
404
  ----------
405
405
  choppers:
406
406
  A dict of DiskChopper objects representing the choppers in the beamline. See
407
- https://scipp.github.io/scippneutron/user-guide/chopper/processing-nexus-choppers.html#Build-DiskChopper
407
+ https://scipp.github.io/scippneutron/user-guide/chopper/processing-nexus-choppers.html
408
408
  for more information.
409
409
  source_position:
410
410
  A scalar variable with ``dtype=vector3`` that defines the source position.
@@ -10,12 +10,15 @@ import scipp as sc
10
10
 
11
11
  from ..nexus.types import MonitorType, RunType
12
12
 
13
- TimeOfFlightLookupTableFilename = NewType("TimeOfFlightLookupTableFilename", str)
13
+ TofLookupTableFilename = NewType("TofLookupTableFilename", str)
14
14
  """Filename of the time-of-flight lookup table."""
15
15
 
16
+ TimeOfFlightLookupTableFilename = TofLookupTableFilename
17
+ """Filename of the time-of-flight lookup table (alias)."""
18
+
16
19
 
17
20
  @dataclass
18
- class TimeOfFlightLookupTable:
21
+ class TofLookupTable:
19
22
  """
20
23
  Lookup table giving time-of-flight as a function of distance and time of arrival.
21
24
  """
@@ -47,6 +50,10 @@ class TimeOfFlightLookupTable:
47
50
  return self.array.plot(*args, **kwargs)
48
51
 
49
52
 
53
+ TimeOfFlightLookupTable = TofLookupTable
54
+ """Lookup table giving time-of-flight as a function of distance and time of arrival
55
+ (alias)."""
56
+
50
57
  PulseStrideOffset = NewType("PulseStrideOffset", int | None)
51
58
  """
52
59
  When pulse-skipping, the offset of the first pulse in the stride. This is typically
@@ -9,14 +9,14 @@ from ..nexus import GenericNeXusWorkflow
9
9
  from . import eto_to_tof
10
10
  from .types import (
11
11
  PulseStrideOffset,
12
- TimeOfFlightLookupTable,
13
- TimeOfFlightLookupTableFilename,
12
+ TofLookupTable,
13
+ TofLookupTableFilename,
14
14
  )
15
15
 
16
16
 
17
17
  def load_tof_lookup_table(
18
- filename: TimeOfFlightLookupTableFilename,
19
- ) -> TimeOfFlightLookupTable:
18
+ filename: TofLookupTableFilename,
19
+ ) -> TofLookupTable:
20
20
  """Load a time-of-flight lookup table from an HDF5 file."""
21
21
  table = sc.io.load_hdf5(filename)
22
22
 
@@ -40,7 +40,7 @@ def load_tof_lookup_table(
40
40
  "error_threshold": table.coords["error_threshold"].value,
41
41
  }
42
42
 
43
- return TimeOfFlightLookupTable(**table)
43
+ return TofLookupTable(**table)
44
44
 
45
45
 
46
46
  def GenericTofWorkflow(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: essreduce
3
- Version: 25.12.1
3
+ Version: 26.1.0
4
4
  Summary: Common data reduction tools for the ESS facility
5
5
  Author: Scipp contributors
6
6
  License-Expression: BSD-3-Clause
@@ -26,7 +26,7 @@ def test_lut_workflow_computes_table():
26
26
  wf[time_of_flight.DistanceResolution] = dres
27
27
  wf[time_of_flight.TimeResolution] = tres
28
28
 
29
- table = wf.compute(time_of_flight.TimeOfFlightLookupTable)
29
+ table = wf.compute(time_of_flight.TofLookupTable)
30
30
 
31
31
  assert table.array.coords['distance'].min() < lmin
32
32
  assert table.array.coords['distance'].max() > lmax
@@ -56,7 +56,7 @@ def test_lut_workflow_computes_table_in_chunks():
56
56
  wf[time_of_flight.DistanceResolution] = dres
57
57
  wf[time_of_flight.TimeResolution] = tres
58
58
 
59
- table = wf.compute(time_of_flight.TimeOfFlightLookupTable)
59
+ table = wf.compute(time_of_flight.TofLookupTable)
60
60
 
61
61
  assert table.array.coords['distance'].min() < lmin
62
62
  assert table.array.coords['distance'].max() > lmax
@@ -85,7 +85,7 @@ def test_lut_workflow_pulse_skipping():
85
85
  wf[time_of_flight.DistanceResolution] = dres
86
86
  wf[time_of_flight.TimeResolution] = tres
87
87
 
88
- table = wf.compute(time_of_flight.TimeOfFlightLookupTable)
88
+ table = wf.compute(time_of_flight.TofLookupTable)
89
89
 
90
90
  assert table.array.coords['event_time_offset'].max() == 2 * sc.scalar(
91
91
  1 / 14, unit='s'
@@ -108,7 +108,7 @@ def test_lut_workflow_non_exact_distance_range():
108
108
  wf[time_of_flight.DistanceResolution] = dres
109
109
  wf[time_of_flight.TimeResolution] = tres
110
110
 
111
- table = wf.compute(time_of_flight.TimeOfFlightLookupTable)
111
+ table = wf.compute(time_of_flight.TofLookupTable)
112
112
 
113
113
  assert table.array.coords['distance'].min() < lmin
114
114
  assert table.array.coords['distance'].max() > lmax
@@ -75,9 +75,7 @@ def _make_workflow_event_mode(
75
75
  lut_wf[time_of_flight.LtotalRange] = distance, distance
76
76
  lut_wf[time_of_flight.LookupTableRelativeErrorThreshold] = error_threshold
77
77
 
78
- pl[time_of_flight.TimeOfFlightLookupTable] = lut_wf.compute(
79
- time_of_flight.TimeOfFlightLookupTable
80
- )
78
+ pl[time_of_flight.TofLookupTable] = lut_wf.compute(time_of_flight.TofLookupTable)
81
79
 
82
80
  return pl, ref
83
81
 
@@ -104,9 +102,7 @@ def _make_workflow_histogram_mode(dim, distance, choppers, lut_workflow, seed):
104
102
  lut_wf = lut_workflow.copy()
105
103
  lut_wf[time_of_flight.LtotalRange] = distance, distance
106
104
 
107
- pl[time_of_flight.TimeOfFlightLookupTable] = lut_wf.compute(
108
- time_of_flight.TimeOfFlightLookupTable
109
- )
105
+ pl[time_of_flight.TofLookupTable] = lut_wf.compute(time_of_flight.TofLookupTable)
110
106
 
111
107
  return pl, ref
112
108
 
@@ -340,9 +336,7 @@ def test_pulse_skipping_unwrap_when_first_half_of_first_pulse_is_missing() -> No
340
336
  pl[RawDetector[SampleRun]] = a.bins.concat('event_time_zero')
341
337
  pl[time_of_flight.DetectorLtotal[SampleRun]] = distance
342
338
 
343
- pl[time_of_flight.TimeOfFlightLookupTable] = lut_wf.compute(
344
- time_of_flight.TimeOfFlightLookupTable
345
- )
339
+ pl[time_of_flight.TofLookupTable] = lut_wf.compute(time_of_flight.TofLookupTable)
346
340
  pl[time_of_flight.PulseStrideOffset] = 1 # Start the stride at the second pulse
347
341
 
348
342
  tofs = pl.compute(time_of_flight.TofDetector[SampleRun])
@@ -137,9 +137,7 @@ def setup_workflow(
137
137
  lut_wf[time_of_flight.LtotalRange] = ltotal.min(), ltotal.max()
138
138
  lut_wf[time_of_flight.LookupTableRelativeErrorThreshold] = error_threshold
139
139
 
140
- pl[time_of_flight.TimeOfFlightLookupTable] = lut_wf.compute(
141
- time_of_flight.TimeOfFlightLookupTable
142
- )
140
+ pl[time_of_flight.TofLookupTable] = lut_wf.compute(time_of_flight.TofLookupTable)
143
141
  return pl
144
142
 
145
143
 
@@ -70,7 +70,7 @@ def test_TofLookupTableWorkflow_can_compute_tof_lut():
70
70
  sc.scalar(100.0, unit="m"),
71
71
  )
72
72
  wf[time_of_flight.SourcePosition] = fakes.source_position()
73
- lut = wf.compute(time_of_flight.TimeOfFlightLookupTable)
73
+ lut = wf.compute(time_of_flight.TofLookupTable)
74
74
  assert lut.array is not None
75
75
  assert lut.distance_resolution is not None
76
76
  assert lut.time_resolution is not None
@@ -95,7 +95,7 @@ def test_GenericTofWorkflow_with_tof_lut_from_tof_simulation(
95
95
  _ = wf.compute(RawDetector[SampleRun])
96
96
  # By default, the workflow tries to load the LUT from file
97
97
  with pytest.raises(sciline.UnsatisfiedRequirement):
98
- _ = wf.compute(time_of_flight.TimeOfFlightLookupTable)
98
+ _ = wf.compute(time_of_flight.TofLookupTable)
99
99
  with pytest.raises(sciline.UnsatisfiedRequirement):
100
100
  _ = wf.compute(time_of_flight.TofDetector[SampleRun])
101
101
 
@@ -107,9 +107,9 @@ def test_GenericTofWorkflow_with_tof_lut_from_tof_simulation(
107
107
  sc.scalar(100.0, unit="m"),
108
108
  )
109
109
  lut_wf[time_of_flight.SourcePosition] = fakes.source_position()
110
- table = lut_wf.compute(time_of_flight.TimeOfFlightLookupTable)
110
+ table = lut_wf.compute(time_of_flight.TofLookupTable)
111
111
 
112
- wf[time_of_flight.TimeOfFlightLookupTable] = table
112
+ wf[time_of_flight.TofLookupTable] = table
113
113
  # Should now be able to compute DetectorData with chopper and simulation params
114
114
  detector = wf.compute(time_of_flight.TofDetector[SampleRun])
115
115
  assert 'tof' in detector.bins.coords
@@ -128,20 +128,18 @@ def test_GenericTofWorkflow_with_tof_lut_from_file(
128
128
  sc.scalar(100.0, unit="m"),
129
129
  )
130
130
  lut_wf[time_of_flight.SourcePosition] = fakes.source_position()
131
- lut = lut_wf.compute(time_of_flight.TimeOfFlightLookupTable)
131
+ lut = lut_wf.compute(time_of_flight.TofLookupTable)
132
132
  lut.save_hdf5(filename=tmp_path / "lut.h5")
133
133
 
134
134
  wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])
135
135
  wf[EmptyDetector[SampleRun]] = calibrated_beamline
136
136
  wf[NeXusData[snx.NXdetector, SampleRun]] = nexus_data
137
- wf[time_of_flight.TimeOfFlightLookupTableFilename] = (
138
- tmp_path / "lut.h5"
139
- ).as_posix()
137
+ wf[time_of_flight.TofLookupTableFilename] = (tmp_path / "lut.h5").as_posix()
140
138
  # Unused because calibrated_beamline contains Ltotal but needed by wf structure
141
139
  wf[Position[snx.NXsample, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
142
140
  wf[Position[snx.NXsource, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
143
141
 
144
- loaded_lut = wf.compute(time_of_flight.TimeOfFlightLookupTable)
142
+ loaded_lut = wf.compute(time_of_flight.TofLookupTable)
145
143
  assert_identical(lut.array, loaded_lut.array)
146
144
  assert_identical(lut.pulse_period, loaded_lut.pulse_period)
147
145
  assert lut.pulse_stride == loaded_lut.pulse_stride
@@ -167,7 +165,7 @@ def test_GenericTofWorkflow_with_tof_lut_from_file_old_format(
167
165
  sc.scalar(100.0, unit="m"),
168
166
  )
169
167
  lut_wf[time_of_flight.SourcePosition] = fakes.source_position()
170
- lut = lut_wf.compute(time_of_flight.TimeOfFlightLookupTable)
168
+ lut = lut_wf.compute(time_of_flight.TofLookupTable)
171
169
  old_lut = sc.DataArray(
172
170
  data=lut.array.data,
173
171
  coords={
@@ -182,6 +180,73 @@ def test_GenericTofWorkflow_with_tof_lut_from_file_old_format(
182
180
  )
183
181
  old_lut.save_hdf5(filename=tmp_path / "lut.h5")
184
182
 
183
+ wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])
184
+ wf[EmptyDetector[SampleRun]] = calibrated_beamline
185
+ wf[NeXusData[snx.NXdetector, SampleRun]] = nexus_data
186
+ wf[time_of_flight.TofLookupTableFilename] = (tmp_path / "lut.h5").as_posix()
187
+ # Unused because calibrated_beamline contains Ltotal but needed by wf structure
188
+ wf[Position[snx.NXsample, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
189
+ wf[Position[snx.NXsource, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
190
+
191
+ loaded_lut = wf.compute(time_of_flight.TofLookupTable)
192
+ assert_identical(lut.array, loaded_lut.array)
193
+ assert_identical(lut.pulse_period, loaded_lut.pulse_period)
194
+ assert lut.pulse_stride == loaded_lut.pulse_stride
195
+ assert_identical(lut.distance_resolution, loaded_lut.distance_resolution)
196
+ assert_identical(lut.time_resolution, loaded_lut.time_resolution)
197
+ assert lut.error_threshold == loaded_lut.error_threshold
198
+ assert loaded_lut.choppers is None # No chopper info in old format
199
+
200
+ detector = wf.compute(time_of_flight.TofDetector[SampleRun])
201
+ assert 'tof' in detector.bins.coords
202
+
203
+
204
+ def test_GenericTofWorkflow_with_tof_lut_from_tof_simulation_using_alias(
205
+ calibrated_beamline: sc.DataArray, nexus_data: sc.DataArray
206
+ ):
207
+ wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])
208
+ wf[EmptyDetector[SampleRun]] = calibrated_beamline
209
+ wf[NeXusData[snx.NXdetector, SampleRun]] = nexus_data
210
+ # Unused because calibrated_beamline contains Ltotal but needed by wf structure
211
+ wf[Position[snx.NXsample, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
212
+ wf[Position[snx.NXsource, SampleRun]] = sc.vector([1e10, 1e10, 1e10], unit='m')
213
+
214
+ # Should be able to compute DetectorData without chopper and simulation params
215
+ # This contains event_time_offset (time-of-arrival).
216
+ _ = wf.compute(RawDetector[SampleRun])
217
+
218
+ lut_wf = TofLookupTableWorkflow()
219
+ lut_wf[DiskChoppers[AnyRun]] = fakes.psc_choppers()
220
+ lut_wf[time_of_flight.NumberOfSimulatedNeutrons] = 10_000
221
+ lut_wf[time_of_flight.LtotalRange] = (
222
+ sc.scalar(0.0, unit="m"),
223
+ sc.scalar(100.0, unit="m"),
224
+ )
225
+ lut_wf[time_of_flight.SourcePosition] = fakes.source_position()
226
+ table = lut_wf.compute(time_of_flight.TimeOfFlightLookupTable)
227
+
228
+ wf[time_of_flight.TimeOfFlightLookupTable] = table
229
+ # Should now be able to compute DetectorData with chopper and simulation params
230
+ detector = wf.compute(time_of_flight.TofDetector[SampleRun])
231
+ assert 'tof' in detector.bins.coords
232
+
233
+
234
+ def test_GenericTofWorkflow_with_tof_lut_from_file_using_alias(
235
+ calibrated_beamline: sc.DataArray,
236
+ nexus_data: sc.DataArray,
237
+ tmp_path: pytest.TempPathFactory,
238
+ ):
239
+ lut_wf = TofLookupTableWorkflow()
240
+ lut_wf[DiskChoppers[AnyRun]] = fakes.psc_choppers()
241
+ lut_wf[time_of_flight.NumberOfSimulatedNeutrons] = 10_000
242
+ lut_wf[time_of_flight.LtotalRange] = (
243
+ sc.scalar(0.0, unit="m"),
244
+ sc.scalar(100.0, unit="m"),
245
+ )
246
+ lut_wf[time_of_flight.SourcePosition] = fakes.source_position()
247
+ lut = lut_wf.compute(time_of_flight.TimeOfFlightLookupTable)
248
+ lut.save_hdf5(filename=tmp_path / "lut.h5")
249
+
185
250
  wf = GenericTofWorkflow(run_types=[SampleRun], monitor_types=[])
186
251
  wf[EmptyDetector[SampleRun]] = calibrated_beamline
187
252
  wf[NeXusData[snx.NXdetector, SampleRun]] = nexus_data
@@ -199,7 +264,7 @@ def test_GenericTofWorkflow_with_tof_lut_from_file_old_format(
199
264
  assert_identical(lut.distance_resolution, loaded_lut.distance_resolution)
200
265
  assert_identical(lut.time_resolution, loaded_lut.time_resolution)
201
266
  assert lut.error_threshold == loaded_lut.error_threshold
202
- assert loaded_lut.choppers is None # No chopper info in old format
267
+ assert_identical(lut.choppers, loaded_lut.choppers)
203
268
 
204
269
  detector = wf.compute(time_of_flight.TofDetector[SampleRun])
205
270
  assert 'tof' in detector.bins.coords
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes