essdiffraction 26.6.1__tar.gz → 26.8.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 (134) hide show
  1. {essdiffraction-26.6.1/src/essdiffraction.egg-info → essdiffraction-26.8.0}/PKG-INFO +4 -2
  2. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/conf.py +2 -2
  3. essdiffraction-26.8.0/docs/user-guide/beer/beer_powder_mcstas_analytical.ipynb +345 -0
  4. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/beer/index.md +15 -0
  5. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/common/vanadium_processing.ipynb +1 -1
  6. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/workflow-widget-dream.ipynb +1 -1
  7. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/pyproject.toml +3 -1
  8. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/data.py +26 -1
  9. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/io/__init__.py +2 -1
  10. essdiffraction-26.8.0/src/ess/dream/io/_common.py +21 -0
  11. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/io/cif.py +4 -9
  12. essdiffraction-26.8.0/src/ess/dream/io/xye.py +36 -0
  13. {essdiffraction-26.6.1 → essdiffraction-26.8.0/src/essdiffraction.egg-info}/PKG-INFO +4 -2
  14. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/essdiffraction.egg-info/SOURCES.txt +3 -0
  15. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/essdiffraction.egg-info/requires.txt +3 -1
  16. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/essdiffraction.egg-info/scm_file_list.json +87 -84
  17. essdiffraction-26.8.0/src/essdiffraction.egg-info/scm_version.json +8 -0
  18. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/geant4_reduction_test.py +5 -0
  19. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/io/cif_test.py +47 -2
  20. essdiffraction-26.6.1/src/essdiffraction.egg-info/scm_version.json +0 -8
  21. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/.copier-answers.ess.yml +0 -0
  22. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/.copier-answers.yml +0 -0
  23. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/LICENSE +0 -0
  24. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/README.md +0 -0
  25. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/anaconda-icon.js +0 -0
  26. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/essdiffraction-search-logo.png +0 -0
  27. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/favicon.svg +0 -0
  28. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/logo-dark.svg +0 -0
  29. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/logo.svg +0 -0
  30. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/beer_mcstas_dark.svg +0 -0
  31. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/beer_mcstas_light.svg +0 -0
  32. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/dream_advanced_powder_reduction_dark.svg +0 -0
  33. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/dream_advanced_powder_reduction_light.svg +0 -0
  34. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/dream_basic_powder_reduction_dark.svg +0 -0
  35. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_static/thumbnails/dream_basic_powder_reduction_light.svg +0 -0
  36. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_templates/class-template.rst +0 -0
  37. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_templates/doc_version.html +0 -0
  38. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_templates/layout.html +0 -0
  39. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/_templates/module-template.rst +0 -0
  40. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/about/bibliography.rst +0 -0
  41. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/about/index.md +0 -0
  42. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/api-reference/index.md +0 -0
  43. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/bibliography.bib +0 -0
  44. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/developer/coding-conventions.md +0 -0
  45. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/developer/dependency-management.md +0 -0
  46. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/developer/getting-started.md +0 -0
  47. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/developer/index.md +0 -0
  48. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/index.md +0 -0
  49. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/beer/beer_modulation_mcstas.ipynb +0 -0
  50. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/common/index.md +0 -0
  51. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-advanced-powder-reduction.ipynb +0 -0
  52. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-detector-diagnostics.ipynb +0 -0
  53. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-instrument-view.ipynb +0 -0
  54. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-make-wavelength-lookup-table.ipynb +0 -0
  55. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-powder-reduction.ipynb +0 -0
  56. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/dream-visualize-absorption.ipynb +0 -0
  57. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/dream/index.md +0 -0
  58. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/index.md +0 -0
  59. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/installation.md +0 -0
  60. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/magic/index.md +0 -0
  61. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/sns-instruments/POWGEN_data_reduction.ipynb +0 -0
  62. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/docs/user-guide/sns-instruments/index.md +0 -0
  63. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/resources/logo.svg +0 -0
  64. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/setup.cfg +0 -0
  65. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/__init__.py +0 -0
  66. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/clustering.py +0 -0
  67. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/conversions.py +0 -0
  68. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/io.py +0 -0
  69. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/mcstas/__init__.py +0 -0
  70. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/mcstas/beamline.py +0 -0
  71. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/mcstas/load.py +0 -0
  72. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/peakfinding.py +0 -0
  73. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/types.py +0 -0
  74. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/beer/workflow.py +0 -0
  75. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/diffraction/__init__.py +0 -0
  76. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/diffraction/pdf.py +0 -0
  77. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/diffraction/peaks.py +0 -0
  78. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/diffraction/py.typed +0 -0
  79. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/__init__.py +0 -0
  80. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/beamline.py +0 -0
  81. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/data.py +0 -0
  82. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/diagnostics.py +0 -0
  83. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/instrument_view.py +0 -0
  84. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/io/geant4.py +0 -0
  85. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/parameters.py +0 -0
  86. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/py.typed +0 -0
  87. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/dream/workflows.py +0 -0
  88. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/magic/__init__.py +0 -0
  89. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/magic/beamline.py +0 -0
  90. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/magic/data.py +0 -0
  91. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/magic/types.py +0 -0
  92. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/magic/workflow.py +0 -0
  93. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/__init__.py +0 -0
  94. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/_util.py +0 -0
  95. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/calibration.py +0 -0
  96. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/conversion.py +0 -0
  97. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/correction.py +0 -0
  98. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/filtering.py +0 -0
  99. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/grouping.py +0 -0
  100. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/logging.py +0 -0
  101. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/masking.py +0 -0
  102. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/py.typed +0 -0
  103. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/smoothing.py +0 -0
  104. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/types.py +0 -0
  105. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/powder/workflow.py +0 -0
  106. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/__init__.py +0 -0
  107. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/beamline.py +0 -0
  108. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/calibration.py +0 -0
  109. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/data.py +0 -0
  110. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/instrument_view.py +0 -0
  111. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/peaks.py +0 -0
  112. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/ess/snspowder/powgen/workflow.py +0 -0
  113. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/essdiffraction.egg-info/dependency_links.txt +0 -0
  114. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/src/essdiffraction.egg-info/top_level.txt +0 -0
  115. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/beer/mcstas_beamline_test.py +0 -0
  116. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/beer/mcstas_reduction_test.py +0 -0
  117. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/conftest.py +0 -0
  118. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/diffraction/pdf_test.py +0 -0
  119. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/diffraction/peaks_test.py +0 -0
  120. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/diagnostics_test.py +0 -0
  121. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/instrument_view_test.py +0 -0
  122. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/io/geant4_test.py +0 -0
  123. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/dream/workflows/dream_generic_workflow_test.py +0 -0
  124. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/magic/workflow_test.py +0 -0
  125. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/package_test.py +0 -0
  126. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/powder/conversion_test.py +0 -0
  127. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/powder/correction_test.py +0 -0
  128. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/powder/filtering_test.py +0 -0
  129. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/snspowder/powgen/load_test.py +0 -0
  130. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tests/snspowder/powgen/powgen_reduction_test.py +0 -0
  131. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tools/docs/beer-thumbnails.ipynb +0 -0
  132. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tools/docs/dream-thumbnails.ipynb +0 -0
  133. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tools/preprocess_pg3_files.ipynb +0 -0
  134. {essdiffraction-26.6.1 → essdiffraction-26.8.0}/tools/shrink_nexus.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: essdiffraction
3
- Version: 26.6.1
3
+ Version: 26.8.0
4
4
  Summary: Diffraction data reduction for the European Spallation Source
5
5
  Author: Scipp contributors
6
6
  License-Expression: BSD-3-Clause
@@ -25,7 +25,6 @@ Requires-Dist: graphviz>=0.20
25
25
  Requires-Dist: essreduce>=26.6.0
26
26
  Requires-Dist: numpy>=2
27
27
  Requires-Dist: plopp>=26.5.0
28
- Requires-Dist: pythreejs>=2.4.1
29
28
  Requires-Dist: tof>=25.12.0
30
29
  Requires-Dist: ncrystal[cif]>=4.1.0
31
30
  Requires-Dist: spglib!=2.7,>=2.0.0
@@ -34,6 +33,8 @@ Requires-Dist: pandas>=2.1.2; extra == "test"
34
33
  Requires-Dist: pooch>=1.5; extra == "test"
35
34
  Requires-Dist: pytest>=7.0; extra == "test"
36
35
  Requires-Dist: ipywidgets>=8.1.7; extra == "test"
36
+ Requires-Dist: anywidget>=0.8.0; extra == "test"
37
+ Requires-Dist: pythreejs>=2.4.1; extra == "test"
37
38
  Provides-Extra: docs
38
39
  Requires-Dist: autodoc-pydantic>=2.0.0; extra == "docs"
39
40
  Requires-Dist: ipykernel>=6.20.0; extra == "docs"
@@ -50,6 +51,7 @@ Requires-Dist: sphinx-copybutton>=0.5.2; extra == "docs"
50
51
  Requires-Dist: sphinx-design>=0.5.0; extra == "docs"
51
52
  Requires-Dist: sphinxcontrib-bibtex>=2.5.0; extra == "docs"
52
53
  Requires-Dist: pyarrow>=12.0.0; extra == "docs"
54
+ Requires-Dist: pythreejs>=2.4.1; extra == "docs"
53
55
  Dynamic: license-file
54
56
 
55
57
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
@@ -74,7 +74,7 @@ intersphinx_mapping = {
74
74
  "pydantic": ("https://docs.pydantic.dev/latest", None),
75
75
  "python": ("https://docs.python.org/3", None),
76
76
  # Scipp:
77
- "essreduce": ("https://scipp.github.io/essreduce", None),
77
+ "essreduce": ("https://scipp.github.io/ess/reduce", None),
78
78
  "plopp": ("https://scipp.github.io/plopp", None),
79
79
  "sciline": ("https://scipp.github.io/sciline", None),
80
80
  "scipp": ("https://scipp.github.io/", None),
@@ -181,7 +181,7 @@ html_theme_options = {
181
181
  "image_dark": "_static/logo-dark.svg",
182
182
  },
183
183
  "external_links": [
184
- {"name": "ESSreduce", "url": "https://scipp.github.io/essreduce"},
184
+ {"name": "ESSreduce", "url": "https://scipp.github.io/ess/reduce"},
185
185
  {"name": "Plopp", "url": "https://scipp.github.io/plopp"},
186
186
  {"name": "Sciline", "url": "https://scipp.github.io/sciline"},
187
187
  {"name": "Scipp", "url": "https://scipp.github.io"},
@@ -0,0 +1,345 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "0",
6
+ "metadata": {},
7
+ "source": [
8
+ "# BEER McStas powder data reduction\n",
9
+ "\n",
10
+ "- Audience: BEER users reducing McStas pulse-shaping powder data\n",
11
+ "- Prerequisites: Basic knowledge of Scipp and Sciline workflows\n",
12
+ "\n",
13
+ "This guide reduces a McStas silicon-in-vanadium-can sample run using matching vanadium and empty-can runs. The result is `EmptyCanSubtractedIofDspacing`, the normalized intensity as a function of $d$-spacing after subtracting the empty can."
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "markdown",
18
+ "id": "1",
19
+ "metadata": {},
20
+ "source": [
21
+ "The example files are downloaded through the ESSdiffraction data registry. To run the notebook you will have to install `pooch` to access them: `pip install pooch`."
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "code",
26
+ "execution_count": null,
27
+ "id": "2",
28
+ "metadata": {},
29
+ "outputs": [],
30
+ "source": [
31
+ "%matplotlib ipympl\n",
32
+ "import scipp as sc\n",
33
+ "\n",
34
+ "from ess import beer, powder\n",
35
+ "import ess.beer.data # noqa: F401\n",
36
+ "from ess.beer.types import DetectorBank\n",
37
+ "from ess.diffraction.peaks import dspacing_peaks_from_cif\n",
38
+ "from ess.powder.types import *"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "markdown",
43
+ "id": "3",
44
+ "metadata": {},
45
+ "source": [
46
+ "## Configure the workflow\n",
47
+ "\n",
48
+ "Start with the BEER powder McStas workflow and set the run files. We use monitor-histogram normalization here because the McStas files include a wavelength monitor."
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "id": "4",
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "workflow = beer.BeerPowderMcStasWorkflowAnalytical(\n",
59
+ " run_norm=powder.RunNormalization.monitor_histogram\n",
60
+ ")\n",
61
+ "\n",
62
+ "workflow[Filename[SampleRun]] = beer.data.mcstas_powder_silicon_in_vanadium_can()\n",
63
+ "workflow[Filename[VanadiumRun]] = beer.data.mcstas_powder_vanadium()\n",
64
+ "workflow[Filename[EmptyCanRun]] = beer.data.mcstas_powder_empty_can()"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "markdown",
69
+ "id": "5",
70
+ "metadata": {},
71
+ "source": [
72
+ "Next set the detector bank and the $d$-spacing range. The notebook only reduces the north bank and only histograms the range from 0.6 Å to 2.0 Å."
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "code",
77
+ "execution_count": null,
78
+ "id": "6",
79
+ "metadata": {},
80
+ "outputs": [],
81
+ "source": [
82
+ "workflow[DetectorBank] = DetectorBank.north\n",
83
+ "workflow[DspacingBins] = sc.linspace(\"dspacing\", 0.6, 2.0, 701, unit=\"angstrom\")"
84
+ ]
85
+ },
86
+ {
87
+ "cell_type": "markdown",
88
+ "id": "7",
89
+ "metadata": {},
90
+ "source": [
91
+ "To keep the events in the output, to allow post reduction filtering or other processing, set `KeepEvents` to `True`."
92
+ ]
93
+ },
94
+ {
95
+ "cell_type": "code",
96
+ "execution_count": null,
97
+ "id": "8",
98
+ "metadata": {},
99
+ "outputs": [],
100
+ "source": [
101
+ "workflow[KeepEvents[SampleRun]] = KeepEvents(True)\n",
102
+ "workflow[KeepEvents[VanadiumRun]] = KeepEvents(True)\n",
103
+ "workflow[KeepEvents[EmptyCanRun]] = KeepEvents(True)\n",
104
+ "\n",
105
+ "workflow[MaskedDetectorIDs] = MaskedDetectorIDs({})\n",
106
+ "workflow[UncertaintyBroadcastMode] = UncertaintyBroadcastMode.drop"
107
+ ]
108
+ },
109
+ {
110
+ "cell_type": "markdown",
111
+ "id": "9",
112
+ "metadata": {},
113
+ "source": [
114
+ "A finer region of interest can be applied with the standard powder masks. Mask callables return `True` for values to remove. This example keeps a broad two-theta range for the selected detector data and leaves the other masks disabled."
115
+ ]
116
+ },
117
+ {
118
+ "cell_type": "code",
119
+ "execution_count": null,
120
+ "id": "10",
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "two_theta_min = sc.scalar(76.0, unit=\"deg\").to(unit=\"rad\")\n",
125
+ "two_theta_max = sc.scalar(104.0, unit=\"deg\").to(unit=\"rad\")\n",
126
+ "\n",
127
+ "workflow[TwoThetaMask] = lambda two_theta: (two_theta < two_theta_min) | (\n",
128
+ " two_theta > two_theta_max\n",
129
+ ")\n",
130
+ "workflow[TofMask] = None\n",
131
+ "workflow[WavelengthMask] = None"
132
+ ]
133
+ },
134
+ {
135
+ "cell_type": "markdown",
136
+ "id": "11",
137
+ "metadata": {},
138
+ "source": [
139
+ "Some events can have ambiguous wavelength assignments. We first keep all detector events so the baseline spectrum shows the full result."
140
+ ]
141
+ },
142
+ {
143
+ "cell_type": "code",
144
+ "execution_count": null,
145
+ "id": "12",
146
+ "metadata": {},
147
+ "outputs": [],
148
+ "source": [
149
+ "workflow[LookupTableRelativeErrorThreshold] = {\n",
150
+ " \"detector\": float(\"inf\"),\n",
151
+ " \"monitor_bunker\": float(\"inf\"),\n",
152
+ " \"monitor_cave\": float(\"inf\"),\n",
153
+ "}"
154
+ ]
155
+ },
156
+ {
157
+ "cell_type": "markdown",
158
+ "id": "13",
159
+ "metadata": {},
160
+ "source": [
161
+ "## Compute the empty-can-subtracted spectrum"
162
+ ]
163
+ },
164
+ {
165
+ "cell_type": "code",
166
+ "execution_count": null,
167
+ "id": "14",
168
+ "metadata": {},
169
+ "outputs": [],
170
+ "source": [
171
+ "iof_dspacing = workflow.compute(EmptyCanSubtractedIofDspacing)\n",
172
+ "histogram = iof_dspacing.hist()\n",
173
+ "histogram"
174
+ ]
175
+ },
176
+ {
177
+ "cell_type": "markdown",
178
+ "id": "15",
179
+ "metadata": {},
180
+ "source": [
181
+ "Compute the expected silicon peak positions from the CIF and draw the peaks that fall in the plotted $d$ range."
182
+ ]
183
+ },
184
+ {
185
+ "cell_type": "code",
186
+ "execution_count": null,
187
+ "id": "16",
188
+ "metadata": {},
189
+ "outputs": [],
190
+ "source": [
191
+ "silicon_peaks = dspacing_peaks_from_cif(\"codid::1526655\").coords[\"dspacing\"]\n",
192
+ "silicon_peaks = silicon_peaks[\n",
193
+ " (silicon_peaks > histogram.coords[\"dspacing\"].min())\n",
194
+ " & (silicon_peaks < histogram.coords[\"dspacing\"].max())\n",
195
+ "]\n",
196
+ "\n",
197
+ "fig = histogram.plot(\n",
198
+ " title=\"Intensity over dspacing\",\n",
199
+ " xlabel=r\"$d$-spacing [$\\AA$]\",\n",
200
+ " ylabel=f\"Intensity [{histogram.unit}]\",\n",
201
+ " xmin=sc.scalar(0.6, unit=\"angstrom\"),\n",
202
+ " xmax=sc.scalar(2.0, unit=\"angstrom\"),\n",
203
+ ")\n",
204
+ "\n",
205
+ "ymin, ymax = fig.ax.get_ylim()\n",
206
+ "for peak in silicon_peaks.values:\n",
207
+ " fig.ax.axvline(peak, color=\"black\", alpha=0.25, linewidth=1)\n",
208
+ "\n",
209
+ "fig.ax.set_ylim(ymin, ymax)\n",
210
+ "fig"
211
+ ]
212
+ },
213
+ {
214
+ "cell_type": "markdown",
215
+ "id": "17",
216
+ "metadata": {},
217
+ "source": [
218
+ "## Reduce frame-overlap artifacts\n",
219
+ "\n",
220
+ "The detector wavelength-assignment relative-error threshold removes events in regions where the wavelength assignment is ambiguous. The thresholds are set separately for the detector and the monitors."
221
+ ]
222
+ },
223
+ {
224
+ "cell_type": "code",
225
+ "execution_count": null,
226
+ "id": "18",
227
+ "metadata": {},
228
+ "outputs": [],
229
+ "source": [
230
+ "thresholded_workflow = workflow.copy()\n",
231
+ "thresholded_workflow[LookupTableRelativeErrorThreshold] = {\n",
232
+ " \"detector\": 0.005,\n",
233
+ " \"monitor_bunker\": float(\"inf\"),\n",
234
+ " \"monitor_cave\": float(\"inf\"),\n",
235
+ "}\n",
236
+ "\n",
237
+ "thresholded_histogram = thresholded_workflow.compute(\n",
238
+ " EmptyCanSubtractedIofDspacing\n",
239
+ ").hist()"
240
+ ]
241
+ },
242
+ {
243
+ "cell_type": "markdown",
244
+ "id": "19",
245
+ "metadata": {},
246
+ "source": [
247
+ "The threshold removes events in specific regions of scattering angle and wavelength. We can see this directly by comparing `CorrectedDetector` before and after applying the threshold."
248
+ ]
249
+ },
250
+ {
251
+ "cell_type": "code",
252
+ "execution_count": null,
253
+ "id": "20",
254
+ "metadata": {},
255
+ "outputs": [],
256
+ "source": [
257
+ "unfiltered_detector = workflow.compute(CorrectedDetector[SampleRun])\n",
258
+ "filtered_detector = thresholded_workflow.compute(CorrectedDetector[SampleRun])\n",
259
+ "\n",
260
+ "two_theta_bins = sc.linspace(\"two_theta\", 76.0, 104.0, 201, unit=\"deg\").to(\n",
261
+ " unit=\"rad\"\n",
262
+ ")\n",
263
+ "wavelength_bins = sc.linspace(\"wavelength\", 0.8, 3.2, 241, unit=\"angstrom\")\n",
264
+ "\n",
265
+ "unfiltered_map = unfiltered_detector.hist(\n",
266
+ " two_theta=two_theta_bins,\n",
267
+ " wavelength=wavelength_bins,\n",
268
+ " dim=unfiltered_detector.dims,\n",
269
+ ")\n",
270
+ "filtered_map = filtered_detector.hist(\n",
271
+ " two_theta=two_theta_bins,\n",
272
+ " wavelength=wavelength_bins,\n",
273
+ " dim=filtered_detector.dims,\n",
274
+ ")"
275
+ ]
276
+ },
277
+ {
278
+ "cell_type": "code",
279
+ "execution_count": null,
280
+ "id": "21",
281
+ "metadata": {},
282
+ "outputs": [],
283
+ "source": [
284
+ "filtered_map.plot(title=\"Kept by threshold\", norm=\"log\")"
285
+ ]
286
+ },
287
+ {
288
+ "cell_type": "code",
289
+ "execution_count": null,
290
+ "id": "22",
291
+ "metadata": {},
292
+ "outputs": [],
293
+ "source": [
294
+ "(unfiltered_map - filtered_map).plot(title=\"Removed by threshold\", norm=\"log\")"
295
+ ]
296
+ },
297
+ {
298
+ "cell_type": "code",
299
+ "execution_count": null,
300
+ "id": "23",
301
+ "metadata": {},
302
+ "outputs": [],
303
+ "source": [
304
+ "fig = sc.plot(\n",
305
+ " {\n",
306
+ " \"baseline\": histogram,\n",
307
+ " \"detector relative error < 0.02\": thresholded_histogram,\n",
308
+ " },\n",
309
+ " xlabel=r\"$d$-spacing [$\\AA$]\",\n",
310
+ " ylabel=f\"Intensity [{histogram.unit}]\",\n",
311
+ " xmin=sc.scalar(0.6, unit=\"angstrom\"),\n",
312
+ " xmax=sc.scalar(2.0, unit=\"angstrom\"),\n",
313
+ ")\n",
314
+ "\n",
315
+ "ymin, ymax = fig.ax.get_ylim()\n",
316
+ "for peak in silicon_peaks.values:\n",
317
+ " fig.ax.axvline(peak, color=\"black\", alpha=0.25, linewidth=1)\n",
318
+ "\n",
319
+ "fig.ax.set_ylim(ymin, ymax)\n",
320
+ "fig"
321
+ ]
322
+ }
323
+ ],
324
+ "metadata": {
325
+ "kernelspec": {
326
+ "display_name": "Python 3 (ipykernel)",
327
+ "language": "python",
328
+ "name": "python3"
329
+ },
330
+ "language_info": {
331
+ "codemirror_mode": {
332
+ "name": "ipython",
333
+ "version": 3
334
+ },
335
+ "file_extension": ".py",
336
+ "mimetype": "text/x-python",
337
+ "name": "python",
338
+ "nbconvert_exporter": "python",
339
+ "pygments_lexer": "ipython3",
340
+ "version": "3.11.13"
341
+ }
342
+ },
343
+ "nbformat": 4,
344
+ "nbformat_minor": 5
345
+ }
@@ -18,6 +18,20 @@
18
18
  ```
19
19
  :::
20
20
 
21
+ :::{grid-item-card} Powder McStas data reduction
22
+ :link: beer_powder_mcstas_analytical.ipynb
23
+ :text-align: center
24
+
25
+ ```{image} ../../_static/thumbnails/beer_mcstas_light.svg
26
+ :class: only-light
27
+ :width: 75%
28
+ ```
29
+ ```{image} ../../_static/thumbnails/beer_mcstas_dark.svg
30
+ :class: only-dark
31
+ :width: 75%
32
+ ```
33
+ :::
34
+
21
35
  ::::
22
36
 
23
37
  ```{toctree}
@@ -26,4 +40,5 @@ hidden:
26
40
  ---
27
41
 
28
42
  beer_modulation_mcstas
43
+ beer_powder_mcstas_analytical
29
44
  ```
@@ -196,7 +196,7 @@
196
196
  "Importantly, we remove variances from the data.\n",
197
197
  "If we kept the variances, subtracting the fitted models would introduce correlations between the data points.\n",
198
198
  "This corresponds to [UncertaintyBroadcastMode.drop](../../generated/modules/ess.powder.types.UncertaintyBroadcastMode.rst) in the main workflow.\n",
199
- "See also the [guide in ESSreduce](https://scipp.github.io/essreduce/user-guide/reduction-workflow-guidelines.html#s-8-propagation-of-uncertainties-in-broadcast-operations-should-support-drop-and-upper-bound-strategies-upper-bound-shall-be-the-default)."
199
+ "See also the [guide in ESSreduce](https://scipp.github.io/ess/reduce/user-guide/reduction-workflow-guidelines.html#s-8-propagation-of-uncertainties-in-broadcast-operations-should-support-drop-and-upper-bound-strategies-upper-bound-shall-be-the-default)."
200
200
  ]
201
201
  },
202
202
  {
@@ -7,7 +7,7 @@
7
7
  "source": [
8
8
  "# Workflow widgets example\n",
9
9
  "\n",
10
- "This notebook illustrates how we can use ESSreduce's [workflow widgets](https://scipp.github.io/essreduce/user-guide/widget.html) to generate a graphical interface for running the [DREAM GEANT4 workflow](./dream-powder-reduction.rst).\n",
10
+ "This notebook illustrates how we can use ESSreduce's [workflow widgets](https://scipp.github.io/ess/reduce/user-guide/widget.html) to generate a graphical interface for running the [DREAM GEANT4 workflow](./dream-powder-reduction.rst).\n",
11
11
  "\n",
12
12
  "## Initializing the GUI\n",
13
13
  "\n",
@@ -34,7 +34,6 @@ dependencies = [
34
34
  "essreduce>=26.6.0",
35
35
  "numpy>=2",
36
36
  "plopp>=26.5.0",
37
- "pythreejs>=2.4.1",
38
37
  "tof>=25.12.0",
39
38
  "ncrystal[cif]>=4.1.0",
40
39
  "spglib>=2.0.0,!=2.7", # https://github.com/mctools/ncrystal/issues/320
@@ -48,6 +47,8 @@ test = [
48
47
  "pooch>=1.5",
49
48
  "pytest>=7.0",
50
49
  "ipywidgets>=8.1.7",
50
+ "anywidget>=0.8.0",
51
+ "pythreejs>=2.4.1",
51
52
  ]
52
53
  docs = [
53
54
  "autodoc-pydantic>=2.0.0",
@@ -67,6 +68,7 @@ docs = [
67
68
  "sphinxcontrib-bibtex>=2.5.0",
68
69
  # needed by pandas < 3.0
69
70
  "pyarrow>=12.0.0",
71
+ "pythreejs>=2.4.1",
70
72
  ]
71
73
 
72
74
  [project.urls]
@@ -8,7 +8,13 @@ import scipp as sc
8
8
 
9
9
  from ess.reduce.data import make_registry
10
10
 
11
- __all__ = ["mcstas_duplex", "mcstas_silicon_medium_resolution"]
11
+ __all__ = [
12
+ "mcstas_duplex",
13
+ "mcstas_powder_empty_can",
14
+ "mcstas_powder_silicon_in_vanadium_can",
15
+ "mcstas_powder_vanadium",
16
+ "mcstas_silicon_medium_resolution",
17
+ ]
12
18
 
13
19
  _registry = make_registry(
14
20
  "ess/beer",
@@ -46,6 +52,10 @@ _registry = make_registry(
46
52
  # - only used to verify we can load the 3D geometry.
47
53
  "few_neutrons_3d_detector_example.h5": "md5:88cbe29cb539c8acebf9fd7cee9d3c57",
48
54
  "silicon-mode9-3d-more-neutrons.h5": "md5:a6afdc4ee9827a57f88c2a3c6ef27383",
55
+ # Pulse-shaping powder diffraction simulation tutorial data.
56
+ "beer-powder-si-in-vcan-mode4.h5": "md5:7c1ba0fb0b2bb812ff59d0e4e1021ef7",
57
+ "beer-powder-vanadium-mode4.h5": "md5:17eed50ddf979789259b212d0be15f37",
58
+ "beer-powder-empty-can-mode4.h5": "md5:c374d5a8379749fb807b8f835291ce18",
49
59
  },
50
60
  )
51
61
 
@@ -79,6 +89,21 @@ def mcstas_silicon_new_model(mode: int) -> Path:
79
89
  return _registry.get_path(f'silicon-mode{mode}-new-model.h5')
80
90
 
81
91
 
92
+ def mcstas_powder_silicon_in_vanadium_can() -> Path:
93
+ """Return the BEER McStas silicon-in-vanadium-can powder sample file."""
94
+ return _registry.get_path('beer-powder-si-in-vcan-mode4.h5')
95
+
96
+
97
+ def mcstas_powder_vanadium() -> Path:
98
+ """Return the BEER McStas powder vanadium normalization file."""
99
+ return _registry.get_path('beer-powder-vanadium-mode4.h5')
100
+
101
+
102
+ def mcstas_powder_empty_can() -> Path:
103
+ """Return the BEER McStas powder empty-can file."""
104
+ return _registry.get_path('beer-powder-empty-can-mode4.h5')
105
+
106
+
82
107
  def mcstas_few_neutrons_3d_detector_example():
83
108
  return _registry.get_path('few_neutrons_3d_detector_example.h5')
84
109
 
@@ -5,7 +5,8 @@
5
5
 
6
6
  from .cif import prepare_reduced_tof_cif
7
7
  from .geant4 import load_geant4_csv
8
+ from .xye import save_xye
8
9
 
9
10
  providers = (prepare_reduced_tof_cif,)
10
11
 
11
- __all__ = ["load_geant4_csv", "prepare_reduced_tof_cif", "providers"]
12
+ __all__ = ["load_geant4_csv", "prepare_reduced_tof_cif", "providers", "save_xye"]
@@ -0,0 +1,21 @@
1
+ # SPDX-License-Identifier: BSD-3-Clause
2
+ # Copyright (c) 2026 Scipp contributors (https://github.com/scipp)
3
+
4
+ import scipp as sc
5
+ from scipp.core import irreducible_mask
6
+
7
+
8
+ def prepare_reduced_data(da: sc.DataArray) -> sc.DataArray:
9
+ """Prepare reduced data for saving."""
10
+ if da.ndim != 1:
11
+ raise sc.DimensionError(f"Can only save 1D data, got {da.sizes}")
12
+
13
+ hist = da.hist() if da.is_binned else da.copy(deep=False)
14
+ hist.coords[hist.dim] = sc.midpoints(hist.coords[hist.dim])
15
+
16
+ if (mask := irreducible_mask(hist.masks, hist.dim)) is not None:
17
+ # No file format we use here supports masks, so we remove masked data points
18
+ hist = hist[~mask]
19
+ hist.masks.clear()
20
+
21
+ return hist
@@ -1,9 +1,8 @@
1
1
  # SPDX-License-Identifier: BSD-3-Clause
2
- # Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
2
+ # Copyright (c) 2026 Scipp contributors (https://github.com/scipp)
3
3
 
4
4
  """CIF writer for DREAM."""
5
5
 
6
- import scipp as sc
7
6
  from ess.powder.calibration import OutputCalibrationData
8
7
  from ess.powder.types import (
9
8
  Beamline,
@@ -19,6 +18,8 @@ from ess.powder.types import (
19
18
  )
20
19
  from scippneutron.io import cif
21
20
 
21
+ from ._common import prepare_reduced_data
22
+
22
23
 
23
24
  def prepare_reduced_tof_cif(
24
25
  da: IntensityTof,
@@ -126,7 +127,7 @@ def _prepare_reduced_tof_cif_impl(
126
127
  reducers: ReducerSoftware,
127
128
  calibration: OutputCalibrationData,
128
129
  ) -> ReducedTofCIF:
129
- to_save = _prepare_data(da)
130
+ to_save = prepare_reduced_data(da)
130
131
  return ReducedTofCIF(
131
132
  cif.CIF('reduced_tof')
132
133
  .with_measurement(measurement)
@@ -136,9 +137,3 @@ def _prepare_reduced_tof_cif_impl(
136
137
  .with_powder_calibration(calibration.to_cif_format())
137
138
  .with_reduced_powder_data(to_save)
138
139
  )
139
-
140
-
141
- def _prepare_data(da: sc.DataArray) -> sc.DataArray:
142
- hist = da.copy(deep=False) if da.bins is None else da.hist()
143
- hist.coords[hist.dim] = sc.midpoints(hist.coords[hist.dim])
144
- return hist
@@ -0,0 +1,36 @@
1
+ # SPDX-License-Identifier: BSD-3-Clause
2
+ # Copyright (c) 2026 Scipp contributors (https://github.com/scipp)
3
+
4
+ """XYE writer for DREAM."""
5
+
6
+ import scippneutron as scn
7
+ from ess.powder.types import IntensityTof, OutFilename
8
+
9
+ from ._common import prepare_reduced_data
10
+
11
+
12
+ def save_xye(filename: OutFilename, da: IntensityTof) -> None:
13
+ """Save reduced data to an XYE file.
14
+
15
+ This function can be used as
16
+
17
+ .. code-block:: python
18
+
19
+ from ess.powder.types import OutFilename
20
+ from ess.dream.io import save_xye
21
+
22
+ workflow = ...
23
+ workflow[OutFilename] = "..."
24
+ workflow.bind_and_call(save_xye)
25
+
26
+ Note that this function is not suitable as a provider as it
27
+ has side effects (writes a file).
28
+
29
+ Parameters
30
+ ----------
31
+ filename:
32
+ Path of a file to write to.
33
+ da:
34
+ Reduced 1d data with a ``'tof'`` dimension and coordinate.
35
+ """
36
+ scn.io.save_xye(filename, prepare_reduced_data(da), coord="tof")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: essdiffraction
3
- Version: 26.6.1
3
+ Version: 26.8.0
4
4
  Summary: Diffraction data reduction for the European Spallation Source
5
5
  Author: Scipp contributors
6
6
  License-Expression: BSD-3-Clause
@@ -25,7 +25,6 @@ Requires-Dist: graphviz>=0.20
25
25
  Requires-Dist: essreduce>=26.6.0
26
26
  Requires-Dist: numpy>=2
27
27
  Requires-Dist: plopp>=26.5.0
28
- Requires-Dist: pythreejs>=2.4.1
29
28
  Requires-Dist: tof>=25.12.0
30
29
  Requires-Dist: ncrystal[cif]>=4.1.0
31
30
  Requires-Dist: spglib!=2.7,>=2.0.0
@@ -34,6 +33,8 @@ Requires-Dist: pandas>=2.1.2; extra == "test"
34
33
  Requires-Dist: pooch>=1.5; extra == "test"
35
34
  Requires-Dist: pytest>=7.0; extra == "test"
36
35
  Requires-Dist: ipywidgets>=8.1.7; extra == "test"
36
+ Requires-Dist: anywidget>=0.8.0; extra == "test"
37
+ Requires-Dist: pythreejs>=2.4.1; extra == "test"
37
38
  Provides-Extra: docs
38
39
  Requires-Dist: autodoc-pydantic>=2.0.0; extra == "docs"
39
40
  Requires-Dist: ipykernel>=6.20.0; extra == "docs"
@@ -50,6 +51,7 @@ Requires-Dist: sphinx-copybutton>=0.5.2; extra == "docs"
50
51
  Requires-Dist: sphinx-design>=0.5.0; extra == "docs"
51
52
  Requires-Dist: sphinxcontrib-bibtex>=2.5.0; extra == "docs"
52
53
  Requires-Dist: pyarrow>=12.0.0; extra == "docs"
54
+ Requires-Dist: pythreejs>=2.4.1; extra == "docs"
53
55
  Dynamic: license-file
54
56
 
55
57
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
@@ -31,6 +31,7 @@ docs/developer/index.md
31
31
  docs/user-guide/index.md
32
32
  docs/user-guide/installation.md
33
33
  docs/user-guide/beer/beer_modulation_mcstas.ipynb
34
+ docs/user-guide/beer/beer_powder_mcstas_analytical.ipynb
34
35
  docs/user-guide/beer/index.md
35
36
  docs/user-guide/common/index.md
36
37
  docs/user-guide/common/vanadium_processing.ipynb
@@ -70,8 +71,10 @@ src/ess/dream/parameters.py
70
71
  src/ess/dream/py.typed
71
72
  src/ess/dream/workflows.py
72
73
  src/ess/dream/io/__init__.py
74
+ src/ess/dream/io/_common.py
73
75
  src/ess/dream/io/cif.py
74
76
  src/ess/dream/io/geant4.py
77
+ src/ess/dream/io/xye.py
75
78
  src/ess/magic/__init__.py
76
79
  src/ess/magic/beamline.py
77
80
  src/ess/magic/data.py